which translates forwards and backwards, no problem.
- 'properties' - a way to annotate or otherwise mark private fields
so that vanilla get, set, and optionally, addPropertyListener, is
generated. The only question in translating back and forth is where
the getter and setter methods should show up in the code
(alphabetically sorted, inserted right below the field? grouped?).
It's not quite the full blown properties that Joe wants, but its a
step in the right direction.
- list and map literals.
- default parameter values.
- map foreach (for (K key, V value : someMap) { /* code */ } instead
of using Map.Entry directly ).
- infer type for local final variables (just 'final foo = "hello"; is
valid).
Answers inline. On Oct 10, 9:44 am, "Viktor Klang" <viktor.kl...@gmail.com> wrote:Why not: Thread({/*Code*/}) ?Because that's not CICE.
- infer type for local final variables (just 'final foo = "hello"; is valid).
In regards to the annoyance of explicit checked exceptions and closures: oh, yeah - sure. Checked exceptions are annoying in the context of closures. Scratch that: Checked exceptions are annoying generally. The theory behind it is definitely sound, and proper usage of them would have been great, but 90% of all java libraries, including java core, does not use checked/unchecked exceptions correctly. We should get rid of them. But that's not for java.next to decide (at least not v1.0) - AGAIN, that's far too much of a change. That's a step that something on the scale of Scala should take. So, you're not getting the point of this exercise.
public <T,E> T call() throws E;where E can represent 0 or more throwable types. Allowing this to propagate up a generic stack so that you can just pass something that throws E to a body of code that throws F and express that this body of code will then throw E and F would make generic code more reusable.
Frankly I really dislike the idea of inferring types in this context, but I guess there are those who like this. I'm all for addressing all the cases where one has to respecify types that are obvious on the right side of the equals, though.
Yes. What I don't like about this is that:Also, don't forget that an IDE can figure all this out for you; floating over 'someMethodCall()' in a good IDE should tell you that its a String.Similarly, floating over the variable name should do the same thing in a java.next aware IDE. This is part of the polish I was talking about, adding stuff like this. I know there's a common argument that 'code should be readable even without an IDE', but, frankly, I think that's bull; java code fundamentally isn't very readable without tools to help you navigate the quagmire. With tools, java is unbeaten in how easy it is to navigate. Play to your strengths, don't try to cover a weakness that realisitically isn't going away.
System.out.println( someMethodCall() );but that only impacts the single line -- and once they call someMethodCall() twice most folk are smart enough to stick it in a local variable instead of calling it repeatedly. Allowing
final foo = someMethodCall();encourages these downsides to be propagated throughout dozens and dozens of usages of 'foo' and thus has a more corrosive effect.
This is an important issue, because there's no waffling on this. Because things get translated back and forth, in java.next, if this final inference thing is in, it would be IMPOSSIBLE to write: final String foo = someMethodCall(); after all, on save this gets stored in the .java file as per the above, and then on load, the pattern detector will eliminate the 'String' part when it realizes that the return type of the call is the same as the type of the variable. Other than magic comments (Which as I mentioned, are out, at least for this sort of thing), there's no way to store this on disk in a way to differentiate.
I'm not talking about Java Joe, I'm talking star developers leaving the sinking Java-ship, and putting some lipstick on the pig ain't gonna have them staying onboard.
That kind of attitude is not useful to this project, unfortunately.
Your insinuation that e.g. inference of everything is clearly superior
to java will for example instantly lose Jess Holle; he'll never join
your side until you've become very mainstream. A lot of language
nuts / scala converts forget this point.
I'm not sure how feasible all of these are via source re-writing -- I'll honestly say I just didn't ponder that question long for each of these. Some strike me as less than amenable to this approach (e.g. #8 in particular).Here are my suggestions:
If you can't specify "I don't care about nullness", it would be -
impossible-, given the following code:
List<X> list = someMethodThatReturnsAStringList();
list.add("foo");
in such a way that the method can return either a list of strings-or-
nulls, or a list of definitely-not-null-strings.
Eventhough, given the only thing it does is add a non-null string, it
doesn't matter.
I'm pretty much positive not being able to do that makes this feature
very stupid.
No; it doesn't. The above means that 'list.add(null);' should be
On Oct 15, 3:04 pm, "Viktor Klang" <viktor.kl...@gmail.com> wrote:
> This expands to:
>
> List?<X?> list = someMethodThatReturnsAStringList();
> list.add("foo");
legal. This is a meaningful property of a type, but it does come with
caveats. Specifically, if the 'someMethodThatReturnsAStringList'
method returns a list that does not allow nulls, this should be a
compile-time error.
There's really no way that I can see to get around
the notion that you need 3 different properties in generics
parameters:
A. Definitely allows null, (benefit: Can write nulls in)
B. Definitely does not allow null (benefit: No need to null-check when
reading)
C. Don't know / Don't care if its allowed (benefit: Accept anything)
Yes, but, now try to work with these. As you said before, '?? extends
Foo' is general purpose: It's compatible with ?! extends Foo..
However, neither ?! super Foo, nor ?? super Foo, are general
purpose. ?! cannot be assigned to ?? because, obviously, ?? would
allow you to add nulls to this list.
However, ?? cannot be assigned to ?! either. Okay, sure, when adding
things this works out fine (forced to add non-null, so that's great),
but, you can still read from these things; you just get Object back.
However, in the case of ?! super Foo, it would be really -really-
strange if "Object?" instead of "Object!" rolled out.
Now try this with no bounds, just a type, e.g "List<String>". Without
all three modifiers (non-null, definitely null, unknown), you just
can't cover all reasonable use cases.
Inline...
That's the goal, yes, but, look at the backwash against generics. It
On Oct 21, 1:55 pm, "Viktor Klang" <viktor.kl...@gmail.com> wrote:
>
> If many of the ugly if-checks are eliminated, and many NPEs are avoided, I
> would be rather surprised if LoC wouldn't drop drastically (even though the
> "problem" mentioned above)
has to be pretty perfect.
No, that makes no sense. <? extends Foo> would yield Foo or Foo! ; ?
>
> List!<?! super Foo>.get(0) would yield either an OOBE or Foo! (and Foo! can
> be autocasted to Foo?)
super Foo 'yields' Object.
You can *ADD* "Foo" to it. Assuming you meanet that List<?! super
Foo>.get(0) yields an OOBE or Object!, then...
we have a problem. If we do that, then <?! super Foo> is not capable
of holding a <?? super Foo>. Contrast this to extends, where we've
proven that:
<?? extends Foo> is capable of holding a <?! extends Foo> without any
issues.
We can solve the problem by letting the rarely used get()-style
operation (return type of T) in combination with <?! super Foo> return
T? and not T!, but that makes very little sense; why would ?! return
non-! - that's kind of weird.
No - try writing a non-particular generics bound (non-particular in
>
>
>
> > Now try this with no bounds, just a type, e.g "List<String>". Without
> > all three modifiers (non-null, definitely null, unknown), you just
> > can't cover all reasonable use cases.
>
> List<String> is syntactic sugar for List?<String?> :)
the sense of nullness). You've got 3 options here, and they are all
vastly different and incompatible:
String! - can not be null (advantage: you can read out without null-
checks).
String? - can be null (advantage: you can write nulls into this thing)
String- - can be either, you don't know (advantage: You can accept
either String! or String?).
Again, not having that third option sounds to me like a recipe for
utter disaster. It's not only generally annoying, but in light of the
fact that legacy code will lead to lots of situations where types have
the wrong type of nullity, it seems extremely important to be able to
write flexible methods that accept either.
It's good - no doubt about it. Just like generics was good - no doubt
>
> So, if we boil it down, what are the benefits and drawbacks?
>
about it. The drawback is, that it's just as complicated as generics,
with just as much funky syntax. The one advantage, due to limited
types (specifically, only three types: non-null, allows-null, unknown-
null), is that I foresee far fewer 'puzzlers'.
The problem you point out doesn't seem specific to the String!/String?
relationship. You get the same problem with any subtyping relationship
already.
I must admit I didn't study your previous discussion about the ??/?!
in all detail (due to time constraints -- sorry), but why wouldn't a
(relatively) simple List<? extends String?> as formal parameter type
do the trick? Since String? allows all values String! allows, String!
should classify as subtype.
Of course that doesn't guarantee the client the safety of not having
nulls, but it seems the author of the method doesn't want to give that
guarantee, which is unfortunate for the client but the author's right
in the type system we discuss.
Admittably explaining all the combinations of <(\?[\?|!]?
[super|extends] )?X[\?|!]?> (untested RegExp, but hopefully good
enough to give the idea) would keep Angelika Langer busy for a while
adding another few dozen pages to her FAQ. And some combinations are
nonsensical, such as requesting a nullable subtype of a non-nullable
type and its dual (both would be the empty set of types, even
excluding the named type). But an approach like the proposed one seems
doable to me.
Peter
--
What happened to Schroedinger's cat? My invisible saddled white dragon ate it.
Viktor, I mean no offense, but that 'solution' is going to send the
torches and pitchforks to sun. That's not a solution at all. You want
to create a view method for every class that has a generics bound,
everywhere? What about generics in generics? e.g. List<Set<Foo>>?
I hadn't noticed the blog post before my last post to the list due to
inbox ordering, but I've read it now.
If you have a List<? extends String?> it allows both a List<String?>
and a List<String!> (and the List<String>, too). You couldn't add
nulls to a List<? extends String?>, but you would have to expect them.
It's really the same as with any List<? extends X> once you start
thinking of String! as a subtype of String?, which seems perfectly
valid to me.
More interesting is what the relation between String and String? is:
extensionally they are both the same type, and in some way I prefer
treating them that way, considering the question mark only as
syntactic sugar. Arguing about type differences based only on
intentional difference seems asking for trouble and disagrees
completly with my thinking (which is heavily influenced by Formal
Concept Analysis and other conceptual modelling approaches).
I would always consider two types with the same extention in the
universe of discourse as the same for the purpose of whatever you are
doing. If they do not separate anything in your world, any difference
is irrelevant (others might use the word "academic" here).
So in short my proposal would be:
- introduce "T!" as a notation for non-nullable types
- consider T! as subtype of T for all purposes
- allow "T?" as syntactic variation of "T"
And that should be it. T as well as T? are legacy for me, the whole
problem with the other variants should be solvable using the
mechanisms generics already offers. Admittably it ain't pretty, but
that's Java's generics for you -- adding other features to avoid
generics for those use cases seems to just add to the cruft.
The one drawback you could find in my approach is that with allowing
nulls you would always allow any other subtype, but for me that's only
consistent. In many ways null is an instance of the bottom type, i.e.
of the subtype of all types. The Java compiler sees it that way
already and even if the JVM doesn't and it screws up everything
DbC/LSP it seems sensible to stick with that idea. Once you have
accepted that, you might as well allow anything in the interval
between your T and the bottom if you allow nulls, it seems consistent
to me since I can't see any subtype object being worse than null.
I'm not entirely sure if this is only radical or maybe plainly naive,
but so far this model seems the best to me -- I have been thinking
this way for a while and it still seems the least evil solution (the
only good one being disallowing nulls which unfortunately doesn't seem
feasible).
Peter