I like the new language features a lot, but I don't like the proposed syntax. I thought the great thing about Java was that it got us away from the awful C++ punctuation soup. Here's my proposal for a more readable syntax without adding new keywords to the language:
for each (Item i in collection) { ... }
'for' is already a keyword. By separating this, we can part this production as:
ForStatement: for Identifier ( Type VariableDeclaratorId Identifier Expression ) Statement
(Using the productions and terminals in the JLS).
Note that, after the first 'for' is encountered, the parser can look at the next token (right-paren or Identifier) to determine whether this is a 'for each' or an old-style 'for' statement. We don't need to make 'each' or 'in' into an keyword, and they don't conflict with variable, method, or class names. Semantic checking will simply ensure that the Identifiers mentioned have the appropriate contents.
The '&' is not otherwise allowed in parameterized types before 'extends', so there is no grammar ambiguity. The Identifier following & in this production is checked to be only 'subclasses' or 'superclasses' (otherwise a syntax error). There is no conflict with class names, because Set<Integer & Foo> is not a legal use for a class named 'Foo'.
To save typing, perhaps 'subclasses'/'superclasses' can be shortened to 'sub'/'super' without sacrificing readability. I expect invariant types will still be most-heavily used, so I don't think fingers will be hurting all that much.
Perhaps this Identifier-not-keyword idea can be taken further with some of the other new grammar productions? I await suggestions!
Not going to say I complete understand what you are getting at because I really haven't bothered learning the proposed generic syntax but let me ask one question.
Set<Integer & subclasses>
Isn't the above assumed? I mean when a method accepts a java.util.Date I can give it a java.sql.Date.
Set<Integer & superclasses>
Here's the heart of your idea. My question is, if any instance of any superclass is allowed and every class is derived from Object, isn't this allowing anything? It evaulates to allowing instances of Object.
I'm not very enthusiastic about using identifiers as a sort of pseudo reserved word. Currently so called syntax colouring can be done with simple lexical analysis. I would not like to see the 'each', 'in', etc coloured as identifiers in these contexts because that doesn't really reflect their use.
The difficulty of adding 'foreach' as a reserved word is probably less than 'assert' was, while 'in' is a much more difficult proposition. I think I would prefer the compromise
foreach (Item i: collection) {}
While I sympathize with your dislike of the variance syntax, I'm not convinced that your proposal is better. Sorry.
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 10:18 AM
(reply 3
of 60) (In reply to
#1 )
Not going to say I complete understand what you are getting at because I really haven't bothered learning the proposed generic syntax but let me ask one question.
Read the papers on variance. In a nutshell, a generic type A<X> is not related to the generic type A<Y>, regardless of the relationship between X and Y. Variance changes that and is a proposed addition in the (very) new generics implementation.
I like the new language features a lot, but I don't like the proposed syntax.
Agreed. What you've proposed is a definite improvement, and I'd take it in a second over the current syntax. I'm not convinced, though, that we couldn't do even better. (I know - lame criticism).
Note that, after the first 'for' is encountered, the
parser can look at the next token (right-paren or
Identifier) to determine whether this is a 'for each'
or an old-style 'for' statement. We don't need to
There's the primary problem right there.
People in the compiler community hate look ahead because it causes nasty issues. Recall recent discussions in this forum over how much trouble <List<Map>> gives them because it can be ambiguos with a >> b.
Unfortunately its been years since my compiler courses, so I'll have to leave it to someone who works actively to post a more detailed rationale. Unless I'm mistaken they won't go for a solution that requires look-ahead though.
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 10:56 AM
(reply 6
of 60) (In reply to
#3 )
Read the papers on variance. In a nutshell, a generic
type A<X> is not related to the generic type A<Y>,
regardless of the relationship between X and Y.
Variance changes that and is a proposed addition in
the (very) new generics implementation.
I find your comment confusing. Maybe I am misunderstanding the OPs intentions with this syntax.
Right now:
List<java.util.Date> is a List that only allows instances of java.util.Date. I can still add a java.sql.Date to this list, though, because an instance java.sql.Date is an instance of java.util.Date.
His proposal:
List<String & superclasses> Now given the current syntax, I would take this to mean that this defines a List that takes instances of String and an instances of any superclass of String i.e. instances of Object i.e. anything other than primitives.
I think what you are saying is that if I define a method (for example) like so, method(List<java.util.Date>) that I can't pass an List<java.sql.Date> to it. Understood, though I find that puzzling because that means an method that accepts a List shouldn't accept a List<String>. I didn't see anything in the OPs post that makes me think that is the context which this syntax would be used though it could be. Clarification would be nice.
In that context, however, List<String & superclasses> would still be quite useless because wouldn't it still evaluate to a method that accepts a List<Object>? What would be the value of rejecting more specifc List types but allow the most generic List type?
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 11:14 AM
(reply 7
of 60) (In reply to
#6 )
<i>I find your comment confusing.</i>
The OP is suggesting a change in syntax for the new variance language change. Rather then describe variance in detail to you, let me suggest again that you read the papers on variance.
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 11:18 AM
(reply 8
of 60) (In reply to
#5 )
Unfortunately its been years since my compiler
courses, so I'll have to leave it to someone who works
actively to post a more detailed rationale. Unless I'm
mistaken they won't go for a solution that requires
look-ahead though.
Um, I've written LALR(1) grammars for Java and JSR-14. See
http://cag.lcs.mit.edu/~cananian/Projects/GJ/
So I know what I'm talking about: the proposed syntax will not have grammar problems.
After you've passed the 'for' the token you're looking at is not actually "lookahead" in the technical sense of the term. It's the current token.
Besides, it's arbitrary lookahead which gives parsers problems. Any finite amount of lookahead is easily handled by known techniques. The 'jikes' compiler, for example, uses an LALR(N) parser generator; the 'N' means that any fixed amount of lookahead can be accomodated.
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 11:18 AM
(reply 9
of 60) (In reply to
#6 )
List<String & superclasses> Now given the current
syntax, I would take this to mean that this defines a
List that takes instances of String and an instances
of any superclass of String i.e. instances of Object
i.e. anything other than primitives.
Although I think your message ended up in the wrong forum, this is a cruical point, and I missed it at first too. As I now understand it:
List<-String> means
List<String> or List<Object>
List<Integer> is not allowed to be assigned to List<-String>.
It means String and strictly its super types, not anything that happens to be a subclass of any of them.
Similarly
List<-Integer> allows List<Integer>, List<Number>, List<Object>, but NOT List<Double>, List<Short> etc...
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 11:19 AM
(reply 10
of 60) (In reply to
#7 )
The OP is suggesting a change in syntax for the new
variance language change. Rather then describe
variance in detail to you, let me suggest again that
you read the papers on variance.
Did you ignore the rest of what I posted or do you not understand it. Where in the OPs post does he state that the context this applies to is the same as you the context are assuming it applies to?
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 11:26 AM
(reply 11
of 60) (In reply to
#9 )
Although I think your message ended up in the wrong
forum, this is a cruical point, and I missed it at
first too. As I now understand it:
List<-String> means
List<String> or List<Object>
List<Integer> is not allowed to be assigned to
List<-String>.
It means String and strictly its super types, not
anything that happens to be a subclass of any of
them.
Similarly
List<-Integer> allows List<Integer>, List<Number>,
List<Object>, but NOT List<Double>, List<Short> etc...
Thank you for the explanation. Now my question is, what is the value of List<-Integer>? Sure I can't assign a List<String> to it, but I can assign a List<Object> filled with Strings. Can you explain why this is useful?
Re: A plea for a readable Java (for each, Set<Integer & subclasses>)
May 30, 2003 11:26 AM
(reply 12
of 60) (In reply to
#8 )
Um, I've written LALR(1) grammars for Java and JSR-14.
Besides, it's arbitrary lookahead which gives
parsers problems. Any finite amount of lookahead is
easily handled by known techniques. The 'jikes'
compiler, for example, uses an LALR(N) parser
generator; the 'N' means that any fixed amount of
lookahead can be accomodated.
Ah. Apologies. In that case you're exactly the sort of person I was hoping would comment one way or the other. I even read some of your earlier posts on the LALR(1) stuff, though clearly not closely enough to associate them with your name yet. I should have checked who was speaking.
I must say I find the whole topic a bit of a non-issue though. C's for loop syntax is probably among the least readable syntax anyway. I grew up seeing for loops which looked like this:
for n = 1 to 100 step 10
Obviously those are nowhere near as flexible as C's "while loop with syntactic sugar" approach, but I find worrying about 'for (x : xs)' difficult when you look at how unreadable 'for( expr ; expr ; expr )' already is. In any case 'x : xs' seems quite natural, but that's probably because I've done some functional programing in my time.