From sean.drucker at frameworkplus.com Tue Sep 1 09:30:38 2009 From: sean.drucker at frameworkplus.com (Sean R. Drucker) Date: Tue, 01 Sep 2009 11:30:38 -0500 Subject: Proposal: Automatic Resource Management References: 15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com Message-ID: <4A9D4C2E.8020606@frameworkPLUS.com> Automatic Resource Management should also apply to an Iterator that implements Disposable and is used in the enhanced for-each. So, if an Iterator is connected to JDBC, once iteration ends, the close method is called: for (Row row: database.getIterable()) { ... } So, when the iterator() method is called on database, if it implements Disposable, then it should be disposed. Thanks... Sean From neal at gafter.com Tue Sep 1 14:23:24 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 1 Sep 2009 14:23:24 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <4A9D4C2E.8020606@frameworkPLUS.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> Message-ID: <15e8b9d20909011423i35e04a36sd8c36de832496439@mail.gmail.com> That's an excellent point. Hopefully the proposal will evolve as required. On Tue, Sep 1, 2009 at 9:30 AM, Sean R. Drucker < sean.drucker at frameworkplus.com> wrote: > Automatic Resource Management should also apply to an Iterator that > implements Disposable and is used in the enhanced for-each. So, if > an Iterator is connected to JDBC, once iteration ends, the close method > is called: > > > for (Row row: database.getIterable()) { > ... > } > > So, when the iterator() method is called on database, if it implements > Disposable, then it should be disposed. > > Thanks... Sean > > > > From jjb at google.com Tue Sep 1 14:51:07 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 1 Sep 2009 14:51:07 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <4A9D4C2E.8020606@frameworkPLUS.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> Message-ID: <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> Sean, Thanks for the suggestion. Josh On Tue, Sep 1, 2009 at 9:30 AM, Sean R. Drucker < sean.drucker at frameworkplus.com> wrote: > Automatic Resource Management should also apply to an Iterator that > implements Disposable and is used in the enhanced for-each. So, if > an Iterator is connected to JDBC, once iteration ends, the close method > is called: > > > for (Row row: database.getIterable()) { > ... > } > > So, when the iterator() method is called on database, if it implements > Disposable, then it should be disposed. > > Thanks... Sean > > > > From forax at univ-mlv.fr Tue Sep 1 16:24:44 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 02 Sep 2009 01:24:44 +0200 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> Message-ID: <4A9DAD3C.4040409@univ-mlv.fr> This will require to introduce a new interface IterableDisposable or something like that to ease the use of such pattern. Also note that nio2 API java.nio.file.DirectoryStream is already an iterable/disposable (using Closable instead of Disposable). R?mi Le 01/09/2009 23:51, Joshua Bloch a ?crit : > Sean, > Thanks for the suggestion. > > Josh > > On Tue, Sep 1, 2009 at 9:30 AM, Sean R. Drucker< > sean.drucker at frameworkplus.com> wrote: > > >> Automatic Resource Management should also apply to an Iterator that >> implements Disposable and is used in the enhanced for-each. So, if >> an Iterator is connected to JDBC, once iteration ends, the close method >> is called: >> >> >> for (Row row: database.getIterable()) { >> ... >> } >> >> So, when the iterator() method is called on database, if it implements >> Disposable, then it should be disposed. >> >> Thanks... Sean >> >> >> >> >> > From neal at gafter.com Tue Sep 1 17:13:05 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 1 Sep 2009 17:13:05 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <4A9DAD3C.4040409@univ-mlv.fr> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> Message-ID: <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> On Tue, Sep 1, 2009 at 4:24 PM, R?mi Forax wrote: > This will require to introduce a new interface IterableDisposable or > something like that to ease the use of such pattern. > That's one way to do it. Here are two others: 1. Dynamically test the type of the iterator to see if it extends Disposable. 2. Statically test the static return type of iterableExpression.iterator(), which due to covariance may be a type that extends both Iterable and Disposable. I think (2) works best, so that the compiler can see the exceptions statically thrown by iterableExpression.iterator().close() and the programmer won't have to catch(Exception). Cheers, Neal From sean.drucker at frameworkplus.com Tue Sep 1 19:32:39 2009 From: sean.drucker at frameworkplus.com (Sean R. Drucker) Date: Tue, 01 Sep 2009 21:32:39 -0500 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> Message-ID: <4A9DD947.8090308@frameworkPLUS.com> My suggestion was assuming an implementation like (2). Here is a use case: interface SQLIterator extends Iterator, Disposable { } interface SQLTable extends Iterable { SQLIterator iterator(); } Current usage pattern: public static void current(SQLTable table) throws SQLException { final SQLIterator itr = table.iterator(); try { while (itr.hasNext()) { final Row row = itr.next(); ... } } finally { itr.close(); } } Equivalent using Automatic Resource Management: public static void arm(SQLTable table) throws SQLException { for (final Row row: table) { ... } } The specification added to Disposable would be something like: If an implementation of Iterable.iterator() returns a static type that extends both Iterator and Disposable (which is possible due to covariance), then when an instance of that Iterable is used in a for-each loop, the Iterable.iterator() will always have its Disposable.close() method called after iteration is complete or terminated (either an early return or an iteration exception). Any checked exception X thrown from Disposable.close() will need to be caught or rethrown and will suppress any prior iteration exception. Suppressing exceptions seems reasonable as that is what is done in the current usage pattern. Also, as a practical matter, if a close() method was ever to throw an exception (which is highly rare), it would indicate a far greater problem (usually a lost resource connection) than any problem in the iteration. Thanks... Sean Neal Gafter wrote: > On Tue, Sep 1, 2009 at 4:24 PM, R?mi Forax > wrote: > > This will require to introduce a new interface IterableDisposable or > something like that to ease the use of such pattern. > > > That's one way to do it. Here are two others: > > 1. Dynamically test the type of the iterator to see if it extends > Disposable. > > 2. Statically test the static return type of > iterableExpression.iterator(), which due to covariance may be a type > that extends both Iterable and Disposable. > > I think (2) works best, so that the compiler can see the exceptions > statically thrown by iterableExpression.iterator().close() and the > programmer won't have to catch(Exception). > > Cheers, > Neal > From jjb at google.com Tue Sep 1 19:39:25 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 1 Sep 2009 19:39:25 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <4A9DD947.8090308@frameworkPLUS.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> <4A9DD947.8090308@frameworkPLUS.com> Message-ID: <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> Sean, Perhaps I am missing something, but wouldn't this change the semantics of existing programs? Josh On Tue, Sep 1, 2009 at 7:32 PM, Sean R. Drucker < sean.drucker at frameworkplus.com> wrote: > My suggestion was assuming an implementation like (2). Here is a use case: > > interface SQLIterator extends Iterator, Disposable { > } > > interface SQLTable extends Iterable { > SQLIterator iterator(); > } > > Current usage pattern: > > public static void current(SQLTable table) throws SQLException { > final SQLIterator itr = table.iterator(); > try { > while (itr.hasNext()) { > final Row row = itr.next(); > ... > } > } finally { > itr.close(); > } > } > > Equivalent using Automatic Resource Management: > > public static void arm(SQLTable table) throws SQLException { > for (final Row row: table) { > ... > } > } > > The specification added to Disposable would be something like: > > If an implementation of Iterable.iterator() returns a static type that > extends both Iterator and Disposable (which is possible due to > covariance), then when an instance of that Iterable is used in a for-each > loop, the Iterable.iterator() will always have its Disposable.close() method > called after iteration is complete or terminated (either an early return or > an iteration exception). Any checked exception X thrown from > Disposable.close() will need to be caught or rethrown and will suppress any > prior iteration exception. > > Suppressing exceptions seems reasonable as that is what is done in the > current usage pattern. Also, as a practical matter, if a close() method was > ever to throw an exception (which is highly rare), it would indicate a far > greater problem (usually a lost resource connection) than any problem in the > iteration. > > Thanks... Sean > > Neal Gafter wrote: > > On Tue, Sep 1, 2009 at 4:24 PM, R?mi Forax > forax at univ-mlv.fr>> wrote: >> >> This will require to introduce a new interface IterableDisposable or >> something like that to ease the use of such pattern. >> >> >> That's one way to do it. Here are two others: >> >> 1. Dynamically test the type of the iterator to see if it extends >> Disposable. >> >> 2. Statically test the static return type of >> iterableExpression.iterator(), which due to covariance may be a type that >> extends both Iterable and Disposable. >> >> I think (2) works best, so that the compiler can see the exceptions >> statically thrown by iterableExpression.iterator().close() and the >> programmer won't have to catch(Exception). >> >> Cheers, >> Neal >> >> From neal at gafter.com Tue Sep 1 20:13:47 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 1 Sep 2009 20:13:47 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> <4A9DD947.8090308@frameworkPLUS.com> <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> Message-ID: <15e8b9d20909012013g6637b927x54ca742bae46b177@mail.gmail.com> On Tue, Sep 1, 2009 at 7:39 PM, Joshua Bloch wrote: > Perhaps I am missing something, but wouldn't this change the semantics of > existing programs? > No existing types extend Disposable. From jjb at google.com Tue Sep 1 21:01:34 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 1 Sep 2009 21:01:34 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20909012013g6637b927x54ca742bae46b177@mail.gmail.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> <4A9DD947.8090308@frameworkPLUS.com> <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> <15e8b9d20909012013g6637b927x54ca742bae46b177@mail.gmail.com> Message-ID: <17b2302a0909012101p9309c8ek1396052020ba6675@mail.gmail.com> Neal, Many existing types will be retrofitted to extend Disposable. If such a type also implements Iterable, the semantics of a for-each loop on an instance of the type would change, as I understand Sean's suggestion. Josh On Tue, Sep 1, 2009 at 8:13 PM, Neal Gafter wrote: > On Tue, Sep 1, 2009 at 7:39 PM, Joshua Bloch wrote: > >> Perhaps I am missing something, but wouldn't this change the semantics of >> existing programs? >> > > No existing types extend Disposable. > > From neal at gafter.com Tue Sep 1 22:04:54 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 1 Sep 2009 22:04:54 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0909012101p9309c8ek1396052020ba6675@mail.gmail.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> <4A9DD947.8090308@frameworkPLUS.com> <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> <15e8b9d20909012013g6637b927x54ca742bae46b177@mail.gmail.com> <17b2302a0909012101p9309c8ek1396052020ba6675@mail.gmail.com> Message-ID: <15e8b9d20909012204u2007b685q612564ad553e8e9@mail.gmail.com> On Tue, Sep 1, 2009 at 9:01 PM, Joshua Bloch wrote: > Many existing types will be retrofitted to extend Disposable. If such a > type also implements Iterable, the semantics of a for-each loop on an > instance of the type would change, as I understand Sean's suggestion. > Josh- In theory, yes. However, I doubt you'll find a confluence of events that would cause the change of behavior: (1) an existing implementation of Iterable that make use of covariant returns to (2) return a type that will be retrofitted with Disposable and is (3) used in a for-each loop in some existing client code. If you do find such a case, you've found a resource leak in existing code, and its maintainers should be glad to have the change in behavior. -Neal From sean.drucker at frameworkplus.com Wed Sep 2 00:13:29 2009 From: sean.drucker at frameworkplus.com (Sean R. Drucker) Date: Wed, 02 Sep 2009 02:13:29 -0500 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20909012204u2007b685q612564ad553e8e9@mail.gmail.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> <4A9DD947.8090308@frameworkPLUS.com> <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> <15e8b9d20909012013g6637b927x54ca742bae46b177@mail.gmail.com> <17b2302a0909012101p9309c8ek1396052020ba6675@mail.gmail.com> <15e8b9d20909012204u2007b685q612564ad553e8e9@mail.gmail.com> Message-ID: <4A9E1B19.2030100@frameworkPLUS.com> I didn't consider retrofitting. Two options come to mind: 1. Move the for-each for disposable iterators to the new try syntax: try (Row row: table) { } In addition to table.iterator() being disposed, if Row implements Disposable, then each row would be disposed after each iteration. The variable table would not be disposed unless the following syntax is used: try (Table table = new Table("Ex"); Row row: table) { } 2. Add a DisposableIterator (or similar) interface: interface DisposableIterator extends Iterator, Disposable { } The implementation of Iterable.iterator() would need to be a static class that extends DisposableIterator. Nothing in the existing JDK would be retrofitted with DisposableIterator. Thanks... Sean Neal Gafter wrote: > On Tue, Sep 1, 2009 at 9:01 PM, Joshua Bloch > wrote: > > Many existing types will be retrofitted to extend Disposable. If > such a type also implements Iterable, the semantics of a for-each > loop on an instance of the type would change, as I understand Sean's > suggestion. > > > Josh- > > In theory, yes. However, I doubt you'll find a confluence of events > that would cause the change of behavior: (1) an existing implementation > of Iterable that make use of covariant returns to (2) return a type that > will be retrofitted with Disposable and is (3) used in a for-each loop > in some existing client code. If you do find such a case, you've found > a resource leak in existing code, and its maintainers should be glad to > have the change in behavior. > > -Neal From pbenedict at apache.org Wed Sep 2 08:40:57 2009 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 2 Sep 2009 10:40:57 -0500 Subject: Proposal: Automatic Resource Management Message-ID: Sean, >> In addition to table.iterator() being disposed, if Row implements >> Disposable, then each row would be disposed after each iteration. The >> variable table would not be disposed unless the following syntax is used: >> >> try (Table table = new Table("Ex"); Row row: table) { >> } How about this: try (Table table = new Table("Ex")) { for (Row row : table) { } } Wouldn't this allow the table to be automatically be disposed, plus automatically dispose each row? PS: Josh, didn't you once publish your ARM proposal under http://docs.google.com? I may be wrong, but I thought you kept the most-current copy on the web somewhere. Paul From jjb at google.com Wed Sep 2 08:50:26 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 2 Sep 2009 08:50:26 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: References: Message-ID: <17b2302a0909020850p7df2ccaaq3f9ebedfc669299e@mail.gmail.com> Paul, I believe that this is the most current version: http://docs.google.com/View?id=ddv8ts74_3fs7483dp . Josh On Wed, Sep 2, 2009 at 8:40 AM, Paul Benedict wrote: > Sean, > > >> In addition to table.iterator() being disposed, if Row implements > >> Disposable, then each row would be disposed after each iteration. The > >> variable table would not be disposed unless the following syntax is > used: > >> > >> try (Table table = new Table("Ex"); Row row: table) { > >> } > > How about this: > > try (Table table = new Table("Ex")) { > for (Row row : table) { > } > } > > Wouldn't this allow the table to be automatically be disposed, plus > automatically dispose each row? > > PS: Josh, didn't you once publish your ARM proposal under > http://docs.google.com? I may be wrong, but I thought you kept the > most-current copy on the web somewhere. > > Paul > > From serge.boulay at gmail.com Wed Sep 2 09:15:04 2009 From: serge.boulay at gmail.com (Serge Boulay) Date: Wed, 2 Sep 2009 12:15:04 -0400 Subject: Resource Block from do() { } to try() { } ? Message-ID: <855b507d0909020915o540233e0i6e243c10510cfbb2@mail.gmail.com> What was the reason the resource block changed from the keyword ?do? to the keyword ?try?. Is it possibly more confusing using the ?try? keyword since you can attach a catch and finally clause to the block or was this intended for some reason? What is the scope of exceptions in that block ? From serge_boulay at hotmail.com Wed Sep 2 06:11:27 2009 From: serge_boulay at hotmail.com (serge Boulay) Date: Wed, 2 Sep 2009 13:11:27 +0000 Subject: Resource Block from do() { } to try() { } Message-ID: What was the reason the resource block changed from the keyword ?do? to the keyword ?try?. Is it possibly more confusing using the ?try? keyword since you can attach a catch and finally clause to the block. What is the scope of exceptions in that block? _________________________________________________________________ New! Get to Messenger faster: Sign-in here now! http://go.microsoft.com/?linkid=9677407 From jjb at google.com Wed Sep 2 11:46:18 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 2 Sep 2009 11:46:18 -0700 Subject: Resource Block from do() { } to try() { } In-Reply-To: References: Message-ID: <17b2302a0909021146s4a743e3dw955bb0a424652e52@mail.gmail.com> On Wed, Sep 2, 2009 at 6:11 AM, serge Boulay wrote: > > What was the reason the resource block changed from the keyword ?do? to the > keyword ?try?. It feels more like a try-catch ("attempt this computation, then do cleanup") than a loop ("keep doing this until some condition occurs"). Is it possibly more confusing using the ?try? keyword since you can attach > a catch and finally clause to the block. We didn't have to permit this, but found it to be useful in practice. > What is the scope of exceptions in that block? > Not sure I understand what you're driving at; can you provide me with an example? Thanks, Josh From markmahieu at googlemail.com Wed Sep 2 16:19:43 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 3 Sep 2009 00:19:43 +0100 Subject: Resource Block from do() { } to try() { } In-Reply-To: <17b2302a0909021146s4a743e3dw955bb0a424652e52@mail.gmail.com> References: <17b2302a0909021146s4a743e3dw955bb0a424652e52@mail.gmail.com> Message-ID: <126FF5A4-481A-4219-958D-B3EA5E5F77F2@googlemail.com> On 2 Sep 2009, at 19:46, Joshua Bloch wrote: > On Wed, Sep 2, 2009 at 6:11 AM, serge Boulay > wrote: > >> >> What was the reason the resource block changed from the keyword >> ?do? to the >> keyword ?try?. > > > It feels more like a try-catch ("attempt this computation, then do > cleanup") > than a loop ("keep doing this until some condition occurs"). Personally, I never confused the 'do' variant with a 'do...while', but having experimented with both I think you're right that 'try' is the superior option if you're going to stick with one of those two; it conveys to the reader that the code contained within may 'fail' (but be automagically cleaned-up). > > Is it possibly more confusing using the ?try? keyword since you > can attach >> a catch and finally clause to the block. > > > We didn't have to permit this, but found it to be useful in practice. > Definitely. > > Josh > Cheers, Mark From xmirog at gmail.com Wed Sep 2 22:16:26 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Thu, 03 Sep 2009 07:16:26 +0200 Subject: Proposal: Automatic Resource Management In-Reply-To: <4A9E1B19.2030100@frameworkPLUS.com> References: <4A9D4C2E.8020606@frameworkPLUS.com> <17b2302a0909011451m157a0414o43d64df0910ea1b0@mail.gmail.com> <4A9DAD3C.4040409@univ-mlv.fr> <15e8b9d20909011713t7ae84f9dqb33dbde69d60c5f6@mail.gmail.com> <4A9DD947.8090308@frameworkPLUS.com> <17b2302a0909011939k2454ac30i682ebcee0e19cf09@mail.gmail.com> <15e8b9d20909012013g6637b927x54ca742bae46b177@mail.gmail.com> <17b2302a0909012101p9309c8ek1396052020ba6675@mail.gmail.com> <15e8b9d20909012204u2007b685q612564ad553e8e9@mail.gmail.com> <4A9E1B19.2030100@frameworkPLUS.com> Message-ID: <4A9F512A.8080900@gmail.com> I see this iterator autoclean construction very powerful but as a potential user of it I would prefer a slightly different syntax. The current proposal would change the semantics of existing programs, as Josh has pointed, and although it is likely that it wouldn't break existing programs, I think a different syntax would make clearer for a programmer to see it would do something more than the current foreach construction. I mean I would prefer something like: (1) try for (final Row row: table) { ... } or (2) for (final Row row: table) try { ... } instead of (3) for (final Row row: table) { ... } For me it's easier to understand with (1) or (2) that it's going to _try_ to do something _for_ each of those elements; it will iterate and for each element it will autoclean. With (3) I can see the same construction we use today, "for each element do this" and depending on the version of Java it will only iterate or it will iterate and autoclean. I know that only with elements that implement a Disposable interface it would autoclean, but in order to actually know it I must check the interfaces (which can be in another source code file); with a different syntax I could know it instantly. In addition, if we use a different syntax the compiler can complain if the elements don't implement Disposable, so if the programmer forgets to make them implement it he or she can notice it. If the syntax is the same, forgetting to implement the interface would be silently ignored and the programmer would think the elements would be cleaned up and they would not. The (1) and (2) syntax are only two possibilities, maybe we can find a better one, but in my humble opinion it would be best to differentiate the different semantics with different syntaxes. Regards, Xavi Sean R. Drucker escribi?: > I didn't consider retrofitting. > > Two options come to mind: > > 1. Move the for-each for disposable iterators to the new try syntax: > > try (Row row: table) { > } > > In addition to table.iterator() being disposed, if Row implements > Disposable, then each row would be disposed after each iteration. The > variable table would not be disposed unless the following syntax is used: > > try (Table table = new Table("Ex"); Row row: table) { > } > > > 2. Add a DisposableIterator (or similar) interface: > > interface DisposableIterator > extends Iterator, Disposable { > } > > The implementation of Iterable.iterator() would need to be a static > class that extends DisposableIterator. Nothing in the existing JDK > would be retrofitted with DisposableIterator. > > > Thanks... Sean > > Neal Gafter wrote: > >> On Tue, Sep 1, 2009 at 9:01 PM, Joshua Bloch > > wrote: >> >> Many existing types will be retrofitted to extend Disposable. If >> such a type also implements Iterable, the semantics of a for-each >> loop on an instance of the type would change, as I understand Sean's >> suggestion. >> >> >> Josh- >> >> In theory, yes. However, I doubt you'll find a confluence of events >> that would cause the change of behavior: (1) an existing implementation >> of Iterable that make use of covariant returns to (2) return a type that >> will be retrofitted with Disposable and is (3) used in a for-each loop >> in some existing client code. If you do find such a case, you've found >> a resource leak in existing code, and its maintainers should be glad to >> have the change in behavior. >> >> -Neal >> > > > From david at walend.net Thu Sep 3 14:52:52 2009 From: david at walend.net (David Walend) Date: Thu, 3 Sep 2009 17:52:52 -0400 Subject: Proposal: Automatic Resource Management (Xavi Mir?) In-Reply-To: References: Message-ID: <1DE64AAF-3A31-4744-A008-80D02238CA5A@walend.net> On Sep 3, 2009, at 3:00 PM, coin-dev-request at openjdk.java.net wrote: > > Date: Thu, 03 Sep 2009 07:16:26 +0200 > From: Xavi Mir? > Subject: Re: Proposal: Automatic Resource Management > To: "Sean R. Drucker" > Cc: coin-dev at openjdk.java.net > Message-ID: <4A9F512A.8080900 at gmail.com> > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > I see this iterator autoclean construction very powerful but as a > potential user of it I would prefer a slightly different syntax. The > current proposal would change the semantics of existing programs, as > Josh has pointed, and although it is likely that it wouldn't break > existing programs, I think a different syntax would make clearer for a > programmer to see it would do something more than the current foreach > construction. I mean I would prefer something like: > > (1) > > try for (final Row row: table) { > ... > } > > or > > (2) > > for (final Row row: table) try { > ... > } > > instead of > > (3) > > for (final Row row: table) { > ... > } > > For me it's easier to understand with (1) or (2) that it's going to > _try_ to do something _for_ each of those elements; it will iterate > and > for each element it will autoclean. With (3) I can see the same > construction we use today, "for each element do this" and depending on > the version of Java it will only iterate or it will iterate and > autoclean. I know that only with elements that implement a Disposable > interface it would autoclean, but in order to actually know it I must > check the interfaces (which can be in another source code file); > with a > different syntax I could know it instantly. > > In addition, if we use a different syntax the compiler can complain if > the elements don't implement Disposable, so if the programmer > forgets to > make them implement it he or she can notice it. If the syntax is the > same, forgetting to implement the interface would be silently ignored > and the programmer would think the elements would be cleaned up and > they > would not. > > The (1) and (2) syntax are only two possibilities, maybe we can find a > better one, but in my humble opinion it would be best to differentiate > the different semantics with different syntaxes. > > Regards, > > Xavi > (2) already compiles and works fine already. int[] ints = {0,1,2,3}; for(final int i: ints) try { System.out.println(i); } catch(RuntimeException re) { .. (1) doesn't. I think it's only because "try" requires {}s, which is inconsistent with other kinds of control flow. Maybe use something that doesn't look like it would work now: try (final Row row: table) { ... } Dave From i30817 at gmail.com Sun Sep 6 08:37:16 2009 From: i30817 at gmail.com (Paulo Levi) Date: Sun, 6 Sep 2009 16:37:16 +0100 Subject: Proposal: Automatic Resource Management Message-ID: <212322090909060837o3bedfe2bmc32a191cdab79f99@mail.gmail.com> What's the interaction of autoclosing iterables with threads inside the for? From i30817 at gmail.com Sun Sep 6 08:41:11 2009 From: i30817 at gmail.com (Paulo Levi) Date: Sun, 6 Sep 2009 16:41:11 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <212322090909060837o3bedfe2bmc32a191cdab79f99@mail.gmail.com> References: <212322090909060837o3bedfe2bmc32a191cdab79f99@mail.gmail.com> Message-ID: <212322090909060841j7683069bn170b9d27aff71400@mail.gmail.com> I meant autoclosing the iterable results, passed on to a (running) thread ofcourse. For example the parallel array from JSR 166. On Sun, Sep 6, 2009 at 4:37 PM, Paulo Levi wrote: > What's the interaction of autoclosing iterables with threads inside the for? > From neal at gafter.com Sun Sep 6 10:48:54 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 6 Sep 2009 10:48:54 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <212322090909060841j7683069bn170b9d27aff71400@mail.gmail.com> References: <212322090909060837o3bedfe2bmc32a191cdab79f99@mail.gmail.com> <212322090909060841j7683069bn170b9d27aff71400@mail.gmail.com> Message-ID: <15e8b9d20909061048k55f81312s94761cf7412ab974@mail.gmail.com> I would expect it to be the same as if the iterator had been closed explicitly. On Sun, Sep 6, 2009 at 8:41 AM, Paulo Levi wrote: > I meant autoclosing the iterable results, passed on to a (running) > thread ofcourse. For example the parallel array from JSR 166. > > On Sun, Sep 6, 2009 at 4:37 PM, Paulo Levi wrote: > > What's the interaction of autoclosing iterables with threads inside the > for? > > > > From i30817 at gmail.com Sun Sep 6 12:12:18 2009 From: i30817 at gmail.com (Paulo Levi) Date: Sun, 6 Sep 2009 20:12:18 +0100 Subject: Fwd: Proposal: Automatic Resource Management In-Reply-To: <212322090909061211w6c3ce18by49dbd428542edc24@mail.gmail.com> References: <212322090909060837o3bedfe2bmc32a191cdab79f99@mail.gmail.com> <212322090909060841j7683069bn170b9d27aff71400@mail.gmail.com> <15e8b9d20909061048k55f81312s94761cf7412ab974@mail.gmail.com> <212322090909061211w6c3ce18by49dbd428542edc24@mail.gmail.com> Message-ID: <212322090909061212m7829115ledd15579ac301637@mail.gmail.com> ---------- Forwarded message ---------- From: Paulo Levi Date: Sun, Sep 6, 2009 at 8:11 PM Subject: Re: Proposal: Automatic Resource Management To: Neal Gafter Actually isn't parallelarray a fork-join variant, so no problem there. Disregard this. On Sun, Sep 6, 2009 at 6:48 PM, Neal Gafter wrote: > I would expect it to be the same as if the iterator had been closed > explicitly. > > On Sun, Sep 6, 2009 at 8:41 AM, Paulo Levi wrote: >> >> I meant autoclosing the iterable results, passed on to a (running) >> thread ofcourse. For example the parallel array from JSR 166. >> >> On Sun, Sep 6, 2009 at 4:37 PM, Paulo Levi wrote: >> > What's the interaction of autoclosing iterables with threads inside the >> > for? >> > >> > > From frederic.martini at gmail.com Mon Sep 7 02:50:18 2009 From: frederic.martini at gmail.com (=?ISO-8859-1?Q?Fr=E9d=E9ric_Martini?=) Date: Mon, 7 Sep 2009 11:50:18 +0200 Subject: Proposal: ARM and SuppressedException Message-ID: Hello (and sorry for my poor english), I've juste reading the most recent version of the proposal : http://docs.google.com/View?id=ddv8ts74_3fs7483dp And I've a suggestion about the suppressed's exception. Instead of adding addSuppressedException()/getSuppressedExceptions() to throwable, we can use the "initCause" to store the suppressed exception. For example by adding a method like this on Throwable : public void addInitCause(Throwable suppressedException) { Throwable t = this; while (t.getCause()!=null) { t = t.getCause(); } t.initCause(suppressedException); } So we have not need to modify the printStackTrace()'s method, the suppressed's exception will be added at the end of the initCause... Fred, From neal at gafter.com Mon Sep 7 10:08:54 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 7 Sep 2009 10:08:54 -0700 Subject: Proposal: ARM and SuppressedException In-Reply-To: References: Message-ID: <15e8b9d20909071008i105ad4ecgc545bf26555033c4@mail.gmail.com> I have a problem with this from a software engineering point of view. While you've certainly found a place to put these exceptions without adding any further fields, it's hard to see how making the suppressed exception masquerade as a cause of some other exception will assist in locating or diagnosing the problem. On the other hand, this isn't much worse than the current proposal. It's to see how the current proposal supports handling of suppressed exceptions, unless code to check for them are sprinkled liberally throughout (the exception handlers of) a code base. 2009/9/7 Fr?d?ric Martini > Hello (and sorry for my poor english), > > > I've juste reading the most recent version of the proposal : > http://docs.google.com/View?id=ddv8ts74_3fs7483dp > And I've a suggestion about the suppressed's exception. > > > Instead of adding addSuppressedException()/getSuppressedExceptions() to > throwable, we can use the "initCause" to store the suppressed exception. > For example by adding a method like this on Throwable : > > > > public void addInitCause(Throwable suppressedException) { > Throwable t = this; > while (t.getCause()!=null) { > t = t.getCause(); > } > t.initCause(suppressedException); > } > > > > So we have not need to modify the printStackTrace()'s method, the > suppressed's exception will be added at the end of the initCause... > > > Fred, > > From mthornton at optrak.co.uk Mon Sep 7 11:58:19 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Mon, 07 Sep 2009 19:58:19 +0100 Subject: Proposal: ARM and SuppressedException In-Reply-To: <15e8b9d20909071008i105ad4ecgc545bf26555033c4@mail.gmail.com> References: <15e8b9d20909071008i105ad4ecgc545bf26555033c4@mail.gmail.com> Message-ID: <4AA557CB.8030004@optrak.co.uk> Neal Gafter wrote: > I have a problem with this from a software engineering point of view. While > you've certainly found a place to put these exceptions without adding any > further fields, it's hard to see how making the suppressed exception > masquerade as a cause of some other exception will assist in locating or > diagnosing the problem. > > On the other hand, this isn't much worse than the current proposal. It's to > see how the current proposal supports handling of suppressed exceptions, > unless code to check for them are sprinkled liberally throughout (the > exception handlers of) a code base. > > 2009/9/7 Fr?d?ric Martini > It might be silghtly better to create a SuppressedException which has the actual suppressed exception as its cause and then chain that on the cause as suggested. Mark Thornton From pcj at roundroom.net Mon Sep 7 14:13:33 2009 From: pcj at roundroom.net (Peter Jones) Date: Mon, 7 Sep 2009 17:13:33 -0400 Subject: Proposal: ARM and SuppressedException In-Reply-To: <15e8b9d20909071008i105ad4ecgc545bf26555033c4@mail.gmail.com> References: <15e8b9d20909071008i105ad4ecgc545bf26555033c4@mail.gmail.com> Message-ID: <7CA471BF-835C-43E7-8B85-5133D0117662@roundroom.net> On Sep 7, 2009, at 1:08 PM, Neal Gafter wrote: > I have a problem with this from a software engineering point of > view. While > you've certainly found a place to put these exceptions without > adding any > further fields, it's hard to see how making the suppressed exception > masquerade as a cause of some other exception will assist in > locating or > diagnosing the problem. I agree that this would be undesirably confusing. Also, it wouldn't work: a Throwable's cause can be initialized to null, at which point the chain can't be extended. > On the other hand, this isn't much worse than the current proposal. > It's to > see how the current proposal supports handling of suppressed > exceptions, > unless code to check for them are sprinkled liberally throughout (the > exception handlers of) a code base. I assume that the expectation is that suppressed exceptions would be largely for consumption by humans (in log files, etc.), not programs. I just reread through the proposal linked below, and while I concur with the motivation for adding a mechanism to retain what would otherwise be suppressed exceptions, like the debugging complications mentioned here: >> Even the ?correct? idioms for manual resource management are >> deficient: if an exception is thrown in the try block, and another >> when closing the resource in the finally block, the second >> exception supplants the first, making it difficult to determine the >> real cause of the trouble. In other words, by responsibly closing >> your resource even during some catastrophic event, you can actually >> erase all record of the event, resulting in many wasted hours of >> debugging. While it is possible to write code to suppress the >> second exception in favor of the first, virtually no one does, as >> it is just too verbose. This is not a theoretical problem; it has >> greatly complicated the debugging of large systems. it seems to me that this problem is more general than just the try/ finally cases that apply to ARM, so I wonder if the orthogonality of the mechanism to ARM can be further maximized. For example, I could imagine liking an alternate universe where all finally blocks made use of Throwable.addSuppressedException, but in the opposite sense (so as to minimally differ from existing semantics)-- i.e., if a finally block completes with an exception after its try block (or the executed catch block) also completed with an exception, then the exception thrown by the try/catch gets recorded as a suppressed exception of the one ultimately thrown by the finally. I think that this could aid in the above-mentioned debugging of much existing code. But without having thought about it deeply, I suspect that making such a change now would be deemed too disruptive. -- Peter > 2009/9/7 Fr?d?ric Martini > >> Hello (and sorry for my poor english), >> >> >> I've juste reading the most recent version of the proposal : >> http://docs.google.com/View?id=ddv8ts74_3fs7483dp >> And I've a suggestion about the suppressed's exception. >> >> >> Instead of adding addSuppressedException()/ >> getSuppressedExceptions() to >> throwable, we can use the "initCause" to store the suppressed >> exception. >> For example by adding a method like this on Throwable : >> >> >> >> public void addInitCause(Throwable suppressedException) { >> Throwable t = this; >> while (t.getCause()!=null) { >> t = t.getCause(); >> } >> t.initCause(suppressedException); >> } >> >> >> >> So we have not need to modify the printStackTrace()'s method, the >> suppressed's exception will be added at the end of the initCause... >> >> >> Fred, >> >> > From Joe.Darcy at Sun.COM Mon Sep 14 18:10:14 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 14 Sep 2009 18:10:14 -0700 Subject: General community and Process Questions (blog comment followups) In-Reply-To: <4A821E52.5090008@sun.com> References: <6013007.1248727620865.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> <6713E780-FBF4-45F2-8CAD-96A223EB8BFD@zwitserloot.com> <4A6EE265.3090106@peralex.com> <15e8b9d20907280735l6567b8c7y4f9e8e513848f1c9@mail.gmail.com> <4A6F1EA5.1000709@sun.com> <4A797AE5.8030304@peralex.com> <4A79CE18.5000705@sun.com> <4A821E52.5090008@sun.com> Message-ID: <4AAEE976.5060406@sun.com> Joe Darcy wrote: > Joseph D. Darcy wrote: >> I'll look into creating a wiki for Project Coin under >> http://wikis.sun.com. > > Created: > http://wikis.sun.com/display/ProjectCoin/Home Wiki created and eagerly awaiting to be populated. -Joe > > -Joe > >> >> Regards, >> >> -Joe >> >> >> Noel Grandin wrote: >>> If someone sets up a wiki and gives me edit rights, I'll trawl the >>> mailing list records and create some entries. >>> >>> If nothing else, it should help to jump-start the discussions for >>> Coin2. >>> >>> (I was surprised to see that the openjdk website does not have a wiki - >>> I thought that came for free with java.net hosting?) >>> >>> -- Noel >>> >>> Joseph D. Darcy wrote: >>> >>>> Neal Gafter wrote: >>>> >>>>> Noel- >>>>> >>>>> This is a great idea; it would certainly help casual observers to >>>>> follow the >>>>> status of the proposals and discussion. That would also be useful >>>>> as a >>>>> starting point for any future Coin-like project. >>>>> >>>>> I volunteer to provide web hosting and software support if you'll >>>>> agree to >>>>> set up and maintain the Wiki based on the existing discussion record. >>>>> Please let me know. >>>>> >>>> I can set up a wiki under http://wikis.sun.com, as done for the Da >>>> Vinci Machine Project (the JSR 292 RI). However, I will not actively >>>> maintain a wiki so someone else would have to volunteer to do this >>>> work. Additionally, one purpose of my Coin blog posts is to provide a >>>> lower volume way to track what is going on; posts under >>>> http://blogs.sun.com/main/tags/projectcoin provide news of major >>>> developments and links to the latest versions of proposals, etc. >>>> >>>> -Joe >>>> >>> >>> >>> Disclaimer: http://www.peralex.com/disclaimer.html >>> >>> >>> >> > From lk at teamten.com Wed Sep 16 23:12:03 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Wed, 16 Sep 2009 23:12:03 -0700 Subject: General community and Process Questions (blog comment followups) In-Reply-To: <4AAEE976.5060406@sun.com> References: <6013007.1248727620865.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> <6713E780-FBF4-45F2-8CAD-96A223EB8BFD@zwitserloot.com> <4A6EE265.3090106@peralex.com> <15e8b9d20907280735l6567b8c7y4f9e8e513848f1c9@mail.gmail.com> <4A6F1EA5.1000709@sun.com> <4A797AE5.8030304@peralex.com> <4A79CE18.5000705@sun.com> <4A821E52.5090008@sun.com> <4AAEE976.5060406@sun.com> Message-ID: <997cab100909162312g3f38295ex74da1110c45f6c2a@mail.gmail.com> Joe, > Wiki created and eagerly awaiting to be populated. Noel's suggestion for a wiki was for Coin2, but the description you wrote in its home page specifies JDK7. Which is it? Are we only allowed to write about the final five changes (or so), or can we write up proposals that we hope will be considered for JDK8? Lawrence Kesteloot From Joe.Darcy at Sun.COM Fri Sep 18 09:38:55 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 18 Sep 2009 09:38:55 -0700 Subject: General community and Process Questions (blog comment followups) In-Reply-To: <997cab100909162312g3f38295ex74da1110c45f6c2a@mail.gmail.com> References: <6013007.1248727620865.JavaMail.root@mswamui-bichon.atl.sa.earthlink.net> <6713E780-FBF4-45F2-8CAD-96A223EB8BFD@zwitserloot.com> <4A6EE265.3090106@peralex.com> <15e8b9d20907280735l6567b8c7y4f9e8e513848f1c9@mail.gmail.com> <4A6F1EA5.1000709@sun.com> <4A797AE5.8030304@peralex.com> <4A79CE18.5000705@sun.com> <4A821E52.5090008@sun.com> <4AAEE976.5060406@sun.com> <997cab100909162312g3f38295ex74da1110c45f6c2a@mail.gmail.com> Message-ID: <4AB3B79F.9010901@sun.com> Lawrence Kesteloot wrote: > Joe, > > >> Wiki created and eagerly awaiting to be populated. >> > > Noel's suggestion for a wiki was for Coin2, but the description you > No, it was for a wiki giving status of the current proposals: http://mail.openjdk.java.net/pipermail/coin-dev/2009-July/002126.html > wrote in its home page specifies JDK7. Which is it? Are we only > JDK 7. -Joe -------------- next part -------------- An embedded message was scrubbed... From: Noel Grandin Subject: Re: General community and Process Questions (blog comment followups) Date: Tue, 28 Jul 2009 13:35:01 +0200 Size: 13390 Url: http://mail.openjdk.java.net/pipermail/coin-dev/attachments/20090918/ccf4bdb8/attachment.mht From mkrueger at gmx.net Fri Sep 18 12:11:35 2009 From: mkrueger at gmx.net (=?ISO-8859-15?Q?Martin_Kr=FCger?=) Date: Fri, 18 Sep 2009 21:11:35 +0200 Subject: Proposal: bean type Message-ID: <4AB3DB67.8010301@gmx.net> Hi, hope this is the right place. My proposal is to introduce a new class type called bean. For example, one can define a bean with the keyword bean: bean Car { ... }. Then one can define fields by the keyword property: bean Car { property String type; property int ps; }. Now, I introduce some modifiers, which are set, get and notify. So one can define a property: bean Car { property set get String type; property set notify int ps; }. set means that a setter is automatically generated. The same with get. Notify means, that an PropertyChangeEvent is thrown if this property is set. The benefit of this proposal is the very short definition of value objects. Greetings, Martin From mthornton at optrak.co.uk Fri Sep 18 12:33:23 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Fri, 18 Sep 2009 20:33:23 +0100 Subject: Proposal: bean type In-Reply-To: <4AB3DB67.8010301@gmx.net> References: <4AB3DB67.8010301@gmx.net> Message-ID: <4AB3E083.5060402@optrak.co.uk> Martin Kr?ger wrote: > Hi, > > hope this is the right place. My proposal is to introduce a new class > type called bean. For example, one can define a bean with the keyword bean: > > It is much too late --- the deadline for proposals closed months ago. In any case I seem to remember that the invitation for proposals said that "properties" were out of bounds for consideration. Mark Thornton From Joe.Darcy at Sun.COM Fri Sep 18 12:54:08 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 18 Sep 2009 12:54:08 -0700 Subject: Proposal: bean type In-Reply-To: <4AB3E083.5060402@optrak.co.uk> References: <4AB3DB67.8010301@gmx.net> <4AB3E083.5060402@optrak.co.uk> Message-ID: <4AB3E560.9030802@sun.com> Mark Thornton wrote: > Martin Kr?ger wrote: > >> Hi, >> >> hope this is the right place. My proposal is to introduce a new class >> type called bean. For example, one can define a bean with the keyword bean: >> >> >> > It is much too late --- the deadline for proposals closed months ago. In > any case I seem to remember that the invitation for proposals said that > "properties" were out of bounds for consideration. Yes, months past the call for proposals deadline, the proposal form [1] wasn't filled out, and out of scope. [2] -Joe [1] http://openjdk.java.net/projects/coin/#proposal_form [2] http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size From hjohn at xs4all.nl Sun Sep 20 02:00:22 2009 From: hjohn at xs4all.nl (John Hendrikx) Date: Sun, 20 Sep 2009 11:00:22 +0200 Subject: Method argument inference? Message-ID: <4AB5EF26.3010900@xs4all.nl> I'm wondering if there's anything upcoming for Java 7 that's gonna fix this problem: dealWithStringSet(Collections.emptySet()); Where the method is defined as: public void dealWithStringSet(Set strings); This gets flagged as a warning by the compiler, as it cannot infer the type from the method parameters. The code below is warning free however with an unnecessary intermediate assignment: Set emptySet = Collections.emptySet(); dealWithStringSet(emptySet); The question is, why is it being flagged at all? Collections.empySet() is clearly setup to conform to any generic type you want it to be, and there's no danger (that I can tell) in doing the same inference for methods as it is not allowed to write two methods anyway with the same erasures. Even if it is allowed later to write two methods that only differ in generic parameters, one could apply the same error as is used for null values (where you have to cast null to conform to the intended type). It is just a minor annoyance, but one that gets more frequent as more and more frameworks and methods adopt generics :) --John From neal at gafter.com Sun Sep 20 08:50:18 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 20 Sep 2009 08:50:18 -0700 Subject: Method argument inference? In-Reply-To: <4AB5EF26.3010900@xs4all.nl> References: <4AB5EF26.3010900@xs4all.nl> Message-ID: <15e8b9d20909200850q744abcc4wf4929d54c2306b2a@mail.gmail.com> John- This was considered at one time for Java 7, but it's no longer on the list. Perhaps for some later revision. My main concern regarding this change is that choices made for the changes that are slated for Java 7 might conflict with this change and therefore make it more difficult to do in the future. It doesn't appear that the folks working on Java 7 are thinking about that. Cheers, Neal On Sun, Sep 20, 2009 at 2:00 AM, John Hendrikx wrote: > I'm wondering if there's anything upcoming for Java 7 that's gonna fix > this problem: > > dealWithStringSet(Collections.emptySet()); > > Where the method is defined as: > > public void dealWithStringSet(Set strings); > > This gets flagged as a warning by the compiler, as it cannot infer the > type from the method parameters. The code below is warning free however > with an unnecessary intermediate assignment: > > Set emptySet = Collections.emptySet(); > dealWithStringSet(emptySet); > > The question is, why is it being flagged at all? Collections.empySet() > is clearly setup to conform to any generic type you want it to be, and > there's no danger (that I can tell) in doing the same inference for > methods as it is not allowed to write two methods anyway with the same > erasures. > > Even if it is allowed later to write two methods that only differ in > generic parameters, one could apply the same error as is used for null > values (where you have to cast null to conform to the intended type). > > It is just a minor annoyance, but one that gets more frequent as more > and more frameworks and methods adopt generics :) > > --John > > > > From fw at deneb.enyo.de Sun Sep 20 21:58:28 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Mon, 21 Sep 2009 04:58:28 +0000 Subject: Method argument inference? In-Reply-To: <4AB5EF26.3010900@xs4all.nl> (John Hendrikx's message of "Sun, 20 Sep 2009 11:00:22 +0200") References: <4AB5EF26.3010900@xs4all.nl> Message-ID: <87tyywhp1n.fsf@mid.deneb.enyo.de> * John Hendrikx: > This gets flagged as a warning by the compiler, as it cannot infer the > type from the method parameters. The code below is warning free however > with an unnecessary intermediate assignment: > > Set emptySet = Collections.emptySet(); > dealWithStringSet(emptySet); FWIW, you can also use: dealWithStringSet(Collections.>emptySet()); From Joe.Darcy at Sun.COM Mon Sep 21 21:52:22 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 21 Sep 2009 21:52:22 -0700 Subject: Method argument inference? In-Reply-To: <87tyywhp1n.fsf@mid.deneb.enyo.de> References: <4AB5EF26.3010900@xs4all.nl> <87tyywhp1n.fsf@mid.deneb.enyo.de> Message-ID: <4AB85806.1040902@sun.com> On 09/20/09 09:58 PM, Florian Weimer wrote: > * John Hendrikx: > > >> This gets flagged as a warning by the compiler, as it cannot infer the >> type from the method parameters. The code below is warning free however >> with an unnecessary intermediate assignment: >> >> Set emptySet = Collections.emptySet(); >> dealWithStringSet(emptySet); >> > > FWIW, you can also use: > > dealWithStringSet(Collections.>emptySet()); > > That should be dealWithStringSet(Collections.emptySet()); -Joe From nick.parlante at cs.stanford.edu Sat Sep 26 13:37:34 2009 From: nick.parlante at cs.stanford.edu (Nick Parlante) Date: Sat, 26 Sep 2009 13:37:34 -0700 Subject: list literal gotcha and suggestion Message-ID: <4ABE7B8E.1070605@cs.stanford.edu> Hi there -- up until recently I taught Stanford's Tons Of Java course, CS108, for many years, so I've got a good feel for how new engineers get started with the language and where they have problems. I also run http://javabat.com where you really see what beginner programmers write. Looking at the Project Coin stuff, one corner of the syntax for collection literals jumped out at me as a potential source of problems. Here's the proposed syntax, as lifted from Mark Reinhold's slides. List piDigits = [ 3, 1, 4, 1, 5, 9, 2, 6, 5 ]; Set primes = { 2, 7, 31, 127, 8191, 131071 }; My concern is that students will write code like this: List piDigits = new ArrayList<>({3, 1, 4, 1}); This code looks so reasonable but sadly does something unexpected, since the set literal eliminates the second 1. The students will write it this way, with the { }, since they are accustomed to array initializers that way in Java, and also C/C++. So here's my suggestion: 1. Use { } for list literals, not [ ]. It's most consistent with array literals and avoids the above list/set gotcha. 2. Use [ ] for set literals, or if that causes problems, just don't have a literal for sets. Lists and maps are the most common, so having a syntax for those cases is the most important. Even without a special syntax, a set is easy to express based on a list literal, like new HashSet({1, 2, 3, 1}) // { } meaning List here It's nice that there's no gotcha with the slight []/{} mis-match going this direction. Cheers, Nick From jjb at google.com Sun Sep 27 19:20:47 2009 From: jjb at google.com (Joshua Bloch) Date: Sun, 27 Sep 2009 19:20:47 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <4ABE7B8E.1070605@cs.stanford.edu> References: <4ABE7B8E.1070605@cs.stanford.edu> Message-ID: <17b2302a0909271920k3a332b3axe8221e13fd81948d@mail.gmail.com> Nick, Hi! Thanks for the suggestion. Your point is entirely valid. That said, I first wrote the proposal the way you want it, and this ensued: ---------- Forwarded message ---------- From: Tim Peierls Date: Fri, Mar 27, 2009 at 4:45 AM Subject: Re: Collection Literals Proposal To: Joshua Bloch Cc: Neal Gafter , Java-council , Doug Lea
, "Joseph D. Darcy" On Fri, Mar 27, 2009 at 2:01 AM, Joshua Bloch wrote: > Incidentally, I picked curly braces for List because the language already > uses them for array initializers, but the more I look at what I proposed the > more I think I got it backwards. It's the opposite of Python, and it just > feels wrong. > Yes, you got it backwards. Years of Perl hacking have burned it into me: [] is empty list/array, {} is empty map/hash/associative array. Also Python, Javascript, Ruby, ... Not something you want to fight. --tim *********************************************************************************** So I suppose it's a question of who gets confused:( Perhaps I could keep the syntax as it stands, but encourage IDE maintainers to generate a warning if programmers fall into the trap that you describe? Josh On Sat, Sep 26, 2009 at 1:37 PM, Nick Parlante < nick.parlante at cs.stanford.edu> wrote: > Hi there -- up until recently I taught Stanford's Tons Of Java course, > CS108, for many years, so I've got a good feel for how new engineers get > started with the language and where they have problems. I also run > http://javabat.com where you really see what beginner programmers write. > > Looking at the Project Coin stuff, one corner of the syntax for > collection literals jumped out at me as a potential source of problems. > Here's the proposed syntax, as lifted from Mark Reinhold's slides. > > List piDigits = [ 3, 1, 4, 1, 5, 9, 2, 6, 5 ]; > Set primes = { 2, 7, 31, 127, 8191, 131071 }; > > My concern is that students will write code like this: > > List piDigits = new ArrayList<>({3, 1, 4, 1}); > > This code looks so reasonable but sadly does something unexpected, since > the set literal eliminates the second 1. > > The students will write it this way, with the { }, since they are > accustomed to array initializers that way in Java, and also C/C++. > > So here's my suggestion: > > 1. Use { } for list literals, not [ ]. It's most consistent with array > literals and avoids the above list/set gotcha. > > 2. Use [ ] for set literals, or if that causes problems, just don't have > a literal for sets. Lists and maps are the most common, so having a > syntax for those cases is the most important. Even without a special > syntax, a set is easy to express based on a list literal, like > new HashSet({1, 2, 3, 1}) // { } meaning List here > It's nice that there's no gotcha with the slight []/{} mis-match going > this direction. > > Cheers, > > Nick > > > > > > From lk at teamten.com Sun Sep 27 19:25:07 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Sun, 27 Sep 2009 19:25:07 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909271920k3a332b3axe8221e13fd81948d@mail.gmail.com> References: <4ABE7B8E.1070605@cs.stanford.edu> <17b2302a0909271920k3a332b3axe8221e13fd81948d@mail.gmail.com> Message-ID: <997cab100909271925u73e1b98bsf25ee25a76a4ac0f@mail.gmail.com> I would optimize for consistency with other languages. Eventually we can stop teaching the array syntax altogether. (I barely know it myself and the rare times I use it I have to look it up.) Lawrence On Sun, Sep 27, 2009 at 7:20 PM, Joshua Bloch wrote: > Nick, > Hi! Thanks for the suggestion. ?Your point is entirely valid. ?That said, I > first wrote the proposal the way you want it, and this ensued: > > ---------- Forwarded message ---------- > From: Tim Peierls > Date: Fri, Mar 27, 2009 at 4:45 AM > Subject: Re: Collection Literals Proposal > To: Joshua Bloch > Cc: Neal Gafter , Java-council , > Doug Lea
, "Joseph D. Darcy" > > > On Fri, Mar 27, 2009 at 2:01 AM, Joshua Bloch wrote: > >> Incidentally, I picked curly braces for List because the language already >> uses them for array initializers, but the more I look at what I proposed the >> more I think I got it backwards. ?It's the opposite of Python, and it just >> feels wrong. >> > > Yes, you got it backwards. Years of Perl hacking have burned it into me: [] > is empty list/array, {} is empty map/hash/associative array. Also Python, > Javascript, Ruby, ... Not something you want to fight. > > --tim > > *********************************************************************************** > > So I suppose it's a question of who gets confused:( ?Perhaps I could keep > the syntax as it stands, but encourage IDE maintainers to generate a warning > if programmers fall into the trap that you describe? > > ? ? ? ? ? ? ?Josh > > On Sat, Sep 26, 2009 at 1:37 PM, Nick Parlante < > nick.parlante at cs.stanford.edu> wrote: > >> Hi there -- up until recently I taught Stanford's Tons Of Java course, >> CS108, for many years, so I've got a good feel for how new engineers get >> started with the language and where they have problems. I also run >> http://javabat.com where you really see what beginner programmers write. >> >> Looking at the Project Coin stuff, one corner of the syntax for >> collection literals jumped out at me as a potential source of problems. >> Here's the proposed syntax, as lifted from Mark Reinhold's slides. >> >> List piDigits = [ 3, 1, 4, 1, 5, 9, 2, 6, 5 ]; >> Set primes = { 2, 7, 31, 127, 8191, 131071 }; >> >> My concern is that students will write code like this: >> >> List piDigits = new ArrayList<>({3, 1, 4, 1}); >> >> This code looks so reasonable but sadly does something unexpected, since >> the set literal eliminates the second 1. >> >> The students will write it this way, with the { }, since they are >> accustomed to array initializers that way in Java, and also C/C++. >> >> So here's my suggestion: >> >> 1. Use { } for list literals, not [ ]. It's most consistent with array >> literals and avoids the above list/set gotcha. >> >> 2. Use [ ] for set literals, or if that causes problems, just don't have >> a literal for sets. Lists and maps are the most common, so having a >> syntax for those cases is the most important. Even without a special >> syntax, a set is easy to express based on a list literal, like >> ? new HashSet({1, 2, 3, 1}) ?// ?{ } meaning List here >> It's nice that there's no gotcha with the slight []/{} mis-match going >> this direction. >> >> Cheers, >> >> Nick >> >> >> >> >> >> > > From adamrabung at gmail.com Mon Sep 28 07:12:13 2009 From: adamrabung at gmail.com (Adam Rabung) Date: Mon, 28 Sep 2009 10:12:13 -0400 Subject: Method argument inference? In-Reply-To: <4AB85806.1040902@sun.com> References: <4AB5EF26.3010900@xs4all.nl> <87tyywhp1n.fsf@mid.deneb.enyo.de> <4AB85806.1040902@sun.com> Message-ID: In systems I've worked on, this lack of inference seems to cause more "noise" than even the lack of collection literals. On Tue, Sep 22, 2009 at 12:52 AM, Joe Darcy wrote: > On 09/20/09 09:58 PM, Florian Weimer wrote: >> * John Hendrikx: >> >> >>> This gets flagged as a warning by the compiler, as it cannot infer the >>> type from the method parameters. ?The code below is warning free however >>> with an unnecessary intermediate assignment: >>> >>> ? Set emptySet = Collections.emptySet(); >>> ? dealWithStringSet(emptySet); >>> >> >> FWIW, you can also use: >> >> ? ? dealWithStringSet(Collections.>emptySet()); >> >> > > That should be > > ? ? ? ?dealWithStringSet(Collections.emptySet()); > > -Joe > > From pbenedict at apache.org Mon Sep 28 13:53:20 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 28 Sep 2009 15:53:20 -0500 Subject: list literal gotcha and suggestion Message-ID: Joshua, What will the official proposal be? If a different syntax is required to initialize based on the type, it's too much thought for something so trivial. Paul From jjb at google.com Mon Sep 28 17:48:22 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 28 Sep 2009 17:48:22 -0700 Subject: list literal gotcha and suggestion In-Reply-To: References: Message-ID: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> Paul, I'm not sure what you mean. If you mean type parameter, no. But if you mean List vs. Set vs. Map, yes, the compiler needs a different syntax to tell them apart. Josh On Mon, Sep 28, 2009 at 1:53 PM, Paul Benedict wrote: > Joshua, > > What will the official proposal be? If a different syntax is required to > initialize based on the type, it's too much thought for something so > trivial. > > Paul > > From pbenedict at apache.org Mon Sep 28 19:54:22 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 28 Sep 2009 21:54:22 -0500 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> Message-ID: Josh, I thought the proposal used brackets or braces depending on what was the left-hand side of the assignment. If I have my facts straight, I would like to see a proposal where that's not the case and only one is actually used. List stringList = { "1", "2", "3" }; Set stringSet = { "1", "2", "3" }; Map stringMap = { "1" : "A", "2" : "B", "3" : "C" }; I don't think it matters if { } or [ ] is used, but not both. Paul On Mon, Sep 28, 2009 at 7:48 PM, Joshua Bloch wrote: > Paul, > I'm not sure what you mean. If you mean type parameter, no. But if you > mean List vs. Set vs. Map, yes, the compiler needs a different syntax to > tell them apart. > > Josh > > > On Mon, Sep 28, 2009 at 1:53 PM, Paul Benedict wrote: > >> Joshua, >> >> What will the official proposal be? If a different syntax is required to >> initialize based on the type, it's too much thought for something so >> trivial. >> >> Paul >> >> > From jjb at google.com Mon Sep 28 21:43:53 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 28 Sep 2009 21:43:53 -0700 Subject: list literal gotcha and suggestion In-Reply-To: References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> Message-ID: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> Paul, On Mon, Sep 28, 2009 at 7:54 PM, Paul Benedict wrote: > Josh, > > I thought the proposal used brackets or braces depending on what was the > left-hand side of the assignment. Yep. > If I have my facts straight, I would like > to see a proposal where that's not the case and only one is actually used. > > List stringList = { "1", "2", "3" }; > Set stringSet = { "1", "2", "3" }; > Map stringMap = { "1" : "A", "2" : "B", "3" : "C" }; > This sort of "target typing" is notoriously tricking from a type-theoretic perspective, and there's very, very little of it in Java. I would be reluctant to introduce more of it. > > I don't think it matters if { } or [ ] is used, but not both. > As above, I don't know whether it would be practical to have once syntax do double duty. I haven't even tried to specify it. Josh From pbenedict at apache.org Mon Sep 28 22:28:42 2009 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 29 Sep 2009 00:28:42 -0500 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> Message-ID: Josh, I think using braces or brackets to indicate the correct type is hardly intuitive or easy to remember. Choosing the wrong syntax by accident will instantiate the wrong type, and the difference between the brace or bracket is pretty subtle visually. If Java developers have to begin saying, "Which syntax do I need to use for a List vs. Set?", then I question the whole cost-to-benefit-ratio of this "small" (i.e, coin) proposal. I can see the JDK 7 certification tests already asking this question -- it's a good gotcha question. Not being a language expert, and recognizing that other languages already use what's being proposed, the syntax still doesn't pass my common sense meter. Do the technical justifications really outweigh simplicity? Paul On Mon, Sep 28, 2009 at 11:43 PM, Joshua Bloch wrote: > Paul, > > On Mon, Sep 28, 2009 at 7:54 PM, Paul Benedict wrote: > >> Josh, >> >> I thought the proposal used brackets or braces depending on what was the >> left-hand side of the assignment. > > > Yep. > > >> If I have my facts straight, I would like >> to see a proposal where that's not the case and only one is actually used. >> >> List stringList = { "1", "2", "3" }; >> Set stringSet = { "1", "2", "3" }; >> Map stringMap = { "1" : "A", "2" : "B", "3" : "C" }; >> > > > This sort of "target typing" is notoriously tricking from a type-theoretic > perspective, and there's very, very little of it in Java. I would be > reluctant to introduce more of it. > > >> >> I don't think it matters if { } or [ ] is used, but not both. >> > > As above, I don't know whether it would be practical to have once syntax do > double duty. I haven't even tried to specify it. > > Josh > From jjb at google.com Mon Sep 28 22:34:31 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 28 Sep 2009 22:34:31 -0700 Subject: list literal gotcha and suggestion In-Reply-To: References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> Message-ID: <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> Paul, On Mon, Sep 28, 2009 at 10:28 PM, Paul Benedict wrote: > Josh, > > I think using braces or brackets to indicate the correct type is hardly > intuitive or easy to remember. Choosing the wrong syntax by accident will > instantiate the wrong type, and the difference between the brace or bracket > is pretty subtle visually. Usually it won't compile: you can't assign a Set to a List or vice-versa. Nick's example was carefully chosen: he invoked a constructor that took a Collection, which admits either a Set or a List. > If Java developers have to begin saying, "Which syntax do I need to use for > a List vs. Set?", then I question the whole cost-to-benefit-ratio of this > "small" (i.e, coin) proposal. Agreed, I do think the syntax we settled on is reasonably evocative, memorable, and consistent with other languages. Braces (AKA curly braces) are used to represent a Set in mathematical notation, and square brackets are used to index into and to declare arrays, which are list-like. > I can see the JDK 7 certification tests already asking this question -- > it's a good gotcha question. Not being a language expert, and recognizing > that other languages already use what's being proposed, the syntax still > doesn't pass my common sense meter. Do the technical justifications really > outweigh simplicity? > I think it's probably the best that we can do, but I could be wrong. I will investigate other options. Josh From reinier at zwitserloot.com Mon Sep 28 23:14:28 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 29 Sep 2009 08:14:28 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> Message-ID: If we insist on having both short-hand set and list literals, then some people are neccessarily going to be confused about the syntax, regardless of {} being used for sets and [] being used for lists, or vice versa, for reasons already covered: [] is lists and {} is sets in other languages, but in java, {} is more closely associated with lists due to array literals. There's no answer out of this unless this answer involves either eliminating set literals, or forcing the need to mention the target type somehow: e.g. something like "Set["a", "b", "c"]" versus "List["a", "b", "c"]" which is quite a price to pay to eliminate the confusion. Perhaps if the literal syntax defaults to Lists if you omit the type, this is a workable alternative. Unfortunately, this is hard to rhyme with the parser: Is "Set[10]" to be interpreted as: Please create a Set, and populate it with the number '10', or should it be interpreted as: "Set" is a variable that points to an array, and I want the 11th item in this array. (variables ought to start with a lowercase letter, but this is merely convention and not something the parser can rely on). So, such a change would probably move this proposal beyond the scope of coin. So, let's turn this argument on its head: Why are we trying so hard to make set literals work? Why don't we just remove them from the proposal? The need for them seems minor compared to lists. When the collection size is small (below about a 100), O(1) lookup performance is irrelevant (and even if it was relevant, due to the extra housekeeping that Sets have to do, Lists tend to actually beat Sets in performance, even for contains(), if the list/set is small!), and yet, if the initial list or set is being created via a literal, the list/ set will most likely remain small. If only list literals existed, creating a set is much cleaner than what you get now: new HashSet<>({"a", "b", "c"}); versus: new HashSet(Arrays.asList("a", "b", "c")); This doesn't work if you reverse the scenario; you can't make lists from set literals (as the duplicates would have already been removed at thiat point). Even in this longer form of set literal, you've eliminated the biggest problem in the status quo: A reliance on a completely unrelated class (Arrays - what does the arrays utility class have to do with the creation of collections from explicit values? It SHOULD have no relation whatsoever), and extremely wordiness - partly because of the accepted diamond proposal. Perhaps some research needs to be done for how often "set literals" are created now in real life java code. Search for the patterns: new HashSet(Arrays.asList(T...)); googlecollections.ImmutableSet.of(T...); HashSet/Set x = new HashSet(); x.add(t); //repeated 1 or more times. If not very often, then isn't the right answer here to just leave them out entirely, eliminating the confusion in the process? I may have missed it, but I can't remember seeing the technical details on this proposal. What does a list literal construct? A mutable ArrayList, or an immutable undefined implementation of List? I would strongly suggest these literals are immutable by default, particularly because making them mutable is easy: new ArrayList<>({"a", "b", "c"});. If only the static methods in interfaces proposal had been taken more seriously, this could have been solved decently with a library, especially because of the acceptance of the easier varargs invocation proposal: List.of("a", "b", "c"); is even better than: ["a", "b", "c"]; because it avoids the "Is it a Set or a List" issue entirely, and doesn't require taking up valuable parser flexibility the way real literals would. Even in complex situations: List> complicated = List.of(Set.of("a", "b", "a"), null, Set.empty()); methodCall(List.of("a", "b, "c")); compared to: List> complicated = [{"a", "b", "a"}, null, {}]; methodCall(["a", "b", "c"]); the interface-based static methods are probably slightly worse overall than true literals in these slightly more complex situations, but the difference isn't that big, and the static methods still win in eliminating list/set confusion. Right now the static method based solution would cause a warning you can safely ignore, and is thus useless (try it yourself with the google collections API's "of" methods), but as mentioned the simpler varargs invocation proposal eliminates the unneccessary warnings, making that form a decent alternative. NB: I doubt it'll help at this point in time, but I'll vouch for writing up the JLS patch and a prototype compiler, delivered within a month after greenlighting the idea. The implementation would work along the lines of the proposal I handed in for coin to allow static methods in interfaces without requiring any changes to the JVM. The strategy boils down to creating a new inner class in the interface, named "$Methods", and moving all static methods into this new class, then requiring that these static methods are called only via their original class name, and not on instances or subtypes (Every style checker I know of generates a warning if you call static methods via an instance anyway, so I don't consider this a big loss), and translating any static method call on an interface type from InterfaceName.methodName(params) to InterfaceName. $Methods.methodName(params). As plenty of other languages running on the JVM do allow it, there's a modicum of benefit for JVM language interop if the proposal is accepted as well, by standardizing the approach. --Reinier Zwitserloot On 2009/29/09, at 07:34, Joshua Bloch wrote: > Paul, > > On Mon, Sep 28, 2009 at 10:28 PM, Paul Benedict > wrote: > >> Josh, >> >> I think using braces or brackets to indicate the correct type is >> hardly >> intuitive or easy to remember. Choosing the wrong syntax by >> accident will >> instantiate the wrong type, and the difference between the brace or >> bracket >> is pretty subtle visually. > > > Usually it won't compile: you can't assign a Set to a List or vice- > versa. > Nick's example was carefully chosen: he invoked a constructor that > took a > Collection, which admits either a Set or a List. > > > >> If Java developers have to begin saying, "Which syntax do I need to >> use for >> a List vs. Set?", then I question the whole cost-to-benefit-ratio >> of this >> "small" (i.e, coin) proposal. > > > Agreed, I do think the syntax we settled on is reasonably evocative, > memorable, and consistent with other languages. Braces (AKA curly > braces) > are used to represent a Set in mathematical notation, and square > brackets > are used to index into and to declare arrays, which are list-like. > > >> I can see the JDK 7 certification tests already asking this >> question -- >> it's a good gotcha question. Not being a language expert, and >> recognizing >> that other languages already use what's being proposed, the syntax >> still >> doesn't pass my common sense meter. Do the technical justifications >> really >> outweigh simplicity? >> > > I think it's probably the best that we can do, but I could be > wrong. I will > investigate other options. > > Josh > From lk at teamten.com Mon Sep 28 23:33:10 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Mon, 28 Sep 2009 23:33:10 -0700 Subject: list literal gotcha and suggestion In-Reply-To: References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> Message-ID: <997cab100909282333h4ceb7df3v784528a17d7a7ec3@mail.gmail.com> In support of Reinier's point is that Python has no set literal. They discussed adding it to Python 3, but I don't think it made it in. Removing it fixes the ambiguity about the empty braces {} being a set or a map. Lawrence On Mon, Sep 28, 2009 at 11:14 PM, Reinier Zwitserloot wrote: > If we insist on having both short-hand set and list literals, then > some people are neccessarily going to be confused about the syntax, > regardless of {} being used for sets and [] being used for lists, or > vice versa, for reasons already covered: [] is lists and {} is sets in > other languages, but in java, {} is more closely associated with lists > due to array literals. There's no answer out of this unless this > answer involves either eliminating set literals, or forcing the need > to mention the target type somehow: e.g. something like "Set["a", "b", > "c"]" versus "List["a", "b", "c"]" which is quite a price to pay to > eliminate the confusion. Perhaps if the literal syntax defaults to > Lists if you omit the type, this is a workable alternative. > Unfortunately, this is hard to rhyme with the parser: Is "Set[10]" to > be interpreted as: Please create a Set, and populate it with > the number '10', or should it be interpreted as: "Set" is a variable > that points to an array, and I want the 11th item in this array. > (variables ought to start with a lowercase letter, but this is merely > convention and not something the parser can rely on). So, such a > change would probably move this proposal beyond the scope of coin. > > So, let's turn this argument on its head: Why are we trying so hard to > make set literals work? Why don't we just remove them from the > proposal? The need for them seems minor compared to lists. When the > collection size is small (below about a 100), O(1) lookup performance > is irrelevant (and even if it was relevant, due to the extra > housekeeping that Sets have to do, Lists tend to actually beat Sets in > performance, even for contains(), if the list/set is small!), and yet, > if the initial list or set is being created via a literal, the list/ > set will most likely remain small. If only list literals existed, > creating a set is much cleaner than what you get now: > > new HashSet<>({"a", "b", "c"}); > > versus: > > new HashSet(Arrays.asList("a", "b", "c")); > > This doesn't work if you reverse the scenario; you can't make lists > from set literals (as the duplicates would have already been removed > at thiat point). Even in this longer form of set literal, you've > eliminated the biggest problem in the status quo: A reliance on a > completely unrelated class (Arrays - what does the arrays utility > class have to do with the creation of collections from explicit > values? It SHOULD have no relation whatsoever), and extremely > wordiness - partly because of the accepted diamond proposal. > > Perhaps some research needs to be done for how often "set literals" > are created now in real life java code. Search for the patterns: > > new HashSet(Arrays.asList(T...)); > googlecollections.ImmutableSet.of(T...); > HashSet/Set x = new HashSet(); x.add(t); //repeated 1 or more > times. > > If not very often, then isn't the right answer here to just leave them > out entirely, eliminating the confusion in the process? > > I may have missed it, but I can't remember seeing the technical > details on this proposal. What does a list literal construct? A > mutable ArrayList, or an immutable undefined implementation of List? I > would strongly suggest these literals are immutable by default, > particularly because making them mutable is easy: new > ArrayList<>({"a", "b", "c"});. > > If only the static methods in interfaces proposal had been taken more > seriously, this could have been solved decently with a library, > especially because of the acceptance of the easier varargs invocation > proposal: > > List.of("a", "b", "c"); > > is even better than: > > ["a", "b", "c"]; > > because it avoids the "Is it a Set or a List" issue entirely, and > doesn't require taking up valuable parser flexibility the way real > literals would. > > Even in complex situations: > > List> complicated = List.of(Set.of("a", "b", "a"), null, > Set.empty()); > > methodCall(List.of("a", "b, "c")); > > compared to: > > List> complicated = [{"a", "b", "a"}, null, {}]; > methodCall(["a", "b", "c"]); > > the interface-based static methods are probably slightly worse overall > than true literals in these slightly more complex situations, but the > difference isn't that big, and the static methods still win in > eliminating list/set confusion. Right now the static method based > solution would cause a warning you can safely ignore, and is thus > useless (try it yourself with the google collections API's "of" > methods), but as mentioned the simpler varargs invocation proposal > eliminates the unneccessary warnings, making that form a decent > alternative. > > NB: I doubt it'll help at this point in time, but I'll vouch for > writing up the JLS patch and a prototype compiler, delivered within a > month after greenlighting the idea. The implementation would work > along the lines of the proposal I handed in for coin to allow static > methods in interfaces without requiring any changes to the JVM. The > strategy boils down to creating a new inner class in the interface, > named "$Methods", and moving all static methods into this new class, > then requiring that these static methods are called only via their > original class name, and not on instances or subtypes (Every style > checker I know of generates a warning if you call static methods via > an instance anyway, so I don't consider this a big loss), and > translating any static method call on an interface type from > InterfaceName.methodName(params) to InterfaceName. > $Methods.methodName(params). As plenty of other languages running on > the JVM do allow it, there's a modicum of benefit for JVM language > interop if the proposal is accepted as well, by standardizing the > approach. > > ?--Reinier Zwitserloot > > On 2009/29/09, at 07:34, Joshua Bloch wrote: > >> Paul, >> >> On Mon, Sep 28, 2009 at 10:28 PM, Paul Benedict >> wrote: >> >>> Josh, >>> >>> I think using braces or brackets to indicate the correct type is >>> hardly >>> intuitive or easy to remember. Choosing the wrong syntax by >>> accident will >>> instantiate the wrong type, and the difference between the brace or >>> bracket >>> is pretty subtle visually. >> >> >> Usually it won't compile: you can't assign a Set to a List or vice- >> versa. >> Nick's example was carefully chosen: he invoked a constructor that >> took a >> Collection, which admits either a Set or a List. >> >> >> >>> If Java developers have to begin saying, "Which syntax do I need to >>> use for >>> a List vs. Set?", then I question the whole cost-to-benefit-ratio >>> of this >>> "small" (i.e, coin) proposal. >> >> >> Agreed, I do think the syntax we settled on is reasonably evocative, >> memorable, and consistent with other languages. ?Braces (AKA curly >> braces) >> are used to represent a Set in mathematical notation, and square >> brackets >> are used to index into and to declare arrays, which are list-like. >> >> >>> I can see the JDK 7 certification tests already asking this >>> question -- >>> it's a good gotcha question. Not being a language expert, and >>> recognizing >>> that other languages already use what's being proposed, the syntax >>> still >>> doesn't pass my common sense meter. Do the technical justifications >>> really >>> outweigh simplicity? >>> >> >> I think it's probably the best that we can do, but I could be >> wrong. ?I will >> investigate other options. >> >> ? ? ? ? ? ? Josh >> > > > From forax at univ-mlv.fr Tue Sep 29 00:03:13 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Tue, 29 Sep 2009 09:03:13 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> Message-ID: <4AC1B131.1010708@univ-mlv.fr> Le 29/09/2009 06:43, Joshua Bloch a ?crit : > Paul, > > On Mon, Sep 28, 2009 at 7:54 PM, Paul Benedict wrote: > > >> Josh, >> >> I thought the proposal used brackets or braces depending on what was the >> left-hand side of the assignment. >> > > Yep. > > > >> If I have my facts straight, I would like >> to see a proposal where that's not the case and only one is actually used. >> >> List stringList = { "1", "2", "3" }; >> Set stringSet = { "1", "2", "3" }; >> Map stringMap = { "1" : "A", "2" : "B", "3" : "C" }; >> >> > > This sort of "target typing" is notoriously tricking from a type-theoretic > perspective, and there's very, very little of it in Java. I would be > reluctant to introduce more of it. > The question here is, what is the runtime class of foo, if foo is defined like that : Collection foo = { "1", "2", "3" }; > > >> I don't think it matters if { } or [ ] is used, but not both. >> >> > As above, I don't know whether it would be practical to have once syntax do > double duty. I haven't even tried to specify it. > > Josh > > R?mi From rssh at gradsoft.com.ua Mon Sep 28 17:53:05 2009 From: rssh at gradsoft.com.ua (Ruslan Shevchenko) Date: Tue, 29 Sep 2009 03:53:05 +0300 (EEST) Subject: list literal gotcha and suggestion In-Reply-To: <4AC1B131.1010708@univ-mlv.fr> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <4AC1B131.1010708@univ-mlv.fr> Message-ID: <8b319b20fe2496baa31566b093c28741.squirrel@wmail.gradsoft.ua> > Le 29/09/2009 06:43, Joshua Bloch a ?crit : >> Paul, >> >> On Mon, Sep 28, 2009 at 7:54 PM, Paul Benedict >> wrote: >> >> >>> Josh, >>> >>> I thought the proposal used brackets or braces depending on what was >>> the >>> left-hand side of the assignment. >>> >> >> Yep. >> >> >> >>> If I have my facts straight, I would like >>> to see a proposal where that's not the case and only one is actually >>> used. >>> >>> List stringList = { "1", "2", "3" }; >>> Set stringSet = { "1", "2", "3" }; >>> Map stringMap = { "1" : "A", "2" : "B", "3" : "C" }; >>> >>> >> >> This sort of "target typing" is notoriously tricking from a >> type-theoretic >> perspective, and there's very, very little of it in Java. I would be >> reluctant to introduce more of it. >> > > The question here is, what is the runtime class of foo, if foo is > defined like that : > Collection foo = { "1", "2", "3" }; > Why this situation differ from List l = { "1","2","3","4" }; (l will be ArrayList or LinkedList ?) if we know, that for 'List' exists default implementation class, then we can or bind default implementation class to collection, or just say that Collection have no default implementation class. >> >> >>> I don't think it matters if { } or [ ] is used, but not both. >>> >>> >> As above, I don't know whether it would be practical to have once syntax >> do >> double duty. I haven't even tried to specify it. >> >> Josh >> >> > > R?mi > > From jjb at google.com Tue Sep 29 00:38:54 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 29 Sep 2009 00:38:54 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <8b319b20fe2496baa31566b093c28741.squirrel@wmail.gradsoft.ua> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <4AC1B131.1010708@univ-mlv.fr> <8b319b20fe2496baa31566b093c28741.squirrel@wmail.gradsoft.ua> Message-ID: <17b2302a0909290038q6facfa08ha1076a9f6023f0c6@mail.gmail.com> I suspect we'll always provide immutable but otherwise unspecified implementations. Josh 2009/9/28 Ruslan Shevchenko > > Le 29/09/2009 06:43, Joshua Bloch a ?crit : > >> Paul, > >> > >> On Mon, Sep 28, 2009 at 7:54 PM, Paul Benedict > >> wrote: > >> > >> > >>> Josh, > >>> > >>> I thought the proposal used brackets or braces depending on what was > >>> the > >>> left-hand side of the assignment. > >>> > >> > >> Yep. > >> > >> > >> > >>> If I have my facts straight, I would like > >>> to see a proposal where that's not the case and only one is actually > >>> used. > >>> > >>> List stringList = { "1", "2", "3" }; > >>> Set stringSet = { "1", "2", "3" }; > >>> Map stringMap = { "1" : "A", "2" : "B", "3" : "C" }; > >>> > >>> > >> > >> This sort of "target typing" is notoriously tricking from a > >> type-theoretic > >> perspective, and there's very, very little of it in Java. I would be > >> reluctant to introduce more of it. > >> > > > > The question here is, what is the runtime class of foo, if foo is > > defined like that : > > Collection foo = { "1", "2", "3" }; > > > > Why this situation differ from > List l = { "1","2","3","4" }; > (l will be ArrayList or LinkedList ?) > > if we know, that for 'List' exists default implementation class, then we > can or bind default implementation class to collection, or just say that > Collection have no default implementation class. > > > > >> > >> > >>> I don't think it matters if { } or [ ] is used, but not both. > >>> > >>> > >> As above, I don't know whether it would be practical to have once syntax > >> do > >> double duty. I haven't even tried to specify it. > >> > >> Josh > >> > >> > > > > R?mi > > > > > > > From mthornton at optrak.co.uk Tue Sep 29 00:42:06 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 29 Sep 2009 08:42:06 +0100 Subject: list literal gotcha and suggestion In-Reply-To: References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> Message-ID: <4AC1BA4E.5040108@optrak.co.uk> Reinier Zwitserloot wrote: > So, let's turn this argument on its head: Why are we trying so hard to > make set literals work? Why don't we just remove them from the > proposal? The need for them seems minor compared to lists. When the > collection size is small (below about a 100), O(1) lookup performance > is irrelevant (and even if it was relevant, due to the extra > So that we can supply them as arguments to methods that take a Set and onot a List or Collection, or to initialise Set typed fields. Mark Thornton From reinier at zwitserloot.com Tue Sep 29 00:52:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 29 Sep 2009 09:52:06 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <4AC1BA4E.5040108@optrak.co.uk> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> Message-ID: <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> new HashSet<>(["a", "b", "c"]); is too much effort in the rare cases where you need to initialize a set-typed parameter? This is java, not perl. Golfing isn't the end goal. --Reinier Zwitserloot On 2009/29/09, at 09:42, Mark Thornton wrote: > Reinier Zwitserloot wrote: >> So, let's turn this argument on its head: Why are we trying so hard >> to make set literals work? Why don't we just remove them from the >> proposal? The need for them seems minor compared to lists. When >> the collection size is small (below about a 100), O(1) lookup >> performance is irrelevant (and even if it was relevant, due to the >> extra > So that we can supply them as arguments to methods that take a Set > and onot a List or Collection, or to initialise Set typed fields. > > Mark Thornton > From mthornton at optrak.co.uk Tue Sep 29 01:02:19 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 29 Sep 2009 09:02:19 +0100 Subject: list literal gotcha and suggestion In-Reply-To: <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> Message-ID: <4AC1BF0B.9000109@optrak.co.uk> Reinier Zwitserloot wrote: > new HashSet<>(["a", "b", "c"]); > > is too much effort in the rare cases where you need to initialize a > set-typed parameter? This is java, not perl. Golfing isn't the end goal. > Without scanning my codebase I wouldn't expect Set parameters and fields to be rare. I use Set's quite frequently. Mark Thornton From reinier at zwitserloot.com Tue Sep 29 01:19:05 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 29 Sep 2009 10:19:05 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <4AC1BF0B.9000109@optrak.co.uk> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> Message-ID: <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> Scanning my codebase, they are quite rare. As the set literals are causing rather a lot of pain, let's see some proof before going too far down this road. Pain caused by set literals: - ambiguity of {} - is that the empty set or the empty map? - set/list confusion. - the parser becomes quite a bit more complicated to handle the difference between sets and maps. --Reinier Zwitserloot On 2009/29/09, at 10:02, Mark Thornton wrote: > Reinier Zwitserloot wrote: >> new HashSet<>(["a", "b", "c"]); >> >> is too much effort in the rare cases where you need to initialize a >> set-typed parameter? This is java, not perl. Golfing isn't the end >> goal. >> > Without scanning my codebase I wouldn't expect Set parameters and > fields to be rare. I use Set's quite frequently. > > Mark Thornton > From nick.parlante at cs.stanford.edu Tue Sep 29 11:20:03 2009 From: nick.parlante at cs.stanford.edu (Nick Parlante) Date: Tue, 29 Sep 2009 11:20:03 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> References: <17b2302a0909281748i277437a1u7cddd57aa63e10bb@mail.gmail.com> <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> Message-ID: <4AC24FD3.5070103@cs.stanford.edu> (snip lots of discussion) The fact that list-[] syntax is so widely used I find to be a pretty convincing argument, so I can live with list-[]. Even the Java Collections toString() and Arrays.toString() use list-[] to print. But, if list-[] is the syntax, then I think the {} syntax should not represent a set, so the obvious misuse is a compile error. My gotcha example new ArrayList({3, 1, 4, 1}) looks reasonable but does something else -- I've found that to be exactly the time and enthusiasm destroying combination for students. If the set literal were some awesome feature the tradeoff might be worthwhile, but set literals seem kind of rare compared to lists and maps. Indeed, list construction is probably the single most common case, so making the common case a little more error-prone for the benefit of the rare case seems like a bad tradeoff. As a supporting example and as Reinier pointed out, Python does fine without a set literal, so in Java that would be new HashSet<>([1, 2, 3]) which doesn't seem like a hardship. Cheers, Nick From pbenedict at apache.org Tue Sep 29 14:51:38 2009 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 29 Sep 2009 16:51:38 -0500 Subject: list literal gotcha and suggestion Message-ID: Reinier, you showed an interesting example. >> new HashSet<>(["a", "b", "c"]); It immediately reminded me of: public static List java.util.Arrays.asList(T... a) Likewise, what if static utility methods were introduced into existing collection classes? It would fit nicely with the on-going JDK 7 effort (i.e, java.util.Objects) to add highly-requested utility methods. public class ArrayList { public static ArrayList newList(E... o) {..} } public class LinkedList { public static LinkedList newList(E... o) {..} } public class HashSet { public static HashSet newSet(E... o) {..} } public class TreeSet { public static TreeSet newSet(E... o) {..} } I don't have a good answer here for a HashMap/TreeMap, but at least 80% could be handled using this pattern. The two major benefits are (1) the type is clearly being called out and (2) immutability can be achieved by wrapping the return with Collections.unmodifiableXXX. Collections.unmodifableSet(TreeSet.newSet(1, 2, 3, 4, 5)); This example is very readable to me, the type is visible, and (im)mutability is an option. Paul From evildeathmath at yahoo.com Tue Sep 29 12:07:07 2009 From: evildeathmath at yahoo.com (Gene Ray) Date: Tue, 29 Sep 2009 12:07:07 -0700 (PDT) Subject: list literal gotcha and suggestion In-Reply-To: <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> Message-ID: <995658.30901.qm@web112304.mail.gq1.yahoo.com> "Rare"? In my experience, Sets are not rare in well-written code; they're only rare in code where for whatever reason the developer has refused to use them, and instead expends effort and CPU time iterating through an array or ArrayList to achieve the equivalent functionality.? Encouraging this sort of behavior further by including only Lists in the new syntax is not a good plan. --- On Tue, 9/29/09, Reinier Zwitserloot wrote: From: Reinier Zwitserloot Subject: Re: list literal gotcha and suggestion To: "Mark Thornton" Cc: coin-dev at openjdk.java.net Date: Tuesday, September 29, 2009, 7:52 AM new HashSet<>(["a", "b", "c"]); is too much effort in the rare cases where you need to initialize a? set-typed parameter? This is java, not perl. Golfing isn't the end goal. ? --Reinier Zwitserloot On 2009/29/09, at 09:42, Mark Thornton wrote: > Reinier Zwitserloot wrote: >> So, let's turn this argument on its head: Why are we trying so hard? >> to? make set literals work? Why don't we just remove them from the??? >> proposal? The need for them seems minor compared to lists. When? >> the? collection size is small (below about a 100), O(1) lookup? >> performance? is irrelevant (and even if it was relevant, due to the? >> extra > So that we can supply them as arguments to methods that take a Set? > and onot a List or Collection, or to initialise Set typed fields. > > Mark Thornton > From scolebourne at joda.org Tue Sep 29 02:53:19 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 29 Sep 2009 10:53:19 +0100 Subject: list literal gotcha and suggestion In-Reply-To: <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> Message-ID: <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> Over the 1.4million LOC codebase I work on, I found 12 set literals. We're not talking about large numbers. Interestingly, the majority of these were constants, and may be more common than list constants. There weren't any cases of parameter passing of a set literal. That said, I strongly dislike the confusion apparent here. We should avoid new puzzlers if possible. I'd prefer List list = {"1", "2", "3"} - List literal Map list = {1 : "1", 2 : "2", 3 : "3"} - Map literal No set literal (I don't think this conflicts with the array literals...) Perhaps there is also an argument for adding the static of methods to construct mutable Set/List: Set set = HashSet.of("1", "2", "3"); // mutable set List list = ArrayList.of("1", "2", "3"); // mutable list List list2 = {"1", "2", "3"}; // immutable list One final thought. It would be possible to add a "method" to the list literal: Set set = {1, 2, 3}.toSet(); // immutable set This approach would handle additional interfaces too: SortedSet set = {1, 2, 3}.toSortedSet(); // immutable sorted set MultiSet mset = {1, 2, 3}.toMultiSet(); // immutable multiset/bag (if added to JDK) Stephen 2009/9/29 Reinier Zwitserloot : > Scanning my codebase, they are quite rare. As the set literals are > causing rather a lot of pain, let's see some proof before going too > far down this road. > > Pain caused by set literals: > > ?- ambiguity of {} - is that the empty set or the empty map? > ?- set/list confusion. > ?- the parser becomes quite a bit more complicated to handle the > difference between sets and maps. > > ?--Reinier Zwitserloot > > > > On 2009/29/09, at 10:02, Mark Thornton wrote: > >> Reinier Zwitserloot wrote: >>> new HashSet<>(["a", "b", "c"]); >>> >>> is too much effort in the rare cases where you need to initialize a >>> set-typed parameter? This is java, not perl. Golfing isn't the end >>> goal. >>> >> Without scanning my codebase I wouldn't expect Set parameters and >> fields to be rare. I use Set's quite frequently. >> >> Mark Thornton >> > > > From gkbrown at mac.com Tue Sep 29 17:34:47 2009 From: gkbrown at mac.com (Greg Brown) Date: Tue, 29 Sep 2009 20:34:47 -0400 Subject: list literal gotcha and suggestion In-Reply-To: <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> Message-ID: <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> I know this proposal has already been approved for inclusion in Java 7, but it really seems like it might not be worth the effort. Wouldn't it be simpler to just add a varargs constructor to the collection classes? To me, this: List list = ["a", "b", "c"]; isn't much better than: List list = new ArrayList("a", "b", "c"); With the improved type inference feature, declarations such as this will be even less verbose. I recognize that maps are trickier, but I still think that this: Map map = new HashMap(new AbstractMap.SimpleImmutableEntry("a", 0), new AbstractMap.SimpleImmutableEntry("b", 1), new AbstractMap.SimpleImmutableEntry("c", 2)); is preferable to modifying the language for what (to me) seems like a fairly marginal use case. Greg On Sep 29, 2009, at 5:53 AM, Stephen Colebourne wrote: > Over the 1.4million LOC codebase I work on, I found 12 set literals. > We're not talking about large numbers. Interestingly, the majority of > these were constants, and may be more common than list constants. > There weren't any cases of parameter passing of a set literal. > > That said, I strongly dislike the confusion apparent here. We should > avoid new puzzlers if possible. I'd prefer > > List list = {"1", "2", "3"} - List literal > Map list = {1 : "1", 2 : "2", 3 : "3"} - Map literal > No set literal > (I don't think this conflicts with the array literals...) > > Perhaps there is also an argument for adding the static of methods to > construct mutable Set/List: > > Set set = HashSet.of("1", "2", "3"); // mutable set > List list = ArrayList.of("1", "2", "3"); // mutable list > List list2 = {"1", "2", "3"}; // immutable list > > > One final thought. It would be possible to add a "method" to the > list literal: > > Set set = {1, 2, 3}.toSet(); // immutable set > > This approach would handle additional interfaces too: > > SortedSet set = {1, 2, 3}.toSortedSet(); // immutable > sorted set > MultiSet mset = {1, 2, 3}.toMultiSet(); // immutable > multiset/bag (if added to JDK) > > Stephen > > > 2009/9/29 Reinier Zwitserloot : >> Scanning my codebase, they are quite rare. As the set literals are >> causing rather a lot of pain, let's see some proof before going too >> far down this road. >> >> Pain caused by set literals: >> >> - ambiguity of {} - is that the empty set or the empty map? >> - set/list confusion. >> - the parser becomes quite a bit more complicated to handle the >> difference between sets and maps. >> >> --Reinier Zwitserloot >> >> >> >> On 2009/29/09, at 10:02, Mark Thornton wrote: >> >>> Reinier Zwitserloot wrote: >>>> new HashSet<>(["a", "b", "c"]); >>>> >>>> is too much effort in the rare cases where you need to initialize a >>>> set-typed parameter? This is java, not perl. Golfing isn't the end >>>> goal. >>>> >>> Without scanning my codebase I wouldn't expect Set parameters and >>> fields to be rare. I use Set's quite frequently. >>> >>> Mark Thornton >>> >> >> >> > From jjb at google.com Tue Sep 29 17:53:28 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 29 Sep 2009 17:53:28 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> References: <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> Message-ID: <17b2302a0909291753w32963dacm35b441d06bf0630a@mail.gmail.com> Greg, On Tue, Sep 29, 2009 at 5:34 PM, Greg Brown wrote: > I know this proposal has already been approved for inclusion in Java > 7, but it really seems like it might not be worth the effort. The project Coin selection committee disagrees;) Josh From gkbrown at mac.com Tue Sep 29 18:38:08 2009 From: gkbrown at mac.com (Greg Brown) Date: Tue, 29 Sep 2009 21:38:08 -0400 Subject: list literal gotcha and suggestion In-Reply-To: <17b2302a0909291753w32963dacm35b441d06bf0630a@mail.gmail.com> References: <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> <17b2302a0909291753w32963dacm35b441d06bf0630a@mail.gmail.com> Message-ID: Yes, I understand that - hence, my opening with "I know this proposal has already been approved". :-) But I still think it is a marginal use case that doesn't justify a language modification. On Sep 29, 2009, at 8:53 PM, Joshua Bloch wrote: > Greg, > > On Tue, Sep 29, 2009 at 5:34 PM, Greg Brown wrote: > I know this proposal has already been approved for inclusion in Java > 7, but it really seems like it might not be worth the effort. > > The project Coin selection committee disagrees;) > > Josh > From reinier at zwitserloot.com Tue Sep 29 20:15:45 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 30 Sep 2009 05:15:45 +0200 Subject: list literal gotcha and suggestion In-Reply-To: References: Message-ID: <0342958B-08A1-436E-BFCD-C81EF454D95E@zwitserloot.com> Too wordy. As I said in my post, this would be fine if you could add static methods to interfaces. If we can't do that there's still a workable alternative in what you suggest, though I wouldn't call them 'newList'. How about: return list(set("foo", "bar", "baz")) with list and set imported from Collections. Biggest problem is java's lousy inferencing; often you need to override generics but you can't do that with a statically imported method. One of the reasons why List.of() is quite superior in my opinion. Immutability should be the default - if you want mutability, you can always wrap whatever you are building into a new ArrayList/new HashSet/ new HashMap. Also, the exact type is far less important for immutables, so it becomes less confusing to add a generic 'create Set' without requiring the calling out of the type explicitly. --Reinier Zwitserloot On 2009/29/09, at 23:51, Paul Benedict wrote: > Reinier, you showed an interesting example. > >>> new HashSet<>(["a", "b", "c"]); > > It immediately reminded me of: > public static List java.util.Arrays.asList(T... a) > > Likewise, what if static utility methods were introduced into existing > collection classes? It would fit nicely with the on-going JDK 7 effort > (i.e, java.util.Objects) to add highly-requested utility methods. > > public class ArrayList { > public static ArrayList newList(E... o) {..} > } > > public class LinkedList { > public static LinkedList newList(E... o) {..} > } > > public class HashSet { > public static HashSet newSet(E... o) {..} > } > > public class TreeSet { > public static TreeSet newSet(E... o) {..} > } > > I don't have a good answer here for a HashMap/TreeMap, but at least > 80% could be handled using this pattern. The two major benefits are > (1) the type is clearly being called out and (2) immutability can be > achieved by wrapping the return with Collections.unmodifiableXXX. > > Collections.unmodifableSet(TreeSet.newSet(1, 2, 3, 4, 5)); > > This example is very readable to me, the type is visible, and > (im)mutability is an option. > > Paul > From reinier at zwitserloot.com Tue Sep 29 20:38:37 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 30 Sep 2009 05:38:37 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <995658.30901.qm@web112304.mail.gq1.yahoo.com> References: <995658.30901.qm@web112304.mail.gq1.yahoo.com> Message-ID: <37FB5960-589C-47B3-B378-1E41610D8EAE@zwitserloot.com> Stephen - adding various toX methods to the as yet undefined but immutable list subtype that list literals return is an excellent idea. The notion of using ExplicitType.of() to create mutables, and list literals + an optional method call to create immutables is quite flexible, and while unfortunately not obvious from a casual glance (in that neither form explicitly includes the characters 'immutable' or 'mutable' or some sort of variant thereof), its very consistent, and thus one may reasonably expect even beginning java programmers to pick up on the pattern. One change that may be better is to replace the 'of' method from a varargs line to a literal - a wrapper for the copy constructor. In practice it just boils down to adding 2 braces so you get your list literal, and it would be better for HashMap, as trying to do a Map literal via a static method isn't all that nice. (You can do it - google collections API does it, sort of - but it's not very elegant). There's still a point to duplicating the functionality: Eliminate the generics (even if in java7 you can get away with the diamond operator, that makes things look a bit perly). Switching to this standard also throws a bone to the alternative collections APIs out there, as they can copy the syntax - e.g. to create a (mutable) ArrayList, you'd go: ArrayList.of({1, 2, 3}); and to create a new ImmutableList (google collections API), you'd have to write ImmutableList.of({1, 2, 3}); - so the general rule is then: To create any collections literal, write: Type.of(list literal); NB: Gene, you're trying to argue that a _literal_ set is going to make some sort of speed difference compared to a a_literal_ list. That notion is frankly ridiculous. You also lost track of the first rule of discussing speed: Test it first. So, go ahead. Benchmark a bunch of .contains() calls on a list and a set with the same items in it, both with say, 20 items in them (we are talking about literals, after all. I don't think anyone is seriously considering sticking hundreds of lines of code in a .java file to store constant data!) - on my own machine Lists are less than a factor of 2 slower. For about 7 items and down, lists are in fact faster. Also, just in case someone IS tempted to write such a large collections literal: For such a large literal, the added burden of wrapping the literal in a "new HashSet<>()" or sticking a ".toSet();" at the end seems trivial. I think the 'set literals are rare' seem to have it, so I repeat my plea to the set literal fans: Give us some proof they aren't rare. Given that set literals cause so much pain, the burden is clearly on the supporters of a set literal to prove why we need them. --Reinier Zwitserloot On 2009/29/09, at 21:07, Gene Ray wrote: > "Rare"? > > In my experience, Sets are not rare in well-written code; they're > only rare in code where for whatever reason the developer has > refused to use them, and instead expends effort and CPU time > iterating through an array or ArrayList to achieve the equivalent > functionality. Encouraging this sort of behavior further by > including only Lists in the new syntax is not a good plan. > > > > --- On Tue, 9/29/09, Reinier Zwitserloot > wrote: > > From: Reinier Zwitserloot > Subject: Re: list literal gotcha and suggestion > To: "Mark Thornton" > Cc: coin-dev at openjdk.java.net > Date: Tuesday, September 29, 2009, 7:52 AM > > new HashSet<>(["a", "b", "c"]); > > is too much effort in the rare cases where you need to initialize a > set-typed parameter? This is java, not perl. Golfing isn't the end > goal. > > --Reinier Zwitserloot > > > On 2009/29/09, at 09:42, Mark Thornton wrote: > >> Reinier Zwitserloot wrote: >>> So, let's turn this argument on its head: Why are we trying so hard >>> to make set literals work? Why don't we just remove them from the >>> proposal? The need for them seems minor compared to lists. When >>> the collection size is small (below about a 100), O(1) lookup >>> performance is irrelevant (and even if it was relevant, due to the >>> extra >> So that we can supply them as arguments to methods that take a Set >> and onot a List or Collection, or to initialise Set typed fields. >> >> Mark Thornton >> > > > > > > > From hjohn at xs4all.nl Wed Sep 30 00:14:00 2009 From: hjohn at xs4all.nl (John Hendrikx) Date: Wed, 30 Sep 2009 09:14:00 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> Message-ID: <4AC30538.1040104@xs4all.nl> Varargs constructors for the various Sets and Lists would have solved a lot of problems already and would also fit nicely with the call for standard utility methods in java.util/lang. Any enhancement that gets rid of the Arrays.asList(...) construct would be most helpful. Maps however would remain a pain to instantiate. So a good syntax for creating maps or more generally, pairs or groups of values would alleviate that. Personally I was thinking more along the lines of providing a constructor like this for Maps: public HashMap(Pair... pairs); With some new syntax to easily create Pairs: Pair p = {1: "A"}; Resulting in: new HashMap({1: "A"}, {2: "B"}, {3: "C"}); It's a bit more verbose than the proposed syntax, but it has the advantage of also offering a standard way for returning pairs of values (from a map) and for adding single entries: for(Pair pair : map) { } myMap.add({4: "D"}); etc.. -- John Hendrikx Greg Brown wrote: > I know this proposal has already been approved for inclusion in Java > 7, but it really seems like it might not be worth the effort. Wouldn't > it be simpler to just add a varargs constructor to the collection > classes? To me, this: > > List list = ["a", "b", "c"]; > > isn't much better than: > > List list = new ArrayList("a", "b", "c"); > > With the improved type inference feature, declarations such as this > will be even less verbose. > > I recognize that maps are trickier, but I still think that this: > > Map map = new HashMap(new > AbstractMap.SimpleImmutableEntry("a", 0), > new AbstractMap.SimpleImmutableEntry("b", 1), > new AbstractMap.SimpleImmutableEntry("c", 2)); > > is preferable to modifying the language for what (to me) seems like a > fairly marginal use case. > > Greg > > > On Sep 29, 2009, at 5:53 AM, Stephen Colebourne wrote: > > >> Over the 1.4million LOC codebase I work on, I found 12 set literals. >> We're not talking about large numbers. Interestingly, the majority of >> these were constants, and may be more common than list constants. >> There weren't any cases of parameter passing of a set literal. >> >> That said, I strongly dislike the confusion apparent here. We should >> avoid new puzzlers if possible. I'd prefer >> >> List list = {"1", "2", "3"} - List literal >> Map list = {1 : "1", 2 : "2", 3 : "3"} - Map literal >> No set literal >> (I don't think this conflicts with the array literals...) >> >> Perhaps there is also an argument for adding the static of methods to >> construct mutable Set/List: >> >> Set set = HashSet.of("1", "2", "3"); // mutable set >> List list = ArrayList.of("1", "2", "3"); // mutable list >> List list2 = {"1", "2", "3"}; // immutable list >> >> >> One final thought. It would be possible to add a "method" to the >> list literal: >> >> Set set = {1, 2, 3}.toSet(); // immutable set >> >> This approach would handle additional interfaces too: >> >> SortedSet set = {1, 2, 3}.toSortedSet(); // immutable >> sorted set >> MultiSet mset = {1, 2, 3}.toMultiSet(); // immutable >> multiset/bag (if added to JDK) >> >> Stephen >> >> >> 2009/9/29 Reinier Zwitserloot : >> >>> Scanning my codebase, they are quite rare. As the set literals are >>> causing rather a lot of pain, let's see some proof before going too >>> far down this road. >>> >>> Pain caused by set literals: >>> >>> - ambiguity of {} - is that the empty set or the empty map? >>> - set/list confusion. >>> - the parser becomes quite a bit more complicated to handle the >>> difference between sets and maps. >>> >>> --Reinier Zwitserloot >>> >>> >>> >>> On 2009/29/09, at 10:02, Mark Thornton wrote: >>> >>> >>>> Reinier Zwitserloot wrote: >>>> >>>>> new HashSet<>(["a", "b", "c"]); >>>>> >>>>> is too much effort in the rare cases where you need to initialize a >>>>> set-typed parameter? This is java, not perl. Golfing isn't the end >>>>> goal. >>>>> >>>>> >>>> Without scanning my codebase I wouldn't expect Set parameters and >>>> fields to be rare. I use Set's quite frequently. >>>> >>>> Mark Thornton >>>> >>>> >>> >>> > > > From mthornton at optrak.co.uk Wed Sep 30 00:51:55 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Wed, 30 Sep 2009 08:51:55 +0100 Subject: list literal gotcha and suggestion In-Reply-To: <37FB5960-589C-47B3-B378-1E41610D8EAE@zwitserloot.com> References: <995658.30901.qm@web112304.mail.gq1.yahoo.com> <37FB5960-589C-47B3-B378-1E41610D8EAE@zwitserloot.com> Message-ID: <4AC30E1B.4060601@optrak.co.uk> Reinier Zwitserloot wrote: > NB: Gene, you're trying to argue that a _literal_ set is going to make > some sort of speed difference compared to a a_literal_ list. That > notion is frankly ridiculous. You also lost track of the first rule of > discussing speed: Test it first. So, go ahead. Benchmark a bunch > No, I think he is arguing that many people have used ArrayList in place of what should have been a Set. That is a List is used with supplementary documentation to the effect that the elements in the list occur once only and usually that the order isn't important. In other words ArrayList is used because it is more compact and faster to iterate. All this naturally having been done without testing if it is really important. Another reason for some excess use of List in existing code is that Arrays.asList() is the most compact way of creating a collection with more than one element (excluding EnumSet's). Mark Thornton From gkbrown at mac.com Wed Sep 30 01:31:09 2009 From: gkbrown at mac.com (Greg Brown) Date: Wed, 30 Sep 2009 04:31:09 -0400 Subject: list literal gotcha and suggestion In-Reply-To: <4AC30538.1040104@xs4all.nl> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> <4AC30538.1040104@xs4all.nl> Message-ID: I had actually suggested something very similar back in July: http://mail.openjdk.java.net/pipermail/coin-dev/2009-July/002097.html However, at this point I don't think I'd advocate any language changes associated with this feature. I think adding the varargs constructor (and/or unmodifiableList(), map, etc. methods) would solve this problem quite nicely within the existing Java feature set. But that is just my 2 cents. The Project Coin selection committee disagrees with me. :-) Greg On Sep 30, 2009, at 3:14 AM, John Hendrikx wrote: > Varargs constructors for the various Sets and Lists would have > solved a lot of problems already and would also fit nicely with the > call for standard utility methods in java.util/lang. Any > enhancement that gets rid of the Arrays.asList(...) construct would > be most helpful. > > Maps however would remain a pain to instantiate. So a good syntax > for creating maps or more generally, pairs or groups of values would > alleviate that. Personally I was thinking more along the lines of > providing a constructor like this for Maps: > > public HashMap(Pair... pairs); > > With some new syntax to easily create Pairs: > > Pair p = {1: "A"}; > > Resulting in: > > new HashMap({1: "A"}, {2: "B"}, {3: "C"}); > > It's a bit more verbose than the proposed syntax, but it has the > advantage of also offering a standard way for returning pairs of > values (from a map) and for adding single entries: > > for(Pair pair : map) { > } > > myMap.add({4: "D"}); > > etc.. > > -- > John Hendrikx > > > Greg Brown wrote: >> I know this proposal has already been approved for inclusion in >> Java 7, but it really seems like it might not be worth the effort. >> Wouldn't it be simpler to just add a varargs constructor to the >> collection classes? To me, this: >> >> List list = ["a", "b", "c"]; >> >> isn't much better than: >> >> List list = new ArrayList("a", "b", "c"); >> >> With the improved type inference feature, declarations such as >> this will be even less verbose. >> >> I recognize that maps are trickier, but I still think that this: >> >> Map map = new HashMap(new >> AbstractMap.SimpleImmutableEntry("a", 0), >> new AbstractMap.SimpleImmutableEntry("b", 1), >> new AbstractMap.SimpleImmutableEntry("c", 2)); >> >> is preferable to modifying the language for what (to me) seems like >> a fairly marginal use case. >> >> Greg >> >> >> On Sep 29, 2009, at 5:53 AM, Stephen Colebourne wrote: >> >> >>> Over the 1.4million LOC codebase I work on, I found 12 set literals. >>> We're not talking about large numbers. Interestingly, the majority >>> of >>> these were constants, and may be more common than list constants. >>> There weren't any cases of parameter passing of a set literal. >>> >>> That said, I strongly dislike the confusion apparent here. We should >>> avoid new puzzlers if possible. I'd prefer >>> >>> List list = {"1", "2", "3"} - List literal >>> Map list = {1 : "1", 2 : "2", 3 : "3"} - Map >>> literal >>> No set literal >>> (I don't think this conflicts with the array literals...) >>> >>> Perhaps there is also an argument for adding the static of methods >>> to >>> construct mutable Set/List: >>> >>> Set set = HashSet.of("1", "2", "3"); // mutable set >>> List list = ArrayList.of("1", "2", "3"); // mutable list >>> List list2 = {"1", "2", "3"}; // immutable list >>> >>> >>> One final thought. It would be possible to add a "method" to the >>> list literal: >>> >>> Set set = {1, 2, 3}.toSet(); // immutable set >>> >>> This approach would handle additional interfaces too: >>> >>> SortedSet set = {1, 2, 3}.toSortedSet(); // immutable >>> sorted set >>> MultiSet mset = {1, 2, 3}.toMultiSet(); // immutable >>> multiset/bag (if added to JDK) >>> >>> Stephen >>> >>> >>> 2009/9/29 Reinier Zwitserloot : >>> >>>> Scanning my codebase, they are quite rare. As the set literals are >>>> causing rather a lot of pain, let's see some proof before going too >>>> far down this road. >>>> >>>> Pain caused by set literals: >>>> >>>> - ambiguity of {} - is that the empty set or the empty map? >>>> - set/list confusion. >>>> - the parser becomes quite a bit more complicated to handle the >>>> difference between sets and maps. >>>> >>>> --Reinier Zwitserloot >>>> >>>> >>>> >>>> On 2009/29/09, at 10:02, Mark Thornton wrote: >>>> >>>> >>>>> Reinier Zwitserloot wrote: >>>>> >>>>>> new HashSet<>(["a", "b", "c"]); >>>>>> >>>>>> is too much effort in the rare cases where you need to >>>>>> initialize a >>>>>> set-typed parameter? This is java, not perl. Golfing isn't the >>>>>> end >>>>>> goal. >>>>>> >>>>>> >>>>> Without scanning my codebase I wouldn't expect Set parameters and >>>>> fields to be rare. I use Set's quite frequently. >>>>> >>>>> Mark Thornton >>>>> >>>>> >>>> >>>> >> >> >> > From scolebourne at joda.org Wed Sep 30 05:19:23 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 30 Sep 2009 13:19:23 +0100 Subject: list literal gotcha and suggestion In-Reply-To: <995658.30901.qm@web112304.mail.gq1.yahoo.com> References: <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <995658.30901.qm@web112304.mail.gq1.yahoo.com> Message-ID: <4b4f45e00909300519l306a23eg6dd984c5a4fc11d1@mail.gmail.com> 2009/9/29 Gene Ray : > "Rare"? > > In my experience, Sets are not rare in well-written code; they're only rare in code where for whatever reason the developer has refused to use them I asked around a little where I work (corporate type environment). In general, the impression was that either developers don't know about Set, or can't be bothered using them as List will do. Being comfortable with List (and thus not having to think about another type) was a factor. One point I keep on making is that those of us here on this mailing list, or reading any kind of blog, are completely atypical of the vast bulk of developers. When taking decisions we have to be mindful of that, as in essence its very hard to hear the view of the famed "Java-Joe". The question here seems simple - whether having a Set literal in the language would encourage more usage of sets. Based on what I've seen, I'd say thats marginal. However, we know that the current syntax adds a (serious) language puzzler. To me, that strongly suggests omitting set literals, hopefully in favour of ListLiteral.toSet(). Stephen From schulz at e-spirit.de Wed Sep 30 05:47:50 2009 From: schulz at e-spirit.de (Schulz, Stefan) Date: Wed, 30 Sep 2009 14:47:50 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com><17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com><4AC1BA4E.5040108@optrak.co.uk><05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com><4AC1BF0B.9000109@optrak.co.uk><0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC1375A857@osiris2.e-spirit.de> Stephen wrote: > List list = {"1", "2", "3"} - List literal > Map list = {1 : "1", 2 : "2", 3 : "3"} - Map literal > No set literal > (I don't think this conflicts with the array literals...) Just wanted to add a little side-note that, despite not being technically confusable with Lists, Map literals would behave exactly like Sets wrt. duplicate keys. I'd rather prefer clearly typed factory methods over potentially confusing literals in the language. The only really awkward thing regarding creation to me are Maps. Cheers, Stefan From forax at univ-mlv.fr Wed Sep 30 05:54:59 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 30 Sep 2009 14:54:59 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <7D2077BFF677D2429DDDEE095D9A48AC1375A857@osiris2.e-spirit.de> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com><17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com><4AC1BA4E.5040108@optrak.co.uk><05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com><4AC1BF0B.9000109@optrak.co.uk><0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <7D2077BFF677D2429DDDEE095D9A48AC1375A857@osiris2.e-spirit.de> Message-ID: <4AC35523.8000902@univ-mlv.fr> Le 30/09/2009 14:47, Schulz, Stefan a ?crit : > Stephen wrote: > >> List list = {"1", "2", "3"} - List literal >> Map list = {1 : "1", 2 : "2", 3 : "3"} - Map literal >> No set literal >> (I don't think this conflicts with the array literals...) >> > Just wanted to add a little side-note that, despite not being technically confusable with Lists, Map literals would behave exactly like Sets wrt. duplicate keys. I'd rather prefer clearly typed factory methods over potentially confusing literals in the language. The only really awkward thing regarding creation to me are Maps. > Hi Stefan, I don't follow you. With a literal syntax, the compiler can detect duplicate keys at compile time if keys are constants. > Cheers, Stefan > R?mi From schulz at e-spirit.de Wed Sep 30 06:21:06 2009 From: schulz at e-spirit.de (Schulz, Stefan) Date: Wed, 30 Sep 2009 15:21:06 +0200 Subject: list literal gotcha and suggestion In-Reply-To: <4AC35523.8000902@univ-mlv.fr> References: <7D2077BFF677D2429DDDEE095D9A48AC1375A857@osiris2.e-spirit.de> <4AC35523.8000902@univ-mlv.fr> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC1375A860@osiris2.e-spirit.de> R?mi wrote > > Just wanted to add a little side-note that, despite not > being technically confusable with Lists, Map literals would > behave exactly like Sets wrt. duplicate keys. I'd rather > prefer clearly typed factory methods over potentially > confusing literals in the language. The only really awkward > thing regarding creation to me are Maps. > > > > Hi Stefan, > I don't follow you. With a literal syntax, the compiler can detect > duplicate keys at compile time > if keys are constants. Sorry, if my comment was too unclear. As the discussion included, whether to use [] or {} for Sets vs. Lists, I just wanted to add that, visually, with the suggestion by Stephen one still has curly braces for Lists, which keep duplicate entries, as well as for Maps, which remove duplicates similar to Sets. As said, this is no technical issue, but may be confusing especially wrt. not having a Set literal. Thinking of it, I am not sure, if this would make people abuse Map literals for Sets. Would the following be valid Java? Set set = {"a" :0, "b" :0, "c" :0}.keySet(); Stefan From evildeathmath at yahoo.com Wed Sep 30 07:03:08 2009 From: evildeathmath at yahoo.com (Gene Ray) Date: Wed, 30 Sep 2009 07:03:08 -0700 (PDT) Subject: literals Message-ID: <326620.4804.qm@web112309.mail.gq1.yahoo.com> Reinier-- I benchmarked this, and appear to have arrived at different results than you.? I used lists/sets of 10-character strings of lowercase letters, which is close a lot of use-cases I've seen, and ran 10^7 trials for each implementation (I used HashSet/ArrayList).? For 20 elements, set was a little over 3x faster (891 ms vs 2906 ms); for 7 elements set was still close to twice as fast (872/1550); for 2 elements set was still slightly faster (859/969).?? List was indeed faster with only one element (906/844), but at this point, I personally would just be using the .equals method instead.?? Varying the string length (I tried 5, 20, and 50) increased or decreased overall times slightly, but did not affect relative performance.? I would be curious to learn what you benchmarked against. The above was done with jdk1.6.0_12-b04, according to java -version. Perfomance is not the only concern.? "Sets" in java represent the mathematical notion of a set; lists do not, and pretending that the latter is equivalent to the former is a logical error regardless of common practice. ? > NB: Gene, you're trying to argue that a _literal_ set is > going to make ? > some sort of speed difference compared to a a_literal_ > list. That ? > notion is frankly ridiculous. You also lost track of the > first rule of ? > discussing speed: Test it first. So, go ahead. Benchmark a > bunch ? > of .contains() calls on a list and a set with the same > items in it, ? > both with say, 20 items in them (we are talking about > literals, after ? > all. I don't think anyone is seriously considering sticking > hundreds ? > of lines of code in a .java file to store constant data!) > -? on my own ? > machine Lists are less than a factor of 2 slower. For about > 7 items ? > and down, lists are in fact faster. Also, just in case > someone IS ? > tempted to write such a large collections literal: For such > a large ? > literal, the added burden of wrapping the literal in a > "new ? > HashSet<>()" or sticking a ".toSet();" at the end > seems trivial. > > I think the 'set literals are rare' seem to have it, so I > repeat my ? > plea to the set literal fans: Give us some proof they > aren't rare. ? > Given that set literals cause so much pain, the burden is > clearly on ? > the supporters of a set literal to prove why we need them. > >?? --Reinier Zwitserloot > > > > On 2009/29/09, at 21:07, Gene Ray wrote: > > > "Rare"? > > > > In my experience, Sets are not rare in well-written > code; they're ? > > only rare in code where for whatever reason the > developer has ? > > refused to use them, and instead expends effort and > CPU time ? > > iterating through an array or ArrayList to achieve the > equivalent ? > > functionality.? Encouraging this sort of behavior > further by ? > > including only Lists in the new syntax is not a good > plan. > > From mthornton at optrak.co.uk Wed Sep 30 07:21:51 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Wed, 30 Sep 2009 15:21:51 +0100 Subject: literals In-Reply-To: <326620.4804.qm@web112309.mail.gq1.yahoo.com> References: <326620.4804.qm@web112309.mail.gq1.yahoo.com> Message-ID: <4AC3697F.7010506@optrak.co.uk> Gene Ray wrote: > Reinier-- > > I benchmarked this, and appear to have arrived at > different results than you. I used lists/sets of 10-character strings > of lowercase letters, which is close a lot of use-cases I've seen, and > ran 10^7 trials for each implementation (I used HashSet/ArrayList). > Obujects with cheaper equals methods (e.g. Integer) will probably give different results. > Perfomance > is not the only concern. "Sets" in java represent the mathematical > notion of a set; lists do not, and pretending that the latter is > equivalent to the former is a logical error regardless of common practice. > > As a mathematician I do tend to use Set where that is the logical requirement, but I suspect that Stephen's ordinary Joe programmers are less fussy about such matters. Mark Thornton From Jonathan.Gibbons at Sun.COM Wed Sep 30 11:31:37 2009 From: Jonathan.Gibbons at Sun.COM (Jonathan Gibbons) Date: Wed, 30 Sep 2009 11:31:37 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> Message-ID: <4AC3A409.7090905@sun.com> +1 for the suggestion regarding HashSet.of, ArrayList.of, etc. This whole discussion over which type of brackets to use for which literal illustrates well why Java Is Not C. Java's design point is to go for clarity over obscurity at the cost of typing a few more characters. The fact that there can be such an ongoing discussion here illustrates why these literals are such a bad idea, when there are such clear and relatively simple alternatives. That all being said, I think map literals *are* a good idea, just because there is no reasonable alternative that can be used today. And even then, you really only need a syntax for a "pair", as in Expression ":" Expression. If you had that construct, then you could easily write HashMap.of(1: "1", 2: "2"), or TreeMap.of(1: "1", 2: "2"), etc -- Jon Stephen Colebourne wrote: > Over the 1.4million LOC codebase I work on, I found 12 set literals. > We're not talking about large numbers. Interestingly, the majority of > these were constants, and may be more common than list constants. > There weren't any cases of parameter passing of a set literal. > > That said, I strongly dislike the confusion apparent here. We should > avoid new puzzlers if possible. I'd prefer > > List list = {"1", "2", "3"} - List literal > Map list = {1 : "1", 2 : "2", 3 : "3"} - Map literal > No set literal > (I don't think this conflicts with the array literals...) > > Perhaps there is also an argument for adding the static of methods to > construct mutable Set/List: > > Set set = HashSet.of("1", "2", "3"); // mutable set > List list = ArrayList.of("1", "2", "3"); // mutable list > List list2 = {"1", "2", "3"}; // immutable list > > > One final thought. It would be possible to add a "method" to the list literal: > > Set set = {1, 2, 3}.toSet(); // immutable set > > This approach would handle additional interfaces too: > > SortedSet set = {1, 2, 3}.toSortedSet(); // immutable sorted set > MultiSet mset = {1, 2, 3}.toMultiSet(); // immutable > multiset/bag (if added to JDK) > > Stephen > > > 2009/9/29 Reinier Zwitserloot : > >> Scanning my codebase, they are quite rare. As the set literals are >> causing rather a lot of pain, let's see some proof before going too >> far down this road. >> >> Pain caused by set literals: >> >> - ambiguity of {} - is that the empty set or the empty map? >> - set/list confusion. >> - the parser becomes quite a bit more complicated to handle the >> difference between sets and maps. >> >> --Reinier Zwitserloot >> >> >> >> On 2009/29/09, at 10:02, Mark Thornton wrote: >> >> >>> Reinier Zwitserloot wrote: >>> >>>> new HashSet<>(["a", "b", "c"]); >>>> >>>> is too much effort in the rare cases where you need to initialize a >>>> set-typed parameter? This is java, not perl. Golfing isn't the end >>>> goal. >>>> >>>> >>> Without scanning my codebase I wouldn't expect Set parameters and >>> fields to be rare. I use Set's quite frequently. >>> >>> Mark Thornton >>> >>> >> >> > > From pbenedict at apache.org Wed Sep 30 12:24:31 2009 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 30 Sep 2009 14:24:31 -0500 Subject: list literal gotcha and suggestion Message-ID: Stephen, My apologies for not seeing that you already responded with a similar suggestion. I am glad to know that you and others are not alone in wanting static methods. PS: To those managing the Java language, please let's try to avoid having two ways of doing the same thing. If this proposal can be done with static methods and varargs, I find the utility of literal collections to be sorely diminished. Paul From fw at deneb.enyo.de Wed Sep 30 12:32:54 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 30 Sep 2009 19:32:54 +0000 Subject: list literal gotcha and suggestion In-Reply-To: <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> (Greg Brown's message of "Tue, 29 Sep 2009 20:34:47 -0400") References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> Message-ID: <87eipo2pp5.fsf@mid.deneb.enyo.de> * Greg Brown: > classes? To me, this: > > List list = ["a", "b", "c"]; > > isn't much better than: > > List list = new ArrayList("a", "b", "c"); But this doesn't work: List list = new ArrayList(1); So it has to be something like Collections.list() (the result of Arrays.asList() can't grow). > I recognize that maps are trickier, but I still think that this: > > Map map = new HashMap(new > AbstractMap.SimpleImmutableEntry("a", 0), > new AbstractMap.SimpleImmutableEntry("b", 1), > new AbstractMap.SimpleImmutableEntry("c", 2)); > > is preferable to modifying the language for what (to me) seems like a > fairly marginal use case. Really? You could write Map map = new HashMap() {{ put("a", 0); put("b", 1); put("c", 2); }}; today, but with a slightly surprising overhead, especially if the parameters aren't constant. From gkbrown at mac.com Wed Sep 30 12:38:28 2009 From: gkbrown at mac.com (Greg Brown) Date: Wed, 30 Sep 2009 15:38:28 -0400 Subject: list literal gotcha and suggestion In-Reply-To: <87eipo2pp5.fsf@mid.deneb.enyo.de> References: <17b2302a0909282143ib4a031dmc9a3869ec8fd6ed8@mail.gmail.com> <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <3D929785-8058-40B2-B18C-EDAA82A455AB@mac.com> <87eipo2pp5.fsf@mid.deneb.enyo.de> Message-ID: <6C5E1317-9430-4D4C-832C-8F16BE85B80F@mac.com> > But this doesn't work: > > List list = new ArrayList(1); > > So it has to be something like Collections.list() (the result of > Arrays.asList() can't grow). You are right. My original suggestion was actually to add a varargs version of unmodifiableList(), etc. (see http://mail.openjdk.java.net/pipermail/coin-dev/2009-July/002097.html ): List list = ArrayList.unmodifiableList(1, 2, 3); Set set = HashSet.unmodifiableSet("a", "b", "c"); But varargs constructors would be handy as well. Greg From fw at deneb.enyo.de Wed Sep 30 12:46:44 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 30 Sep 2009 19:46:44 +0000 Subject: list literal gotcha and suggestion In-Reply-To: <995658.30901.qm@web112304.mail.gq1.yahoo.com> (Gene Ray's message of "Tue, 29 Sep 2009 12:07:07 -0700 (PDT)") References: <995658.30901.qm@web112304.mail.gq1.yahoo.com> Message-ID: <87y6nw1ahn.fsf@mid.deneb.enyo.de> * Gene Ray: > "Rare"? > > In my experience, Sets are not rare in well-written code; they're > only rare in code where for whatever reason the developer has > refused to use them, and instead expends effort and CPU time > iterating through an array or ArrayList to achieve the equivalent > functionality.? Encouraging this sort of behavior further by > including only Lists in the new syntax is not a good plan. At least in JDK 6, the HashSet and TreeSet are wrappers around the corresponding maps. If there were more users, there would be a compelling reason to reimplement them without superfluous value references. 8-) From neal at gafter.com Wed Sep 30 13:02:13 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 30 Sep 2009 13:02:13 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <4AC3A409.7090905@sun.com> References: <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <4AC3A409.7090905@sun.com> Message-ID: <15e8b9d20909301302s584de29fm875bead2e853ee94@mail.gmail.com> On Wed, Sep 30, 2009 at 11:31 AM, Jonathan Gibbons wrote: > +1 for the suggestion regarding HashSet.of, ArrayList.of, etc. > > This whole discussion over which type of brackets to use for which > literal illustrates well why Java Is Not C. Java's design point is to > go for clarity over obscurity at the cost of typing a few more > characters. The fact that there can be such an ongoing discussion here > illustrates why these literals are such a bad idea, when there are such > clear and relatively simple alternatives. > > That all being said, I think map literals *are* a good idea, just > because there is no reasonable alternative that can be used today. And > even then, you really only need a syntax for a "pair", as in Expression > ":" Expression. If you had that construct, then you could easily write > HashMap.of(1: "1", 2: "2"), or TreeMap.of(1: "1", 2: "2"), etc > I agree that a solution along these lines is a better approach for these literals. However, I don't think the binary ":" operator is the best way to introduce a pair literal. Besides the ambiguity in the second position of a ?: expression (which can be resolved by precedence), this conflicts with the most likely syntax for named parameters*. This is an example of an ongoing problem with the Coin design process. There seems to be a lack of consideration for the long-term evolution of the language. Many of the Coin proposals (including accepted ones) conflict with reasonable (and likely and worthwhile) future directions. In other words, they may be local improvements in the language design space, but they are not always working toward global maxima. Cheers, Neal * Incidentally, I take issue with parts of Alex Buckley's analysis of the design space for named parameters. He sets up some strawman designs and then shows how they fail to support named parameters with reordering. We added support for named parameters in version 4.0 of the C# language, including support for reordering, and our experience is that the change is quite beneficial. Alex's analysis demonstrates that the design space requires more exploration before committing to a particular design for Java. From Jonathan.Gibbons at Sun.COM Wed Sep 30 13:36:25 2009 From: Jonathan.Gibbons at Sun.COM (Jonathan Gibbons) Date: Wed, 30 Sep 2009 13:36:25 -0700 Subject: list literal gotcha and suggestion In-Reply-To: <15e8b9d20909301302s584de29fm875bead2e853ee94@mail.gmail.com> References: <17b2302a0909282234g76793a10s4410e3bd9b6d38b7@mail.gmail.com> <4AC1BA4E.5040108@optrak.co.uk> <05B24737-9714-4078-87BD-87D36952E5EF@zwitserloot.com> <4AC1BF0B.9000109@optrak.co.uk> <0828DA51-FD90-44C3-925A-A2AA3F196308@zwitserloot.com> <4b4f45e00909290253n6233da74we0c900a23b6a4003@mail.gmail.com> <4AC3A409.7090905@sun.com> <15e8b9d20909301302s584de29fm875bead2e853ee94@mail.gmail.com> Message-ID: <4AC3C149.5090507@sun.com> Neal, I agree that ':' may not be the best choice of separator for these so-called pair literals, and that there must be some other token we can use. We could also use JSR 308 annotations to achieve some amount of compile time checking of varargs argument lists. For example, class HashSet { static HashSet of(@Unique T...) } -- Jon Neal Gafter wrote: > On Wed, Sep 30, 2009 at 11:31 AM, Jonathan Gibbons >> wrote: >> > > >> +1 for the suggestion regarding HashSet.of, ArrayList.of, etc. >> >> This whole discussion over which type of brackets to use for which >> literal illustrates well why Java Is Not C. Java's design point is to >> go for clarity over obscurity at the cost of typing a few more >> characters. The fact that there can be such an ongoing discussion here >> illustrates why these literals are such a bad idea, when there are such >> clear and relatively simple alternatives. >> >> That all being said, I think map literals *are* a good idea, just >> because there is no reasonable alternative that can be used today. And >> even then, you really only need a syntax for a "pair", as in Expression >> ":" Expression. If you had that construct, then you could easily write >> HashMap.of(1: "1", 2: "2"), or TreeMap.of(1: "1", 2: "2"), etc >> >> > > I agree that a solution along these lines is a better approach for these > literals. However, I don't think the binary ":" operator is the best way to > introduce a pair literal. Besides the ambiguity in the second position of a > ?: expression (which can be resolved by precedence), this conflicts with the > most likely syntax for named parameters*. > > This is an example of an ongoing problem with the Coin design process. > There seems to be a lack of consideration for the long-term evolution of the > language. Many of the Coin proposals (including accepted ones) conflict > with reasonable (and likely and worthwhile) future directions. In other > words, they may be local improvements in the language design space, but they > are not always working toward global maxima. > > Cheers, > Neal > > * Incidentally, I take issue with parts of Alex Buckley's analysis of the > design space for named > parameters. > He sets up some strawman designs and then shows how they fail to support > named parameters with reordering. We added support for named parameters in > version 4.0 of the C# language, including support for reordering, and our > experience is that the change is quite beneficial. Alex's analysis > demonstrates that the design space requires more exploration before > committing to a particular design for Java. > >