From howard.lovatt at iee.org Mon Nov 2 03:42:24 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 2 Nov 2009 12:42:24 +0100 Subject: Reference implementation In-Reply-To: <15e8b9d20910300748l4322aca0i379763b15816745@mail.gmail.com> References: <3dd3f56a0910290904m3a70673dn5dee12eec55a776@mail.gmail.com> <4AE9C0C1.4060306@sun.com> <3dd3f56a0910300206v7f33d527u5693065f9d0288f2@mail.gmail.com> <15e8b9d20910300748l4322aca0i379763b15816745@mail.gmail.com> Message-ID: <3dd3f56a0911020342y28b7d4b2h91358c92e25ea891@mail.gmail.com> Hi Neal, Having written a lot of embedded code, though not for WiFi, as well as more conventionally deployed software, I would say that normally-deployed code has it easy. This is maybe why you don't appreciate how useful the version number is. All my experience with embedded code is that the code has a long lifetime and is continually improved, just like more conventional code, and just like the hardware it runs on. It is a continuous system of evolution with continuous deployment, the catch is that you can't offer an upgrade once deployed so you are much more concerned about bugs and much more concerned with backward compatibility. Take the WiFi example, a WiFi device typically supports multiple versions and if a newer device talks to an older device then it uses the older version of the spec. and can't necessarily use all the new facilities (I will come back to this point). Re. spec.; the WiFi spec. is much more complicated than the Java spec., so saying that the spec. is too hard seems to me to be stretching a point a little. For example the differnt versions of WiFi use completely different techniques for coping with multiple path interference. For Java we could choose to say that the first non-comment, non-whitespace line in any Java 7 program has to be a source statement. If the first line isn't a source statement then it isn't Java 7 and is described in JLS ed. 3. Then make module a proper keyword and don't introduce the diamond operator (I will come back to this point). The new version of the JLS could be called JLS7 (note name of JLS matches version number, 1.7). Now that isn't a big change to the JLS, therefore demonstrating that source can be introduced without large changes to the JLS. The compiler vendor would be free to produce a compiler that is Java 7 only, but I suspect that most would produce a compiler that would compile 6 as well (just like WiFi vendors support some of the old standards). (I suspect that the above proposal of only a module statement is so minor that you could mandate that a Java 7 compiler must support all past versions as described in JLS ed. 3.) A tool could be produced that finds all the uses of module as a name and these could be automatically changed to use the new exotic identifiers (exotic identifiers are already scheduled for 7). In the next version of Java, when more time and more resources are available, the type system could be overhauled and something more ambitious than the diamond operator added. The point is that the source keyword has positioned you to make such changes. Unlike the changes I suggested above for Java 7 these might not be backward compatible, but this would be on a case by case basis. To make this case-by-case point concrete, lets go back to the WiFi example. Some aspects of the new standard are typically not compatible with the old, the most obvious is speed (this would be a case were the new system drops down to the old standard). Other aspects are, e.g. better RF systems and the new system would still be able to use its better RF. The above WiFi example is migration compatibility in action, proven for a complicated system over many versions with many vendors and over a short time scale. Currently in Java you have one choice, all new systems must be compatible with the past, which is why change is so hard. Source breaks this viscous cycle. You effectively have the source version embedded in the class file already; since the class file is already versioned, therefore you can have this optional migration once you have source. IE just like WiFi, you might not be able to use a new feature if you want to call old code and you might not (on a case by case basis). Therefore the source statement positions you for future migration on a case by case basis, instead of the current 'race condition' (to use a computer science analogy) where all changes must be compatible. Think how much easier the 1.4 transition would have been if we had had source and exotic identifiers, a tool could have migrated the code automatically for files that you wanted to use the new features of enum and assert in and other files wouldn't need touching! Now you can't tell me in all seriousness that source wouldn't have been great for that transition and I assert (pun intended) it will *help* for all future transitions. Since Joe's answer appeared to be along the lines of "over my dead body", re. the source statement, you are correct in saying the point is moot. :( -- Howard. 2009/10/30 Neal Gafter > Howard- > > Let me recap the conclusions as I recall them. > > Your parallel with WiFi breaks down; your proposal for a source declaration > would be an enormous change to the specification; the change would be a tiny > benefit (if any). > > The parallel with WiFi breaks down because software, by its very nature, > evolves. While wireless devices are generally fixed once manufactured, any > given program is likely to undergo extensive changes over its lifetime. One > of the main purposes of changes to the Java language is to make such program > evolution easier by providing further facilities for programmers to use. > But if a prerequisite to using language features in version 8, for example, > requires modifying your source code remove or refactor the use of features > that are no longer supported (e.g. wildcards, presuming we come up with an > alternative that is migration-compatible), it could become an enormous > burden to use any new features in existing code. One might as well give > version 8 a new name (e.g. Scala). > > It is an enormous change because, by moving the version specification into > the realm of the language, the language specification must provide a precise > meaning to any given value of the version string. That means it must > incorporate a full specification for all of the supported versions. In > addition, it must specify the meaning of programs composed of a mixture of > source file versions. While that kind of specification would be useful > today, it is not required as part of the language specification, and it is > not provided in the JLS. I can easily imagine that would double the size of > the JLS. Clearly, that is far outside the scope of project Coin. > > Finally, the proposal would only be of the smallest benefit. All of the > issues we've been wranging with for each of the proposed language features > still has to be addressed. We still have to consider backward compatibility > if we want programmers to be able to use these features *in the context of > an existing code base*. So adding that enormous work item to project coin > would not reduce the amount of work for any of the individual features under > consideration. > > In short, a version declaration is neither a silver bullet, nor a solution > to any problem we've been struggling with. > > Cheers, > Neal > > On Fri, Oct 30, 2009 at 2:06 AM, Howard Lovatt wrote: > >> Joe, >> >> As I recall the discussions on source, for that matter the diamond >> operator >> re. more extensive type inference, was that the technical discussion had >> not >> reached a consensus, but the discussions ended because the outcome was >> decreed (presumable by some process within Sun). Your reply, "discussed >> extensively ...", implies that some form of consensus was reached, which >> is >> not my recollection. >> >> You, and many others, have more in-depth knowledge of the compiler than I >> have, undoubtedly. However an in-depth knowledge can be both a blessing >> and >> a curse. There are many examples were someone with a wider breadth, but >> not >> so in-depth, knowledge can come up with a solution by bringing expertise >> for >> other areas. An example of where versioning is very successful is WiFi, >> over >> a short time scale we have gone from 802.11a to n. The letters are the >> version numbers, the protocols are different, but the hardware can run >> multiple versions because much of the infrastructure is common (RF >> amplifiers, aerials, etc.). Can you not see the parallels: different >> versions a to n (Java source versions) and the same underlying hardware >> (the >> JVM)? The committees that specify WiFi have the same issues: a formal >> specification, mass deployment, multiple vendors, etc., and the solution >> that has proven to work well is versioning. >> >> Taking ideas from others and other domains is well established in science >> in >> general, e.g. Isaac Newton, in 1676 said, "If I have seen a little further >> it is by standing on the shoulders of Giants." Perhaps you could consider >> standing on the shoulders of the WiFi giants. >> >> -- Howard. >> >> 2009/10/29 Joseph D. Darcy >> >> > No Howard, your source statement was discussed extensively on this list >> > (see the archives) and it is not a silver bullet and is not going to be >> part >> > of JDK 7, no matter how many times you bring it up or in how many >> venues. >> > >> > -Joe >> > >> > >> > Howard Lovatt wrote: >> > >> >> Wouldn't it be simpler to introduce a source statement in Coin, forget >> the >> >> diamond operator, and get 7 out. Having introduced source, 8 can be >> >> incompatible with previous Java versions (except at the JVM level), >> >> wildcards dropped, generics reified, and type inference for methods and >> >> declarations improved. >> >> >> >> -- Howard. >> >> >> >> ---------- Forwarded message ---------- >> >> From: Maurizio Cimadamore >> >> To: Reinier Zwitserloot >> >> Date: Thu, 29 Oct 2009 15:13:21 +0000 >> >> Subject: Re: Reference implementation >> >> Reinier Zwitserloot wrote: >> >> >> >> >> >> >> >>> Actually, those 3 examples don't seem too bad for future expansion. >> Sure, >> >>> reification is a hard nut to crack, but it always has been. >> >>> >> >>> >> >>> >> >> Just to clarify - I said that these 3 decisions have made reification >> >> *nearly* impossible - not impossible at all. I guess that the length of >> >> your >> >> proposal for dealing with cast speak for itself (if we need to kinda >> >> workaround to the fact that now it's possible to write generic cast >> even >> >> without reification support that means that the decision does >> jeopardize >> >> further language evolution - e.g it prevents reified Java from using >> >> classic >> >> syntax for casts - note that this problem does not occur with >> >> instanceof). >> >> >> >> As far as my other two issues - I'm not concerned about typing and >> safety >> >> - >> >> what I'm concerned about is performances - if you have instances of >> >> Foo<#1> >> >> or Foo<#1 extends Object & Comparable> ... >> >> > >> >> >> >> >> >>> are you sure that the VM could still perform decently? The Java >> subtyping >> >>> >> >>> >> >> algorithm with generics and wildcards is complex enough that it >> suffices a >> >> bit of twists and turns to make javac to run out of Stack (even in >> cases >> >> where subtyping can be proved). What does that mean to have such a >> >> subtyping >> >> test inside the JVM ? That's what I'm worried about. >> >> >> >> Maurizio >> >> >> >> >> >> >> > >> > >> > ______________________________________________________________________ >> > This email has been scanned by the MessageLabs Email Security System. >> > For more information please visit >> http://www.messagelabs.com/email______________________________________________________________________ >> > >> >> >> >> -- >> -- Howard. >> >> > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. From barney at frontofficedeveloper.com Mon Nov 2 14:27:27 2009 From: barney at frontofficedeveloper.com (Barney Pitt) Date: Mon, 2 Nov 2009 22:27:27 +0000 Subject: One-sided instantiation (diamond, collection literals) Message-ID: I've watched the recent diamond and collection literal threads with interest, but also with a certain bemusement; I believe there is a remarkably simple language change which is entirely free of ambiguity, complexity and (maybe even!) controversy, which elegantly negates the need for either in pursuit of a more concise yet clear java language. In either case, the principal motivation is the desire to be able to declare and instantiate an object without unnecessary verbosity, and to improve the clarity of such statements. Let me propose a simple language change which achieves this not only when declaring collections and generically defined objects, but for all cases where an object is declared and instantiated. Any statement of the form Foo foo=new Foo(myBar, myBaz); can be replaced by Foo foo(myBar, myBaz); With this simple change (which, like most language changes, will look a little odd the first few times you see it, but will very quickly become natural), plus the addition of varargs arguments to the major collections (ArrayList, LinkedList, HashSet, TreeSet and LinkedHashSet is probably enough), we have concise and unambigous collection instantiation, with or without generics. ArrayList myList(myOtherStringList); // uses #ArrayList(Collection) ctr LinkedHashSet mySet("one", "two", "three"); // uses varargs ctr MyNonGenericClassWithLongName myObject(someArgument); // improves readability and conciseness for any instantiating declaration There is no inference necessary regarding the type of either the LHS *or* RHS, because there *is* no LHS or LHS ("one-sided instantiation"). I can foresee some objections that may be raised here ... (i) I can't declare using the interface/base class but instantiate with a subclass. Good. If its a TreeSet, say its a TreeSet. Thankfully, Java isn't Groovy or Scala, and in Java-land we think it is as important to say what we mean as it is to mean what we say. Obviously, in API declarations like Collections.sort(X), X should be the most generally applicable interface or base class. Not so for a local variable declaration or field declaration - the author of the code knows which (e.g.) Set subclass is actually used, and should state so clearly - the reader of the code then also knows, from the get-go, the characteristics of the subclass in use. The cases where it is actually useful to say Map map=new HashMap(); // (do something) map=new TreeSet(); (or anything similar) are incredibly rare, in my experience, and where you feel the need to write code like this, then you can still do so - just not using one-sided instantiation. (ii) I can't pass a collection literal straight into a method without using new-varargs or a generic static method. Again, I say good. foo(Immutable.list("one", "two", "three")); or foo(new TreeSet("x", "y", "z")) are admittedly more verbose than foo({"x", "y", "z"}) or foo(["a", "b", "c"]) but elide any of the ambiguity (already discussed at length in this list) regarding the exact type of collection. Again, don't just mean what you say, say what you mean. I don't think that having to clearly state the type of something which you pass to a method annoys or inhibits the productivity "Joe Java", whereas I do think that stating everything twice, as in HashMap> map=new HashMap(...); does. (iii) I can't use diamond to infer the type arguments in a method call. True, the proposal does not enable one to say foo(new ArrayList<>(bar, baz)); and have the compiler perform some elaborate inference algorithm (with all the pitfalls which entail, see many mails to this list) to determine the type argument. It does allow one to say ArrayList widgets(bar, baz); foo(widgets); I think, again, it is preferable to say what you mean than for the compiler to infer what you meant. The next developer who reads your code is not a compiler. (iv) In C++, that notation means "instantiate on the stack", not "instantiate on the heap". So what. I think we long, long ago passed the point where familiarity to/acceptance by C or C++ programmers was a language design goal. All objects go on the heap in Java, so no change there. (v) It doesn't address Map literals at all. True. I'm really not sold on the need for them, personally, but my approach doesn't *preclude* using some special syntax for Map.Entry (though I would be against it), e.g. HashMap wordCounts("the":25, "of":16, "and":12); So one simple change makes *all* combined declare-and-instantiate statements as concise (in fact more concise) as in Groovy/Scala/whatever, whilst at the same time retaining/strengthening Java's strong typing, *and* maintaining Java's "blue collar" philosophy: that readability and maintainability by ones colleagues are more important than saving keystrokes. A huge benefit of this proposal is that the change to the compiler code is almost trivial. I've only recently started hacking javac, but even I was able to figure out what needed to be changed, and where, in about an hour. In Parser#variableDeclaratorRest(...), replace // ... if (S.token() == EQ) { S.nextToken(); init = variableInitializer(); } else if (reqInit) // ... with // ... if (S.token() == EQ) { S.nextToken(); init = variableInitializer(); } // BEGIN CHANGE else if (S.token() == LPAREN || S.token() == LT) { List typeArguments = null; if (S.token() == LT) { // Explicit type args on constructor. // Extremely rarely used, replaces e.g. Foo foo=new Foo(); // with Foo foo(); typeArguments=typeArguments(); } JCExpression newClass = classCreatorRest(S.pos(), null, typeArguments, type); init = newClass; } // END CHANGE else if (reqInit) // ... (plus of course the trivial changes required to add varargs ctrs to the principal collections). It seems to me that this seven line compiler change does as much or more for Java's conciseness and readability as diamond and collection literals put together. And it doesn't (so far as I can see) introduce any "gotchas", nor require "Joe Java" to wrangle with mysterious synthetic collection types or wonder what three pages of JLS gobbledegook about generic type inference actually means. I realize that the official window for suggestions for Java 7 language enhancements passed some time ago. But having followed the debate on apparently the two most contentious proposals and noted a simple alternative to both which I think is far preferable, I thought it was appropriate to post it here. (PS. My apologies if this idea has already been discussed here before I started watching the list and dismissed for various reasons, in which case please direct me to that discussion.) Barney _________________________________________________________________ Be one of the first to try Windows Live Mail. http://ideas.live.com/programpage.aspx?versionId=5d21c51a-b161-4314-9b0e-4911fb2b2e6d From markmahieu at googlemail.com Mon Nov 2 14:52:13 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 2 Nov 2009 22:52:13 +0000 Subject: One-sided instantiation (diamond, collection literals) In-Reply-To: References: Message-ID: <48074214-BE8C-42C0-B120-6592DB26B5B1@googlemail.com> On 2 Nov 2009, at 22:27, Barney Pitt wrote: > > Let me propose a simple language change which achieves this not > only when declaring collections and generically defined objects, > but for all cases where an object is declared and instantiated. > > Any statement of the form > > Foo foo=new Foo(myBar, myBaz); > > can be replaced by > > Foo foo(myBar, myBaz); OK, so what would this mean? interface I { String s(); } Regards, Mark From reinier at zwitserloot.com Mon Nov 2 14:55:05 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 2 Nov 2009 22:55:05 +0000 Subject: One-sided instantiation (diamond, collection literals) In-Reply-To: References: Message-ID: <560fb5ed0911021455i1835fcd3n55ce6abd3d269685@mail.gmail.com> So, all your solution really solves is this one case: Type type = new Type(); by introducing some fairly odd syntax that looks exactly like a method declaration, but isn't. Being able to pass lists in-line inside method arguments seems like rather a big deal to give up. Your concern that list literals will not be obvious and that it is of crucial importance that all know that you're really talking about ArrayList and not just any list does not bear out at all in my own code base - all lists are really just that, lists. Some maybe LinkedLists, others are ImmutableLists, but the times where I care about this distinction anywhere except when creating the list is exceedingly rare for me. How are others' list concerns? --Reinier Zwitserloot On Mon, Nov 2, 2009 at 10:27 PM, Barney Pitt < barney at frontofficedeveloper.com> wrote: > > > > > > > > > > > > > > > > > > I've watched the recent diamond and collection literal threads with > interest, but also with a certain bemusement; I believe there is a > remarkably simple language change which is entirely free of ambiguity, > complexity and (maybe even!) controversy, which elegantly negates the need > for either in pursuit of a more concise yet clear java language. > > In either case, the principal motivation is the desire to be able to > declare and instantiate an object without unnecessary verbosity, and to > improve the clarity of such statements. > > Let me propose a simple language change which achieves this not only when > declaring collections and generically defined objects, but for all cases > where an object is declared and instantiated. > > Any statement of the form > > Foo foo=new Foo(myBar, myBaz); > > can be replaced by > > Foo foo(myBar, myBaz); > > With this simple change (which, like most language changes, will look a > little odd the first few times you see it, but will very quickly become > natural), plus the addition of varargs arguments to the major collections > (ArrayList, LinkedList, HashSet, TreeSet and LinkedHashSet is probably > enough), we have concise and unambigous collection instantiation, with or > without generics. > > ArrayList myList(myOtherStringList); // uses #ArrayList(Collection) > ctr > > LinkedHashSet mySet("one", "two", "three"); // uses varargs ctr > > MyNonGenericClassWithLongName myObject(someArgument); // improves > readability and conciseness for any instantiating declaration > > There is no inference necessary regarding the type of either the LHS *or* > RHS, because there *is* no LHS or LHS ("one-sided instantiation"). > > I can foresee some objections that may be raised here ... > > > > (i) I can't declare using the interface/base class but instantiate with a > subclass. > > Good. If its a TreeSet, say its a TreeSet. Thankfully, Java isn't Groovy or > Scala, and in Java-land we think it is as important to say what we mean as > it is to mean what we say. Obviously, in API declarations like > Collections.sort(X), X should be the most generally applicable interface or > base class. Not so for a local variable declaration or field declaration - > the author of the code knows which (e.g.) Set subclass is actually used, and > should state so clearly - the reader of the code then also knows, from the > get-go, the characteristics of the subclass in use. > > The cases where it is actually useful to say > > Map map=new HashMap(); > // (do something) > map=new TreeSet(); > > (or anything similar) are incredibly rare, in my experience, and where you > feel the need to write code like this, then you can still do so - just not > using one-sided instantiation. > > (ii) I can't pass a collection literal straight into a method without using > new-varargs or a generic static method. > > Again, I say good. > > foo(Immutable.list("one", "two", "three")); > > or > > foo(new TreeSet("x", "y", "z")) > > are admittedly more verbose than > > foo({"x", "y", "z"}) > > or > > foo(["a", "b", "c"]) > > but elide any of the ambiguity (already discussed at length in this list) > regarding the exact type of collection. Again, don't just mean what you say, > say what you mean. > > I don't think that having to clearly state the type of something which you > pass to a method annoys or inhibits the productivity "Joe Java", whereas I > do think that stating everything twice, as in > > HashMap> map=new HashMap Baz>(...); > > does. > > (iii) I can't use diamond to infer the type arguments in a method call. > > True, the proposal does not enable one to say > > foo(new ArrayList<>(bar, baz)); > > and have the compiler perform some elaborate inference algorithm (with all > the pitfalls which entail, see many mails to this list) to determine the > type argument. It does allow one to say > > ArrayList widgets(bar, baz); > foo(widgets); > > I think, again, it is preferable to say what you mean than for the compiler > to infer what you meant. The next developer who reads your code is not a > compiler. > > (iv) In C++, that notation means "instantiate on the stack", not > "instantiate on the heap". > > So what. I think we long, long ago passed the point where familiarity > to/acceptance by C or C++ programmers was a language design goal. All > objects go on the heap in Java, so no change there. > > (v) It doesn't address Map literals at all. > > True. I'm really not sold on the need for them, personally, but my approach > doesn't *preclude* using some special syntax for Map.Entry (though I would > be against it), e.g. > > HashMap wordCounts("the":25, "of":16, "and":12); > > > > So one simple change makes *all* combined declare-and-instantiate > statements as concise (in fact more concise) as in Groovy/Scala/whatever, > whilst at the same time retaining/strengthening Java's strong typing, *and* > maintaining Java's "blue collar" philosophy: that readability and > maintainability by ones colleagues are more important than saving > keystrokes. > > A huge benefit of this proposal is that the change to the compiler code is > almost trivial. I've only recently started hacking javac, but even I was > able to figure out what needed to be changed, and where, in about an hour. > In Parser#variableDeclaratorRest(...), replace > > // ... > if (S.token() == EQ) { > S.nextToken(); > init = variableInitializer(); > } > else if (reqInit) // ... > > with > > // ... > if (S.token() == EQ) { > S.nextToken(); > init = variableInitializer(); > } > // BEGIN CHANGE > else if (S.token() == LPAREN || S.token() == LT) { > List typeArguments = null; > if (S.token() == LT) { > // Explicit type args on constructor. > // Extremely rarely used, replaces e.g. Foo foo=new > Foo(); > // with Foo foo(); > typeArguments=typeArguments(); > } > JCExpression newClass = classCreatorRest(S.pos(), null, > typeArguments, type); > init = newClass; > } > // END CHANGE > else if (reqInit) // ... > > (plus of course the trivial changes required to add varargs ctrs to the > principal collections). > > It seems to me that this seven line compiler change does as much or more > for Java's conciseness and readability as diamond and collection literals > put together. > > And it doesn't (so far as I can see) introduce any "gotchas", nor require > "Joe Java" to wrangle with mysterious synthetic collection types or wonder > what three pages of JLS gobbledegook about generic type inference actually > means. > > I realize that the official window for suggestions for Java 7 language > enhancements passed some time ago. But having followed the debate on > apparently the two most contentious proposals and noted a simple alternative > to both which I think is far preferable, I thought it was appropriate to > post it here. > > > (PS. My apologies if this idea has already been discussed here before I > started watching the list and dismissed for various reasons, in which case > please direct me to that discussion.) > > > Barney > > > > > _________________________________________________________________ > Be one of the first to try Windows Live Mail. > > http://ideas.live.com/programpage.aspx?versionId=5d21c51a-b161-4314-9b0e-4911fb2b2e6d > > From neal at gafter.com Mon Nov 2 17:26:21 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 2 Nov 2009 17:26:21 -0800 Subject: One-sided instantiation (diamond, collection literals) In-Reply-To: References: Message-ID: <15e8b9d20911021726t182ab432u8172914291ae6e69@mail.gmail.com> Barney- I suspect you're reading more confusion and controversy into this than is really present. This is the normal process of language design. We explore the corners of a proposed specification until we have it in just the right shape. It may take a lot of discussion and tweaking, and it may even require some hard work from the participants, but that isn't necessarily because we're finding the basic approach unworkable. The failure of your proposal to generalize (in the future) to argument contexts is a killer for me. The suggested "workaround" *ArrayList widgets(bar, baz); foo(widgets); * doesn't work unless the method invocation is a top-level statement or you don't care about the order of evaluation (try doing this in a base class constructor invocation). I'm also not thrilled that you can't declare the variable of an interface type and initialize it with a class type, and that it looks too much like a method declaration, but those are secondary. If you're going to take the approach that you only get to specify one type, and that the construct only applies to local variable declarations, I'd rather see a context-sensitive keyword *var widgets = new ArrayList(bar, baz);* In any case, this is all far too late for project Coin. Cheers, Neal From barney at frontofficedeveloper.com Tue Nov 3 03:05:09 2009 From: barney at frontofficedeveloper.com (Barney Pitt) Date: Tue, 3 Nov 2009 11:05:09 +0000 Subject: One-sided instantiation (diamond, collection literals) Message-ID: Newbie apologies, reinierz at gmail.com has just pointed out that I have been replying to members without a CC to coin-dev! From: barney at frontofficedeveloper.com To: markmahieu at googlemail.com Subject: RE: One-sided instantiation (diamond, collection literals) Date: Tue, 3 Nov 2009 10:56:28 +0000 I'm sure that in the first example you meant interface I { String s();}class C { String s = new String();} as "s" could not be field in an interface. But I still don't really see what you're getting at. Shadowing an accessible method name or field name in a subclass/implementation is an appalling practise which should have been outlawed by the language from the off. But I don't see how my proposal makes the situation any worse. Barney From: markmahieu at googlemail.com Subject: Re: One-sided instantiation (diamond, collection literals) Date: Tue, 3 Nov 2009 10:16:08 +0000 To: barney at frontofficedeveloper.com Thanks for the reply. What I mean though, is that the following currently legal example declares an interface and a class each with a field named 's': interface I { String s = new String();}class C { String s = new String();} Under your proposal, I could then change the above to: interface I { String s();}class C { String s();} In the interface, I now have a method called 's', yet in the class I've still got the field just using different declaration syntax. That's highly inconsistent, in my opinion. Regards, Mark On 3 Nov 2009, at 09:47, Barney Pitt wrote: It would mean that your interface declares a method s() returning String. Were it an abstract class, it would mean that your field s is initialized empty. I'm not sure I've ever seen a practical example of a Java class which wasn't written with fields declared first in a block and methods declared afterwards, although I confess that if you do mix abstract method declarations willy-nilly with field declarations the notation might confuse a newcomer. I'm more concerned with the everyday practicalities of succinct readable code - though of course I fully accept that readability is subjective. Barney CC: coin-dev at openjdk.java.net From: markmahieu at googlemail.com Subject: Re: One-sided instantiation (diamond, collection literals) Date: Mon, 2 Nov 2009 22:52:13 +0000 To: barney at frontofficedeveloper.com On 2 Nov 2009, at 22:27, Barney Pitt wrote: Let me propose a simple language change which achieves this not only when declaring collections and generically defined objects, but for all cases where an object is declared and instantiated. Any statement of the form Foo foo=new Foo(myBar, myBaz); can be replaced by Foo foo(myBar, myBaz); OK, so what would this mean? interface I { String s();} Regards, Mark Be one of the first to try Windows Live Mail. Be one of the first to try Windows Live Mail. _________________________________________________________________ Be one of the first to try Windows Live Mail. http://ideas.live.com/programpage.aspx?versionId=5d21c51a-b161-4314-9b0e-4911fb2b2e6d From barney at frontofficedeveloper.com Tue Nov 3 03:33:31 2009 From: barney at frontofficedeveloper.com (Barney Pitt) Date: Tue, 3 Nov 2009 11:33:31 +0000 Subject: One-sided instantiation (diamond, collection literals) Message-ID: From: barney at frontofficedeveloper.com Subject: RE: One-sided instantiation (diamond, collection literals) Date: Tue, 3 Nov 2009 11:30:25 +0000 My sincere apologies Mark, I had completely forgotten that interfaces can declare static fields without the keyword static. I haven't seen it done in years. Personally I'd include that case as "shadowing" and a dreadful practice which should be outlawed - but I don't have a ready solution as to how it would work with my proposal :( From: markmahieu at googlemail.com Subject: Re: One-sided instantiation (diamond, collection literals) Date: Tue, 3 Nov 2009 11:04:00 +0000 To: barney at frontofficedeveloper.com No, I meant what I wrote. The following is perfectly legal in Java: interface I { String s = new String();} This has nothing to do with shadowing. Mark On 3 Nov 2009, at 10:56, Barney Pitt wrote: I'm sure that in the first example you meant interface I { String s();}class C { String s = new String();} as "s" could not be field in an interface. But I still don't really see what you're getting at. Shadowing an accessible method name or field name in a subclass/implementation is an appalling practise which should have been outlawed by the language from the off. But I don't see how my proposal makes the situation any worse. Barney From: markmahieu at googlemail.com Subject: Re: One-sided instantiation (diamond, collection literals) Date: Tue, 3 Nov 2009 10:16:08 +0000 To: barney at frontofficedeveloper.com Thanks for the reply. What I mean though, is that the following currently legal example declares an interface and a class each with a field named 's': interface I { String s = new String();}class C { String s = new String();} Under your proposal, I could then change the above to: interface I { String s();}class C { String s();} In the interface, I now have a method called 's', yet in the class I've still got the field just using different declaration syntax. That's highly inconsistent, in my opinion. Regards, Mark On 3 Nov 2009, at 09:47, Barney Pitt wrote: It would mean that your interface declares a method s() returning String. Were it an abstract class, it would mean that your field s is initialized empty. I'm not sure I've ever seen a practical example of a Java class which wasn't written with fields declared first in a block and methods declared afterwards, although I confess that if you do mix abstract method declarations willy-nilly with field declarations the notation might confuse a newcomer. I'm more concerned with the everyday practicalities of succinct readable code - though of course I fully accept that readability is subjective. Barney CC: coin-dev at openjdk.java.net From: markmahieu at googlemail.com Subject: Re: One-sided instantiation (diamond, collection literals) Date: Mon, 2 Nov 2009 22:52:13 +0000 To: barney at frontofficedeveloper.com On 2 Nov 2009, at 22:27, Barney Pitt wrote: Let me propose a simple language change which achieves this not only when declaring collections and generically defined objects, but for all cases where an object is declared and instantiated. Any statement of the form Foo foo=new Foo(myBar, myBaz); can be replaced by Foo foo(myBar, myBaz); OK, so what would this mean? interface I { String s();} Regards, Mark Be one of the first to try Windows Live Mail. Be one of the first to try Windows Live Mail. _________________________________________________________________ Be one of the first to try Windows Live Mail. http://ideas.live.com/programpage.aspx?versionId=5d21c51a-b161-4314-9b0e-4911fb2b2e6d From Joe.Darcy at Sun.COM Tue Nov 3 10:23:15 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 03 Nov 2009 10:23:15 -0800 Subject: Strings in switch implementation checked into JDK 7 m05 code base Message-ID: <4AF07513.4060909@sun.com> Greetings. Joining the diamond operator, improved integer literals, and language support for JSR 292, as of last night a strings in switch implementation is now in the JDK 7 milestone 5 code base: http://hg.openjdk.java.net/jdk7/m5/langtools/rev/8fb9b4be3cb1 JDK 7 binary builds with this feature will follow in due course. -Joe From Barry at Burd.org Tue Nov 3 12:37:16 2009 From: Barry at Burd.org (Barry Burd) Date: Tue, 03 Nov 2009 15:37:16 -0500 Subject: Strings in switch implementation checked into JDK 7 m05 code base Message-ID: <4AF04E2C.618A.0054.0@Burd.org> Joe, >From what I can gather, this feature isn't in Build 75 (but Build 75 is the last build in M5). Am I right about all this? --Barry From Tim.Bell at Sun.COM Tue Nov 3 12:42:36 2009 From: Tim.Bell at Sun.COM (Tim Bell) Date: Tue, 03 Nov 2009 12:42:36 -0800 Subject: Strings in switch implementation checked into JDK 7 m05 code base In-Reply-To: <4AF04E2C.618A.0054.0@Burd.org> References: <4AF04E2C.618A.0054.0@Burd.org> Message-ID: <4AF095BC.2040800@sun.com> Barry Burd wrote: >>From what I can gather, this feature isn't in Build 75 (but Build 75 is the last build in M5). Am I right about all this? An extra build was added to M5 so we could pull in a few more things. Here is the announcement email: http://mail.openjdk.java.net/pipermail/jdk7-dev/2009-October/001016.html HTH- Tim Bell From markmahieu at googlemail.com Tue Nov 3 14:02:40 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 3 Nov 2009 22:02:40 +0000 Subject: One-sided instantiation (diamond, collection literals) In-Reply-To: References: Message-ID: <6C2091BA-20B1-437D-90FA-E8B06CF53DE4@googlemail.com> Barney, No apology needed - like most mature languages, Java has its share of dark forgotten corners, and they've certainly caught me out when I've ventured into this arena. But more importantly I think it's great that you're willing to try modifying the compiler to investigate your ideas. Please continue to do so. Cheers, Mark On 3 Nov 2009, at 11:33, Barney Pitt wrote: > > > > From: barney at frontofficedeveloper.com > Subject: RE: One-sided instantiation (diamond, collection literals) > Date: Tue, 3 Nov 2009 11:30:25 +0000 > > > > > > > > > > > > > > > > > > > My sincere apologies Mark, I had completely forgotten that > interfaces can declare static fields without the keyword static. I > haven't seen it done in years. > > Personally I'd include that case as "shadowing" and a dreadful > practice which should be outlawed - but I don't have a ready > solution as to how it would work with my proposal :( > > From: markmahieu at googlemail.com > Subject: Re: One-sided instantiation (diamond, collection literals) > Date: Tue, 3 Nov 2009 11:04:00 +0000 > To: barney at frontofficedeveloper.com > > > No, I meant what I wrote. The following is perfectly legal in Java: > interface I { String s = new String();} > > This has nothing to do with shadowing. > Mark > > > On 3 Nov 2009, at 10:56, Barney Pitt wrote: > I'm sure that in the first example you meant > > interface I { String s();}class C { String s = new String();} > > as "s" could not be field in an interface. But I still don't really > see what you're getting at. Shadowing an accessible method name or > field name in a subclass/implementation is an appalling practise > which should have been outlawed by the language from the off. But I > don't see how my proposal makes the situation any worse. > > Barney > > > From: markmahieu at googlemail.com > Subject: Re: One-sided instantiation (diamond, collection literals) > Date: Tue, 3 Nov 2009 10:16:08 +0000 > To: barney at frontofficedeveloper.com > > Thanks for the reply. > What I mean though, is that the following currently legal example > declares an interface and a class each with a field named 's': > interface I { String s = new String();}class C { String s = new > String();} > > Under your proposal, I could then change the above to: > interface I { String s();}class C { String s();} > > In the interface, I now have a method called 's', yet in the class > I've still got the field just using different declaration syntax. > That's highly inconsistent, in my opinion. > Regards, > Mark > > > On 3 Nov 2009, at 09:47, Barney Pitt wrote: > It would mean that your interface declares a method s() returning > String. > > Were it an abstract class, it would mean that your field s is > initialized empty. > > I'm not sure I've ever seen a practical example of a Java class > which wasn't written with fields declared first in a block and > methods declared afterwards, although I confess that if you do mix > abstract method declarations willy-nilly with field declarations > the notation might confuse a newcomer. > > I'm more concerned with the everyday practicalities of succinct > readable code - though of course I fully accept that readability is > subjective. > > Barney > > CC: coin-dev at openjdk.java.net > From: markmahieu at googlemail.com > Subject: Re: One-sided instantiation (diamond, collection literals) > Date: Mon, 2 Nov 2009 22:52:13 +0000 > To: barney at frontofficedeveloper.com > > > On 2 Nov 2009, at 22:27, Barney Pitt wrote: > Let me propose a simple language change which achieves this not > only when declaring collections and generically defined objects, > but for all cases where an object is declared and instantiated. > Any statement of the form > Foo foo=new Foo(myBar, myBaz); > can be replaced by > Foo foo(myBar, myBaz); > > OK, so what would this mean? > interface I { String s();} > > Regards, > Mark > Be one of the first to try Windows Live Mail. > > Be one of the first to try Windows Live Mail. > > _________________________________________________________________ > Be one of the first to try Windows Live Mail. > http://ideas.live.com/programpage.aspx?versionId=5d21c51a- > b161-4314-9b0e-4911fb2b2e6d > From Maurizio.Cimadamore at Sun.COM Fri Nov 6 03:31:15 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Fri, 06 Nov 2009 11:31:15 +0000 Subject: on diamond and evolution Message-ID: <4AF40903.1090800@sun.com> Hi Following the recent discussions in this mailing list about the diamond implementation, I decided to spent some more time in order to figure out exactly what it means, in term of language evolution, supporting the simple approach currently checked in the JDK 7 repository. Quick recap: *) Simple approach: infers the diamond type using the *only* the expected type (if available) - similar (if not identical) to 15.12.2.8 *) Complex approach: infers the diamond type using a full inference round (arguments + return type) - 15.12.2.7 + 15.12.2.8 *) Full-complex approach: an hypothetical approach that is based upon complex (see above) - in addition, it throws the constraint about the expected type earlier in the inference process (precisely in 15.12.2.7), so that argument type inference cannot infer a type that, by being too specific, is incompatible with the expected type. As it was shown in [1] there is no subset relationship between simple and complex - that is the two inference routines simply yield different results - in this sense, the simple approach cannot be viewed as a proper subset of the complex approach. This is bad for evolution, as pointed out by Neal. My argument was that there existed a full-complex approach capable of subsuming both simple and complex at the same time - this would have allowed for further language extension (e.g. argument type inference) w/o breaking compatibility. After a more detailed analysis I found out that the full-complex approach, while feasible is not fully backward compatible with the simple approach. The full-complex works nicely when the attribution context has an expected type (because the type inferred for diamond is compatible with the types inferred by both approaches). However, when the attribution context is missing an expected type, things don't go as planned. Here's a simple example: class Foo { Foo(X x) {} Foo get() { return this; } } Foo = new Foo<>(1).get(); With the simple approach this works just fine. The argument type is never considered during inference - because of that, diamond ends up inferring Object (the bound of X) for X. Calling get() on a Foo yields a Foo which is compatible with the LHS type in the assignment. Now suppose that in some release >7 we enable the full-complex approach. What would happen to this particular example? When a type is to be inferred for Foo<>, both argument and expected type are considered. Here there's no expected type (the LHS type of the assignment is the expected type for the get() call) - so full-complex is roughly equivalent to existing 15.12.2.7. Which (again) would yield a different type than the one returned by the simple approach - namely Foo instead of Foo. Now, calling get() on Foo would yield Foo which is clearly incompatible with Foo. Btw: I'm not saying that accepting the above code is a must - an inference scheme can either accept (as simple) that or reject that (as complex); however, if we now choose a scheme that allows it, future releases will also have to cope with that, and we have seen clearly that even the full-complex approach cannot guarantee that. Bottom line: the full-complex approach doesn't represent a viable alternative for reconciling the diamond inference routine with the standard javac's method inference routine - as a result, the simple approach currently implemented in the JDK7 would represent an obstacle for future language extensions. In principle, it would be possible to limit the scope of the simple approach to those contexts that have an expected type, so that the simple approach would fail when no expected type is given. While this is clearly a forward compatible solution, we believe it would be unnecessarily restrictive and ultimately not worth pursuing it. Recalling from my earlier emails, the biggest disadvantage of the complex approach vs. simple is the following example: Foo foo = new Foo<>(1); However I believe this can eventually be fixed by an inference overhaul on the lines of the full-complex approach, so that the argument type inference would take into account the expected return type (thus inferring Object instead of Integer). Actually, that's also the biggest advantage of the complex approach: any change that will positively affect javac's standard type-inference, will positively affect diamond as a side-effect. The next obvious step is to simply switch the diamond implementation in the jdk 7 repository, as we already have a working prototype (see [2]). Thanks to everyone for participating in the discussion and helping in making Java a better language. Maurizio [1] - http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ From forax at univ-mlv.fr Fri Nov 6 05:49:16 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Nov 2009 14:49:16 +0100 Subject: on diamond and evolution In-Reply-To: <4AF40903.1090800@sun.com> References: <4AF40903.1090800@sun.com> Message-ID: <4AF4295C.8070504@univ-mlv.fr> Le 06/11/2009 12:31, Maurizio Cimadamore a ?crit : > Hi > Following the recent discussions in this mailing list about the diamond > implementation, I decided to spent some more time in order to figure > out exactly what it means, in term of language evolution, supporting > the simple approach currently checked in the JDK 7 repository. > > Quick recap: > > *) Simple approach: infers the diamond type using the *only* the > expected type (if available) - similar (if not identical) to 15.12.2.8 > > *) Complex approach: infers the diamond type using a full inference > round (arguments + return type) - 15.12.2.7 + 15.12.2.8 > > *) Full-complex approach: an hypothetical approach that is based upon > complex (see above) - in addition, it throws the constraint about the > expected type earlier in the inference process (precisely in 15.12.2.7), > so that argument type inference cannot infer a type that, by being too > specific, is incompatible with the expected type. > > As it was shown in [1] there is no subset relationship between simple > and complex - that is the two inference routines simply yield different > results - in this sense, the simple approach cannot be viewed as a > proper subset of the complex approach. > > This is bad for evolution, as pointed out by Neal. My argument was that > there existed a full-complex approach capable of subsuming both simple > and complex at the same time - this would have allowed for further > language extension (e.g. argument type inference) w/o breaking > compatibility. > > After a more detailed analysis I found out that the full-complex > approach, while feasible is not fully backward compatible with the > simple approach. The full-complex works nicely when the attribution > context has an expected type (because the type inferred for diamond is > compatible with the types inferred by both approaches). However, when > the attribution context is missing an expected type, things don't go as > planned. Here's a simple example: > > class Foo { > Foo(X x) {} > Foo get() { return this; } > } > > Foo = new Foo<>(1).get(); > > With the simple approach this works just fine. The argument type is > never considered during inference - because of that, diamond ends up > inferring Object (the bound of X) for X. Calling get() on a Foo > yields a Foo which is compatible with the LHS type in the > assignment. > > Now suppose that in some release>7 we enable the full-complex approach. > What would happen to this particular example? When a type is to be > inferred for Foo<>, both argument and expected type are considered. Here > there's no expected type (the LHS type of the assignment is the expected > type for the get() call) - so full-complex is roughly equivalent to > existing 15.12.2.7. Which (again) would yield a different type than the > one returned by the simple approach - namely Foo instead of > Foo. Now, calling get() on Foo would yield Foo > which is clearly incompatible with Foo. Btw: I'm not saying that > accepting the above code is a must - an inference scheme can either > accept (as simple) that or reject that (as complex); however, if we now > choose a scheme that allows it, future releases will also have to cope > with that, and we have seen clearly that even the full-complex approach > cannot guarantee that. > > Bottom line: the full-complex approach doesn't represent a viable > alternative for reconciling the diamond inference routine with the > standard javac's method inference routine - as a result, the simple > approach currently implemented in the JDK7 would represent an obstacle > for future language extensions. In principle, it would be possible to > limit the scope of the simple approach to those contexts that have an > expected type, so that the simple approach would fail when no expected > type is given. While this is clearly a forward compatible solution, we > believe it would be unnecessarily restrictive and ultimately not worth > pursuing it. > > Recalling from my earlier emails, the biggest disadvantage of the > complex approach vs. simple is the following example: > > Foo foo = new Foo<>(1); > > However I believe this can eventually be fixed by an inference overhaul > on the lines of the full-complex approach, so that the argument type > inference would take into account the expected return type (thus > inferring Object instead of Integer). Actually, that's also the biggest > advantage of the complex approach: any change that will positively > affect javac's standard type-inference, will positively affect diamond > as a side-effect. > > The next obvious step is to simply switch the diamond implementation in > the jdk 7 repository, as we already have a working prototype (see [2]). > > Thanks to everyone for participating in the discussion and helping in > making Java a better language. > Maurizio > > [1] - > http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html > [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ > > Hi Maurizio, Correct me, If I'm wrong. You want to change the already existing inference algorithm in order to be able to compile that code: public static List list(T t) { ... } public static void main(String[] args) { List l = list("foo"); } And use the same algorithm for the diamond syntax. R?mi From reinier at zwitserloot.com Fri Nov 6 05:51:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 6 Nov 2009 14:51:46 +0100 Subject: on diamond and evolution In-Reply-To: <4AF4295C.8070504@univ-mlv.fr> References: <4AF40903.1090800@sun.com> <4AF4295C.8070504@univ-mlv.fr> Message-ID: <560fb5ed0911060551k404fd8d1i782b6e17947ff4ce@mail.gmail.com> I believe he meant that, while that doesn't work now, it's feasible that it might work later, simply by adding more brains to the inference engine (specifically: Letting the inference engine take the target type into account). And when that is done, by making the diamond operator consistent with this inference, it'll get the ability to do so 'for free'. Correct me if I'm wrong, too :P --Reinier Zwitserloot On Fri, Nov 6, 2009 at 2:49 PM, R?mi Forax wrote: > Le 06/11/2009 12:31, Maurizio Cimadamore a ?crit : > > Hi > > Following the recent discussions in this mailing list about the diamond > > implementation, I decided to spent some more time in order to figure > > out exactly what it means, in term of language evolution, supporting > > the simple approach currently checked in the JDK 7 repository. > > > > Quick recap: > > > > *) Simple approach: infers the diamond type using the *only* the > > expected type (if available) - similar (if not identical) to 15.12.2.8 > > > > *) Complex approach: infers the diamond type using a full inference > > round (arguments + return type) - 15.12.2.7 + 15.12.2.8 > > > > *) Full-complex approach: an hypothetical approach that is based upon > > complex (see above) - in addition, it throws the constraint about the > > expected type earlier in the inference process (precisely in 15.12.2.7), > > so that argument type inference cannot infer a type that, by being too > > specific, is incompatible with the expected type. > > > > As it was shown in [1] there is no subset relationship between simple > > and complex - that is the two inference routines simply yield different > > results - in this sense, the simple approach cannot be viewed as a > > proper subset of the complex approach. > > > > This is bad for evolution, as pointed out by Neal. My argument was that > > there existed a full-complex approach capable of subsuming both simple > > and complex at the same time - this would have allowed for further > > language extension (e.g. argument type inference) w/o breaking > > compatibility. > > > > After a more detailed analysis I found out that the full-complex > > approach, while feasible is not fully backward compatible with the > > simple approach. The full-complex works nicely when the attribution > > context has an expected type (because the type inferred for diamond is > > compatible with the types inferred by both approaches). However, when > > the attribution context is missing an expected type, things don't go as > > planned. Here's a simple example: > > > > class Foo { > > Foo(X x) {} > > Foo get() { return this; } > > } > > > > Foo = new Foo<>(1).get(); > > > > With the simple approach this works just fine. The argument type is > > never considered during inference - because of that, diamond ends up > > inferring Object (the bound of X) for X. Calling get() on a Foo > > yields a Foo which is compatible with the LHS type in the > > assignment. > > > > Now suppose that in some release>7 we enable the full-complex approach. > > What would happen to this particular example? When a type is to be > > inferred for Foo<>, both argument and expected type are considered. Here > > there's no expected type (the LHS type of the assignment is the expected > > type for the get() call) - so full-complex is roughly equivalent to > > existing 15.12.2.7. Which (again) would yield a different type than the > > one returned by the simple approach - namely Foo instead of > > Foo. Now, calling get() on Foo would yield Foo > > which is clearly incompatible with Foo. Btw: I'm not saying that > > accepting the above code is a must - an inference scheme can either > > accept (as simple) that or reject that (as complex); however, if we now > > choose a scheme that allows it, future releases will also have to cope > > with that, and we have seen clearly that even the full-complex approach > > cannot guarantee that. > > > > Bottom line: the full-complex approach doesn't represent a viable > > alternative for reconciling the diamond inference routine with the > > standard javac's method inference routine - as a result, the simple > > approach currently implemented in the JDK7 would represent an obstacle > > for future language extensions. In principle, it would be possible to > > limit the scope of the simple approach to those contexts that have an > > expected type, so that the simple approach would fail when no expected > > type is given. While this is clearly a forward compatible solution, we > > believe it would be unnecessarily restrictive and ultimately not worth > > pursuing it. > > > > Recalling from my earlier emails, the biggest disadvantage of the > > complex approach vs. simple is the following example: > > > > Foo foo = new Foo<>(1); > > > > However I believe this can eventually be fixed by an inference overhaul > > on the lines of the full-complex approach, so that the argument type > > inference would take into account the expected return type (thus > > inferring Object instead of Integer). Actually, that's also the biggest > > advantage of the complex approach: any change that will positively > > affect javac's standard type-inference, will positively affect diamond > > as a side-effect. > > > > The next obvious step is to simply switch the diamond implementation in > > the jdk 7 repository, as we already have a working prototype (see [2]). > > > > Thanks to everyone for participating in the discussion and helping in > > making Java a better language. > > Maurizio > > > > [1] - > > http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html > > [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ > > > > > > Hi Maurizio, > Correct me, If I'm wrong. You want to change the already existing > inference algorithm > in order to be able to compile that code: > > public static List list(T t) { > ... > } > > public static void main(String[] args) { > List l = list("foo"); > } > > And use the same algorithm for the diamond syntax. > > R?mi > > From Maurizio.Cimadamore at Sun.COM Fri Nov 6 06:09:17 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Fri, 06 Nov 2009 14:09:17 +0000 Subject: on diamond and evolution In-Reply-To: <560fb5ed0911060551k404fd8d1i782b6e17947ff4ce@mail.gmail.com> References: <4AF40903.1090800@sun.com> <4AF4295C.8070504@univ-mlv.fr> <560fb5ed0911060551k404fd8d1i782b6e17947ff4ce@mail.gmail.com> Message-ID: <4AF42E0D.4010006@sun.com> Hi, Reinier is correct. This code: public static List list(T t) { ... } public static void main(String[] args) { List l = list("foo"); } currently does not work, but I think it would be nice if it would. However this should be handled as a separate inference enhancement that we can pursue (thought not necessarily in the jdk 7 timeframe). In the immediate future there will be no changes to javac's inference algorithm. Moreover, after the diamond implementation switch, diamond will also be relying on javac's type inference (which means only one inference scheme for all cases, diamond and methods). Maurizio Reinier Zwitserloot wrote: > I believe he meant that, while that doesn't work now, it's feasible that it > might work later, simply by adding more brains to the inference engine > (specifically: Letting the inference engine take the target type into > account). And when that is done, by making the diamond operator consistent > with this inference, it'll get the ability to do so 'for free'. > > Correct me if I'm wrong, too :P > > --Reinier Zwitserloot > > > > On Fri, Nov 6, 2009 at 2:49 PM, R?mi Forax wrote: > > >> Le 06/11/2009 12:31, Maurizio Cimadamore a ?crit : >> >>> Hi >>> Following the recent discussions in this mailing list about the diamond >>> implementation, I decided to spent some more time in order to figure >>> out exactly what it means, in term of language evolution, supporting >>> the simple approach currently checked in the JDK 7 repository. >>> >>> Quick recap: >>> >>> *) Simple approach: infers the diamond type using the *only* the >>> expected type (if available) - similar (if not identical) to 15.12.2.8 >>> >>> *) Complex approach: infers the diamond type using a full inference >>> round (arguments + return type) - 15.12.2.7 + 15.12.2.8 >>> >>> *) Full-complex approach: an hypothetical approach that is based upon >>> complex (see above) - in addition, it throws the constraint about the >>> expected type earlier in the inference process (precisely in 15.12.2.7), >>> so that argument type inference cannot infer a type that, by being too >>> specific, is incompatible with the expected type. >>> >>> As it was shown in [1] there is no subset relationship between simple >>> and complex - that is the two inference routines simply yield different >>> results - in this sense, the simple approach cannot be viewed as a >>> proper subset of the complex approach. >>> >>> This is bad for evolution, as pointed out by Neal. My argument was that >>> there existed a full-complex approach capable of subsuming both simple >>> and complex at the same time - this would have allowed for further >>> language extension (e.g. argument type inference) w/o breaking >>> compatibility. >>> >>> After a more detailed analysis I found out that the full-complex >>> approach, while feasible is not fully backward compatible with the >>> simple approach. The full-complex works nicely when the attribution >>> context has an expected type (because the type inferred for diamond is >>> compatible with the types inferred by both approaches). However, when >>> the attribution context is missing an expected type, things don't go as >>> planned. Here's a simple example: >>> >>> class Foo { >>> Foo(X x) {} >>> Foo get() { return this; } >>> } >>> >>> Foo = new Foo<>(1).get(); >>> >>> With the simple approach this works just fine. The argument type is >>> never considered during inference - because of that, diamond ends up >>> inferring Object (the bound of X) for X. Calling get() on a Foo >>> yields a Foo which is compatible with the LHS type in the >>> assignment. >>> >>> Now suppose that in some release>7 we enable the full-complex approach. >>> What would happen to this particular example? When a type is to be >>> inferred for Foo<>, both argument and expected type are considered. Here >>> there's no expected type (the LHS type of the assignment is the expected >>> type for the get() call) - so full-complex is roughly equivalent to >>> existing 15.12.2.7. Which (again) would yield a different type than the >>> one returned by the simple approach - namely Foo instead of >>> Foo. Now, calling get() on Foo would yield Foo >>> which is clearly incompatible with Foo. Btw: I'm not saying that >>> accepting the above code is a must - an inference scheme can either >>> accept (as simple) that or reject that (as complex); however, if we now >>> choose a scheme that allows it, future releases will also have to cope >>> with that, and we have seen clearly that even the full-complex approach >>> cannot guarantee that. >>> >>> Bottom line: the full-complex approach doesn't represent a viable >>> alternative for reconciling the diamond inference routine with the >>> standard javac's method inference routine - as a result, the simple >>> approach currently implemented in the JDK7 would represent an obstacle >>> for future language extensions. In principle, it would be possible to >>> limit the scope of the simple approach to those contexts that have an >>> expected type, so that the simple approach would fail when no expected >>> type is given. While this is clearly a forward compatible solution, we >>> believe it would be unnecessarily restrictive and ultimately not worth >>> pursuing it. >>> >>> Recalling from my earlier emails, the biggest disadvantage of the >>> complex approach vs. simple is the following example: >>> >>> Foo foo = new Foo<>(1); >>> >>> However I believe this can eventually be fixed by an inference overhaul >>> on the lines of the full-complex approach, so that the argument type >>> inference would take into account the expected return type (thus >>> inferring Object instead of Integer). Actually, that's also the biggest >>> advantage of the complex approach: any change that will positively >>> affect javac's standard type-inference, will positively affect diamond >>> as a side-effect. >>> >>> The next obvious step is to simply switch the diamond implementation in >>> the jdk 7 repository, as we already have a working prototype (see [2]). >>> >>> Thanks to everyone for participating in the discussion and helping in >>> making Java a better language. >>> Maurizio >>> >>> [1] - >>> http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html >>> [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ >>> >>> >>> >> Hi Maurizio, >> Correct me, If I'm wrong. You want to change the already existing >> inference algorithm >> in order to be able to compile that code: >> >> public static List list(T t) { >> ... >> } >> >> public static void main(String[] args) { >> List l = list("foo"); >> } >> >> And use the same algorithm for the diamond syntax. >> >> R?mi >> >> >> > > From neal at gafter.com Fri Nov 6 12:43:29 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Nov 2009 12:43:29 -0800 Subject: on diamond and evolution In-Reply-To: <4AF40903.1090800@sun.com> References: <4AF40903.1090800@sun.com> Message-ID: <15e8b9d20911061243y539fcca0xcba261b72116bf74@mail.gmail.com> Maurizio- I think this is the right tradeoff: a slight loss of functionality in the short term to enable further improvements later. Cheers, Neal On Fri, Nov 6, 2009 at 3:31 AM, Maurizio Cimadamore < Maurizio.Cimadamore at sun.com> wrote: > Hi > Following the recent discussions in this mailing list about the diamond > implementation, I decided to spent some more time in order to figure > out exactly what it means, in term of language evolution, supporting > the simple approach currently checked in the JDK 7 repository. > > Quick recap: > > *) Simple approach: infers the diamond type using the *only* the > expected type (if available) - similar (if not identical) to 15.12.2.8 > > *) Complex approach: infers the diamond type using a full inference > round (arguments + return type) - 15.12.2.7 + 15.12.2.8 > > *) Full-complex approach: an hypothetical approach that is based upon > complex (see above) - in addition, it throws the constraint about the > expected type earlier in the inference process (precisely in 15.12.2.7), > so that argument type inference cannot infer a type that, by being too > specific, is incompatible with the expected type. > > As it was shown in [1] there is no subset relationship between simple > and complex - that is the two inference routines simply yield different > results - in this sense, the simple approach cannot be viewed as a > proper subset of the complex approach. > > This is bad for evolution, as pointed out by Neal. My argument was that > there existed a full-complex approach capable of subsuming both simple > and complex at the same time - this would have allowed for further > language extension (e.g. argument type inference) w/o breaking > compatibility. > > After a more detailed analysis I found out that the full-complex > approach, while feasible is not fully backward compatible with the > simple approach. The full-complex works nicely when the attribution > context has an expected type (because the type inferred for diamond is > compatible with the types inferred by both approaches). However, when > the attribution context is missing an expected type, things don't go as > planned. Here's a simple example: > > class Foo { > Foo(X x) {} > Foo get() { return this; } > } > > Foo = new Foo<>(1).get(); > > With the simple approach this works just fine. The argument type is > never considered during inference - because of that, diamond ends up > inferring Object (the bound of X) for X. Calling get() on a Foo > yields a Foo which is compatible with the LHS type in the > assignment. > > Now suppose that in some release >7 we enable the full-complex approach. > What would happen to this particular example? When a type is to be > inferred for Foo<>, both argument and expected type are considered. Here > there's no expected type (the LHS type of the assignment is the expected > type for the get() call) - so full-complex is roughly equivalent to > existing 15.12.2.7. Which (again) would yield a different type than the > one returned by the simple approach - namely Foo instead of > Foo. Now, calling get() on Foo would yield Foo > which is clearly incompatible with Foo. Btw: I'm not saying that > accepting the above code is a must - an inference scheme can either > accept (as simple) that or reject that (as complex); however, if we now > choose a scheme that allows it, future releases will also have to cope > with that, and we have seen clearly that even the full-complex approach > cannot guarantee that. > > Bottom line: the full-complex approach doesn't represent a viable > alternative for reconciling the diamond inference routine with the > standard javac's method inference routine - as a result, the simple > approach currently implemented in the JDK7 would represent an obstacle > for future language extensions. In principle, it would be possible to > limit the scope of the simple approach to those contexts that have an > expected type, so that the simple approach would fail when no expected > type is given. While this is clearly a forward compatible solution, we > believe it would be unnecessarily restrictive and ultimately not worth > pursuing it. > > Recalling from my earlier emails, the biggest disadvantage of the > complex approach vs. simple is the following example: > > Foo foo = new Foo<>(1); > > However I believe this can eventually be fixed by an inference overhaul > on the lines of the full-complex approach, so that the argument type > inference would take into account the expected return type (thus > inferring Object instead of Integer). Actually, that's also the biggest > advantage of the complex approach: any change that will positively > affect javac's standard type-inference, will positively affect diamond > as a side-effect. > > The next obvious step is to simply switch the diamond implementation in > the jdk 7 repository, as we already have a working prototype (see [2]). > > Thanks to everyone for participating in the discussion and helping in > making Java a better language. > Maurizio > > [1] - > http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html > [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ > > > From scolebourne at joda.org Sat Nov 7 03:06:16 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 07 Nov 2009 11:06:16 +0000 Subject: on diamond and evolution In-Reply-To: <15e8b9d20911061243y539fcca0xcba261b72116bf74@mail.gmail.com> References: <4AF40903.1090800@sun.com> <15e8b9d20911061243y539fcca0xcba261b72116bf74@mail.gmail.com> Message-ID: <4AF554A8.7060701@joda.org> All, I just wanted to express thanks that the time and effort has been taken to work through this difficult issue from all parties. Its great to see it come to a clear and positive resolution. I believe that the Java platform has benefitted as a result. Stephen Neal Gafter wrote: > Maurizio- > > I think this is the right tradeoff: a slight loss of functionality in the > short term to enable further improvements later. > > Cheers, > Neal > > On Fri, Nov 6, 2009 at 3:31 AM, Maurizio Cimadamore < > Maurizio.Cimadamore at sun.com> wrote: > >> Hi >> Following the recent discussions in this mailing list about the diamond >> implementation, I decided to spent some more time in order to figure >> out exactly what it means, in term of language evolution, supporting >> the simple approach currently checked in the JDK 7 repository. >> >> Quick recap: >> >> *) Simple approach: infers the diamond type using the *only* the >> expected type (if available) - similar (if not identical) to 15.12.2.8 >> >> *) Complex approach: infers the diamond type using a full inference >> round (arguments + return type) - 15.12.2.7 + 15.12.2.8 >> >> *) Full-complex approach: an hypothetical approach that is based upon >> complex (see above) - in addition, it throws the constraint about the >> expected type earlier in the inference process (precisely in 15.12.2.7), >> so that argument type inference cannot infer a type that, by being too >> specific, is incompatible with the expected type. >> >> As it was shown in [1] there is no subset relationship between simple >> and complex - that is the two inference routines simply yield different >> results - in this sense, the simple approach cannot be viewed as a >> proper subset of the complex approach. >> >> This is bad for evolution, as pointed out by Neal. My argument was that >> there existed a full-complex approach capable of subsuming both simple >> and complex at the same time - this would have allowed for further >> language extension (e.g. argument type inference) w/o breaking >> compatibility. >> >> After a more detailed analysis I found out that the full-complex >> approach, while feasible is not fully backward compatible with the >> simple approach. The full-complex works nicely when the attribution >> context has an expected type (because the type inferred for diamond is >> compatible with the types inferred by both approaches). However, when >> the attribution context is missing an expected type, things don't go as >> planned. Here's a simple example: >> >> class Foo { >> Foo(X x) {} >> Foo get() { return this; } >> } >> >> Foo = new Foo<>(1).get(); >> >> With the simple approach this works just fine. The argument type is >> never considered during inference - because of that, diamond ends up >> inferring Object (the bound of X) for X. Calling get() on a Foo >> yields a Foo which is compatible with the LHS type in the >> assignment. >> >> Now suppose that in some release >7 we enable the full-complex approach. >> What would happen to this particular example? When a type is to be >> inferred for Foo<>, both argument and expected type are considered. Here >> there's no expected type (the LHS type of the assignment is the expected >> type for the get() call) - so full-complex is roughly equivalent to >> existing 15.12.2.7. Which (again) would yield a different type than the >> one returned by the simple approach - namely Foo instead of >> Foo. Now, calling get() on Foo would yield Foo >> which is clearly incompatible with Foo. Btw: I'm not saying that >> accepting the above code is a must - an inference scheme can either >> accept (as simple) that or reject that (as complex); however, if we now >> choose a scheme that allows it, future releases will also have to cope >> with that, and we have seen clearly that even the full-complex approach >> cannot guarantee that. >> >> Bottom line: the full-complex approach doesn't represent a viable >> alternative for reconciling the diamond inference routine with the >> standard javac's method inference routine - as a result, the simple >> approach currently implemented in the JDK7 would represent an obstacle >> for future language extensions. In principle, it would be possible to >> limit the scope of the simple approach to those contexts that have an >> expected type, so that the simple approach would fail when no expected >> type is given. While this is clearly a forward compatible solution, we >> believe it would be unnecessarily restrictive and ultimately not worth >> pursuing it. >> >> Recalling from my earlier emails, the biggest disadvantage of the >> complex approach vs. simple is the following example: >> >> Foo foo = new Foo<>(1); >> >> However I believe this can eventually be fixed by an inference overhaul >> on the lines of the full-complex approach, so that the argument type >> inference would take into account the expected return type (thus >> inferring Object instead of Integer). Actually, that's also the biggest >> advantage of the complex approach: any change that will positively >> affect javac's standard type-inference, will positively affect diamond >> as a side-effect. >> >> The next obvious step is to simply switch the diamond implementation in >> the jdk 7 repository, as we already have a working prototype (see [2]). >> >> Thanks to everyone for participating in the discussion and helping in >> making Java a better language. >> Maurizio >> >> [1] - >> http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html >> [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/ >> >> >> > > From kevinb at google.com Sun Nov 8 08:09:09 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Sun, 8 Nov 2009 08:09:09 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910210808l2a4443f0v24421dd37f5d11b9@mail.gmail.com> <17b2302a0910210839n7f06d584y6db7262ecc990775@mail.gmail.com> <15e8b9d20910210926i4f66ac6ew4666415a497c7c59@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> Message-ID: <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> Thread-resurrect... I think detecting 'iterator instanceof Closeable' is an outstanding idea, and one that would solve problems that have been vexing me as a library developer for years. The foreach construct owns the creation of that instance, and is the only party that has a reference to it. If the instance is Closeable, it feels simply irresponsible to ignore this. As for the potential risks, we're talking about an instance that's unreachable and eligible for GC, so it's difficult to imagine that closing such an instance could be a bad idea. Looked another way, if a user didn't want automatic close for some reason, that reason would already be preventing that user from using foreach anyway. +10 On Thu, Oct 22, 2009 at 8:19 AM, Neal Gafter wrote: > On Thu, Oct 22, 2009 at 8:59 AM, Howard Lovatt wrote: > >> I think you can choose if close to applies to the Iterable or the Iterator. > > > Agreed. But if it applies to the Iterable, the programmer can easily use an > ARM block around the for-each loop. ?If it applies to the Iterator, there is > no way for the programmer to do it. ?That's why support is needed in that > case. > > -- Kevin Bourrillion @ Google internal: http://go/javalibraries external: guava-libraries.googlecode.com From i30817 at gmail.com Wed Nov 11 08:36:52 2009 From: i30817 at gmail.com (Paulo Levi) Date: Wed, 11 Nov 2009 16:36:52 +0000 Subject: Wouldn't this be nice? Message-ID: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> for(int i : infos.length) for(long i : 35L) or even for(int i : -30) (0 being always the start, the second element the end.) I think it would. It would make the for loop actually useful if iterating over more than one (indexed) data structure in the same loop. The ideas come late and later. From i30817 at gmail.com Wed Nov 11 08:38:24 2009 From: i30817 at gmail.com (Paulo Levi) Date: Wed, 11 Nov 2009 16:38:24 +0000 Subject: Wouldn't this be nice? In-Reply-To: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> Message-ID: <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> Probably you figured out i wanted: for(int i : infos.length - 1) sigh. From jjb at google.com Wed Nov 11 08:46:22 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 11 Nov 2009 08:46:22 -0800 Subject: Wouldn't this be nice? In-Reply-To: <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> Message-ID: <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> Paulo, I have a hard time intuiting the semantics by just looking a the statement. What I'm really sorry that I didn't put into the original statement is: for (char c : myString) which would also work on other CharSequences. Oh well, maybe someday. Josh On Wed, Nov 11, 2009 at 8:38 AM, Paulo Levi wrote: > Probably you figured out i wanted: > for(int i : infos.length - 1) > > sigh. > > From mthornton at optrak.co.uk Wed Nov 11 08:54:37 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Wed, 11 Nov 2009 16:54:37 +0000 Subject: Wouldn't this be nice? In-Reply-To: <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> Message-ID: <4AFAEC4D.8080402@optrak.co.uk> Joshua Bloch wrote: > Paulo, > > I have a hard time intuiting the semantics by just looking a the statement. > What I'm really sorry that I didn't put into the original statement is: > > for (char c : myString) > > which would also work on other CharSequences. Oh well, maybe someday. > > and/or perhaps for (int codePoint: myString) I know most programmers are still ignoring the difference between characters and codePoints, but I can't help feeling a bit dirty doing so. Mark Thornton From reinier at zwitserloot.com Wed Nov 11 09:37:31 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 18:37:31 +0100 Subject: Wouldn't this be nice? In-Reply-To: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> Message-ID: <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> Taking a page from python, why not add to one of the common dump spots for functions, say, Collections, the following method: public static void Iterable range(final int i) { return new Iterable() { public Iterator iterator() { return new Iterator() { private int p = 0; public boolean hasNext() { return p < i; } public Integer next() { if (p < i) return p++; throw new NoSuchElementException(); } public void remove() { throw new MethodNotSupportedException(); } }; } }; } then all you need to do is: import static java.util.Collections.range; for (int i : range(50)) { /* do stuff */ } Josh: I'm a bit meh on your suggestion. Is that really so much of an improvement over: for (char c : "someString".toCharArray())? probably yes, but between the extra burden on the JLS and potential confusion between chars and codepoints, it doesn't strike me as a big loss. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 5:36 PM, Paulo Levi wrote: > for(int i : infos.length) > > for(long i : 35L) > > or even > > for(int i : -30) > > (0 being always the start, the second element the end.) > > I think it would. It would make the for loop actually useful if > iterating over more than one (indexed) data structure in the same > loop. > The ideas come late and later. > > From crazybob at crazybob.org Wed Nov 11 10:00:42 2009 From: crazybob at crazybob.org (Bob Lee) Date: Wed, 11 Nov 2009 10:00:42 -0800 Subject: Wouldn't this be nice? In-Reply-To: <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> Message-ID: On Wed, Nov 11, 2009 at 9:37 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Josh: I'm a bit meh on your suggestion. Is that really so much of an > improvement over: > > for (char c : "someString".toCharArray())? Yes. I would never use your suggestion because it results in an extra array copy. Bob From lk at teamten.com Wed Nov 11 10:10:18 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Wed, 11 Nov 2009 10:10:18 -0800 Subject: try/catch expression Message-ID: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> One nice thing about having been on the coin-dev list is realizing that I really like Java as it is. None of the proposals (including my list comprehensions) have seem "worth it" (except ARM). But there's one thing that repeatedly grosses me out, and bothers me more each day: Reader foo = new FileReader(filename); This throws an IOException. I want to keep my catch clauses nice and tight, so I end up writing: Reader foo; try { foo = new FileReader(filename); } catch (IOException e) { log.warn("Cannot open file \"" + filename + "\" (" + e.getMessage() + ")"); ...; } The duplication of "foo" smells bad and four lines of noise were added. I would prefer a try/catch expression: Reader foo = try new FileReader(filename) catch (IOException e) { log.warn("Cannot open file \"" + filename + "\" (" + e.getMessage() + ")"); ...; } I can't think of a change to Java that would please me more day-to-day. Anyone else feel the same? Should I write this up for JDK8? Lawrence Kesteloot From jjb at google.com Wed Nov 11 10:14:51 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 11 Nov 2009 10:14:51 -0800 Subject: Wouldn't this be nice? In-Reply-To: <4AFAFCDE.1060409@sun.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFAFCDE.1060409@sun.com> Message-ID: <17b2302a0911111014i3603f9c9u41119fc729afc02@mail.gmail.com> Eammon, That's a great idea! In fact, it's a compelling reason to support the feature. Josh On Wed, Nov 11, 2009 at 10:05 AM, Eamonn McManus wrote: > What I'm really sorry that I didn't put into the original statement is: > > for (char c : myString) > > which would also work on other CharSequences. Oh well, maybe someday > > That would certainly be awfully nice, especially if it also worked for > code points in general, as in > > for (int c : myString) > > Getting the right behaviour using the codePointCount and codePointAt and > charCount methods of Character is really tedious, but necessary if you want > your code to be fully international. There are ways to abstract it away a > bit in the current language, but they're kind of clunky. > > ?amonn > > Joshua Bloch wrote: > > Paulo, > > I have a hard time intuiting the semantics by just looking a the statement. > What I'm really sorry that I didn't put into the original statement is: > > for (char c : myString) > > which would also work on other CharSequences. Oh well, maybe someday. > > Josh > > On Wed, Nov 11, 2009 at 8:38 AM, Paulo Levi wrote: > > > > Probably you figured out i wanted: > for(int i : infos.length - 1) > > sigh. > > > > > From reinier at zwitserloot.com Wed Nov 11 10:24:51 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 19:24:51 +0100 Subject: try/catch expression In-Reply-To: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> References: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> Message-ID: <560fb5ed0911111024n5baadfdx3922f8febd8051eb@mail.gmail.com> For what it's worth, the java standard way of doing this is generally to bundle both the file open operation as well as the reads (and, arguably, the subsequent close) into a single try block. Even ARM does this - the initializer expression is part of the node that contains the operations done on the ARM block, so if you catch exceptions on the initializer, then you also catch them on the body, unless the body has its own try block, which looks no less ugly than your snippet. Your proposal is vague. What, exactly, is returned from a try/catch expression if the catch block is triggered? An implicit 'null'? Something akin to BGGA's last expression in the block? That would be a rather large change, and, like BGGA, you have to separate accidental from explicit use, for example by having that weird 'last expression must not end with a semi-colon' rule. Assuming you fill in the holes, I think this idea is rather underwhelming. The thing you're trying to fix here isn't used all that often (bundling open with read is more common and can be done much simpler, especially with ARM), the workaround fix isn't all that ugly, so it's not a matter of enabling you to do something that is almost impossible with today's java, and finally, this feels extremely inconsistent. If try/catch becomes an expression, shouldn't for, while, do, if/else, and perhaps even synchronized, be expressions too? That would be a major, major change in how java works. Could be a good change, but such a proposal needs to be written up and analysed, and I have a feeling it's going to play havoc on the parser grammar. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 7:10 PM, Lawrence Kesteloot wrote: > One nice thing about having been on the coin-dev list is realizing > that I really like Java as it is. None of the proposals (including my > list comprehensions) have seem "worth it" (except ARM). But there's > one thing that repeatedly grosses me out, and bothers me more each > day: > > Reader foo = new FileReader(filename); > > This throws an IOException. I want to keep my catch clauses nice and > tight, so I end up writing: > > Reader foo; > try { > foo = new FileReader(filename); > } catch (IOException e) { > log.warn("Cannot open file \"" + filename + "\" (" + > e.getMessage() + ")"); > ...; > } > > The duplication of "foo" smells bad and four lines of noise were > added. I would prefer a try/catch expression: > > Reader foo = try new FileReader(filename) catch (IOException e) { > log.warn("Cannot open file \"" + filename + "\" (" + > e.getMessage() + ")"); > ...; > } > > I can't think of a change to Java that would please me more > day-to-day. Anyone else feel the same? Should I write this up for > JDK8? > > Lawrence Kesteloot > > From schlosna at gmail.com Wed Nov 11 10:25:14 2009 From: schlosna at gmail.com (David Schlosnagle) Date: Wed, 11 Nov 2009 13:25:14 -0500 Subject: Wouldn't this be nice? In-Reply-To: References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> Message-ID: <9146341c0911111025k7432694ck4b083b276a2a4615@mail.gmail.com> I haven't searched through Guava enough yet to see if there is something similar already, but I'd imagine it would easy to define static methods that return an Iterable of the desired type, for example the following to iterate over the characters in a CharSequence. The same could be done to abstract code point iteration. import java.util.Iterator; import java.util.NoSuchElementException; public class Characters { public static void main(String[] args) { for (char c : characters("hello, world")) { System.out.println(c); } } public static Iterable characters(final CharSequence sequence) { return new Iterable() { public Iterator iterator() { return new Iterator() { private int index = 0; public boolean hasNext() { return index < sequence.length(); } public Character next() { if (hasNext()) return sequence.charAt(index++); throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } }; } }; } } On Wed, Nov 11, 2009 at 1:00 PM, Bob Lee wrote: > On Wed, Nov 11, 2009 at 9:37 AM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> Josh: I'm a bit meh on your suggestion. Is that really so much of an >> improvement over: >> >> for (char c : "someString".toCharArray())? > > > Yes. I would never use your suggestion because it results in an extra array > copy. > > Bob > > From neal at gafter.com Wed Nov 11 10:29:05 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 10:29:05 -0800 Subject: Wouldn't this be nice? In-Reply-To: <17b2302a0911111014i3603f9c9u41119fc729afc02@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFAFCDE.1060409@sun.com> <17b2302a0911111014i3603f9c9u41119fc729afc02@mail.gmail.com> Message-ID: <15e8b9d20911111029h1d2dc4edmbb424cceccc5ff70@mail.gmail.com> I wrote this back in 2004 : *Iterable codePoints(final String s) { * *return new Iterable() { * *public Iterator iterator() { * *return new Iterator() { * *int nextIndex = 0; public boolean hasNext() { * *return nextIndex < s.length(); * *} public Integer next() { * *int result = s.codePointAt(nextIndex); nextIndex += Character.charCount(result); return result; * *} public void remove() * *{ throw new UnsupportedOperationException(); } * *}; * *} * *}; * *} * Doing this for CharSequence is only a bit more complicated. If this is likely to be used frequently, direct compiler-generated would certainly be better. Do we have a feel for how often this feature would be used? -Neal On Wed, Nov 11, 2009 at 10:14 AM, Joshua Bloch wrote: > Eammon, > > That's a great idea! In fact, it's a compelling reason to support the > feature. > > Josh > > On Wed, Nov 11, 2009 at 10:05 AM, Eamonn McManus >wrote: > > > What I'm really sorry that I didn't put into the original statement is: > > > > for (char c : myString) > > > > which would also work on other CharSequences. Oh well, maybe someday > > > > That would certainly be awfully nice, especially if it also worked for > > code points in general, as in > > > > for (int c : myString) > > > > Getting the right behaviour using the codePointCount and codePointAt and > > charCount methods of Character is really tedious, but necessary if you > want > > your code to be fully international. There are ways to abstract it away a > > bit in the current language, but they're kind of clunky. > > > > ?amonn > > > > Joshua Bloch wrote: > > > > Paulo, > > > > I have a hard time intuiting the semantics by just looking a the > statement. > > What I'm really sorry that I didn't put into the original statement is: > > > > for (char c : myString) > > > > which would also work on other CharSequences. Oh well, maybe someday. > > > > Josh > > > > On Wed, Nov 11, 2009 at 8:38 AM, Paulo Levi < > i30817 at gmail.com> wrote: > > > > > > > > Probably you figured out i wanted: > > for(int i : infos.length - 1) > > > > sigh. > > > > > > > > > > > > From reinier at zwitserloot.com Wed Nov 11 10:31:19 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 19:31:19 +0100 Subject: Wouldn't this be nice? In-Reply-To: References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> Message-ID: <560fb5ed0911111031x55c0331bx47695447f33a6fe7@mail.gmail.com> How exactly do you imagine the proposed for (char c : string) syntax works? Hardcoded access to the underlying char array of String itself? That makes this far more than syntactic sugar; that would have to be a JVM primitive. That, or the compiler produces a bunch of reflection code which is magically made exempt from the security manager rules, which, come to think of it, still smells of being a JVM primitive. Could be a good idea, but that's rather a lot of impact for a change that is only useful when needing to iterate character-by-character across very large strings, or needing to iterate character-by-character across a large number of large strings. Any other situation and the array copy is an irrelevant drop in the bucket compared to all the other stuff that will be going on. In such niche situations, I get the feeling that you probably should roll with char or even byte arrays from the start, instead of going through java.lang.String. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 7:00 PM, Bob Lee wrote: > On Wed, Nov 11, 2009 at 9:37 AM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> Josh: I'm a bit meh on your suggestion. Is that really so much of an >> improvement over: >> >> for (char c : "someString".toCharArray())? > > > Yes. I would never use your suggestion because it results in an extra array > copy. > > Bob > From lk at teamten.com Wed Nov 11 10:32:32 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Wed, 11 Nov 2009 10:32:32 -0800 Subject: try/catch expression In-Reply-To: <560fb5ed0911111024n5baadfdx3922f8febd8051eb@mail.gmail.com> References: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> <560fb5ed0911111024n5baadfdx3922f8febd8051eb@mail.gmail.com> Message-ID: <997cab100911111032t76f2824fi6f720c258c779144@mail.gmail.com> Rats! I didn't think about what the expression would return. Dammit. In my mind of course it just returns from the enclosing function, but that's not okay in general. Thanks for analyzing it, sorry I didn't do a better job. I don't agree that this change would force all statements to be expressions. And I don't like the sloppy "put the entire code of a function inside a large try/catch block". I've seen it result in too many errors where someone adds a throwing line in the middle and doesn't realize an existing catch will do something other than what they'd want. Also any resulting log message isn't as clear. Lawrence On Wed, Nov 11, 2009 at 10:24 AM, Reinier Zwitserloot wrote: > For what it's worth, the java standard way of doing this is generally to > bundle both the file open operation as well as the reads (and, arguably, the > subsequent close) into a single try block. Even ARM does this - the > initializer expression is part of the node that contains the operations done > on the ARM block, so if you catch exceptions on the initializer, then you > also catch them on the body, unless the body has its own try block, which > looks no less ugly than your snippet. > Your proposal is vague. What, exactly, is returned from a try/catch > expression if the catch block is triggered? An implicit 'null'? Something > akin to BGGA's last expression in the block? That would be a rather large > change, and, like BGGA, you have to separate accidental from explicit use, > for example by having that weird 'last expression must not end with a > semi-colon' rule. > Assuming you fill in the holes, I think this idea is rather underwhelming. > The thing you're trying to fix here isn't used all that often (bundling open > with read is more common and can be done much simpler, especially with ARM), > the workaround fix isn't all that ugly, so it's not a matter of enabling you > to do something that is almost impossible with today's java, and finally, > this feels extremely inconsistent. If try/catch becomes an expression, > shouldn't for, while, do, if/else, and perhaps even synchronized, be > expressions too? > That would be a major, major change in how java works. Could be a good > change, but such a proposal needs to be written up and analysed, and I have > a feeling it's going to play havoc on the parser grammar. > --Reinier Zwitserloot > > > > > On Wed, Nov 11, 2009 at 7:10 PM, Lawrence Kesteloot wrote: >> >> One nice thing about having been on the coin-dev list is realizing >> that I really like Java as it is. None of the proposals (including my >> list comprehensions) have seem "worth it" (except ARM). But there's >> one thing that repeatedly grosses me out, and bothers me more each >> day: >> >> ? ?Reader foo = new FileReader(filename); >> >> This throws an IOException. I want to keep my catch clauses nice and >> tight, so I end up writing: >> >> ? ?Reader foo; >> ? ?try { >> ? ? ? ?foo = new FileReader(filename); >> ? ?} catch (IOException e) { >> ? ? ? ?log.warn("Cannot open file \"" + filename + "\" (" + >> e.getMessage() + ")"); >> ? ? ? ?...; >> ? ?} >> >> The duplication of "foo" smells bad and four lines of noise were >> added. I would prefer a try/catch expression: >> >> ? ?Reader foo = try new FileReader(filename) catch (IOException e) { >> ? ? ? ?log.warn("Cannot open file \"" + filename + "\" (" + >> e.getMessage() + ")"); >> ? ? ? ?...; >> ? ?} >> >> I can't think of a change to Java that would please me more >> day-to-day. Anyone else feel the same? Should I write this up for >> JDK8? >> >> Lawrence Kesteloot >> > > From reinier at zwitserloot.com Wed Nov 11 10:35:43 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 19:35:43 +0100 Subject: try/catch expression In-Reply-To: <997cab100911111032t76f2824fi6f720c258c779144@mail.gmail.com> References: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> <560fb5ed0911111024n5baadfdx3922f8febd8051eb@mail.gmail.com> <997cab100911111032t76f2824fi6f720c258c779144@mail.gmail.com> Message-ID: <560fb5ed0911111035if6d5720k4968aee03983c43d@mail.gmail.com> Closures could solve this rather elegantly - letting you group both an initializing block and an error handler in one method call. NB: Just thought it was that time again to remind coin-dev of the usefulness of closures. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 7:32 PM, Lawrence Kesteloot wrote: > Rats! I didn't think about what the expression would return. Dammit. > In my mind of course it just returns from the enclosing function, but > that's not okay in general. Thanks for analyzing it, sorry I didn't do > a better job. > > I don't agree that this change would force all statements to be > expressions. > > And I don't like the sloppy "put the entire code of a function inside > a large try/catch block". I've seen it result in too many errors where > someone adds a throwing line in the middle and doesn't realize an > existing catch will do something other than what they'd want. Also any > resulting log message isn't as clear. > > Lawrence > > > > > On Wed, Nov 11, 2009 at 10:24 AM, Reinier Zwitserloot > wrote: > > For what it's worth, the java standard way of doing this is generally to > > bundle both the file open operation as well as the reads (and, arguably, > the > > subsequent close) into a single try block. Even ARM does this - the > > initializer expression is part of the node that contains the operations > done > > on the ARM block, so if you catch exceptions on the initializer, then you > > also catch them on the body, unless the body has its own try block, which > > looks no less ugly than your snippet. > > Your proposal is vague. What, exactly, is returned from a try/catch > > expression if the catch block is triggered? An implicit 'null'? Something > > akin to BGGA's last expression in the block? That would be a rather large > > change, and, like BGGA, you have to separate accidental from explicit > use, > > for example by having that weird 'last expression must not end with a > > semi-colon' rule. > > Assuming you fill in the holes, I think this idea is rather > underwhelming. > > The thing you're trying to fix here isn't used all that often (bundling > open > > with read is more common and can be done much simpler, especially with > ARM), > > the workaround fix isn't all that ugly, so it's not a matter of enabling > you > > to do something that is almost impossible with today's java, and finally, > > this feels extremely inconsistent. If try/catch becomes an expression, > > shouldn't for, while, do, if/else, and perhaps even synchronized, be > > expressions too? > > That would be a major, major change in how java works. Could be a good > > change, but such a proposal needs to be written up and analysed, and I > have > > a feeling it's going to play havoc on the parser grammar. > > --Reinier Zwitserloot > > > > > > > > > > On Wed, Nov 11, 2009 at 7:10 PM, Lawrence Kesteloot > wrote: > >> > >> One nice thing about having been on the coin-dev list is realizing > >> that I really like Java as it is. None of the proposals (including my > >> list comprehensions) have seem "worth it" (except ARM). But there's > >> one thing that repeatedly grosses me out, and bothers me more each > >> day: > >> > >> Reader foo = new FileReader(filename); > >> > >> This throws an IOException. I want to keep my catch clauses nice and > >> tight, so I end up writing: > >> > >> Reader foo; > >> try { > >> foo = new FileReader(filename); > >> } catch (IOException e) { > >> log.warn("Cannot open file \"" + filename + "\" (" + > >> e.getMessage() + ")"); > >> ...; > >> } > >> > >> The duplication of "foo" smells bad and four lines of noise were > >> added. I would prefer a try/catch expression: > >> > >> Reader foo = try new FileReader(filename) catch (IOException e) { > >> log.warn("Cannot open file \"" + filename + "\" (" + > >> e.getMessage() + ")"); > >> ...; > >> } > >> > >> I can't think of a change to Java that would please me more > >> day-to-day. Anyone else feel the same? Should I write this up for > >> JDK8? > >> > >> Lawrence Kesteloot > >> > > > > > > From crazybob at crazybob.org Wed Nov 11 10:38:33 2009 From: crazybob at crazybob.org (Bob Lee) Date: Wed, 11 Nov 2009 10:38:33 -0800 Subject: Wouldn't this be nice? In-Reply-To: <560fb5ed0911111031x55c0331bx47695447f33a6fe7@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> <560fb5ed0911111031x55c0331bx47695447f33a6fe7@mail.gmail.com> Message-ID: On Wed, Nov 11, 2009 at 10:31 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > How exactly do you imagine the proposed for (char c : string) syntax works? Using charAt(), like I would normally do. > Any other situation and the array copy is an irrelevant drop in the bucket > compared to all the other stuff that will be going on. In such niche > situations, I get the feeling that you probably should roll with char or > even byte arrays from the start, instead of going through java.lang.String. > I'm writing library code (uri parsing, for example), so I'm stuck with String, and can't tolerate an extra 2 iterations (one to zero out the allocated array, and one to copy the char from the string, in addition to iterating over the chars in the final array). Bob From i30817 at gmail.com Wed Nov 11 10:40:13 2009 From: i30817 at gmail.com (Paulo Levi) Date: Wed, 11 Nov 2009 18:40:13 +0000 Subject: Wouldn't this be nice? In-Reply-To: References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> <560fb5ed0911111031x55c0331bx47695447f33a6fe7@mail.gmail.com> Message-ID: <212322090911111040o9e723b8m582b0bb5a9703eaf@mail.gmail.com> How about adding a keyword (range(Number a) ) for this. After all java 1.5 added enum. From neal at gafter.com Wed Nov 11 10:42:14 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 10:42:14 -0800 Subject: try/catch expression In-Reply-To: <560fb5ed0911111035if6d5720k4968aee03983c43d@mail.gmail.com> References: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> <560fb5ed0911111024n5baadfdx3922f8febd8051eb@mail.gmail.com> <997cab100911111032t76f2824fi6f720c258c779144@mail.gmail.com> <560fb5ed0911111035if6d5720k4968aee03983c43d@mail.gmail.com> Message-ID: <15e8b9d20911111042l29d5e53cr400bd1fce43e6981@mail.gmail.com> On Wed, Nov 11, 2009 at 10:35 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > > > Closures could solve this rather elegantly - letting you group both an > initializing block and an error handler in one method call. > > > > NB: Just thought it was that time again to remind coin-dev of the > usefulness > of closures. > This particular hypothetical API is one of those that is much more useful if the caller can use "nonlocal" control-flow (e.g., a "return" in the try block or the catch block). But when there are two blocks to be executed, as here, even BGGA doesn't make it pretty. From reinier at zwitserloot.com Wed Nov 11 10:46:00 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 19:46:00 +0100 Subject: Wouldn't this be nice? In-Reply-To: <212322090911111040o9e723b8m582b0bb5a9703eaf@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <560fb5ed0911110937ld0290cbtf864946cdcff120c@mail.gmail.com> <560fb5ed0911111031x55c0331bx47695447f33a6fe7@mail.gmail.com> <212322090911111040o9e723b8m582b0bb5a9703eaf@mail.gmail.com> Message-ID: <560fb5ed0911111046q6c59d05ena5e1c484e0329c83@mail.gmail.com> Add a keyword for something that is going to be indistinguishable from a static import? That seems crazy. Bob: You've convinced me. We should overload the range function to also take CharSequences and spit out Iterable objects, that are internally powered by charAt. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 7:40 PM, Paulo Levi wrote: > How about adding a keyword (range(Number a) ) for this. After all java > 1.5 added enum. > From kevinb at google.com Wed Nov 11 12:06:20 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Wed, 11 Nov 2009 12:06:20 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910210808l2a4443f0v24421dd37f5d11b9@mail.gmail.com> <17b2302a0910210839n7f06d584y6db7262ecc990775@mail.gmail.com> <15e8b9d20910210926i4f66ac6ew4666415a497c7c59@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> Message-ID: <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> I realized that this is not as useful as I was hoping it would be. Many users at Google are not iterating through the source data directly, but are passing that iterator through methods like transform() and filter() and many others ( http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterators.html ). I can't stand the thought of having to descend into RandomAccess-style hell, so passing an iterator through these methods will likely wipe the Closeable right off, making the foreach improvement less applicable. I withdraw my +10, which is not to say that I am arguing against it. On Sun, Nov 8, 2009 at 8:09 AM, Kevin Bourrillion wrote: > Thread-resurrect... > > I think detecting 'iterator instanceof Closeable' is an outstanding > idea, and one that would solve problems that have been vexing me as a > library developer for years. > > The foreach construct owns the creation of that instance, and is the > only party that has a reference to it. If the instance is Closeable, > it feels simply irresponsible to ignore this. > > As for the potential risks, we're talking about an instance that's > unreachable and eligible for GC, so it's difficult to imagine that > closing such an instance could be a bad idea. Looked another way, if > a user didn't want automatic close for some reason, that reason would > already be preventing that user from using foreach anyway. > > +10 > > > > On Thu, Oct 22, 2009 at 8:19 AM, Neal Gafter wrote: > > On Thu, Oct 22, 2009 at 8:59 AM, Howard Lovatt >wrote: > > > >> I think you can choose if close to applies to the Iterable or the > Iterator. > > > > > > Agreed. But if it applies to the Iterable, the programmer can easily use > an > > ARM block around the for-each loop. If it applies to the Iterator, there > is > > no way for the programmer to do it. That's why support is needed in that > > case. > > > > > > > > -- > Kevin Bourrillion @ Google > internal: http://go/javalibraries > external: guava-libraries.googlecode.com > -- Kevin Bourrillion @ Google internal: http://go/javalibraries external: guava-libraries.googlecode.com From howard.lovatt at iee.org Wed Nov 11 12:33:16 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 11 Nov 2009 21:33:16 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910210808l2a4443f0v24421dd37f5d11b9@mail.gmail.com> <17b2302a0910210839n7f06d584y6db7262ecc990775@mail.gmail.com> <15e8b9d20910210926i4f66ac6ew4666415a497c7c59@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> Message-ID: <3dd3f56a0911111233l51142902p61e96393ed7d76dc@mail.gmail.com> This issue of passing the iterable (not iterator, in the case of my code) through many methods is why I suggest a SafeCloseable that doesn't throw exceptions. It is practical to pass SafeCloseable through many methods without them all becoming 'infected' with throws exception. Would this solution work with Google Collections? 2009/11/11 Kevin Bourrillion > I realized that this is not as useful as I was hoping it would be. > > Many users at Google are not iterating through the source data directly, > but are passing that iterator through methods like transform() and filter() > and many others ( > http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterators.html > ). > > I can't stand the thought of having to descend into RandomAccess-style > hell, so passing an iterator through these methods will likely wipe the > Closeable right off, making the foreach improvement less applicable. > > I withdraw my +10, which is not to say that I am arguing against it. > > > > On Sun, Nov 8, 2009 at 8:09 AM, Kevin Bourrillion wrote: > >> Thread-resurrect... >> >> I think detecting 'iterator instanceof Closeable' is an outstanding >> idea, and one that would solve problems that have been vexing me as a >> library developer for years. >> >> The foreach construct owns the creation of that instance, and is the >> only party that has a reference to it. If the instance is Closeable, >> it feels simply irresponsible to ignore this. >> >> As for the potential risks, we're talking about an instance that's >> unreachable and eligible for GC, so it's difficult to imagine that >> closing such an instance could be a bad idea. Looked another way, if >> a user didn't want automatic close for some reason, that reason would >> already be preventing that user from using foreach anyway. >> >> +10 >> >> >> >> On Thu, Oct 22, 2009 at 8:19 AM, Neal Gafter wrote: >> > On Thu, Oct 22, 2009 at 8:59 AM, Howard Lovatt > >wrote: >> > >> >> I think you can choose if close to applies to the Iterable or the >> Iterator. >> > >> > >> > Agreed. But if it applies to the Iterable, the programmer can easily use >> an >> > ARM block around the for-each loop. If it applies to the Iterator, >> there is >> > no way for the programmer to do it. That's why support is needed in >> that >> > case. >> > >> > >> >> >> >> -- >> Kevin Bourrillion @ Google >> internal: http://go/javalibraries >> external: guava-libraries.googlecode.com >> > > > > -- > Kevin Bourrillion @ Google > internal: http://go/javalibraries > external: guava-libraries.googlecode.com > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. From tball at google.com Wed Nov 11 12:35:12 2009 From: tball at google.com (Tom Ball) Date: Wed, 11 Nov 2009 12:35:12 -0800 Subject: try/catch expression In-Reply-To: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> References: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> Message-ID: I think you can do your preferred try/catch example using JavaFX Script. That's outside of the discussion of Coin changes, but suggests that rather than this list working toward making Java be the superset of all JVM languages, we should instead encourage the use of other JVM languages when appropriate. Tom On Wed, Nov 11, 2009 at 10:10 AM, Lawrence Kesteloot wrote: > One nice thing about having been on the coin-dev list is realizing > that I really like Java as it is. None of the proposals (including my > list comprehensions) have seem "worth it" (except ARM). But there's > one thing that repeatedly grosses me out, and bothers me more each > day: > > Reader foo = new FileReader(filename); > > This throws an IOException. I want to keep my catch clauses nice and > tight, so I end up writing: > > Reader foo; > try { > foo = new FileReader(filename); > } catch (IOException e) { > log.warn("Cannot open file \"" + filename + "\" (" + > e.getMessage() + ")"); > ...; > } > > The duplication of "foo" smells bad and four lines of noise were > added. I would prefer a try/catch expression: > > Reader foo = try new FileReader(filename) catch (IOException e) { > log.warn("Cannot open file \"" + filename + "\" (" + > e.getMessage() + ")"); > ...; > } > > I can't think of a change to Java that would please me more > day-to-day. Anyone else feel the same? Should I write this up for > JDK8? > > Lawrence Kesteloot > > From neal at gafter.com Wed Nov 11 12:40:04 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 12:40:04 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910210808l2a4443f0v24421dd37f5d11b9@mail.gmail.com> <17b2302a0910210839n7f06d584y6db7262ecc990775@mail.gmail.com> <15e8b9d20910210926i4f66ac6ew4666415a497c7c59@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> Message-ID: <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> On Wed, Nov 11, 2009 at 12:06 PM, Kevin Bourrillion wrote: > I can't stand the thought of having to descend into RandomAccess-style > hell, so passing an iterator through these methods will likely wipe the > Closeable right off, making the foreach improvement less applicable. I can't quite parse this sentence. What is RandomAccess-style hell? What does it mean to "wipe" a Closeable? I wouldn't expect methods that receive an Iterator to close it, since the caller retains a reference to it. Can you please explain the issue you're concerned about? -Neal From neal at gafter.com Wed Nov 11 12:43:06 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 12:43:06 -0800 Subject: try/catch expression In-Reply-To: References: <997cab100911111010i5a91e2a1i28ad326aaf5cad05@mail.gmail.com> Message-ID: <15e8b9d20911111243u397042e8w73692e47cbb1f810@mail.gmail.com> On Wed, Nov 11, 2009 at 12:35 PM, Tom Ball wrote: > I think you can do your preferred try/catch example using JavaFX Script. > That's outside of the discussion of Coin changes, but suggests that rather > than this list working toward making Java be the superset of all JVM > languages, we should instead encourage the use of other JVM languages when > appropriate. > I think it is worth making Java the best language it can be (not the superset of all JVM lanugages). Cheers, Neal From reinier at zwitserloot.com Wed Nov 11 13:13:45 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 22:13:45 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <17b2302a0910210839n7f06d584y6db7262ecc990775@mail.gmail.com> <15e8b9d20910210926i4f66ac6ew4666415a497c7c59@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> Message-ID: <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> I think the idea was thus: Just like the concept of a FilterInputStream, the google codebase contains many instances of filtering Iterators. Possibly, for example, a MapIterator. The concept of having a CloseableIterator does not survive filtering. This is bad. I think that was the gist of the message. The argument has some merit, I think. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 9:40 PM, Neal Gafter wrote: > On Wed, Nov 11, 2009 at 12:06 PM, Kevin Bourrillion >wrote: > > > I can't stand the thought of having to descend into RandomAccess-style > > hell, so passing an iterator through these methods will likely wipe the > > Closeable right off, making the foreach improvement less applicable. > > > I can't quite parse this sentence. What is RandomAccess-style hell? What > does it mean to "wipe" a Closeable? > > I wouldn't expect methods that receive an Iterator to close it, since the > caller retains a reference to it. Can you please explain the issue you're > concerned about? > > -Neal > > From neal at gafter.com Wed Nov 11 13:17:11 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 13:17:11 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910210926i4f66ac6ew4666415a497c7c59@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> Message-ID: <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> On Wed, Nov 11, 2009 at 1:13 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > The concept of having a CloseableIterator does not survive filtering. This > is bad. > There's no reason for it to not survive filtering. From reinier at zwitserloot.com Wed Nov 11 13:21:04 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 22:21:04 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <3dd3f56a0910220023s61776752jdbdfb53ff703b617@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> Message-ID: <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> Unless all existing filters are rewritten to support Closeable, and their close methods do an instanceof check on the contained Iterator and pass on the close call if they are also ClosableIterators, I don't see how that's going to work. That design is not backwards compatible, and forgetting to create this passthrough closeable principle is going to lead to very nasty surprises when you take existing code: for (SomeType x : someClosableThingie) { } and later wrap the someClosableThingie into an iterator which does not have this explicit pass-through mechanism in it. I can easily imagine that happening in day to day java development. May not be a show-stopper, but it's an issue worth thinking about. Or did you have a different mechanism in mind for preserving the closable nature of the iterator? --Reinier Zwitserloot On Wed, Nov 11, 2009 at 10:17 PM, Neal Gafter wrote: > On Wed, Nov 11, 2009 at 1:13 PM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> The concept of having a CloseableIterator does not survive filtering. >> This is bad. >> > > There's no reason for it to not survive filtering. > From neal at gafter.com Wed Nov 11 13:30:26 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 13:30:26 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910220033y6f517dc4g93a3e6b8331eb44c@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> Message-ID: <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Unless all existing filters are rewritten to support Closeable, and their > close methods do an instanceof check on the contained Iterator and pass on > the close call if they are also ClosableIterators, I don't see how that's > going to work. That sounds like a workable approach. From reinier at zwitserloot.com Wed Nov 11 13:34:10 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Nov 2009 22:34:10 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> Message-ID: <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> The problem is: If you forget to retrofit a filter, or you're just using one written with java6 or below in mind, then there's no obvious sign that your resource is not being closed. No compiler error or warning. Not even a pattern in the code you can detect. You'll notice a month later, when you've released your product to your customers, who are starting to call in with strange errors involving full DB pools and such. The fix is to write up a custom findbugs plugin, or something similar. Given the way findbugs is not even close to universally used, let alone used with custom plugins, that is not at all a satisfactory answer. That's a very serious problem. --Reinier Zwitserloot On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter wrote: > On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> Unless all existing filters are rewritten to support Closeable, and their >> close methods do an instanceof check on the contained Iterator and pass on >> the close call if they are also ClosableIterators, I don't see how that's >> going to work. > > > That sounds like a workable approach. > > From i30817 at gmail.com Wed Nov 11 18:02:12 2009 From: i30817 at gmail.com (Paulo Levi) Date: Thu, 12 Nov 2009 02:02:12 +0000 Subject: A iterator with a generic method next()? Message-ID: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> Recently i'm thinking that a iterator with a T next() method is a good idea, for some uses. The interface is different from the normal iterator, so it can't be used for the for loop (or at least it would be fairly useless if so), but i'm thinking of using it as a proxy of ObjectInputStream + factories in case that the object in the file are not there (or the file doesn't exist), where the saved objects are of different types. Just tossing this idea into the melting pot. From reinier at zwitserloot.com Wed Nov 11 18:06:53 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Nov 2009 03:06:53 +0100 Subject: A iterator with a generic method next()? In-Reply-To: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> References: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> Message-ID: <560fb5ed0911111806j7562a43dob8de56e8ce95be67@mail.gmail.com> Er, Iterator HAS a T next() method. coin-dev is not a melting pot for random ill-thought out rough sketches. --Reinier Zwitserloot On Thu, Nov 12, 2009 at 3:02 AM, Paulo Levi wrote: > Recently i'm thinking that a iterator with a > T next() method is a good idea, for some uses. The interface is > different from the normal iterator, so it can't be used for > the for loop (or at least it would be fairly useless if so), but i'm > thinking of using it as a proxy of ObjectInputStream + factories in > case that the object in the file are not there (or the file doesn't > exist), where the saved objects are of different types. > > Just tossing this idea into the melting pot. > > From i30817 at gmail.com Wed Nov 11 18:33:24 2009 From: i30817 at gmail.com (Paulo Levi) Date: Thu, 12 Nov 2009 02:33:24 +0000 Subject: A iterator with a generic method next()? In-Reply-To: <560fb5ed0911111806j7562a43dob8de56e8ce95be67@mail.gmail.com> References: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> <560fb5ed0911111806j7562a43dob8de56e8ce95be67@mail.gmail.com> Message-ID: <212322090911111833h64d2cf57kc12c7bae7da1d56a@mail.gmail.com> Not a T next(); a T next(); > coin-dev is not a melting pot for random ill-thought out rough sketches. Fair enough. From neal at gafter.com Wed Nov 11 20:11:21 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Nov 2009 20:11:21 -0800 Subject: A iterator with a generic method next()? In-Reply-To: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> References: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> Message-ID: <15e8b9d20911112011h463f180dn634b1f1914e09af3@mail.gmail.com> I can't imagine how one could correctly implement such a method. Are you just trying to hide a cast that needs to be in the code? If so, just put the cast in the code. On Wed, Nov 11, 2009 at 6:02 PM, Paulo Levi wrote: > Recently i'm thinking that a iterator with a > T next() method is a good idea, for some uses. The interface is > different from the normal iterator, so it can't be used for > the for loop (or at least it would be fairly useless if so), but i'm > thinking of using it as a proxy of ObjectInputStream + factories in > case that the object in the file are not there (or the file doesn't > exist), where the saved objects are of different types. > > Just tossing this idea into the melting pot. > > From howard.lovatt at iee.org Thu Nov 12 01:55:33 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 12 Nov 2009 10:55:33 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> Message-ID: <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> Reinier has raised a good point that you start with a CloseableIterable and end up with just an Iterable, this loosing of the Cloaseable type hasn't happened in my code (because I am looking for the problem). I can see that it would happen in other peoples code and also by mistake. I think this problem is solved by using: try(final String line : iterableFile) { ... } The above try-for-each block will fail at compile time if iterableFile isn't of type CloseableIterable. Secondly, and more controversially, the for-each loop could fail at compile time if given a CloseableIteratable as opposed to a normal Iterable. 2009/11/11 Reinier Zwitserloot > The problem is: If you forget to retrofit a filter, or you're just using > one written with java6 or below in mind, then there's no obvious sign that > your resource is not being closed. No compiler error or warning. Not even a > pattern in the code you can detect. You'll notice a month later, when you've > released your product to your customers, who are starting to call in with > strange errors involving full DB pools and such. The fix is to write up a > custom findbugs plugin, or something similar. Given the way findbugs is not > even close to universally used, let alone used with custom plugins, that is > not at all a satisfactory answer. > > That's a very serious problem. > > --Reinier Zwitserloot > > > > > On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter wrote: > >> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < >> reinier at zwitserloot.com> wrote: >> >>> Unless all existing filters are rewritten to support Closeable, and their >>> close methods do an instanceof check on the contained Iterator and pass on >>> the close call if they are also ClosableIterators, I don't see how that's >>> going to work. >> >> >> That sounds like a workable approach. >> >> > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. From reinier at zwitserloot.com Thu Nov 12 04:25:27 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Nov 2009 13:25:27 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> Message-ID: <560fb5ed0911120425i1ca2ededp4f73a16ab72e9246@mail.gmail.com> "Controversial" as in: Not even close to backwards compatible? I don't think that's feasible. A separate syntax to indicate that you'd like to iterate-then-close, which warns or errs if you supply a non-closable iterator, seems like a better idea. Lest we overload the try keyword too much, and make code that isn't particularly readable ('try' does not scream: Iterating through something iteratable to me), possibly look into: try for(T a : b) { } We might as well start using the fact that try requires a block body. for try(T a : b) { } and: for(try T a : b) { } or even: for(T a: try b) { } are all also unambiguous given the current JLS and should be easy to retrofit into the existing grammars of javac and ecj. --Reinier Zwitserloot On Thu, Nov 12, 2009 at 10:55 AM, Howard Lovatt wrote: > Reinier has raised a good point that you start with a CloseableIterable and > end up with just an Iterable, this loosing of the Cloaseable type hasn't > happened in my code (because I am looking for the problem). I can see that > it would happen in other peoples code and also by mistake. I think this > problem is solved by using: > > try(final String line : iterableFile) { > ... > } > > The above try-for-each block will fail at compile time if iterableFile > isn't of type CloseableIterable. > > Secondly, and more controversially, the for-each loop could fail at compile > time if given a CloseableIteratable as opposed to a normal Iterable. > > 2009/11/11 Reinier Zwitserloot > >> The problem is: If you forget to retrofit a filter, or you're just using >> one written with java6 or below in mind, then there's no obvious sign that >> your resource is not being closed. No compiler error or warning. Not even a >> pattern in the code you can detect. You'll notice a month later, when you've >> released your product to your customers, who are starting to call in with >> strange errors involving full DB pools and such. The fix is to write up a >> custom findbugs plugin, or something similar. Given the way findbugs is not >> even close to universally used, let alone used with custom plugins, that is >> not at all a satisfactory answer. >> >> That's a very serious problem. >> >> --Reinier Zwitserloot >> >> >> >> >> On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter wrote: >> >>> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < >>> reinier at zwitserloot.com> wrote: >>> >>>> Unless all existing filters are rewritten to support Closeable, and >>>> their close methods do an instanceof check on the contained Iterator and >>>> pass on the close call if they are also ClosableIterators, I don't see how >>>> that's going to work. >>> >>> >>> That sounds like a workable approach. >>> >>> >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> > > > > -- > -- Howard. > From Ulf.Zibis at gmx.de Thu Nov 12 04:48:23 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Thu, 12 Nov 2009 13:48:23 +0100 Subject: Wouldn't this be nice? In-Reply-To: <17b2302a0911111112r6cbed8a3ybfa2a9aa4222acf@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFB09D5.3090003@gmx.de> <17b2302a0911111112r6cbed8a3ybfa2a9aa4222acf@mail.gmail.com> Message-ID: <4AFC0417.7040005@gmx.de> Sorry for missing the mailing list by CC: Am 11.11.2009 20:12, Joshua Bloch schrieb: > Ulf, > > Presumably you mean interface CharSequence implements > Iterable. Yes right > But I really want to avoid the boxing and unboxing. Can you explain where we have boxing and unboxing here? Thanks, Ulf > > Regards, > > Josh > > On Wed, Nov 11, 2009 at 11:00 AM, Ulf Zibis > wrote: > > Am 11.11.2009 17:46, Joshua Bloch schrieb: > > Paulo, > > I have a hard time intuiting the semantics by just looking a > the statement. > What I'm really sorry that I didn't put into the original > statement is: > > for (char c : myString) > > > Another Idea: > > interface CharSequence implements Iterable > > -Ulf > > > From reinier at zwitserloot.com Thu Nov 12 06:39:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Nov 2009 15:39:46 +0100 Subject: Wouldn't this be nice? In-Reply-To: <4AFC0417.7040005@gmx.de> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFB09D5.3090003@gmx.de> <17b2302a0911111112r6cbed8a3ybfa2a9aa4222acf@mail.gmail.com> <4AFC0417.7040005@gmx.de> Message-ID: <560fb5ed0911120639x624655dbn19d91a62db6bd3fd@mail.gmail.com> char to Character, obviously. --Reinier Zwitserloot On Thu, Nov 12, 2009 at 1:48 PM, Ulf Zibis wrote: > Sorry for missing the mailing list by CC: > > > Am 11.11.2009 20:12, Joshua Bloch schrieb: > > Ulf, > > > > Presumably you mean interface CharSequence implements > > Iterable. > Yes right > > But I really want to avoid the boxing and unboxing. > Can you explain where we have boxing and unboxing here? > > Thanks, > Ulf > > > > > Regards, > > > > Josh > > > > On Wed, Nov 11, 2009 at 11:00 AM, Ulf Zibis > > wrote: > > > > Am 11.11.2009 17:46, Joshua Bloch schrieb: > > > > Paulo, > > > > I have a hard time intuiting the semantics by just looking a > > the statement. > > What I'm really sorry that I didn't put into the original > > statement is: > > > > for (char c : myString) > > > > > > Another Idea: > > > > interface CharSequence implements Iterable > > > > -Ulf > > > > > > > > > From markmahieu at googlemail.com Thu Nov 12 07:08:18 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 12 Nov 2009 15:08:18 +0000 Subject: Wouldn't this be nice? In-Reply-To: <560fb5ed0911120639x624655dbn19d91a62db6bd3fd@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFB09D5.3090003@gmx.de> <17b2302a0911111112r6cbed8a3ybfa2a9aa4222acf@mail.gmail.com> <4AFC0417.7040005@gmx.de> <560fb5ed0911120639x624655dbn19d91a62db6bd3fd@mail.gmail.com> Message-ID: <3AD49FC3-1B8B-4EB4-8D50-04E787C8F7DA@googlemail.com> And back again: char -> Character -> char or perhaps an Iterable<@NonNull Character> would be more interesting: char -> @NonNull Character -> char Which begs the question - if one were to optimise this, would the language spec or the VM be a better place to do so? Mark On 12 Nov 2009, at 14:39, Reinier Zwitserloot wrote: > char to Character, obviously. > > --Reinier Zwitserloot > > > On Thu, Nov 12, 2009 at 1:48 PM, Ulf Zibis wrote: > >> Sorry for missing the mailing list by CC: >> >> >> Am 11.11.2009 20:12, Joshua Bloch schrieb: >>> Ulf, >>> >>> Presumably you mean interface CharSequence implements >>> Iterable. >> Yes right >>> But I really want to avoid the boxing and unboxing. >> Can you explain where we have boxing and unboxing here? >> >> Thanks, >> Ulf >> >>> >>> Regards, >>> >>> Josh >>> >>> On Wed, Nov 11, 2009 at 11:00 AM, Ulf Zibis >> > wrote: >>> >>> Am 11.11.2009 17:46, Joshua Bloch schrieb: >>> >>> Paulo, >>> >>> I have a hard time intuiting the semantics by just looking a >>> the statement. >>> What I'm really sorry that I didn't put into the original >>> statement is: >>> >>> for (char c : myString) >>> >>> >>> Another Idea: >>> >>> interface CharSequence implements Iterable >>> >>> -Ulf >>> >>> >>> >> >> >> > From reinier at zwitserloot.com Thu Nov 12 07:37:45 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Nov 2009 16:37:45 +0100 Subject: Wouldn't this be nice? In-Reply-To: <3AD49FC3-1B8B-4EB4-8D50-04E787C8F7DA@googlemail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFB09D5.3090003@gmx.de> <17b2302a0911111112r6cbed8a3ybfa2a9aa4222acf@mail.gmail.com> <4AFC0417.7040005@gmx.de> <560fb5ed0911120639x624655dbn19d91a62db6bd3fd@mail.gmail.com> <3AD49FC3-1B8B-4EB4-8D50-04E787C8F7DA@googlemail.com> Message-ID: <560fb5ed0911120737l3324731fnde84b9cfc047b947@mail.gmail.com> Yes, java should absolutely gain @NonNull as a JVM primitive, and the JVM should be smart enough to treat @NonNull PrimitiveWrapper as primitives, so that you can for example create: List<@NonNull Byte> list = new ArrayList<>(); and have it be as fast as a byte array, and take ~1 byte per byte stored instead of ~24 bytes per byte stored which happens when you try this now, on a 64-bit VM. (8 bytes for the byte itself, 8 bytes for the reference stored in the array, and 8 bytes overhead for the object, which is probably lowballing it). Practically speaking though, that's very hard to get right. The hot spot compiler is not going to be able to figure out that e.g. ArrayList's 'new Object[size]' array construction should actually make a byte[] array unless there's reification, and that's just a glimmer of the complications you're going to run into with this. Keeping it somewhat simpler, the hotspot compiler might just be able to recognize that this flow is happening: A calls method B, which has called invokestatic on method: java/lang/Character - valueOf - (C)Ljava/lang/Character; right before every ARETURN instruction. A, immediately after invoking method B, always runs invokevirtual on method: java/lang/Character - charValue - ()C If this is true, then it should always be legal to ignore both method calls; they are each other's opposite. No need for JVM awareness of @NonNull annotations; if the above situation occurs, then the Character object in question that is never made could never have been null. --Reinier Zwitserloot On Thu, Nov 12, 2009 at 4:08 PM, Mark Mahieu wrote: > And back again: > > char -> Character -> char > > or perhaps an Iterable<@NonNull Character> would be more interesting: > > char -> @NonNull Character -> char > > > Which begs the question - if one were to optimise this, would the language > spec or the VM be a better place to do so? > > > Mark > > > > > On 12 Nov 2009, at 14:39, Reinier Zwitserloot wrote: > > char to Character, obviously. >> >> --Reinier Zwitserloot >> >> >> On Thu, Nov 12, 2009 at 1:48 PM, Ulf Zibis wrote: >> >> Sorry for missing the mailing list by CC: >>> >>> >>> Am 11.11.2009 20:12, Joshua Bloch schrieb: >>> >>>> Ulf, >>>> >>>> Presumably you mean interface CharSequence implements >>>> Iterable. >>>> >>> Yes right >>> >>>> But I really want to avoid the boxing and unboxing. >>>> >>> Can you explain where we have boxing and unboxing here? >>> >>> Thanks, >>> Ulf >>> >>> >>>> Regards, >>>> >>>> Josh >>>> >>>> On Wed, Nov 11, 2009 at 11:00 AM, Ulf Zibis >>> > wrote: >>>> >>>> Am 11.11.2009 17:46, Joshua Bloch schrieb: >>>> >>>> Paulo, >>>> >>>> I have a hard time intuiting the semantics by just looking a >>>> the statement. >>>> What I'm really sorry that I didn't put into the original >>>> statement is: >>>> >>>> for (char c : myString) >>>> >>>> >>>> Another Idea: >>>> >>>> interface CharSequence implements Iterable >>>> >>>> -Ulf >>>> >>>> >>>> >>>> >>> >>> >>> >> > From i30817 at gmail.com Thu Nov 12 07:56:36 2009 From: i30817 at gmail.com (Paulo Levi) Date: Thu, 12 Nov 2009 15:56:36 +0000 Subject: A iterator with a generic method next()? In-Reply-To: <15e8b9d20911112011h463f180dn634b1f1914e09af3@mail.gmail.com> References: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> <15e8b9d20911112011h463f180dn634b1f1914e09af3@mail.gmail.com> Message-ID: <212322090911120756k11aec884k65326a9b7044995a@mail.gmail.com> Yes i am, you're right it's not safe. But it is never safe anyway in some use cases (de-serialization being the one i'm using it for). From Ulf.Zibis at gmx.de Thu Nov 12 08:53:44 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Thu, 12 Nov 2009 17:53:44 +0100 Subject: Wouldn't this be nice? In-Reply-To: <560fb5ed0911120737l3324731fnde84b9cfc047b947@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFB09D5.3090003@gmx.de> <17b2302a0911111112r6cbed8a3ybfa2a9aa4222acf@mail.gmail.com> <4AFC0417.7040005@gmx.de> <560fb5ed0911120639x624655dbn19d91a62db6bd3fd@mail.gmail.com> <3AD49FC3-1B8B-4EB4-8D50-04E787C8F7DA@googlemail.com> <560fb5ed0911120737l3324731fnde84b9cfc047b947@mail.gmail.com> Message-ID: <4AFC3D98.9020203@gmx.de> Oops, I oversaw the intermediate step, as Iterator#next() always returns an Object, regardless if CharSequence contains simple char array. ... but I'm happy that I've triggered the discussion about HotSpot compiler optimization, as I had this in my mind too after solving my question. -Ulf Am 12.11.2009 16:37, Reinier Zwitserloot schrieb: > Yes, java should absolutely gain @NonNull as a JVM primitive, and the JVM > should be smart enough to treat @NonNull PrimitiveWrapper as primitives, so > that you can for example create: > > List<@NonNull Byte> list = new ArrayList<>(); > > and have it be as fast as a byte array, and take ~1 byte per byte stored > instead of ~24 bytes per byte stored which happens when you try this now, on > a 64-bit VM. (8 bytes for the byte itself, 8 bytes for the reference stored > in the array, and 8 bytes overhead for the object, which is probably > lowballing it). > > > Practically speaking though, that's very hard to get right. The hot spot > compiler is not going to be able to figure out that e.g. ArrayList's 'new > Object[size]' array construction should actually make a byte[] array unless > there's reification, and that's just a glimmer of the complications you're > going to run into with this. > > > Keeping it somewhat simpler, the hotspot compiler might just be able to > recognize that this flow is happening: > > A calls method B, which has called invokestatic on method: > > java/lang/Character - valueOf - (C)Ljava/lang/Character; > > right before every ARETURN instruction. > > A, immediately after invoking method B, always runs invokevirtual on method: > > java/lang/Character - charValue - ()C > > If this is true, then it should always be legal to ignore both method calls; > they are each other's opposite. > > No need for JVM awareness of @NonNull annotations; if the above situation > occurs, then the Character object in question that is never made could never > have been null. > > --Reinier Zwitserloot > > > > On Thu, Nov 12, 2009 at 4:08 PM, Mark Mahieu wrote: > > >> And back again: >> >> char -> Character -> char >> >> or perhaps an Iterable<@NonNull Character> would be more interesting: >> >> char -> @NonNull Character -> char >> >> >> Which begs the question - if one were to optimise this, would the language >> spec or the VM be a better place to do so? >> >> >> Mark >> >> >> >> >> On 12 Nov 2009, at 14:39, Reinier Zwitserloot wrote: >> >> char to Character, obviously. >> From kevinb at google.com Thu Nov 12 12:22:18 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Thu, 12 Nov 2009 12:22:18 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <3dd3f56a0910220859j39d799c9l1c965ea5ecb9461f@mail.gmail.com> <15e8b9d20910220919j5a0e1cdfk43f6acd65d601720@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> Message-ID: <108fcdeb0911121222o6337dd70q6fe9543b0467a096@mail.gmail.com> I called this "RandomAccess hell." And God forbid there should be a second aspect you want to carry through -- now you're at four possibilities already. On Wed, Nov 11, 2009 at 1:30 PM, Neal Gafter wrote: > On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> Unless all existing filters are rewritten to support Closeable, and their >> close methods do an instanceof check on the contained Iterator and pass on >> the close call if they are also ClosableIterators, I don't see how that's >> going to work. > > > That sounds like a workable approach. > > -- Kevin Bourrillion @ Google internal: http://go/javalibraries external: guava-libraries.googlecode.com From howard.lovatt at gmail.com Thu Nov 12 12:27:26 2009 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 12 Nov 2009 21:27:26 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <560fb5ed0911120425i1ca2ededp4f73a16ab72e9246@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> <560fb5ed0911120425i1ca2ededp4f73a16ab72e9246@mail.gmail.com> Message-ID: <6FD1ED59-62D7-4FDA-8311-BA140D801442@gmail.com> I think the for loop failing on CloseableIterable is backward compatible because CloseableIterable currently doesn't exist. The reason I said controversially was that it would involve more work. -- Howard Lovatt +61 419 971 263 On 12/11/2009, at 1:25 PM, Reinier Zwitserloot wrote: > "Controversial" as in: Not even close to backwards compatible? I > don't think that's feasible. A separate syntax to indicate that > you'd like to iterate-then-close, which warns or errs if you supply > a non-closable iterator, seems like a better idea. Lest we overload > the try keyword too much, and make code that isn't particularly > readable ('try' does not scream: Iterating through something > iteratable to me), possibly look into: > > try for(T a : b) { > } > > We might as well start using the fact that try requires a block body. > > for try(T a : b) { > } > > and: > > for(try T a : b) { > } > > or even: > > for(T a: try b) { > } > > are all also unambiguous given the current JLS and should be easy to > retrofit into the existing grammars of javac and ecj. > > --Reinier Zwitserloot > > > > On Thu, Nov 12, 2009 at 10:55 AM, Howard Lovatt > wrote: > Reinier has raised a good point that you start with a > CloseableIterable and end up with just an Iterable, this loosing of > the Cloaseable type hasn't happened in my code (because I am looking > for the problem). I can see that it would happen in other peoples > code and also by mistake. I think this problem is solved by using: > > try(final String line : iterableFile) { > ... > } > > The above try-for-each block will fail at compile time if > iterableFile isn't of type CloseableIterable. > > Secondly, and more controversially, the for-each loop could fail at > compile time if given a CloseableIteratable as opposed to a normal > Iterable. > > 2009/11/11 Reinier Zwitserloot > The problem is: If you forget to retrofit a filter, or you're just > using one written with java6 or below in mind, then there's no > obvious sign that your resource is not being closed. No compiler > error or warning. Not even a pattern in the code you can detect. > You'll notice a month later, when you've released your product to > your customers, who are starting to call in with strange errors > involving full DB pools and such. The fix is to write up a custom > findbugs plugin, or something similar. Given the way findbugs is not > even close to universally used, let alone used with custom plugins, > that is not at all a satisfactory answer. > > That's a very serious problem. > > --Reinier Zwitserloot > > > > > On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter wrote: > On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot > wrote: > Unless all existing filters are rewritten to support Closeable, and > their close methods do an instanceof check on the contained Iterator > and pass on the close call if they are also ClosableIterators, I > don't see how that's going to work. > > That sounds like a workable approach. > > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > > > > -- > -- Howard. > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ From reinier at zwitserloot.com Thu Nov 12 12:30:20 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Nov 2009 21:30:20 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <6FD1ED59-62D7-4FDA-8311-BA140D801442@gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> <560fb5ed0911120425i1ca2ededp4f73a16ab72e9246@mail.gmail.com> <6FD1ED59-62D7-4FDA-8311-BA140D801442@gmail.com> Message-ID: <560fb5ed0911121230t586307eey9ac1610d23a8ed0e@mail.gmail.com> Oh, I thought you meant the reverse, that all Iterables had to be CloseableIterators henceforth, errors occuring if they aren't. The act of raising warnings or errors in the face of trying to iterate across a closeable iterator without also calling the close method safely is probably something for findbugs to find. I can come up with a few situations where you want to do that. For example, because you aren't done with the resource yet, because, say, it's a db thing of some sort and you want to add a new row or some such. --Reinier Zwitserloot On Thu, Nov 12, 2009 at 9:27 PM, Howard Lovatt wrote: > I think the for loop failing on CloseableIterable is backward compatible > because CloseableIterable currently doesn't exist. The reason I said > controversially was that it would involve more work. > > -- Howard Lovatt +61 419 971 263 > > On 12/11/2009, at 1:25 PM, Reinier Zwitserloot > wrote: > > "Controversial" as in: Not even close to backwards compatible? I don't > think that's feasible. A separate syntax to indicate that you'd like to > iterate-then-close, which warns or errs if you supply a non-closable > iterator, seems like a better idea. Lest we overload the try keyword too > much, and make code that isn't particularly readable ('try' does not scream: > Iterating through something iteratable to me), possibly look into: > > try for(T a : b) { > } > > We might as well start using the fact that try requires a block body. > > for try(T a : b) { > } > > and: > > for(try T a : b) { > } > > or even: > > for(T a: try b) { > } > > are all also unambiguous given the current JLS and should be easy to > retrofit into the existing grammars of javac and ecj. > > --Reinier Zwitserloot > > > > On Thu, Nov 12, 2009 at 10:55 AM, Howard Lovatt < > howard.lovatt at iee.org> wrote: > >> Reinier has raised a good point that you start with a CloseableIterable >> and end up with just an Iterable, this loosing of the Cloaseable type hasn't >> happened in my code (because I am looking for the problem). I can see that >> it would happen in other peoples code and also by mistake. I think this >> problem is solved by using: >> >> try(final String line : iterableFile) { >> ... >> } >> >> The above try-for-each block will fail at compile time if iterableFile >> isn't of type CloseableIterable. >> >> Secondly, and more controversially, the for-each loop could fail at >> compile time if given a CloseableIteratable as opposed to a normal Iterable. >> >> 2009/11/11 Reinier Zwitserloot < >> reinier at zwitserloot.com> >> >>> The problem is: If you forget to retrofit a filter, or you're just using >>> one written with java6 or below in mind, then there's no obvious sign that >>> your resource is not being closed. No compiler error or warning. Not even a >>> pattern in the code you can detect. You'll notice a month later, when you've >>> released your product to your customers, who are starting to call in with >>> strange errors involving full DB pools and such. The fix is to write up a >>> custom findbugs plugin, or something similar. Given the way findbugs is not >>> even close to universally used, let alone used with custom plugins, that is >>> not at all a satisfactory answer. >>> >>> That's a very serious problem. >>> >>> --Reinier Zwitserloot >>> >>> >>> >>> >>> On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter < >>> neal at gafter.com> wrote: >>> >>>> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < >>>> reinier at zwitserloot.com> wrote: >>>> >>>>> Unless all existing filters are rewritten to support Closeable, and >>>>> their close methods do an instanceof check on the contained Iterator and >>>>> pass on the close call if they are also ClosableIterators, I don't see how >>>>> that's going to work. >>>> >>>> >>>> That sounds like a workable approach. >>>> >>>> >>> >>> ______________________________________________________________________ >>> This email has been scanned by the MessageLabs Email Security System. >>> For more information please visit >>> http://www.messagelabs.com/email >>> ______________________________________________________________________ >>> >> >> >> >> -- >> -- Howard. >> > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > > From howard.lovatt at gmail.com Thu Nov 12 12:41:27 2009 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 12 Nov 2009 21:41:27 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <560fb5ed0911121230t586307eey9ac1610d23a8ed0e@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> <560fb5ed0911120425i1ca2ededp4f73a16ab72e9246@mail.gmail.com> <6FD1ED59-62D7-4FDA-8311-BA140D801442@gmail.com> <560fb5ed0911121230t586307eey9ac1610d23a8ed0e@mail.gmail.com> Message-ID: <992B1088-63C2-40CD-8485-2DB9226A7CAF@gmail.com> Yes, that is a good point. Probably better to leave for each alone. That leaves introducing CloseableIterable and some new syntax for try- for-each loop as the best bet. I would also favour SafeCloseable and SafeCloseableIterable in addition to Closeable and CloseableIterator, since I find the close exception pollutes everything. -- Howard Lovatt +61 419 971 263 On 12/11/2009, at 9:30 PM, Reinier Zwitserloot wrote: > Oh, I thought you meant the reverse, that all Iterables had to be > CloseableIterators henceforth, errors occuring if they aren't. > > The act of raising warnings or errors in the face of trying to > iterate across a closeable iterator without also calling the close > method safely is probably something for findbugs to find. I can come > up with a few situations where you want to do that. For example, > because you aren't done with the resource yet, because, say, it's a > db thing of some sort and you want to add a new row or some such. > > --Reinier Zwitserloot > > > > On Thu, Nov 12, 2009 at 9:27 PM, Howard Lovatt > wrote: > I think the for loop failing on CloseableIterable is backward > compatible because CloseableIterable currently doesn't exist. The > reason I said controversially was that it would involve more work. > > -- Howard Lovatt +61 419 971 263 > > On 12/11/2009, at 1:25 PM, Reinier Zwitserloot > wrote: > >> "Controversial" as in: Not even close to backwards compatible? I >> don't think that's feasible. A separate syntax to indicate that >> you'd like to iterate-then-close, which warns or errs if you supply >> a non-closable iterator, seems like a better idea. Lest we overload >> the try keyword too much, and make code that isn't particularly >> readable ('try' does not scream: Iterating through something >> iteratable to me), possibly look into: >> >> try for(T a : b) { >> } >> >> We might as well start using the fact that try requires a block body. >> >> for try(T a : b) { >> } >> >> and: >> >> for(try T a : b) { >> } >> >> or even: >> >> for(T a: try b) { >> } >> >> are all also unambiguous given the current JLS and should be easy >> to retrofit into the existing grammars of javac and ecj. >> >> --Reinier Zwitserloot >> >> >> >> On Thu, Nov 12, 2009 at 10:55 AM, Howard Lovatt > > wrote: >> Reinier has raised a good point that you start with a >> CloseableIterable and end up with just an Iterable, this loosing of >> the Cloaseable type hasn't happened in my code (because I am >> looking for the problem). I can see that it would happen in other >> peoples code and also by mistake. I think this problem is solved by >> using: >> >> try(final String line : iterableFile) { >> ... >> } >> >> The above try-for-each block will fail at compile time if >> iterableFile isn't of type CloseableIterable. >> >> Secondly, and more controversially, the for-each loop could fail at >> compile time if given a CloseableIteratable as opposed to a normal >> Iterable. >> >> 2009/11/11 Reinier Zwitserloot >> The problem is: If you forget to retrofit a filter, or you're just >> using one written with java6 or below in mind, then there's no >> obvious sign that your resource is not being closed. No compiler >> error or warning. Not even a pattern in the code you can detect. >> You'll notice a month later, when you've released your product to >> your customers, who are starting to call in with strange errors >> involving full DB pools and such. The fix is to write up a custom >> findbugs plugin, or something similar. Given the way findbugs is >> not even close to universally used, let alone used with custom >> plugins, that is not at all a satisfactory answer. >> >> That's a very serious problem. >> >> --Reinier Zwitserloot >> >> >> >> >> On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter >> wrote: >> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot > > wrote: >> Unless all existing filters are rewritten to support Closeable, and >> their close methods do an instanceof check on the contained >> Iterator and pass on the close call if they are also >> ClosableIterators, I don't see how that's going to work. >> >> That sounds like a workable approach. >> >> >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> >> >> >> -- >> -- Howard. >> >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ > From i30817 at gmail.com Thu Nov 12 13:23:07 2009 From: i30817 at gmail.com (Paulo Levi) Date: Thu, 12 Nov 2009 21:23:07 +0000 Subject: A iterator with a generic method next()? In-Reply-To: <212322090911120756k11aec884k65326a9b7044995a@mail.gmail.com> References: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> <15e8b9d20911112011h463f180dn634b1f1914e09af3@mail.gmail.com> <212322090911120756k11aec884k65326a9b7044995a@mail.gmail.com> Message-ID: <212322090911121323i16fac466lf575efa20e36d544@mail.gmail.com> Actually i think i found a bug in the compiler with these shenanigans (one that makes my idea almost useless). One would think that this class would call the method, catch the exception inside it and then return the (correct) instance. Apparently the compiler only introduces the casts at the outer part of the method. Not inside, so the class cast exception is never caught. I'm disappointed. Feet of clay and all that for the compiler. public class Main{ public static void main(String[] args) { String s = failingCatchingClassCastException(new Callable() { public Object call() throws Exception { return "Hi BUG"; } }); } public static T failingCatchingClassCastException(Callable t) { try { Object raw = new Object(); return (T) raw; } catch (ClassCastException ex) { System.out.println("WTF!!!"); } try { return (T) t.call(); } catch (Exception ex) { return null; } } } From Maurizio.Cimadamore at Sun.COM Thu Nov 12 13:38:06 2009 From: Maurizio.Cimadamore at Sun.COM (Maurizio Cimadamore) Date: Thu, 12 Nov 2009 21:38:06 +0000 Subject: A iterator with a generic method next()? In-Reply-To: <212322090911121323i16fac466lf575efa20e36d544@mail.gmail.com> References: <212322090911111802p200fca32gd56d7041b1e7bf5e@mail.gmail.com> <15e8b9d20911112011h463f180dn634b1f1914e09af3@mail.gmail.com> <212322090911120756k11aec884k65326a9b7044995a@mail.gmail.com> <212322090911121323i16fac466lf575efa20e36d544@mail.gmail.com> Message-ID: <4AFC803E.8000808@sun.com> Paulo Levi wrote: > Actually i think i found a bug in the compiler with these shenanigans > (one that makes my idea almost useless). One would think > that this class would call the method, catch the exception inside it > and then return the (correct) instance. > Apparently the compiler only introduces the casts at the outer part of > the method. Not inside, so the class cast exception > is never caught. > The issue described in your email is known as 'heap pollution' - it is a very well-known scenario that is decribed in JLS 3rd edition, section 4.12.2.1 [1]. I think you are complaining about the 'missing' ClassCastException here: return (T) raw; Well, the compiler uses a technique called 'erasure' which removes generics during compilation. This means that your code is actually translated to something like: return (Object)raw; As you can see, there's no ClassCastException generated here, as casting from raw to Object is perfectly legal. On the other hand since the compiler knows that it's statically unsafe to cast an Object into a T, it generates a so-called unchecked warning. This warning is there to remind you that your code doesn't comply with static typing rules enforced by the compiler and can be subject to weird failures, such as the ClassCastException (at a later point) you are complaining about. Where does the CCE comes from? At the call site: String s = failingCatchingClassCastException(new Callable() { ... } is translated String s = (String)failingCatchingClassCastException(new Callable() { Note that the cast here is necessary, as the signature of the method has been erased (meaning that every occurrence of T has been replaced by Object). Bottom line: never ignore unchecked warnings unless you are 100% sure about what you are doing. [1] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.2.1 > I'm disappointed. Feet of clay and all that for the compiler. > > public class Main{ > > public static void main(String[] args) { > String s = failingCatchingClassCastException(new Callable() { > > public Object call() throws Exception { > return "Hi BUG"; > } > }); > } > > public static T failingCatchingClassCastException(Callable t) { > try { > Object raw = new Object(); > return (T) raw; > } catch (ClassCastException ex) { > System.out.println("WTF!!!"); > } > try { > return (T) t.call(); > } catch (Exception ex) { > return null; > } > } > } > > From Joe.Darcy at Sun.COM Thu Nov 12 15:50:24 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Thu, 12 Nov 2009 15:50:24 -0800 Subject: Wouldn't this be nice? In-Reply-To: <15e8b9d20911111029h1d2dc4edmbb424cceccc5ff70@mail.gmail.com> References: <212322090911110836u2465c746sc26886ac8aaf016@mail.gmail.com> <212322090911110838m68de0618o3d10d9b9d0303649@mail.gmail.com> <17b2302a0911110846p10fceb6eta44e077985c6168f@mail.gmail.com> <4AFAFCDE.1060409@sun.com> <17b2302a0911111014i3603f9c9u41119fc729afc02@mail.gmail.com> <15e8b9d20911111029h1d2dc4edmbb424cceccc5ff70@mail.gmail.com> Message-ID: <4AFC9F40.2000007@sun.com> Neal Gafter wrote: > I wrote this back in > 2004 > : > > *Iterable codePoints(final String s) { > * > *return new Iterable() { > * > *public Iterator iterator() { > * > *return new Iterator() { > * > *int nextIndex = 0; > public boolean hasNext() { > * > *return nextIndex < s.length(); > * > *} > public Integer next() { > * > *int result = s.codePointAt(nextIndex); > nextIndex += Character.charCount(result); > return result; > * > *} > public void remove() > * > *{ throw new UnsupportedOperationException(); } > * > *}; > * > *} > * > *}; > * > *} > * > > Doing this for CharSequence is only a bit more complicated. > > If this is likely to be used frequently, direct compiler-generated would > certainly be better. Do we have a feel for how often this feature would be > used? > > Yes, when I had to implement the functionality of iterating over the code points of a string (http://blogs.sun.com/darcy/entry/iterating_over_codepoints), I didn't find writing the canonical loop intuitive: String s = ... for(int cp, i = 0; i < s.length(); i += Character.charCount(cp)) { cp = s.codePointAt(i); // Process cp... } I would certainly be in favor of having a platform library method to do this, 5003547 "add support for iterating over the codepoints in a string" (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003547). -Joe From pbenedict at apache.org Fri Nov 13 07:20:32 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 13 Nov 2009 09:20:32 -0600 Subject: Wouldn't this be nice? Message-ID: Joe, why don't you add that method to String? You are in charge :-) From serge.boulay at gmail.com Wed Nov 18 07:47:42 2009 From: serge.boulay at gmail.com (Serge Boulay) Date: Wed, 18 Nov 2009 10:47:42 -0500 Subject: closures after all? Message-ID: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> Maybe reading into this too much, but are closures in pipe after all? http://puredanger.com/tech/2009/11/18/closures-after-all/ From peter at retep.org.uk Wed Nov 18 08:02:00 2009 From: peter at retep.org.uk (Peter Mount) Date: Wed, 18 Nov 2009 16:02:00 +0000 Subject: closures after all? In-Reply-To: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> Message-ID: <85bf933e0911180802t779c7c74u3db226bcb3574bc5@mail.gmail.com> I'm hearing this from several directions but it does seem to be so (although limited closures). It also seems that JDK7 is going to be at least another year away as well :-( Peter On Wed, Nov 18, 2009 at 3:47 PM, Serge Boulay wrote: > Maybe reading into this too much, but are closures in pipe after all? > > http://puredanger.com/tech/2009/11/18/closures-after-all/ > > -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From howard.lovatt at iee.org Wed Nov 18 12:18:54 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Nov 2009 21:18:54 +0100 Subject: closures after all? Message-ID: <3dd3f56a0911181218r517b71aeie3a550e9bbf0fbb3@mail.gmail.com> Hopefully this is true and we will get something more ambitious than the current proposals. I think a limited form of closures, at the CISE end of the spectrum, i.e. short syntax for inner classes, would be a good edition along with an expanded collections library that includes internal iterators that make good use these new short-syntax inner classes. It would be important to design the addition so that it could latter be expanded if experience showed there was a need at a later date, e.g. possible future expansion could include: non-local returns, write to captured variables, structural typing, control loops, etc. -- Howard. (is the news too good to be true?) ---------- Forwarded message ---------- > From: Serge Boulay > To: coin-dev at openjdk.java.net > Date: Wed, 18 Nov 2009 10:47:42 -0500 > Subject: closures after all? > Maybe reading into this too much, but are closures in pipe after all? > > http://puredanger.com/tech/2009/11/18/closures-after-all/ > From forax at univ-mlv.fr Wed Nov 18 13:08:36 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 18 Nov 2009 22:08:36 +0100 Subject: closures after all? In-Reply-To: <3dd3f56a0911181218r517b71aeie3a550e9bbf0fbb3@mail.gmail.com> References: <3dd3f56a0911181218r517b71aeie3a550e9bbf0fbb3@mail.gmail.com> Message-ID: <4B046254.7010009@univ-mlv.fr> The simplified closure proposal (lambda) is here: http://www.javac.info/closures-v06a.html R?mi Le 18/11/2009 21:18, Howard Lovatt a ?crit : > Hopefully this is true and we will get something more ambitious than the > current proposals. I think a limited form of closures, at the CISE end of > the spectrum, i.e. short syntax for inner classes, would be a good edition > along with an expanded collections library that includes internal iterators > that make good use these new short-syntax inner classes. It would be > important to design the addition so that it could latter be expanded if > experience showed there was a need at a later date, e.g. possible future > expansion could include: non-local returns, write to captured variables, > structural typing, control loops, etc. > > -- Howard. (is the news too good to be true?) > > ---------- Forwarded message ---------- > >> From: Serge Boulay >> To: coin-dev at openjdk.java.net >> Date: Wed, 18 Nov 2009 10:47:42 -0500 >> Subject: closures after all? >> Maybe reading into this too much, but are closures in pipe after all? >> >> http://puredanger.com/tech/2009/11/18/closures-after-all/ >> >> > From Joe.Darcy at Sun.COM Wed Nov 18 13:22:26 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 18 Nov 2009 13:22:26 -0800 Subject: closures after all? In-Reply-To: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> Message-ID: <4B046592.1090603@sun.com> Serge Boulay wrote: > Maybe reading into this too much, but are closures in pipe after all? > > http://puredanger.com/tech/2009/11/18/closures-after-all/ > > I'm attending Devoxx as a speaker this year, as has been reported in various outlets, Mark Reinhold announced today at Devoxx that JDK 7 will have closures, a to-be-developed from of closures smaller than BGGA, and that the JDK 7 schedule will also be extended until around September 2010. More details will be forthcoming, -Joe From jorge.ortiz at gmail.com Wed Nov 18 13:59:05 2009 From: jorge.ortiz at gmail.com (Jorge Ortiz) Date: Wed, 18 Nov 2009 13:59:05 -0800 Subject: closures after all? In-Reply-To: <4B046592.1090603@sun.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> Message-ID: <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> This link has been floating around Twitter. http://www.javac.info/closures-v06a.html --j On Wed, Nov 18, 2009 at 1:22 PM, Joseph D. Darcy wrote: > Serge Boulay wrote: > > Maybe reading into this too much, but are closures in pipe after all? > > > > http://puredanger.com/tech/2009/11/18/closures-after-all/ > > > > > > I'm attending Devoxx as a speaker this year, as has been reported in > various outlets, Mark Reinhold announced today at Devoxx that JDK 7 will > have closures, a to-be-developed from of closures smaller than BGGA, and > that the JDK 7 schedule will also be extended until around September 2010. > > More details will be forthcoming, > > -Joe > > From pbenedict at apache.org Wed Nov 18 14:10:18 2009 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 18 Nov 2009 16:10:18 -0600 Subject: closures after all? Message-ID: This part of the closures spec is very interesting: >> Locks.withLock(lock, #(){ >> System.out.println("hello"); >> }); >> You can think of this kind of type parameter accepting disjunction, "or" types. >> That is to allow it to match the exception signature of a function that throws >> any number of different checked exceptions. If the block throws no exceptions, >> the type argument would be the type Nothing (see below). Since the enhanced try/catch using disjunctive Exception types was thrown out (pun intended) because it "ventured too close to the type system", doesn't the inclusion if closures make rejecting his proposal silly? After all, the impact of closures is WAY beyond project coin. Can his enhanced exception catching be re-considered? It obviously now has some support with the new closure syntax. Paul From markmahieu at googlemail.com Wed Nov 18 14:26:12 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 18 Nov 2009 22:26:12 +0000 Subject: closures after all? In-Reply-To: <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> Message-ID: <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> Quite a few others seem to believe it'll be FCM (eg. http://java.dzone.com/news/devoxx-day-3-conference-day-1). Chinese whispers abound :) On 18 Nov 2009, at 21:59, Jorge Ortiz wrote: > This link has been floating around Twitter. > > http://www.javac.info/closures-v06a.html > > --j > > On Wed, Nov 18, 2009 at 1:22 PM, Joseph D. Darcy wrote: > >> Serge Boulay wrote: >>> Maybe reading into this too much, but are closures in pipe after all? >>> >>> http://puredanger.com/tech/2009/11/18/closures-after-all/ >>> >>> >> >> I'm attending Devoxx as a speaker this year, as has been reported in >> various outlets, Mark Reinhold announced today at Devoxx that JDK 7 will >> have closures, a to-be-developed from of closures smaller than BGGA, and >> that the JDK 7 schedule will also be extended until around September 2010. >> >> More details will be forthcoming, >> >> -Joe >> >> > From forax at univ-mlv.fr Wed Nov 18 15:23:06 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 19 Nov 2009 00:23:06 +0100 Subject: closures after all? In-Reply-To: <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> Message-ID: <4B0481DA.9000800@univ-mlv.fr> This is because the syntax of the new proposal is very close to the FCM syntax. FCM closure: #(int x, int y) { return x + y; } |Proposed lambda expression or lambda statement (v0.6a): ||#(int x, int y) x + y; or ||#(int x, int y) { return x + y; }| FCM function type: |#(int(int, int)) plus;| proposed function type (v0.6a):| #int(int, int) plus;| closure conversion and method reference are also identical. This new proposal can be seen as a simplified BGGA (for the underlying type system) with the FCM syntax. In my opinion the only flaw of this new proposal is that function types are not reified. So expect warning on cast and no way to do an instanceof on a function type. R?mi Le 18/11/2009 23:26, Mark Mahieu a ?crit : > Quite a few others seem to believe it'll be FCM (eg. http://java.dzone.com/news/devoxx-day-3-conference-day-1). > > Chinese whispers abound :) > > > On 18 Nov 2009, at 21:59, Jorge Ortiz wrote: > > >> This link has been floating around Twitter. >> >> http://www.javac.info/closures-v06a.html >> >> --j >> >> On Wed, Nov 18, 2009 at 1:22 PM, Joseph D. Darcy wrote: >> >> >>> Serge Boulay wrote: >>> >>>> Maybe reading into this too much, but are closures in pipe after all? >>>> >>>> http://puredanger.com/tech/2009/11/18/closures-after-all/ >>>> >>>> >>>> >>> I'm attending Devoxx as a speaker this year, as has been reported in >>> various outlets, Mark Reinhold announced today at Devoxx that JDK 7 will >>> have closures, a to-be-developed from of closures smaller than BGGA, and >>> that the JDK 7 schedule will also be extended until around September 2010. >>> >>> More details will be forthcoming, >>> >>> -Joe >>> >>> >>> >> > > From abies at adres.pl Wed Nov 18 15:20:35 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Thu, 19 Nov 2009 00:20:35 +0100 Subject: closures after all? In-Reply-To: <4B0481DA.9000800@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> Message-ID: <4B048143.3090204@adres.pl> R?mi Forax wrote: > In my opinion the only flaw of this new proposal is that function types > are not reified. > So expect warning on cast and no way to do an instanceof on a function type. > > Does it also mean no primitives as arguments or return values? How it will work with closure-as-single-method-interface-implementation trick? Regards, Artur Biesiadowski From forax at univ-mlv.fr Wed Nov 18 15:43:35 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 19 Nov 2009 00:43:35 +0100 Subject: closures after all? In-Reply-To: <4B048143.3090204@adres.pl> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B048143.3090204@adres.pl> Message-ID: <4B0486A7.4030007@univ-mlv.fr> Le 19/11/2009 00:20, Artur Biesiadowski a ?crit : > R?mi Forax wrote: > >> In my opinion the only flaw of this new proposal is that function types >> are not reified. >> So expect warning on cast and no way to do an instanceof on a function type. >> >> >> > Does it also mean no primitives as arguments or return values? How it > will work with closure-as-single-method-interface-implementation trick? > > Regards, > Artur Biesiadowski > > No, you can use primitive types where you want but because the interface corresponding to the function type is always parametrized by an exception type, it's not a refied type. cheers, R?mi From Joe.Darcy at Sun.COM Wed Nov 18 15:48:20 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 18 Nov 2009 15:48:20 -0800 Subject: closures after all? In-Reply-To: <4B0486A7.4030007@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B048143.3090204@adres.pl> <4B0486A7.4030007@univ-mlv.fr> Message-ID: <4B0487C4.2080605@sun.com> R?mi Forax wrote: > Le 19/11/2009 00:20, Artur Biesiadowski a ?crit : > >> R?mi Forax wrote: >> >> >>> In my opinion the only flaw of this new proposal is that function types >>> are not reified. >>> So expect warning on cast and no way to do an instanceof on a function type. >>> >>> >>> >>> >> Does it also mean no primitives as arguments or return values? How it >> will work with closure-as-single-method-interface-implementation trick? >> >> Regards, >> Artur Biesiadowski >> >> >> > > No, you can use primitive types where you want but because > the interface corresponding to the function type is always parametrized > by an exception type, it's not a refied type. > > cheers, > R?mi > The work Mark announced is preliminary; no doubt many further details will be available in the near future so I think analysis of the proposal should be deferred until there is more of a proposal to analyze :-) -Joe From markmahieu at googlemail.com Wed Nov 18 15:49:28 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 18 Nov 2009 23:49:28 +0000 Subject: closures after all? In-Reply-To: <4B0481DA.9000800@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> Message-ID: <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> Well it'll be interesting to see the official details, and (to bring it back on topic) see how it interacts with Coin's language enhancements. // tongue in cheek try (Closeable closure = #() { System.out.println("YOUR HEAD A SPLODE"); }) { // ... } Mark On 18 Nov 2009, at 23:23, R?mi Forax wrote: > This is because the syntax of the new proposal is very close to the FCM > syntax. > > FCM closure: > #(int x, int y) { return x + y; } > > |Proposed lambda expression or lambda statement (v0.6a): > ||#(int x, int y) x + y; > or > ||#(int x, int y) { return x + y; }| > > > FCM function type: > |#(int(int, int)) plus;| > > proposed function type (v0.6a):| > #int(int, int) plus;| > > closure conversion and method reference are also identical. > > This new proposal can be seen as a simplified BGGA (for the underlying > type system) > with the FCM syntax. > > In my opinion the only flaw of this new proposal is that function types > are not reified. > So expect warning on cast and no way to do an instanceof on a function type. > > R?mi > > > Le 18/11/2009 23:26, Mark Mahieu a ?crit : >> Quite a few others seem to believe it'll be FCM (eg. http://java.dzone.com/news/devoxx-day-3-conference-day-1). >> >> Chinese whispers abound :) >> >> >> On 18 Nov 2009, at 21:59, Jorge Ortiz wrote: >> >> >>> This link has been floating around Twitter. >>> >>> http://www.javac.info/closures-v06a.html >>> >>> --j >>> >>> On Wed, Nov 18, 2009 at 1:22 PM, Joseph D. Darcy wrote: >>> >>> >>>> Serge Boulay wrote: >>>> >>>>> Maybe reading into this too much, but are closures in pipe after all? >>>>> >>>>> http://puredanger.com/tech/2009/11/18/closures-after-all/ >>>>> >>>>> >>>>> >>>> I'm attending Devoxx as a speaker this year, as has been reported in >>>> various outlets, Mark Reinhold announced today at Devoxx that JDK 7 will >>>> have closures, a to-be-developed from of closures smaller than BGGA, and >>>> that the JDK 7 schedule will also be extended until around September 2010. >>>> >>>> More details will be forthcoming, >>>> >>>> -Joe >>>> >>>> >>>> >>> >> >> > > From Joe.Darcy at Sun.COM Wed Nov 18 17:01:38 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 18 Nov 2009 17:01:38 -0800 Subject: closures after all? In-Reply-To: <4B046592.1090603@sun.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> Message-ID: <4B0498F2.3090802@sun.com> Joseph D. Darcy wrote: > Serge Boulay wrote: >> Maybe reading into this too much, but are closures in pipe after all? >> >> http://puredanger.com/tech/2009/11/18/closures-after-all/ >> >> > > I'm attending Devoxx as a speaker this year, as has been reported in > various outlets, Mark Reinhold announced today at Devoxx that JDK 7 > will have closures, a to-be-developed from of closures smaller than > BGGA, and that the JDK 7 schedule will also be extended until around > September 2010. > > More details will be forthcoming, PS In terms of Project Coin, with the extended JDK 7 schedule the fate of multi-catch in the release may be reconsidered. -Joe From markmahieu at googlemail.com Thu Nov 19 00:46:31 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 19 Nov 2009 08:46:31 +0000 Subject: closures after all? In-Reply-To: <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> Message-ID: *sigh* I suppose I should have guessed that a deliberately silly bit of code like this would get linked to or reproduced in edited form elsewhere (without my 'tongue-in-cheek' disclaimer). So, for the bloody record: 1) I have absolutely no idea whether it will ever be considered valid Java. 2) Even if it will be valid, I don't think it's remotely representative of code which will use ARM, or closures, or both. 3) Even if it will be valid, and someone decides to write something like this, I don't think it will be hard to understand what it does. 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which some on this list may find mildly ironic. It was not intended as serious commentary on the potential uses of those features, individually or in tandem. If I have serious concerns to raise at some point, I probably won't choose to back them up by quoting an animated mexican wrestler. On the other hand, I was serious about it being interesting to investigate the interaction between the various language features. Sincere apologies for any confusion (!) Mark On 18 Nov 2009, at 23:49, Mark Mahieu wrote: > Well it'll be interesting to see the official details, and (to bring it back on topic) see how it interacts with Coin's language enhancements. > > // tongue in cheek > try (Closeable closure = #() { System.out.println("YOUR HEAD A SPLODE"); }) { > // ... > } > > > Mark From reinier at zwitserloot.com Thu Nov 19 02:31:31 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 19 Nov 2009 11:31:31 +0100 Subject: closures after all? In-Reply-To: References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> Message-ID: <560fb5ed0911190231s77b4b5b5o424af7e1a49a0bf3@mail.gmail.com> Clarifications straight from Mark Reinhold at the later BOF here at #devoxx. 1. His syntax is a strawman written up in de airplane. The point is: Mark and friends have always loved closures, they just weren't sure java should have them, as it has such a big impact on the feel of the language. It is NOT AN ENDORSEMENT OF FCM. He was very specific about that. He was also quite specific about keeping it simple (willing to give up transparency et al). The point is, yes closures, no complexity. Syntax is a teensy tiny detail of this, so don't get hung up on that aspect. 2. For reasons unrelated to the new language features in java7, java7 will be delayed from feb to at least sept. There's time, so, the scope of lang features for java7 has just expanded. Thus, this is NOT AN INDICTMENT on Project Coin at all. On the contrary, Joe Darcy is here, and he's planning on running more coins for the future. Mark Reinhold *SPECIFICALLY* said he does not believe the JCP is a good source of innovation, which seems like an *endorsement* of coin. 3. During the closure wars of 2007, Mark decided to let the dust settle and play with the prototypes. 4. As java7 is delayed A LOT (due to the apache/sun tiff in the JCP), and even the JDK7 has been delayed quite a bit (to at least sept), java8 is of course also going to be around much later. So, Mark has realized that now is probably the right time. 5. Of course there will be discussion with the community about how to do it. He's also been privately talking to lots of key players in sun, and they've all indicated they think it's time for closures, too. 6. Parallel Arrays are involved as a driving force behind the notion that closures are needed. 7. Another feature that's back on the 'maybe' list is multicatch: catch (IllegalAccessException | InvocationTargetException e) { ... do stuff with e...} Reporting from Devoxx, --Reinier Zwitserloot On Thu, Nov 19, 2009 at 9:46 AM, Mark Mahieu wrote: > *sigh* > > I suppose I should have guessed that a deliberately silly bit of code like > this would get linked to or reproduced in edited form elsewhere (without my > 'tongue-in-cheek' disclaimer). > > So, for the bloody record: > > 1) I have absolutely no idea whether it will ever be considered valid Java. > 2) Even if it will be valid, I don't think it's remotely representative of > code which will use ARM, or closures, or both. > 3) Even if it will be valid, and someone decides to write something like > this, I don't think it will be hard to understand what it does. > 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which > some on this list may find mildly ironic. It was not intended as serious > commentary on the potential uses of those features, individually or in > tandem. If I have serious concerns to raise at some point, I probably won't > choose to back them up by quoting an animated mexican wrestler. > > On the other hand, I was serious about it being interesting to investigate > the interaction between the various language features. > > Sincere apologies for any confusion (!) > > Mark > > > On 18 Nov 2009, at 23:49, Mark Mahieu wrote: > > > Well it'll be interesting to see the official details, and (to bring it > back on topic) see how it interacts with Coin's language enhancements. > > > > // tongue in cheek > > try (Closeable closure = #() { System.out.println("YOUR HEAD A SPLODE"); > }) { > > // ... > > } > > > > > > Mark > > > From pdoubleya at gmail.com Thu Nov 19 03:03:12 2009 From: pdoubleya at gmail.com (Patrick Wright) Date: Thu, 19 Nov 2009 12:03:12 +0100 Subject: closures after all? In-Reply-To: <560fb5ed0911190231s77b4b5b5o424af7e1a49a0bf3@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <560fb5ed0911190231s77b4b5b5o424af7e1a49a0bf3@mail.gmail.com> Message-ID: <64efa1ba0911190303lf846937y1a3d2c1aa20e38b0@mail.gmail.com> This is a really helpful summary, Reinier. Matches pretty much what I heard at Devoxx and the BOF. Cheers Patrick From neal at gafter.com Thu Nov 19 15:58:39 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 19 Nov 2009 15:58:39 -0800 Subject: closures after all? In-Reply-To: References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> Message-ID: <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> I also heard a rumor about extension methods. If so, that would suggest a much simpler approach to ARM blocks. From http://www.javac.info/ExtensionMethods.html: One of the biggest advantages of extension methods is that they enable more flexible extension of the language moving forward. For example, suppose a new Automated Resource Management statement were defined in terms of invoking an acquire() method, and then later invoking a release() method on the result of the earlier acquire(). Clearly existing APIs such as Closeable do not implement this protocol, but by providing static factory methods they could be made to act as if they do. Such a statement could then be easily retrofitted onto other resource APIs, such as java.util.concurrent.locks.Lock (an interface), simply by providing extension methods. This retrofitting introduces no breaking changes, since the underlying APIs are not changed. -Neal On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu wrote: > *sigh* > > I suppose I should have guessed that a deliberately silly bit of code like > this would get linked to or reproduced in edited form elsewhere (without my > 'tongue-in-cheek' disclaimer). > > So, for the bloody record: > > 1) I have absolutely no idea whether it will ever be considered valid Java. > 2) Even if it will be valid, I don't think it's remotely representative of > code which will use ARM, or closures, or both. > 3) Even if it will be valid, and someone decides to write something like > this, I don't think it will be hard to understand what it does. > 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which > some on this list may find mildly ironic. It was not intended as serious > commentary on the potential uses of those features, individually or in > tandem. If I have serious concerns to raise at some point, I probably won't > choose to back them up by quoting an animated mexican wrestler. > > On the other hand, I was serious about it being interesting to investigate > the interaction between the various language features. > > Sincere apologies for any confusion (!) > > Mark > > > On 18 Nov 2009, at 23:49, Mark Mahieu wrote: > > > Well it'll be interesting to see the official details, and (to bring it > back on topic) see how it interacts with Coin's language enhancements. > > > > // tongue in cheek > > try (Closeable closure = #() { System.out.println("YOUR HEAD A SPLODE"); > }) { > > // ... > > } > > > > > > Mark > > > From jjb at google.com Thu Nov 19 16:53:41 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 19 Nov 2009 16:53:41 -0800 Subject: closures after all? In-Reply-To: <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> Message-ID: <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> Neal, I'm not sure why you consider this to be simpler than the current, interface-based approach to ARM blocks. To be honest, it strikes me as a bit convoluted. I'm not saying that I don't believe extension methods to be a good thing, but I'm not convinced that they change the preferred approach to ARM blocks. Josh On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter wrote: > I also heard a rumor about extension methods. If so, that would suggest a > much simpler approach to ARM blocks. From > http://www.javac.info/ExtensionMethods.html: > > One of the biggest advantages of extension methods is that they enable more > flexible extension of the language moving forward. For example, suppose a > new Automated Resource Management statement were defined in terms of > invoking an acquire() method, and then later invoking a release() method on > the result of the earlier acquire(). Clearly existing APIs such as > Closeable > do not implement this protocol, but by providing static factory methods > they > could be made to act as if they do. Such a statement could then be easily > retrofitted onto other resource APIs, such as > java.util.concurrent.locks.Lock (an interface), simply by providing > extension methods. This retrofitting introduces no breaking changes, since > the underlying APIs are not changed. > > -Neal > > On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu >wrote: > > > *sigh* > > > > I suppose I should have guessed that a deliberately silly bit of code > like > > this would get linked to or reproduced in edited form elsewhere (without > my > > 'tongue-in-cheek' disclaimer). > > > > So, for the bloody record: > > > > 1) I have absolutely no idea whether it will ever be considered valid > Java. > > 2) Even if it will be valid, I don't think it's remotely representative > of > > code which will use ARM, or closures, or both. > > 3) Even if it will be valid, and someone decides to write something like > > this, I don't think it will be hard to understand what it does. > > 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which > > some on this list may find mildly ironic. It was not intended as serious > > commentary on the potential uses of those features, individually or in > > tandem. If I have serious concerns to raise at some point, I probably > won't > > choose to back them up by quoting an animated mexican wrestler. > > > > On the other hand, I was serious about it being interesting to > investigate > > the interaction between the various language features. > > > > Sincere apologies for any confusion (!) > > > > Mark > > > > > > On 18 Nov 2009, at 23:49, Mark Mahieu wrote: > > > > > Well it'll be interesting to see the official details, and (to bring it > > back on topic) see how it interacts with Coin's language enhancements. > > > > > > // tongue in cheek > > > try (Closeable closure = #() { System.out.println("YOUR HEAD A > SPLODE"); > > }) { > > > // ... > > > } > > > > > > > > > Mark > > > > > > > > From Joe.Darcy at Sun.COM Fri Nov 20 01:02:55 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 20 Nov 2009 01:02:55 -0800 Subject: closures after all? In-Reply-To: <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> Message-ID: <4B065B3F.9040906@sun.com> Since the interface-based approach can be designed and used today, I'd like to see that approach be available in the near future so experience can be gained using ARM. If another approach is later determined to be superior, the approach can be changed. -Joe Joshua Bloch wrote: > Neal, > > I'm not sure why you consider this to be simpler than the current, > interface-based approach to ARM blocks. To be honest, it strikes me as a > bit convoluted. I'm not saying that I don't believe extension methods to be > a good thing, but I'm not convinced that they change the preferred approach > to ARM blocks. > > Josh > > On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter wrote: > > >> I also heard a rumor about extension methods. If so, that would suggest a >> much simpler approach to ARM blocks. From >> http://www.javac.info/ExtensionMethods.html: >> >> One of the biggest advantages of extension methods is that they enable more >> flexible extension of the language moving forward. For example, suppose a >> new Automated Resource Management statement were defined in terms of >> invoking an acquire() method, and then later invoking a release() method on >> the result of the earlier acquire(). Clearly existing APIs such as >> Closeable >> do not implement this protocol, but by providing static factory methods >> they >> could be made to act as if they do. Such a statement could then be easily >> retrofitted onto other resource APIs, such as >> java.util.concurrent.locks.Lock (an interface), simply by providing >> extension methods. This retrofitting introduces no breaking changes, since >> the underlying APIs are not changed. >> >> -Neal >> >> On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu > >>> wrote: >>> >>> *sigh* >>> >>> I suppose I should have guessed that a deliberately silly bit of code >>> >> like >> >>> this would get linked to or reproduced in edited form elsewhere (without >>> >> my >> >>> 'tongue-in-cheek' disclaimer). >>> >>> So, for the bloody record: >>> >>> 1) I have absolutely no idea whether it will ever be considered valid >>> >> Java. >> >>> 2) Even if it will be valid, I don't think it's remotely representative >>> >> of >> >>> code which will use ARM, or closures, or both. >>> 3) Even if it will be valid, and someone decides to write something like >>> this, I don't think it will be hard to understand what it does. >>> 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which >>> some on this list may find mildly ironic. It was not intended as serious >>> commentary on the potential uses of those features, individually or in >>> tandem. If I have serious concerns to raise at some point, I probably >>> >> won't >> >>> choose to back them up by quoting an animated mexican wrestler. >>> >>> On the other hand, I was serious about it being interesting to >>> >> investigate >> >>> the interaction between the various language features. >>> >>> Sincere apologies for any confusion (!) >>> >>> Mark >>> >>> >>> On 18 Nov 2009, at 23:49, Mark Mahieu wrote: >>> >>> >>>> Well it'll be interesting to see the official details, and (to bring it >>>> >>> back on topic) see how it interacts with Coin's language enhancements. >>> >>>> // tongue in cheek >>>> try (Closeable closure = #() { System.out.println("YOUR HEAD A >>>> >> SPLODE"); >> >>> }) { >>> >>>> // ... >>>> } >>>> >>>> >>>> Mark >>>> >>> >>> >> > > From markmahieu at googlemail.com Fri Nov 20 07:14:49 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 20 Nov 2009 15:14:49 +0000 Subject: closures after all? In-Reply-To: <4B065B3F.9040906@sun.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <4B065B3F.9040906@sun.com> Message-ID: At the risk of sounding impatient, do you have any feeling for when we might see an initial implementation based on the current approach? I'm just keen to see how far I can twist Josh's ARM ;-) Mark On 20 Nov 2009, at 09:02, Joseph D. Darcy wrote: > Since the interface-based approach can be designed and used today, I'd > like to see that approach be available in the near future so experience > can be gained using ARM. If another approach is later determined to be > superior, the approach can be changed. > > -Joe > > Joshua Bloch wrote: >> Neal, >> >> I'm not sure why you consider this to be simpler than the current, >> interface-based approach to ARM blocks. To be honest, it strikes me as a >> bit convoluted. I'm not saying that I don't believe extension methods to be >> a good thing, but I'm not convinced that they change the preferred approach >> to ARM blocks. >> >> Josh >> >> On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter wrote: >> >> >>> I also heard a rumor about extension methods. If so, that would suggest a >>> much simpler approach to ARM blocks. From >>> http://www.javac.info/ExtensionMethods.html: >>> >>> One of the biggest advantages of extension methods is that they enable more >>> flexible extension of the language moving forward. For example, suppose a >>> new Automated Resource Management statement were defined in terms of >>> invoking an acquire() method, and then later invoking a release() method on >>> the result of the earlier acquire(). Clearly existing APIs such as >>> Closeable >>> do not implement this protocol, but by providing static factory methods >>> they >>> could be made to act as if they do. Such a statement could then be easily >>> retrofitted onto other resource APIs, such as >>> java.util.concurrent.locks.Lock (an interface), simply by providing >>> extension methods. This retrofitting introduces no breaking changes, since >>> the underlying APIs are not changed. >>> >>> -Neal From neal at gafter.com Fri Nov 20 08:30:49 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 08:30:49 -0800 Subject: closures after all? In-Reply-To: <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> Message-ID: <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> Josh- The extension-method-based approach enables ARM to be retrofitted onto *all *of the use cases we've identified (not just some), and without changing any of those existing types. You've argued repeatedly that language changes that require changes to many existing APIs are questionable, so based on your criterion it is simpler. Cheers, Neal On Thu, Nov 19, 2009 at 4:53 PM, Joshua Bloch wrote: > Neal, > > I'm not sure why you consider this to be simpler than the current, > interface-based approach to ARM blocks. To be honest, it strikes me as a > bit convoluted. I'm not saying that I don't believe extension methods to be > a good thing, but I'm not convinced that they change the preferred approach > to ARM blocks. > > Josh > > > On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter wrote: > >> I also heard a rumor about extension methods. If so, that would suggest a >> much simpler approach to ARM blocks. From >> http://www.javac.info/ExtensionMethods.html: >> >> One of the biggest advantages of extension methods is that they enable >> more >> flexible extension of the language moving forward. For example, suppose a >> new Automated Resource Management statement were defined in terms of >> invoking an acquire() method, and then later invoking a release() method >> on >> the result of the earlier acquire(). Clearly existing APIs such as >> Closeable >> do not implement this protocol, but by providing static factory methods >> they >> could be made to act as if they do. Such a statement could then be easily >> retrofitted onto other resource APIs, such as >> java.util.concurrent.locks.Lock (an interface), simply by providing >> extension methods. This retrofitting introduces no breaking changes, since >> the underlying APIs are not changed. >> >> -Neal >> >> On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu > >wrote: >> >> > *sigh* >> > >> > I suppose I should have guessed that a deliberately silly bit of code >> like >> > this would get linked to or reproduced in edited form elsewhere (without >> my >> > 'tongue-in-cheek' disclaimer). >> > >> > So, for the bloody record: >> > >> > 1) I have absolutely no idea whether it will ever be considered valid >> Java. >> > 2) Even if it will be valid, I don't think it's remotely representative >> of >> > code which will use ARM, or closures, or both. >> > 3) Even if it will be valid, and someone decides to write something like >> > this, I don't think it will be hard to understand what it does. >> > 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which >> > some on this list may find mildly ironic. It was not intended as >> serious >> > commentary on the potential uses of those features, individually or in >> > tandem. If I have serious concerns to raise at some point, I probably >> won't >> > choose to back them up by quoting an animated mexican wrestler. >> > >> > On the other hand, I was serious about it being interesting to >> investigate >> > the interaction between the various language features. >> > >> > Sincere apologies for any confusion (!) >> > >> > Mark >> > >> > >> > On 18 Nov 2009, at 23:49, Mark Mahieu wrote: >> > >> > > Well it'll be interesting to see the official details, and (to bring >> it >> > back on topic) see how it interacts with Coin's language enhancements. >> > > >> > > // tongue in cheek >> > > try (Closeable closure = #() { System.out.println("YOUR HEAD A >> SPLODE"); >> > }) { >> > > // ... >> > > } >> > > >> > > >> > > Mark >> > >> > >> > >> >> > From jjb at google.com Fri Nov 20 11:18:51 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 20 Nov 2009 11:18:51 -0800 Subject: closures after all? In-Reply-To: <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> Message-ID: <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> Neal, Thanks for the explanation. I did take a crack at the JDK, and I found that it was straightforward to retrofit all of the types that mattered. Josh On Fri, Nov 20, 2009 at 8:30 AM, Neal Gafter wrote: > Josh- > > The extension-method-based approach enables ARM to be retrofitted onto *all > *of the use cases we've identified (not just some), and without changing > any of those existing types. You've argued repeatedly that language changes > that require changes to many existing APIs are questionable, so based on > your criterion it is simpler. > > Cheers, > Neal > > > On Thu, Nov 19, 2009 at 4:53 PM, Joshua Bloch wrote: > >> Neal, >> >> I'm not sure why you consider this to be simpler than the current, >> interface-based approach to ARM blocks. To be honest, it strikes me as a >> bit convoluted. I'm not saying that I don't believe extension methods to be >> a good thing, but I'm not convinced that they change the preferred approach >> to ARM blocks. >> >> Josh >> >> >> On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter wrote: >> >>> I also heard a rumor about extension methods. If so, that would suggest >>> a >>> much simpler approach to ARM blocks. From >>> http://www.javac.info/ExtensionMethods.html: >>> >>> One of the biggest advantages of extension methods is that they enable >>> more >>> flexible extension of the language moving forward. For example, suppose a >>> new Automated Resource Management statement were defined in terms of >>> invoking an acquire() method, and then later invoking a release() method >>> on >>> the result of the earlier acquire(). Clearly existing APIs such as >>> Closeable >>> do not implement this protocol, but by providing static factory methods >>> they >>> could be made to act as if they do. Such a statement could then be easily >>> retrofitted onto other resource APIs, such as >>> java.util.concurrent.locks.Lock (an interface), simply by providing >>> extension methods. This retrofitting introduces no breaking changes, >>> since >>> the underlying APIs are not changed. >>> >>> -Neal >>> >>> On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu >> >wrote: >>> >>> > *sigh* >>> > >>> > I suppose I should have guessed that a deliberately silly bit of code >>> like >>> > this would get linked to or reproduced in edited form elsewhere >>> (without my >>> > 'tongue-in-cheek' disclaimer). >>> > >>> > So, for the bloody record: >>> > >>> > 1) I have absolutely no idea whether it will ever be considered valid >>> Java. >>> > 2) Even if it will be valid, I don't think it's remotely representative >>> of >>> > code which will use ARM, or closures, or both. >>> > 3) Even if it will be valid, and someone decides to write something >>> like >>> > this, I don't think it will be hard to understand what it does. >>> > 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, which >>> > some on this list may find mildly ironic. It was not intended as >>> serious >>> > commentary on the potential uses of those features, individually or in >>> > tandem. If I have serious concerns to raise at some point, I probably >>> won't >>> > choose to back them up by quoting an animated mexican wrestler. >>> > >>> > On the other hand, I was serious about it being interesting to >>> investigate >>> > the interaction between the various language features. >>> > >>> > Sincere apologies for any confusion (!) >>> > >>> > Mark >>> > >>> > >>> > On 18 Nov 2009, at 23:49, Mark Mahieu wrote: >>> > >>> > > Well it'll be interesting to see the official details, and (to bring >>> it >>> > back on topic) see how it interacts with Coin's language enhancements. >>> > > >>> > > // tongue in cheek >>> > > try (Closeable closure = #() { System.out.println("YOUR HEAD A >>> SPLODE"); >>> > }) { >>> > > // ... >>> > > } >>> > > >>> > > >>> > > Mark >>> > >>> > >>> > >>> >>> >> > From neal at gafter.com Fri Nov 20 11:26:34 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 11:26:34 -0800 Subject: closures after all? In-Reply-To: <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> Message-ID: <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> Josh- As you are well aware, there is controvery about which types matter. A spec based on extension methods can be used to support all of the types that we discussed, not just the ones you consider to matter. Cheers, Neal On Fri, Nov 20, 2009 at 11:18 AM, Joshua Bloch wrote: > Neal, > > Thanks for the explanation. I did take a crack at the JDK, and I found > that it was straightforward to retrofit all of the types that mattered. > > Josh > > > On Fri, Nov 20, 2009 at 8:30 AM, Neal Gafter wrote: > >> Josh- >> >> The extension-method-based approach enables ARM to be retrofitted onto *all >> *of the use cases we've identified (not just some), and without changing >> any of those existing types. You've argued repeatedly that language changes >> that require changes to many existing APIs are questionable, so based on >> your criterion it is simpler. >> >> Cheers, >> Neal >> >> >> On Thu, Nov 19, 2009 at 4:53 PM, Joshua Bloch wrote: >> >>> Neal, >>> >>> I'm not sure why you consider this to be simpler than the current, >>> interface-based approach to ARM blocks. To be honest, it strikes me as a >>> bit convoluted. I'm not saying that I don't believe extension methods to be >>> a good thing, but I'm not convinced that they change the preferred approach >>> to ARM blocks. >>> >>> Josh >>> >>> >>> On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter wrote: >>> >>>> I also heard a rumor about extension methods. If so, that would suggest >>>> a >>>> much simpler approach to ARM blocks. From >>>> http://www.javac.info/ExtensionMethods.html: >>>> >>>> One of the biggest advantages of extension methods is that they enable >>>> more >>>> flexible extension of the language moving forward. For example, suppose >>>> a >>>> new Automated Resource Management statement were defined in terms of >>>> invoking an acquire() method, and then later invoking a release() method >>>> on >>>> the result of the earlier acquire(). Clearly existing APIs such as >>>> Closeable >>>> do not implement this protocol, but by providing static factory methods >>>> they >>>> could be made to act as if they do. Such a statement could then be >>>> easily >>>> retrofitted onto other resource APIs, such as >>>> java.util.concurrent.locks.Lock (an interface), simply by providing >>>> extension methods. This retrofitting introduces no breaking changes, >>>> since >>>> the underlying APIs are not changed. >>>> >>>> -Neal >>>> >>>> On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu < >>>> markmahieu at googlemail.com>wrote: >>>> >>>> > *sigh* >>>> > >>>> > I suppose I should have guessed that a deliberately silly bit of code >>>> like >>>> > this would get linked to or reproduced in edited form elsewhere >>>> (without my >>>> > 'tongue-in-cheek' disclaimer). >>>> > >>>> > So, for the bloody record: >>>> > >>>> > 1) I have absolutely no idea whether it will ever be considered valid >>>> Java. >>>> > 2) Even if it will be valid, I don't think it's remotely >>>> representative of >>>> > code which will use ARM, or closures, or both. >>>> > 3) Even if it will be valid, and someone decides to write something >>>> like >>>> > this, I don't think it will be hard to understand what it does. >>>> > 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, >>>> which >>>> > some on this list may find mildly ironic. It was not intended as >>>> serious >>>> > commentary on the potential uses of those features, individually or in >>>> > tandem. If I have serious concerns to raise at some point, I probably >>>> won't >>>> > choose to back them up by quoting an animated mexican wrestler. >>>> > >>>> > On the other hand, I was serious about it being interesting to >>>> investigate >>>> > the interaction between the various language features. >>>> > >>>> > Sincere apologies for any confusion (!) >>>> > >>>> > Mark >>>> > >>>> > >>>> > On 18 Nov 2009, at 23:49, Mark Mahieu wrote: >>>> > >>>> > > Well it'll be interesting to see the official details, and (to bring >>>> it >>>> > back on topic) see how it interacts with Coin's language enhancements. >>>> > > >>>> > > // tongue in cheek >>>> > > try (Closeable closure = #() { System.out.println("YOUR HEAD A >>>> SPLODE"); >>>> > }) { >>>> > > // ... >>>> > > } >>>> > > >>>> > > >>>> > > Mark >>>> > >>>> > >>>> > >>>> >>>> >>> >> > From reinier at zwitserloot.com Fri Nov 20 11:46:08 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 20 Nov 2009 20:46:08 +0100 Subject: closures after all? In-Reply-To: <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> Message-ID: <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> Having to litter a barch of static / extension imports in each source file is at least as dubious, from a perfectionist's point of view, as having ARM not work on some rarely used disposable types. What exactly would, say, an ARM-guarded OutputStream look like with your idea, Neal? --Reinier Zwitserloot Need to receive donations via the web? Check http://tipit.to/ On 20 nov 2009, at 20:26, Neal Gafter wrote: > Josh- > > As you are well aware, there is controvery about which types > matter. A spec > based on extension methods can be used to support all of the types > that we > discussed, not just the ones you consider to matter. > > Cheers, > Neal > > On Fri, Nov 20, 2009 at 11:18 AM, Joshua Bloch wrote: > >> Neal, >> >> Thanks for the explanation. I did take a crack at the JDK, and I >> found >> that it was straightforward to retrofit all of the types that >> mattered. >> >> Josh >> >> >> On Fri, Nov 20, 2009 at 8:30 AM, Neal Gafter wrote: >> >>> Josh- >>> >>> The extension-method-based approach enables ARM to be retrofitted >>> onto *all >>> *of the use cases we've identified (not just some), and without >>> changing >>> any of those existing types. You've argued repeatedly that >>> language changes >>> that require changes to many existing APIs are questionable, so >>> based on >>> your criterion it is simpler. >>> >>> Cheers, >>> Neal >>> >>> >>> On Thu, Nov 19, 2009 at 4:53 PM, Joshua Bloch >>> wrote: >>> >>>> Neal, >>>> >>>> I'm not sure why you consider this to be simpler than the current, >>>> interface-based approach to ARM blocks. To be honest, it strikes >>>> me as a >>>> bit convoluted. I'm not saying that I don't believe extension >>>> methods to be >>>> a good thing, but I'm not convinced that they change the >>>> preferred approach >>>> to ARM blocks. >>>> >>>> Josh >>>> >>>> >>>> On Thu, Nov 19, 2009 at 3:58 PM, Neal Gafter >>>> wrote: >>>> >>>>> I also heard a rumor about extension methods. If so, that would >>>>> suggest >>>>> a >>>>> much simpler approach to ARM blocks. From >>>>> http://www.javac.info/ExtensionMethods.html: >>>>> >>>>> One of the biggest advantages of extension methods is that they >>>>> enable >>>>> more >>>>> flexible extension of the language moving forward. For example, >>>>> suppose >>>>> a >>>>> new Automated Resource Management statement were defined in >>>>> terms of >>>>> invoking an acquire() method, and then later invoking a release >>>>> () method >>>>> on >>>>> the result of the earlier acquire(). Clearly existing APIs such as >>>>> Closeable >>>>> do not implement this protocol, but by providing static factory >>>>> methods >>>>> they >>>>> could be made to act as if they do. Such a statement could then be >>>>> easily >>>>> retrofitted onto other resource APIs, such as >>>>> java.util.concurrent.locks.Lock (an interface), simply by >>>>> providing >>>>> extension methods. This retrofitting introduces no breaking >>>>> changes, >>>>> since >>>>> the underlying APIs are not changed. >>>>> >>>>> -Neal >>>>> >>>>> On Thu, Nov 19, 2009 at 12:46 AM, Mark Mahieu < >>>>> markmahieu at googlemail.com>wrote: >>>>> >>>>>> *sigh* >>>>>> >>>>>> I suppose I should have guessed that a deliberately silly bit >>>>>> of code >>>>> like >>>>>> this would get linked to or reproduced in edited form elsewhere >>>>> (without my >>>>>> 'tongue-in-cheek' disclaimer). >>>>>> >>>>>> So, for the bloody record: >>>>>> >>>>>> 1) I have absolutely no idea whether it will ever be considered >>>>>> valid >>>>> Java. >>>>>> 2) Even if it will be valid, I don't think it's remotely >>>>> representative of >>>>>> code which will use ARM, or closures, or both. >>>>>> 3) Even if it will be valid, and someone decides to write >>>>>> something >>>>> like >>>>>> this, I don't think it will be hard to understand what it does. >>>>>> 4) 'YOUR HEAD A SPLODE' refers to the mixing of ARM and closures, >>>>> which >>>>>> some on this list may find mildly ironic. It was not intended as >>>>> serious >>>>>> commentary on the potential uses of those features, >>>>>> individually or in >>>>>> tandem. If I have serious concerns to raise at some point, I >>>>>> probably >>>>> won't >>>>>> choose to back them up by quoting an animated mexican wrestler. >>>>>> >>>>>> On the other hand, I was serious about it being interesting to >>>>> investigate >>>>>> the interaction between the various language features. >>>>>> >>>>>> Sincere apologies for any confusion (!) >>>>>> >>>>>> Mark >>>>>> >>>>>> >>>>>> On 18 Nov 2009, at 23:49, Mark Mahieu wrote: >>>>>> >>>>>>> Well it'll be interesting to see the official details, and (to >>>>>>> bring >>>>> it >>>>>> back on topic) see how it interacts with Coin's language >>>>>> enhancements. >>>>>>> >>>>>>> // tongue in cheek >>>>>>> try (Closeable closure = #() { System.out.println("YOUR HEAD A >>>>> SPLODE"); >>>>>> }) { >>>>>>> // ... >>>>>>> } >>>>>>> >>>>>>> >>>>>>> Mark >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> >>> >> > From crazybob at crazybob.org Fri Nov 20 11:49:59 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 20 Nov 2009 11:49:59 -0800 Subject: closures after all? In-Reply-To: <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> Message-ID: On Fri, Nov 20, 2009 at 11:26 AM, Neal Gafter wrote: > As you are well aware, there is controvery about which types matter. A > spec > based on extension methods can be used to support all of the types that we > discussed, not just the ones you consider to matter. > Neal, Manual resource cleanup is very common and difficult to get right, especially when > 1 resources are involved. Out of the 110 places where the otherwise exemplary JDK code opens and closes resources, 2/3rds can leak. Not one suppresses exceptions in what I think is the proper fashion [1]. Users need a first class solution. ARM blocks rise to that level. My intuition is that a closures + extension methods approach will not, but I haven't seen either of those proposals yet. There isn't much point in arguing about it until I do. Bob [1] http://crazybobs-talks.googlecode.com/svn/trunk/out/foj.pdf From crazybob at crazybob.org Fri Nov 20 11:55:10 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 20 Nov 2009 11:55:10 -0800 Subject: closures after all? In-Reply-To: <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> Message-ID: On Fri, Nov 20, 2009 at 11:46 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > What exactly would, say, an ARM-guarded OutputStream look like with > your idea, Neal? > Here's an example written with ARM that we could try rewriting: try (Reader fin = new FileReader(file); BufferedReader in = new BufferedReader(fin)) { // Parse the first line and return the result. return parse(in.readLine()); } catch (IOException e) { logger.log(e); return null; } Thanks, Bob From markmahieu at googlemail.com Fri Nov 20 11:57:48 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 20 Nov 2009 19:57:48 +0000 Subject: closures after all? In-Reply-To: References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> Message-ID: <7E32AA65-590D-46E1-B6AF-BA8C4A51A5E7@gmail.co.uk> I thought that Neal's post was applicable to ARM + extension methods, not just closures + extension methods. Either way, I agree that we could do with hearing more detail on the form extension methods might take before persuing this much further. Mark On 20 Nov 2009, at 19:49, Bob Lee wrote: > On Fri, Nov 20, 2009 at 11:26 AM, Neal Gafter wrote: > >> As you are well aware, there is controvery about which types >> matter. A >> spec >> based on extension methods can be used to support all of the types >> that we >> discussed, not just the ones you consider to matter. >> > > Neal, > > Manual resource cleanup is very common and difficult to get right, > especially when > 1 resources are involved. Out of the 110 places > where the > otherwise exemplary JDK code opens and closes resources, 2/3rds can > leak. > Not one suppresses exceptions in what I think is the proper fashion > [1]. > > Users need a first class solution. ARM blocks rise to that level. My > intuition is that a closures + extension methods approach will not, > but I > haven't seen either of those proposals yet. There isn't much point in > arguing about it until I do. > > Bob > > [1] http://crazybobs-talks.googlecode.com/svn/trunk/out/foj.pdf > From neal at gafter.com Fri Nov 20 12:06:14 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 12:06:14 -0800 Subject: closures after all? In-Reply-To: References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> Message-ID: <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> Bob- I think the syntax would be identical to any particular ARM proposal. The main difference is that it would *not *be specified in terms of some new interface type, but instead by specified by translation to the invocation of two methods (specified by name). Because it would break compatibility to retrofit some APIs with the proposed interface, such a language change could be retrofitted onto any existing API by the use of extension methods. Closures have nothing to do with it. Cheers, Neal On Fri, Nov 20, 2009 at 11:55 AM, Bob Lee wrote: > On Fri, Nov 20, 2009 at 11:46 AM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> What exactly would, say, an ARM-guarded OutputStream look like with >> your idea, Neal? >> > > Here's an example written with ARM that we could try rewriting: > > try (Reader fin = new FileReader(file); > BufferedReader in = new BufferedReader(fin)) { > // Parse the first line and return the result. > return parse(in.readLine()); > } catch (IOException e) { > logger.log(e); > return null; > } > > Thanks, > Bob > From crazybob at crazybob.org Fri Nov 20 14:02:21 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 20 Nov 2009 16:02:21 -0600 Subject: closures after all? In-Reply-To: <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> Message-ID: Neal, I get it now. My fault. I still prefer the simpler interface-based approach. Bob From neal at gafter.com Fri Nov 20 14:22:47 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 14:22:47 -0800 Subject: closures after all? In-Reply-To: References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> Message-ID: <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> On Fri, Nov 20, 2009 at 2:02 PM, Bob Lee wrote: > I get it now. My fault. I still prefer the simpler interface-based > approach. > I distinguish interface-based and pattern-based this way: An interface-based specification accepts a value of a particular interface, and invokes methods defined on that interface. That is how the for-each loop works. A pattern-based specification is defined by source translation, invoking a method on whatever type results from the translation in each particular circumstance. While the current ARM specification requires that the object implement the AutoCloseable interface, it does not invoke the method from that interface. The requirement that the value be a subtype of AutoCloseable is not actually used by the specification. For example, the specification still makes sense if AutoCloseable is defined with no methods, or if the requirement is simply removed from the specification. The translation is defined in terms of invoking a method on the actual type of the object to be disposed, not the interface method on the interface type. As far as I can tell, ARM is a pattern-based specification but with an additional requirement that the value be a subtype of AutoCloseable. What is the value of that part of the specification that requires the object be an instance of that particular interface? From lk at teamten.com Fri Nov 20 14:50:24 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Fri, 20 Nov 2009 14:50:24 -0800 Subject: closures after all? In-Reply-To: <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> Message-ID: <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> Neal, If I understand pattern-based specification, it's basically compile-time duck typing (e.g., C++ templates). One advantage of interface-based specifications is that there's a javadoc I can read to learn about the contract. For example, I can read the javadoc of Iterable to figure out how to design my class to be foreach-compatible. From there I can find all implementing classes to see how they did it. I'd rather not have to go back to the language spec for that. AutoCloseable's description of what the close() method must do is more convenient (hence will be read more often) than the JLS's. There's power to giving something a name and not just a description. I have a similar objection to closures: it encourages variables and parameters that are anonymous function signatures with no javadoc to help me learn about the contract. (CICE is exempt from this objection.) Lawrence On Fri, Nov 20, 2009 at 2:22 PM, Neal Gafter wrote: > On Fri, Nov 20, 2009 at 2:02 PM, Bob Lee wrote: > >> I get it now. My fault. I still prefer the simpler interface-based >> approach. >> > > I distinguish interface-based and pattern-based this way: ?An > interface-based specification accepts a value of a particular interface, and > invokes methods defined on that interface. ?That is how the for-each loop > works. ?A pattern-based specification is defined by source translation, > invoking a method on whatever type results from the translation in each > particular circumstance. > > While the current ARM specification requires that the object implement the > AutoCloseable interface, it does not invoke the method from that interface. > The requirement that the value be a subtype of AutoCloseable is not actually > used by the specification. ?For example, the specification still makes sense > if AutoCloseable is defined with no methods, or if the requirement is simply > removed from the specification. ?The translation is defined in terms of > invoking a method on the actual type of the object to be disposed, not the > interface method on the interface type. ?As far as I can tell, ARM is a > pattern-based specification but with an additional requirement that the > value be a subtype of AutoCloseable. > > What is the value of that part of the specification that requires the object > be an instance of that particular interface? > > From markmahieu at googlemail.com Fri Nov 20 14:52:53 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 20 Nov 2009 22:52:53 +0000 Subject: closures after all? In-Reply-To: References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> Message-ID: Me too, since I haven't yet seen anything regarding extension methods other than one blog mentioning them by name, and hundreds of Twitter retweets. Personally, I'm keen for something like ARM to be in JDK7, as I'm currently contemplating 12 months of 'cleaning up' a nearly 10 year old system written in Java; right now the main use it's likely to find is in refactoring thousands of methods to remove their bug-ridden, money-wasting boilerplate by 'twisting' it into a before-after construct. That's why I'd like to know, if possible, whether an implementation of the current spec is likely to appear soon. If it's not, then that's fine; I'll know to put one together myself to investigate my perceived use-cases. Cheers, Mark On 20 Nov 2009, at 22:02, Bob Lee wrote: > Neal, > > I get it now. My fault. I still prefer the simpler interface-based > approach. > > Bob > From neal at gafter.com Fri Nov 20 15:02:02 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 15:02:02 -0800 Subject: closures after all? In-Reply-To: <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> Message-ID: <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> On Fri, Nov 20, 2009 at 2:50 PM, Lawrence Kesteloot wrote: > If I understand pattern-based specification, it's basically > compile-time duck typing (e.g., C++ templates). One advantage of > interface-based specifications is that there's a javadoc I can read to > learn about the contract. > A pattern-based specification can still be used with an interface like AutoCloseable. Even if interface-based, its specification can't really say much about a contract. I have a similar objection to closures: it encourages variables and > parameters that are anonymous function signatures with no javadoc to > help me learn about the contract. (CICE is exempt from this > objection.) > Variables don't normally have contracts. Parameters, on the other hand, usually have their contracts specified in the method. In the cases where you would use a function type, there isn't much for the javadoc to day. Just like primitive types, which also don't have contracts. From forax at univ-mlv.fr Fri Nov 20 15:30:47 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 00:30:47 +0100 Subject: Extension methods In-Reply-To: <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> Message-ID: <4B0726A7.4080301@univ-mlv.fr> There is a real problem of performance with extension methods (at least with Hotspot). Extension methods create megamorphic call sites and Hotspot is not able to inline them. R?mi From lk at teamten.com Fri Nov 20 15:30:32 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Fri, 20 Nov 2009 15:30:32 -0800 Subject: closures after all? In-Reply-To: <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <17b2302a0911201118y117c9648l2fa7274ead525e44@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> Message-ID: <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> On Fri, Nov 20, 2009 at 3:02 PM, Neal Gafter wrote: > A pattern-based specification can still be used with an interface like > AutoCloseable. But that's what you were objecting to in the current ARM proposal. >> I have a similar objection to closures: it encourages variables and >> parameters that are anonymous function signatures with no javadoc to >> help me learn about the contract. (CICE is exempt from this >> objection.) > > Variables don't normally have contracts.? Parameters, on the other hand, > usually have their contracts specified in the method. I was referring to the contract of the function the variable (or parameter) points to, not the variable itself. For example, JButton.addMouseListener() takes a MouseListener. I can look up MouseListener's javadoc to figure out how I should implement it. With closures the API designer may have been tempted to create JButton.addMouseClickedListener() that takes an anonymously-defined closure. Then where is the javadoc for that callback? In the javadoc for addMouseClickedListener()? And in the javadoc of every function that wants to pass around and manipulate mouse-clicked listeners? And when internally that listener is assigned to a field, where is the javadoc explaining what that function's contract is? Is that function's contract described a dozen times, or put in only one place and simply missing everywhere else? Ever since generics were introduced people have asked for typedefs. They want it to reduce typing, but I want it because I want a place to explain what the heck is being stored in the map-of-string-to-lists-of-strings. Lawrence ? In the cases where > you would use a function type, there isn't much for the javadoc to day. > Just like primitive types, which also don't have contracts. From Joe.Darcy at Sun.COM Fri Nov 20 15:38:59 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 20 Nov 2009 15:38:59 -0800 Subject: Extension methods In-Reply-To: <4B0726A7.4080301@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B046592.1090603@sun.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> Message-ID: <4B072893.2060203@sun.com> R?mi Forax wrote: > There is a real problem of performance with extension methods > (at least with Hotspot). > Extension methods create megamorphic call sites > and Hotspot is not able to inline them. > > R?mi > > Mark has not yet published a proposal or sketch for extension methods or closures. If extension methods are added to the platform, that will presumably provide motivation for the HotSpot team to create polymorphic inline caches to better handle megamorphic call sites :-) -Joe From neal at gafter.com Fri Nov 20 15:47:15 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 15:47:15 -0800 Subject: closures after all? In-Reply-To: <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201126k30e8b4a9h9fea6622f802caa7@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> Message-ID: <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> On Fri, Nov 20, 2009 at 3:30 PM, Lawrence Kesteloot wrote: > On Fri, Nov 20, 2009 at 3:02 PM, Neal Gafter wrote: > > A pattern-based specification can still be used with an interface like > > AutoCloseable. > > But that's what you were objecting to in the current ARM proposal. > I'm not objecting to allowing it, I'm objecting to requiring it. You allow it simply by not saying anything in the spec at all. > >> I have a similar objection to closures: it encourages variables and > >> parameters that are anonymous function signatures with no javadoc to > >> help me learn about the contract. (CICE is exempt from this > >> objection.) > > > > Variables don't normally have contracts. Parameters, on the other hand, > > usually have their contracts specified in the method. > > I was referring to the contract of the function the variable (or > parameter) points to, not the variable itself. Right. Like for a parameter of primitive type, that would correspond to the contract on the primitive value contained in the parameter, not the primitive parameter itself. Where do you put that documentation? > For example, > JButton.addMouseListener() takes a MouseListener. I can look up > MouseListener's javadoc to figure out how I should implement it. With > closures the API designer may have been tempted to create > JButton.addMouseClickedListener() that takes an anonymously-defined > closure. Then where is the javadoc for that callback? In addMouseListener. But if the type is widely used, as you suggest is the case here, then the API designer would have made an unwise choice. I do not think we can protect against unwise API designers by denying language features that are more wisely used in some circumstances than others. From neal at gafter.com Fri Nov 20 15:52:08 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 15:52:08 -0800 Subject: Extension methods In-Reply-To: <4B0726A7.4080301@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> Message-ID: <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> On Fri, Nov 20, 2009 at 3:30 PM, R?mi Forax wrote: > There is a real problem of performance with extension methods > (at least with Hotspot). > Extension methods create megamorphic call sites > and Hotspot is not able to inline them. > Extension methods are most simply formulated are static methods (as in C#), and are therefore not polymorphic at runtime at all. They can even be inlined trivially. Such a formulation enables existing methods (such as those in Collections and Arrays) to be retrofitted as extension methods as well. Perhaps you have another technique in mind for extension methods? From lk at teamten.com Fri Nov 20 16:35:12 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Fri, 20 Nov 2009 16:35:12 -0800 Subject: closures after all? In-Reply-To: <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <154F02E1-1ACB-494B-BAC3-2ECC1ED1A60F@zwitserloot.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> Message-ID: <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> Neal, > Right.? Like for a parameter of primitive type, that would correspond to the > contract on the primitive value contained in the parameter, not the > primitive parameter itself.? Where do you put that documentation? Describing an integer or float is usually straightforward. It can be done in a sentence or two. Describing a function is more complicated. What would the javadoc even look like? * @param handler function called when the mouse is clicked. * @param mouseEvent information about the click. * @throws NullPointerException if mouseEvent is null. * @return whether the event was handled. And that's for a simple callback. > In addMouseListener.? But if the type is widely used, as you suggest is the > case here, then the API designer would have made an unwise choice. Mouse events are a common example of closure usage. I have no doubt the unwise choice would have been made. > I do not think we can protect against unwise API designers by denying language > features that are more wisely used in some circumstances than others. That's precisely what I'm advocating. I want the language to protect as much as possible against unwise choices, to the point of denying features that are sometimes used wisely. Java has done this pretty well so far, but it's slipping, and once it becomes an expert-only language there will be nowhere for the rest of us to go. Lawrence From neal at gafter.com Fri Nov 20 16:50:48 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 16:50:48 -0800 Subject: closures after all? In-Reply-To: <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> Message-ID: <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> On Fri, Nov 20, 2009 at 4:35 PM, Lawrence Kesteloot wrote: > > I do not think we can protect against unwise API designers by denying > language > > features that are more wisely used in some circumstances than others. > > > That's precisely what I'm advocating. I want the language to protect > as much as possible against unwise choices, to the point of denying > features that are sometimes used wisely. Java has done this pretty > well so far, but it's slipping, and once it becomes an expert-only > language there will be nowhere for the rest of us to go. > It has always been the case that public APIs are best designed by experts. A small percentage of Java developers have the skills to do a good job here. The addition of function types wouldn't change that. There are APIs for which named interfaces would be an unwise API design choice, ParallelArray being the most obvious example. As a practical matter, only allowing named function types results in APIs such as this being simply impractical in Java. With great power comes great responsibility. From forax at univ-mlv.fr Fri Nov 20 17:34:45 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 02:34:45 +0100 Subject: Extension methods In-Reply-To: <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <22a410d00911181359x42bae339t2682c198326b5f07@mail.gmail.com> <00367709-1762-4F06-A861-AC46E8469A3B@googlemail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> Message-ID: <4B0743B5.5020902@univ-mlv.fr> Le 21/11/2009 00:52, Neal Gafter a ?crit : > On Fri, Nov 20, 2009 at 3:30 PM, R?mi Forax > wrote: > > There is a real problem of performance with extension methods > (at least with Hotspot). > Extension methods create megamorphic call sites > and Hotspot is not able to inline them. > > > Extension methods are most simply formulated are static methods (as in > C#), and are therefore not polymorphic at runtime at all. They can > even be inlined trivially. Such a formulation enables existing > methods (such as those in Collections and Arrays) to be retrofitted as > extension methods as well. The problem is not at call site of the extension method but call sites in the extension method. > > Perhaps you have another technique in mind for extension methods? There is another reason why I don't like extension methods is that you can't override an extension method so you install fences for the future. Lets me take an example, suppose you introduce an extension method to do a foreach using a closure on Collection. You can't override this method to write a specialized version for TreeSet. The fundamental problem is that you can't add new methods to an interface. What I porpose is to define There is already an existing mechanism to insert extension methods at runtime: interface injection (http://openjdk.java.net/projects/mlvm/subprojects.html#InterfaceInjection) This mechanism allow to add an interface + implementation to a class at runtime. Written in Java, it will be something like that: package java.util; public extension interface ExtMap extends Map { public Map.entry getEntry(K key) { ... } } package java.util; public interface Map extension ExtMap { ... } You need a slight transformation of the code if you don't want to change the verifier: And this Java code: Map map = ... Entry entry = map.getEntry("hello"); will be translated to: Map map = ... Entry entry = ((ExtMap)map).getEntry("hello"); cheers, R?mi From neal at gafter.com Fri Nov 20 17:27:14 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 17:27:14 -0800 Subject: Extension methods In-Reply-To: <4B0743B5.5020902@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> <4B0743B5.5020902@univ-mlv.fr> Message-ID: <15e8b9d20911201727j55e54e5eyb0daba7c97599bc@mail.gmail.com> On Fri, Nov 20, 2009 at 5:34 PM, R?mi Forax wrote: > Le 21/11/2009 00:52, Neal Gafter a ?crit : > > On Fri, Nov 20, 2009 at 3:30 PM, R?mi Forax wrote: > >> There is a real problem of performance with extension methods >> (at least with Hotspot). >> Extension methods create megamorphic call sites >> and Hotspot is not able to inline them. >> > > Extension methods are most simply formulated are static methods (as in C#), > and are therefore not polymorphic at runtime at all. They can even be > inlined trivially. Such a formulation enables existing methods (such as > those in Collections and Arrays) to be retrofitted as extension methods as > well. > > > The problem is not at call site of the extension method but call sites in > the extension method. > If the extension method is inlined, which it usually should be in performance-critical code (especially for the uses we've been considering), it's no worse than an ordinary virtual method. From neal at gafter.com Fri Nov 20 17:31:46 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 17:31:46 -0800 Subject: Extension methods In-Reply-To: <4B0743B5.5020902@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> <4B0743B5.5020902@univ-mlv.fr> Message-ID: <15e8b9d20911201731t153cef93x6a85114480b4acde@mail.gmail.com> On Fri, Nov 20, 2009 at 5:34 PM, R?mi Forax wrote: > There is already an existing mechanism to insert extension methods > at runtime: interface injection > (http://openjdk.java.net/projects/mlvm/subprojects.html#InterfaceInjection > ) > > This mechanism allow to add an interface + implementation to a class at > runtime. > > Written in Java, it will be something like that: > package java.util; > public extension interface ExtMap extends Map { > public Map.entry getEntry(K key) { > ... > } > } > > package java.util; > public interface Map extension ExtMap { > ... > } > When at runtime is the extension done? When ExtMap is statically initialized? From forax at univ-mlv.fr Fri Nov 20 17:53:11 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 02:53:11 +0100 Subject: Extension methods In-Reply-To: <15e8b9d20911201731t153cef93x6a85114480b4acde@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <4B0481DA.9000800@univ-mlv.fr> <4B502F28-50CC-405E-AE9E-A5FBDA2F45B3@googlemail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> <4B0743B5.5020902@univ-mlv.fr> <15e8b9d20911201731t153cef93x6a85114480b4acde@mail.gmail.com> Message-ID: <4B074807.20600@univ-mlv.fr> Le 21/11/2009 02:31, Neal Gafter a ?crit : > On Fri, Nov 20, 2009 at 5:34 PM, R?mi Forax > wrote: > > There is already an existing mechanism to insert extension methods > at runtime: interface injection > (http://openjdk.java.net/projects/mlvm/subprojects.html#InterfaceInjection) > > This mechanism allow to add an interface + implementation to a > class at runtime. > > Written in Java, it will be something like that: > package java.util; > public extension interface ExtMap extends Map { > public Map.entry getEntry(K key) { > ... > } > } > > package java.util; > public interface Map extension ExtMap { > ... > } > > > When at runtime is the extension done? When ExtMap is statically > initialized? The extension is done for each implementation of Map the first time there is a checkcast (and reflection counterparts) from an implementation of Map to ExtMap. ExtMap is initialized when needed as usual. R?mi From tim at peierls.net Fri Nov 20 21:24:04 2009 From: tim at peierls.net (Tim Peierls) Date: Sat, 21 Nov 2009 00:24:04 -0500 Subject: closures after all? In-Reply-To: <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201206t5cdd28absde0f03932b63624b@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> Message-ID: <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> On Fri, Nov 20, 2009 at 7:50 PM, Neal Gafter wrote: > It has always been the case that public APIs are best designed by experts. > A small percentage of Java developers have the skills to do a good job > here. The addition of function types wouldn't change that. > The addition of function types would raise the threshold of expertise required to do a good job, making that small percentage even smaller. Would the increased difficulty of good API design (and decreased usability due to bad API design) be adequately balanced by the gain in expressive power? I'm not totally convinced either way, which is why the caution being shown so far seems appropriate to me, frustrating as it must be for those who are convinced the answer is "yes". > There are APIs for which named interfaces would be an unwise API design > choice, ParallelArray being the most obvious example. As a practical > matter, only allowing named function types results in APIs such as this > being simply impractical in Java. > I wish people wouldn't pick on ParallelArray. There might be cases where named function types are impractical, but the experiments I've made with ParallelArray (admittedly just for fun) seem more readable and maintainable to me than any of the more concise forms under discussion would be. They're longer, yes, but the names convey helpful information. > With great power comes great responsibility. > Yes. --tim From neal at gafter.com Fri Nov 20 22:01:08 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Nov 2009 22:01:08 -0800 Subject: Extension methods In-Reply-To: <4B074807.20600@univ-mlv.fr> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> <4B0743B5.5020902@univ-mlv.fr> <15e8b9d20911201731t153cef93x6a85114480b4acde@mail.gmail.com> <4B074807.20600@univ-mlv.fr> Message-ID: <15e8b9d20911202201t3b6719fbp5d503b7983936834@mail.gmail.com> So the change in type is visible to applications: If there is a checkcast to some superinterface of ExtMap it fails, but then after a cast to ExtMap, it succeeds? That sounds dangerous. On Fri, Nov 20, 2009 at 5:53 PM, R?mi Forax wrote: > Le 21/11/2009 02:31, Neal Gafter a ?crit : > > On Fri, Nov 20, 2009 at 5:34 PM, R?mi Forax wrote: > >> There is already an existing mechanism to insert extension methods >> at runtime: interface injection >> ( >> http://openjdk.java.net/projects/mlvm/subprojects.html#InterfaceInjection >> ) >> >> This mechanism allow to add an interface + implementation to a class at >> runtime. >> >> Written in Java, it will be something like that: >> package java.util; >> public extension interface ExtMap extends Map { >> public Map.entry getEntry(K key) { >> ... >> } >> } >> >> package java.util; >> public interface Map extension ExtMap { >> ... >> } >> > > When at runtime is the extension done? When ExtMap is statically > initialized? > > > The extension is done for each implementation of Map the first time > there is a checkcast (and reflection counterparts) from an implementation > of Map to ExtMap. > ExtMap is initialized when needed as usual. > > R?mi > From howard.lovatt at iee.org Sat Nov 21 03:04:18 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sat, 21 Nov 2009 12:04:18 +0100 Subject: Extension methods Message-ID: <3dd3f56a0911210304i5650435fo438251ec0c35344f@mail.gmail.com> Extension methods have a number of problems, as already highlighted on coin (also see http://www.artima.com/weblogs/viewpost.jsp?thread=220783). A better alternative would be Traits (see http://www.artima.com/weblogs/viewpost.jsp?thread=220916). Traits would also address optimization problems. -- Howard. From forax at univ-mlv.fr Sat Nov 21 04:23:48 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 13:23:48 +0100 Subject: Extension methods In-Reply-To: <15e8b9d20911202201t3b6719fbp5d503b7983936834@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911191558s2b42591ft57f64b009810e079@mail.gmail.com> <17b2302a0911191653r58f44a7ep498cb22a0bf6f5a1@mail.gmail.com> <15e8b9d20911200830i5729dd3dobbc474a5c9bed6cc@mail.gmail.com> <4B0726A7.4080301@univ-mlv.fr> <15e8b9d20911201552i4c296b9co661c94357c78a13e@mail.gmail.com> <4B0743B5.5020902@univ-mlv.fr> <15e8b9d20911201731t153cef93x6a85114480b4acde@mail.gmail.com> <4B074807.20600@univ-mlv.fr> <15e8b9d20911202201t3b6719fbp5d503b7983936834@mail.gmail.com> Message-ID: <4B07DBD4.1040407@univ-mlv.fr> Le 21/11/2009 07:01, Neal Gafter a ?crit : > So the change in type is visible to applications: If there is a > checkcast to some superinterface of ExtMap it fails, but then after a > cast to ExtMap, it succeeds? That sounds dangerous. ExtMap is an extension interface not an interface. I've reused the keyword extends here between an extension interface and an interface, It seems its not the best keyword to explain the relation between an extension interface and the interface it enhance. Let use 'enhances' instead of extends. package java.util; public extension interface ExtMap enhances Map { public Map.Entry getEntry(K key) { ... } } I propose the following rules: - an extension interface can enhance only one interface (it's simpler at runtime). - an extension interface can neither extends an interface nor extends an extension interface. (the later is because extension methods carry codes). So ExtMap can't extends an interface. R?mi > > On Fri, Nov 20, 2009 at 5:53 PM, R?mi Forax > wrote: > > Le 21/11/2009 02:31, Neal Gafter a ?crit : >> On Fri, Nov 20, 2009 at 5:34 PM, R?mi Forax > > wrote: >> >> There is already an existing mechanism to insert extension >> methods >> at runtime: interface injection >> (http://openjdk.java.net/projects/mlvm/subprojects.html#InterfaceInjection) >> >> This mechanism allow to add an interface + implementation to >> a class at runtime. >> >> Written in Java, it will be something like that: >> package java.util; >> public extension interface ExtMap extends Map { >> public Map.entry getEntry(K key) { >> ... >> } >> } >> >> package java.util; >> public interface Map extension ExtMap { >> ... >> } >> >> >> When at runtime is the extension done? When ExtMap is statically >> initialized? > > The extension is done for each implementation of Map the first time > there is a checkcast (and reflection counterparts) from an > implementation of Map to ExtMap. > ExtMap is initialized when needed as usual. > > R?mi > > From forax at univ-mlv.fr Sat Nov 21 04:29:02 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Sat, 21 Nov 2009 13:29:02 +0100 Subject: Extension methods In-Reply-To: <3dd3f56a0911210304i5650435fo438251ec0c35344f@mail.gmail.com> References: <3dd3f56a0911210304i5650435fo438251ec0c35344f@mail.gmail.com> Message-ID: <4B07DD0E.3050006@univ-mlv.fr> Le 21/11/2009 12:04, Howard Lovatt a ?crit : > Extension methods have a number of problems, as already highlighted on coin > (also see http://www.artima.com/weblogs/viewpost.jsp?thread=220783). A > better alternative would be Traits (see > http://www.artima.com/weblogs/viewpost.jsp?thread=220916). Traits would also > address optimization problems. > > -- Howard. > > I agree about Traits if its not just a compiler metaphor. R?mi From reinier at zwitserloot.com Sat Nov 21 08:44:18 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 21 Nov 2009 17:44:18 +0100 Subject: closures after all? In-Reply-To: <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> Message-ID: <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> Answer inline. On Sat, Nov 21, 2009 at 6:24 AM, Tim Peierls wrote: [in response to Neal's argument that writing libraries is hard already] > The addition of function types would raise the threshold of expertise > required to do a good job, making that small percentage even smaller. > > I'm not sure that argument actually works in practice. One of the skills needed when writing libraries is making sure that the library tries to make the job that HAS to be done by the user of the library as easy as possible. Sometimes this requires some _very_ creative design, such as coming up with something like the builder pattern. Having the ability to use function types may actually alleviate the need to come up with, say, the 80 hook interfaces that ParallelArrays defines, making the job easier instead of harder. From tim at peierls.net Sat Nov 21 13:52:17 2009 From: tim at peierls.net (Tim Peierls) Date: Sat, 21 Nov 2009 16:52:17 -0500 Subject: closures after all? In-Reply-To: <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201422r414fd9edy493214945bd3378d@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> Message-ID: <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> On Sat, Nov 21, 2009 at 11:44 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > On Sat, Nov 21, 2009 at 6:24 AM, Tim Peierls wrote: > [in response to Neal's argument that writing libraries is hard already] > > >> The addition of function types would raise the threshold of expertise >> required to do a good job, making that small percentage even smaller. > > > I'm not sure that argument actually works in practice. One of the skills > needed when writing libraries is making sure that the library tries to make > the job that HAS to be done by the user of the library as easy as possible. > Sometimes this requires some _very_ creative design, such as coming up with > something like the builder pattern. Having the ability to use function types > may actually alleviate the need to come up with, say, the 80 hook interfaces > that ParallelArrays defines, making the job easier instead of harder. > Adding a language feature *does* open the door to new possibilities, but the designer's job *is* harder because now you have to evaluate the benefits and costs of using existing features in creative ways vs. taking advantage of these new possibilities. It's not enough to observe that an approach based on new features is more appealing to expert users (more elegant, say, or more compact) than one that is not -- a feature wouldn't get far if it didn't appeal to experts. But the API designer has to be sensitive to the consequences of using new language features for all users, not just the experts. The pool of good designers possessing that kind of sensitivity is necessarily smaller than the one that doesn't have to worry about new language features; the latter have less to do. How do you know if you belong to that smaller pool? I don't know (and I don't claim membership), but I bet self-nomination is not a guarantee. ;-) And again, I think too many folks are taking it on faith that ParallelArray with function types would be vastly superior to ParallelArray with named interfaces. I'm not at all convinced -- in fact, my limited experience suggests otherwise. A year (two years?) ago, I had what I (naturally) thought was an efficient and externally attractive way to drastically reduce the number of named interfaces needed for ParallelArray. Doug Lea didn't like it, but it's possible I didn't describe it well to him. :-) Maybe I can dust it off and try again. --tim From reinier at zwitserloot.com Sat Nov 21 15:46:00 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Nov 2009 00:46:00 +0100 Subject: closures after all? In-Reply-To: <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <997cab100911201450h615c37e5we871465a3ab13587@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> Message-ID: <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> Maybe. Knowing how to use 86 features normally is probably easier than knowing how to use 85 features very creatively, so, I still don't really agree with your reasoning. --Reinier Zwitserloot On Sat, Nov 21, 2009 at 10:52 PM, Tim Peierls wrote: > On Sat, Nov 21, 2009 at 11:44 AM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> On Sat, Nov 21, 2009 at 6:24 AM, Tim Peierls wrote: >> [in response to Neal's argument that writing libraries is hard already] >> >> >>> The addition of function types would raise the threshold of expertise >>> required to do a good job, making that small percentage even smaller. >> >> >> I'm not sure that argument actually works in practice. One of the skills >> needed when writing libraries is making sure that the library tries to make >> the job that HAS to be done by the user of the library as easy as possible. >> Sometimes this requires some _very_ creative design, such as coming up with >> something like the builder pattern. Having the ability to use function types >> may actually alleviate the need to come up with, say, the 80 hook interfaces >> that ParallelArrays defines, making the job easier instead of harder. >> > > Adding a language feature *does* open the door to new possibilities, but > the designer's job *is* harder because now you have to evaluate the benefits > and costs of using existing features in creative ways vs. taking advantage > of these new possibilities. It's not enough to observe that an approach > based on new features is more appealing to expert users (more elegant, say, > or more compact) than one that is not -- a feature wouldn't get far if it > didn't appeal to experts. But the API designer has to be sensitive to the > consequences of using new language features for all users, not just the > experts. The pool of good designers possessing that kind of sensitivity is > necessarily smaller than the one that doesn't have to worry about new > language features; the latter have less to do. > > How do you know if you belong to that smaller pool? I don't know (and I > don't claim membership), but I bet self-nomination is not a guarantee. ;-) > > And again, I think too many folks are taking it on faith that ParallelArray > with function types would be vastly superior to ParallelArray with named > interfaces. I'm not at all convinced -- in fact, my limited experience > suggests otherwise. A year (two years?) ago, I had what I (naturally) > thought was an efficient and externally attractive way to drastically reduce > the number of named interfaces needed for ParallelArray. Doug Lea didn't > like it, but it's possible I didn't describe it well to him. :-) Maybe I can > dust it off and try again. > > --tim > From neal at gafter.com Sat Nov 21 18:18:43 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Nov 2009 18:18:43 -0800 Subject: Closures discussion list... Message-ID: <15e8b9d20911211818q295b9d55j48e2f76e1110e2b@mail.gmail.com> Folks- I suggest we consolidate discussion of about closures to the openjdk closures project mailing list: http://mail.openjdk.java.net/mailman/listinfo/closures-dev. Cheers, Neal From howard.lovatt at iee.org Mon Nov 23 03:39:13 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 12:39:13 +0100 Subject: Closures, too much or too little? In-Reply-To: <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <7f90bba4-0f40-4346-b984-b18029c5b916@o10g2000yqa.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> Message-ID: <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> Sure for BGGA it suppresses a warning, but there would be nothing to stop inner classes been changed to the same mechanism (I think CISE proposed something similar). For a library as opposed to a language feature you could change the @Shared to provide automatic wrapping in a holder. This is not quite the same, in that you would get an error as opposed to a warning if @Shared was absent. However, I prefer the error since I am not a fan of warning messages and thought Java was better before warnings and I am therefore not fazed by this. I also find the advise that annotations don't change program behavior a little silly. Half the time your program won't even run without the correct annotations in many frameworks! -- Howard. 2009/11/22 Neal Gafter > On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt wrote: > >> I agree with your point that it really only captures finals (which as you >> say are simple values of an expression in the LamdaJ 'closure'), but to me >> this is a secondary issue. A @Shared annotation could be introduced that >> works with inner classes and with LamdaJ closures. >> > > @Shared in BGGA just suppresses a warning; it has no effect on the > semantics of the code. I have no idea what specification for an annotation > you have in mind that could affect the way lambdaj works. > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. -- -- Howard. From tronicek at fit.cvut.cz Mon Nov 23 04:51:12 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 13:51:12 +0100 Subject: Closures, too much or too little? In-Reply-To: <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <7f90bba4-0f40-4346-b984-b18029c5b916@o10g2000yqa.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> Message-ID: <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> Hi Howard, I do not understand your arguments. Warning means "be cautious, there may be an error" and error means "there is an error". The @Shared annotation says "be cautious, the variable will be shared between threads". This warning makes sense because we (programmers) are not used to sharing the local variables. However, it does not mean anything on the bytecode level. That is, the program is compiled the same way regardless of the annotation. So what error you want to report? > I also find the advise that annotations don't change program behavior > a little silly. Half the time your program won't even run without the > correct annotations in many frameworks! There is a difference between the Java language and Java frameworks. If you let the annotations change the semantics of the Java language, what would be the difference between annotations and keywords? None, except the way how they are written. And does it make sense to have two language categories for the same? It may seem that annotations can help in adding new features. To some extent, it is true. But it violates the language consistency. Zdenek -- Zdenek Tronicek FIT CTU in Prague http://kenai.com/projects/refactoringng - refactoring tool for compiler guys Howard Lovatt napsal(a): > Sure for BGGA it suppresses a warning, but there would be nothing to stop > inner classes been changed to the same mechanism (I think CISE proposed > something similar). For a library as opposed to a language feature you > could > change the @Shared to provide automatic wrapping in a holder. This is not > quite the same, in that you would get an error as opposed to a warning if > @Shared was absent. > > However, I prefer the error since I am not a fan of warning messages and > thought Java was better before warnings and I am therefore not fazed by > this. I also find the advise that annotations don't change program > behavior > a little silly. Half the time your program won't even run without the > correct annotations in many frameworks! > > -- Howard. > > 2009/11/22 Neal Gafter > >> On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt >> wrote: >> >>> I agree with your point that it really only captures finals (which as >>> you >>> say are simple values of an expression in the LamdaJ 'closure'), but to >>> me >>> this is a secondary issue. A @Shared annotation could be introduced >>> that >>> works with inner classes and with LamdaJ closures. >>> >> >> @Shared in BGGA just suppresses a warning; it has no effect on the >> semantics of the code. I have no idea what specification for an >> annotation >> you have in mind that could affect the way lambdaj works. >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> > > > > -- > -- Howard. > > > > -- > -- Howard. > > From howard.lovatt at iee.org Mon Nov 23 05:14:59 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 14:14:59 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <108fcdeb0911080809l7e2b99d0l591a855c76816724@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> Message-ID: <3dd3f56a0911230514k2c88e52et429cd9686b1803f4@mail.gmail.com> If you have interfaces I think you can add a Closeable version of a for-each loop; without the "RandomAccess hell", e.g.: interface SafeCloseable { void close(); } interface SafeCloseableIterator extends Iterator, SafeCloseable {} interface SafeCloseableIterable extends Iterable { SafeCloseableIterator safeCloseableIterator(); } class Source implements SafeCloseableIterable { public SafeCloseableIterator safeCloseableIterator() { return new SourceIterator(); } public Iterator iterator() { return new SourceIterator(); } } class SourceIterator implements SafeCloseableIterator { private static final String[] out = { "Hello", "Hello", "World", "World" }; private int index = 0; public boolean hasNext() { return ( index >= 0 ) && ( index < out.length ); } public String next() { return out[ index++ ]; } public void remove() { throw new UnsupportedOperationException( "Not supported." ); } public void close() { index = -1; } } class FilterIterator implements SafeCloseableIterator { private final SafeCloseableIterator source; public FilterIterator( final Source source ) { this.source = source.safeCloseableIterator(); } public boolean hasNext() { if ( source.hasNext() ) { source.next(); } return source.hasNext(); } public String next() { return source.next(); } public void remove() { source.remove(); } public void close() { source.close(); } } class Filter implements SafeCloseableIterable { private final Source source; public Filter( final Source source ) { this.source = source; } public SafeCloseableIterator safeCloseableIterator() { return new FilterIterator( source ); } public Iterator iterator() { return new FilterIterator( source ); } } public class Main { public static void main( final String[] notUsed ) { final Filter filter = new Filter( new Source() ); for ( final String s : filter ) { System.out.println( s ); } final SafeCloseableIterator i = filter.safeCloseableIterator(); try { while ( i.hasNext() ) { final String s = i.next(); System.out.println( s ); } } finally { i.close(); } } } 2009/11/12 Howard Lovatt > Reinier has raised a good point that you start with a CloseableIterable and > end up with just an Iterable, this loosing of the Cloaseable type hasn't > happened in my code (because I am looking for the problem). I can see that > it would happen in other peoples code and also by mistake. I think this > problem is solved by using: > > try(final String line : iterableFile) { > ... > } > > The above try-for-each block will fail at compile time if iterableFile > isn't of type CloseableIterable. > > Secondly, and more controversially, the for-each loop could fail at compile > time if given a CloseableIteratable as opposed to a normal Iterable. > > 2009/11/11 Reinier Zwitserloot > >> The problem is: If you forget to retrofit a filter, or you're just using >> one written with java6 or below in mind, then there's no obvious sign that >> your resource is not being closed. No compiler error or warning. Not even a >> pattern in the code you can detect. You'll notice a month later, when you've >> released your product to your customers, who are starting to call in with >> strange errors involving full DB pools and such. The fix is to write up a >> custom findbugs plugin, or something similar. Given the way findbugs is not >> even close to universally used, let alone used with custom plugins, that is >> not at all a satisfactory answer. >> >> That's a very serious problem. >> >> --Reinier Zwitserloot >> >> >> >> >> On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter wrote: >> >>> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < >>> reinier at zwitserloot.com> wrote: >>> >>>> Unless all existing filters are rewritten to support Closeable, and >>>> their close methods do an instanceof check on the contained Iterator and >>>> pass on the close call if they are also ClosableIterators, I don't see how >>>> that's going to work. >>> >>> >>> That sounds like a workable approach. >>> >>> >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> > > > > -- > -- Howard. > -- -- Howard. From reinier at zwitserloot.com Mon Nov 23 06:08:32 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 15:08:32 +0100 Subject: Closures, too much or too little? In-Reply-To: <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> Message-ID: <560fb5ed0911230608r7dd0dd3ej854e9966434cb7c5@mail.gmail.com> Aside from your other arguments, why would a language have 2 separate constructs for what boils down to doing mostly the same thing? Convenience of course. Annotations are parameterized, pluggable, and have their own namespace, and even need to be imported. Keywords have none of those things, but they are independent of libraries, appear in entirely different places, and are easier to type. Unless you find: @For @ForInit int x = 10; @ForCond x < 20; @ForIncr x++; @ForBlock { } easier to read than for (int x = 10; x < 20; x++) {}, of course. --Reinier Zwitserloot On Mon, Nov 23, 2009 at 1:51 PM, wrote: > Hi Howard, > > I do not understand your arguments. Warning means "be cautious, there may > be an error" and error means "there is an error". > The @Shared annotation says "be cautious, the variable will be shared > between threads". This warning makes sense because we (programmers) are > not used to sharing the local variables. > However, it does not mean anything on the bytecode level. That is, the > program is compiled the same way regardless of the annotation. So what > error you want to report? > > > I also find the advise that annotations don't change program behavior > > a little silly. Half the time your program won't even run without the > > correct annotations in many frameworks! > > There is a difference between the Java language and Java frameworks. If > you let the annotations change the semantics of the Java language, what > would be the difference between annotations and keywords? None, except the > way how they are written. And does it make sense to have two language > categories for the same? > It may seem that annotations can help in adding new features. To some > extent, it is true. But it violates the language consistency. > > Zdenek > -- > Zdenek Tronicek > FIT CTU in Prague > http://kenai.com/projects/refactoringng - refactoring tool for compiler > guys > > > Howard Lovatt napsal(a): > > Sure for BGGA it suppresses a warning, but there would be nothing to stop > > inner classes been changed to the same mechanism (I think CISE proposed > > something similar). For a library as opposed to a language feature you > > could > > change the @Shared to provide automatic wrapping in a holder. This is not > > quite the same, in that you would get an error as opposed to a warning if > > @Shared was absent. > > > > However, I prefer the error since I am not a fan of warning messages and > > thought Java was better before warnings and I am therefore not fazed by > > this. I also find the advise that annotations don't change program > > behavior > > a little silly. Half the time your program won't even run without the > > correct annotations in many frameworks! > > > > -- Howard. > > > > 2009/11/22 Neal Gafter > > > >> On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt > >> wrote: > >> > >>> I agree with your point that it really only captures finals (which as > >>> you > >>> say are simple values of an expression in the LamdaJ 'closure'), but to > >>> me > >>> this is a secondary issue. A @Shared annotation could be introduced > >>> that > >>> works with inner classes and with LamdaJ closures. > >>> > >> > >> @Shared in BGGA just suppresses a warning; it has no effect on the > >> semantics of the code. I have no idea what specification for an > >> annotation > >> you have in mind that could affect the way lambdaj works. > >> > >> ______________________________________________________________________ > >> This email has been scanned by the MessageLabs Email Security System. > >> For more information please visit http://www.messagelabs.com/email > >> ______________________________________________________________________ > >> > > > > > > > > -- > > -- Howard. > > > > > > > > -- > > -- Howard. > > > > > > > From howard.lovatt at iee.org Mon Nov 23 06:44:19 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 15:44:19 +0100 Subject: Closures, too much or too little? In-Reply-To: <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> Message-ID: <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> Hi Zdenek, The following example from Josh Bloch illustrates why I would rather writable captured variables generate an error if you miss off @Shared: public class Test { private static final int N = 10; public static void main(String[] args) { List<{ => int}> closures = new ArrayList<{ => int}>(); for (int i = 0; i < N; i++) closures.add( { => i } ); int total = 0; for ({ => int} closure : closures) total += closure.invoke(); System.out.println(total); } } This example is almost certainly an error; therefore I feel a warning is insufficient, much like "int i = 2.0;" is almost certainly an error and I would find a warning insufficient for this too. To me the warnings that are in Java currently are all dubious; they are just a fudge because of some other problem, e.g. erasure. With regard to annotations, if people really like the concept that an annotation should not be like a keyword then make shared a keyword (I am happy either way). I think Josh Bloch has suggested reusing public, but I would prefer either shared or @Shared. -- Howard. From tronicek at fit.cvut.cz Mon Nov 23 07:03:36 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 16:03:36 +0100 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911230608r7dd0dd3ej854e9966434cb7c5@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> <560fb5ed0911230608r7dd0dd3ej854e9966434cb7c5@mail.gmail.com> Message-ID: > @For > @ForInit int x = 10; > @ForCond x < 20; > @ForIncr x++; > @ForBlock { > } This approach would have been ok, if Java was designed with annotations instead of keywords. But it was not. And so it is, in my opinion, against the spirit of the language. Z. -- Zdenek Tronicek FIT CTU in Prague http://kenai.com/projects/refactoringng - refactoring tool for compiler guys Reinier Zwitserloot napsal(a): > Aside from your other arguments, why would a language have 2 separate > constructs for what boils down to doing mostly the same thing? > > Convenience of course. Annotations are parameterized, pluggable, and have > their own namespace, and even need to be imported. Keywords have none of > those things, but they are independent of libraries, appear in entirely > different places, and are easier to type. Unless you find: > > @For > @ForInit int x = 10; > @ForCond x < 20; > @ForIncr x++; > @ForBlock { > } > > easier to read than for (int x = 10; x < 20; x++) {}, of course. > > --Reinier Zwitserloot > > > > On Mon, Nov 23, 2009 at 1:51 PM, wrote: > >> Hi Howard, >> >> I do not understand your arguments. Warning means "be cautious, there >> may >> be an error" and error means "there is an error". >> The @Shared annotation says "be cautious, the variable will be shared >> between threads". This warning makes sense because we (programmers) are >> not used to sharing the local variables. >> However, it does not mean anything on the bytecode level. That is, the >> program is compiled the same way regardless of the annotation. So what >> error you want to report? >> >> > I also find the advise that annotations don't change program behavior >> > a little silly. Half the time your program won't even run without the >> > correct annotations in many frameworks! >> >> There is a difference between the Java language and Java frameworks. If >> you let the annotations change the semantics of the Java language, what >> would be the difference between annotations and keywords? None, except >> the >> way how they are written. And does it make sense to have two language >> categories for the same? >> It may seem that annotations can help in adding new features. To some >> extent, it is true. But it violates the language consistency. >> >> Zdenek >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> http://kenai.com/projects/refactoringng - refactoring tool for compiler >> guys >> >> >> Howard Lovatt napsal(a): >> > Sure for BGGA it suppresses a warning, but there would be nothing to >> stop >> > inner classes been changed to the same mechanism (I think CISE >> proposed >> > something similar). For a library as opposed to a language feature you >> > could >> > change the @Shared to provide automatic wrapping in a holder. This is >> not >> > quite the same, in that you would get an error as opposed to a warning >> if >> > @Shared was absent. >> > >> > However, I prefer the error since I am not a fan of warning messages >> and >> > thought Java was better before warnings and I am therefore not fazed >> by >> > this. I also find the advise that annotations don't change program >> > behavior >> > a little silly. Half the time your program won't even run without the >> > correct annotations in many frameworks! >> > >> > -- Howard. >> > >> > 2009/11/22 Neal Gafter >> > >> >> On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt >> >> wrote: >> >> >> >>> I agree with your point that it really only captures finals (which >> as >> >>> you >> >>> say are simple values of an expression in the LamdaJ 'closure'), but >> to >> >>> me >> >>> this is a secondary issue. A @Shared annotation could be introduced >> >>> that >> >>> works with inner classes and with LamdaJ closures. >> >>> >> >> >> >> @Shared in BGGA just suppresses a warning; it has no effect on the >> >> semantics of the code. I have no idea what specification for an >> >> annotation >> >> you have in mind that could affect the way lambdaj works. >> >> >> >> ______________________________________________________________________ >> >> This email has been scanned by the MessageLabs Email Security System. >> >> For more information please visit http://www.messagelabs.com/email >> >> ______________________________________________________________________ >> >> >> > >> > >> > >> > -- >> > -- Howard. >> > >> > >> > >> > -- >> > -- Howard. >> > >> > >> >> >> > From reinier at zwitserloot.com Mon Nov 23 07:18:09 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 16:18:09 +0100 Subject: Closures, too much or too little? In-Reply-To: References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> <560fb5ed0911230608r7dd0dd3ej854e9966434cb7c5@mail.gmail.com> Message-ID: <560fb5ed0911230718i3840c4f3s32d60da9710464e3@mail.gmail.com> That was not the right response. The right response was: That looks ridiculous. But, I see I screwed up; that wasn't the right snippet. This is closer to the mark: @For(init=@Declare(type=@Primitive(type=INTEGER), name="x", value=@IntConstant(10)), cond=@Lesser(left=@Local("x"), right=@Constant(20)), incr=@Increment(ref=@Local("x")), block=[ @Call(ref=@Deref(ref=@Global("System"), id="out"), name="println", values=[ @StringConstant("Hello, world!") ]) ]) vs: for (int x = 10; x < 20; x++) System.out.println("Hello, world!"); No keywords, no symbols. Just meta-symbols. Symbols included as things that need to be eliminated, because symbols and keywords really do the same thing too, and according to your own logic, that means java is a badly designed language and we should endeavour to make one of the two go away. --Reinier Zwitserloot NB: Shouldn't we be holding this discussion in closures-dev? On Mon, Nov 23, 2009 at 4:03 PM, wrote: > > > @For > > @ForInit int x = 10; > > @ForCond x < 20; > > @ForIncr x++; > > @ForBlock { > > } > > This approach would have been ok, if Java was designed with annotations > instead of keywords. But it was not. And so it is, in my opinion, against > the spirit of the language. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > http://kenai.com/projects/refactoringng - refactoring tool for compiler > guys > > > Reinier Zwitserloot napsal(a): > > Aside from your other arguments, why would a language have 2 separate > > constructs for what boils down to doing mostly the same thing? > > > > Convenience of course. Annotations are parameterized, pluggable, and have > > their own namespace, and even need to be imported. Keywords have none of > > those things, but they are independent of libraries, appear in entirely > > different places, and are easier to type. Unless you find: > > > > @For > > @ForInit int x = 10; > > @ForCond x < 20; > > @ForIncr x++; > > @ForBlock { > > } > > > > easier to read than for (int x = 10; x < 20; x++) {}, of course. > > > > --Reinier Zwitserloot > > > > > > > > On Mon, Nov 23, 2009 at 1:51 PM, wrote: > > > >> Hi Howard, > >> > >> I do not understand your arguments. Warning means "be cautious, there > >> may > >> be an error" and error means "there is an error". > >> The @Shared annotation says "be cautious, the variable will be shared > >> between threads". This warning makes sense because we (programmers) are > >> not used to sharing the local variables. > >> However, it does not mean anything on the bytecode level. That is, the > >> program is compiled the same way regardless of the annotation. So what > >> error you want to report? > >> > >> > I also find the advise that annotations don't change program behavior > >> > a little silly. Half the time your program won't even run without the > >> > correct annotations in many frameworks! > >> > >> There is a difference between the Java language and Java frameworks. If > >> you let the annotations change the semantics of the Java language, what > >> would be the difference between annotations and keywords? None, except > >> the > >> way how they are written. And does it make sense to have two language > >> categories for the same? > >> It may seem that annotations can help in adding new features. To some > >> extent, it is true. But it violates the language consistency. > >> > >> Zdenek > >> -- > >> Zdenek Tronicek > >> FIT CTU in Prague > >> http://kenai.com/projects/refactoringng - refactoring tool for compiler > >> guys > >> > >> > >> Howard Lovatt napsal(a): > >> > Sure for BGGA it suppresses a warning, but there would be nothing to > >> stop > >> > inner classes been changed to the same mechanism (I think CISE > >> proposed > >> > something similar). For a library as opposed to a language feature you > >> > could > >> > change the @Shared to provide automatic wrapping in a holder. This is > >> not > >> > quite the same, in that you would get an error as opposed to a warning > >> if > >> > @Shared was absent. > >> > > >> > However, I prefer the error since I am not a fan of warning messages > >> and > >> > thought Java was better before warnings and I am therefore not fazed > >> by > >> > this. I also find the advise that annotations don't change program > >> > behavior > >> > a little silly. Half the time your program won't even run without the > >> > correct annotations in many frameworks! > >> > > >> > -- Howard. > >> > > >> > 2009/11/22 Neal Gafter > >> > > >> >> On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt > >> >> wrote: > >> >> > >> >>> I agree with your point that it really only captures finals (which > >> as > >> >>> you > >> >>> say are simple values of an expression in the LamdaJ 'closure'), but > >> to > >> >>> me > >> >>> this is a secondary issue. A @Shared annotation could be introduced > >> >>> that > >> >>> works with inner classes and with LamdaJ closures. > >> >>> > >> >> > >> >> @Shared in BGGA just suppresses a warning; it has no effect on the > >> >> semantics of the code. I have no idea what specification for an > >> >> annotation > >> >> you have in mind that could affect the way lambdaj works. > >> >> > >> >> > ______________________________________________________________________ > >> >> This email has been scanned by the MessageLabs Email Security System. > >> >> For more information please visit http://www.messagelabs.com/email > >> >> > ______________________________________________________________________ > >> >> > >> > > >> > > >> > > >> > -- > >> > -- Howard. > >> > > >> > > >> > > >> > -- > >> > -- Howard. > >> > > >> > > >> > >> > >> > > > > From neal at gafter.com Mon Nov 23 07:26:49 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 23 Nov 2009 07:26:49 -0800 Subject: Closures, too much or too little? Message-ID: <4b0aa9b3.161bf30a.56fa.5a64@mx.google.com> The BGGA proposal implements @Shared, but does not allow its use on the control variable of an old-style for loop. I forgot to put that in the document. -----Original Message----- From: Howard Lovatt Sent: Monday, November 23, 2009 6:44 AM To: tronicek at fit.cvut.cz; coin-dev at openjdk.java.net Subject: Closures, too much or too little? Hi Zdenek, The following example from Josh Bloch illustrates why I would rather writable captured variables generate an error if you miss off @Shared: public class Test { private static final int N = 10; public static void main(String[] args) { List<{ => int}> closures = new ArrayList<{ => int}>(); for (int i = 0; i < N; i++) closures.add( { => i } ); int total = 0; for ({ => int} closure : closures) total += closure.invoke(); System.out.println(total); } } This example is almost certainly an error; therefore I feel a warning is insufficient, much like "int i = 2.0;" is almost certainly an error and I would find a warning insufficient for this too. To me the warnings that are in Java currently are all dubious; they are just a fudge because of some other problem, e.g. erasure. With regard to annotations, if people really like the concept that an annotation should not be like a keyword then make shared a keyword (I am happy either way). I think Josh Bloch has suggested reusing public, but I would prefer either shared or @Shared. -- Howard. From tim at peierls.net Mon Nov 23 07:43:10 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 23 Nov 2009 10:43:10 -0500 Subject: closures after all? In-Reply-To: <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201502q47b75a1ak364464750d823ddd@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> Message-ID: <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> On Sat, Nov 21, 2009 at 6:46 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Maybe. Knowing how to use 86 features normally is probably easier than > knowing how to use 85 features very creatively, so, I still don't really > agree with your reasoning. That's because for a very smart person like you the complexity is linear in the number of features. You probably didn't endure months of frustration converting your code to use generics -- all along thinking, "I know this is good for me. Look at all that lovely additional type-checking. Now why won't this compile?" You probably didn't race to replace all your uses of synchronized with Lock/Condition even when it was completely unnecessary. Well, I did those things -- the latter especially embarrassing given my presence on the JSR 166 EG -- and much more! If you say, "Well, Tim, in that case you probably shouldn't be coding in Java," I'll say, "Maybe not, but there are many, many Java developers like me in that respect." For people like me any new feature, no matter how compelling and desirable in theory, affects the usability of the language in dramatically non-linear ways. An API designer has to take such people into account. I'm not saying a complex new feature is never worth it, only that it definitely does make API design harder because of the need to balance the virtues of using the feature in the API against its effect on the "masses". --tim On Sat, Nov 21, 2009 at 10:52 PM, Tim Peierls wrote: > >> On Sat, Nov 21, 2009 at 11:44 AM, Reinier Zwitserloot < >> reinier at zwitserloot.com> wrote: >> >>> On Sat, Nov 21, 2009 at 6:24 AM, Tim Peierls wrote: >>> [in response to Neal's argument that writing libraries is hard already] >>> >>> >>>> The addition of function types would raise the threshold of expertise >>>> required to do a good job, making that small percentage even smaller. >>> >>> >>> I'm not sure that argument actually works in practice. One of the skills >>> needed when writing libraries is making sure that the library tries to make >>> the job that HAS to be done by the user of the library as easy as possible. >>> Sometimes this requires some _very_ creative design, such as coming up with >>> something like the builder pattern. Having the ability to use function types >>> may actually alleviate the need to come up with, say, the 80 hook interfaces >>> that ParallelArrays defines, making the job easier instead of harder. >>> >> >> Adding a language feature *does* open the door to new possibilities, but >> the designer's job *is* harder because now you have to evaluate the benefits >> and costs of using existing features in creative ways vs. taking advantage >> of these new possibilities. It's not enough to observe that an approach >> based on new features is more appealing to expert users (more elegant, say, >> or more compact) than one that is not -- a feature wouldn't get far if it >> didn't appeal to experts. But the API designer has to be sensitive to the >> consequences of using new language features for all users, not just the >> experts. The pool of good designers possessing that kind of sensitivity is >> necessarily smaller than the one that doesn't have to worry about new >> language features; the latter have less to do. >> >> How do you know if you belong to that smaller pool? I don't know (and I >> don't claim membership), but I bet self-nomination is not a guarantee. ;-) >> >> And again, I think too many folks are taking it on faith that >> ParallelArray with function types would be vastly superior to ParallelArray >> with named interfaces. I'm not at all convinced -- in fact, my limited >> experience suggests otherwise. A year (two years?) ago, I had what I >> (naturally) thought was an efficient and externally attractive way to >> drastically reduce the number of named interfaces needed for ParallelArray. >> Doug Lea didn't like it, but it's possible I didn't describe it well to him. >> :-) Maybe I can dust it off and try again. >> >> --tim >> > > From tronicek at fit.cvut.cz Mon Nov 23 07:48:32 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 16:48:32 +0100 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911230718i3840c4f3s32d60da9710464e3@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> <560fb5ed0911230608r7dd0dd3ej854e9966434cb7c5@mail.gmail.com> <560fb5ed0911230718i3840c4f3s32d60da9710464e3@mail.gmail.com> Message-ID: <2f3845d37771cc23e7d33f32440e4158.squirrel@imap.fit.cvut.cz> Not at all. Both, keywords and annotations, are useful in Java. But for different purposes. Keywords define what the program should do (the semantics) and annotations add some extra information which serve, for example, for static analysis. What would you think about the language where the while loop is written by the "while" keyword and the for loop is expressed by the annotation? Although I do not have any strong argument against such approach, it is very unnatural and illogical for me. Z. -- Zdenek Tronicek FIT CTU in Prague http://kenai.com/projects/refactoringng - refactoring tool for compiler guys Reinier Zwitserloot napsal(a): > That was not the right response. The right response was: That looks > ridiculous. But, I see I screwed up; that wasn't the right snippet. This > is > closer to the mark: > > @For(init=@Declare(type=@Primitive(type=INTEGER), name="x", > value=@IntConstant(10)), > cond=@Lesser(left=@Local("x"), right=@Constant(20)), > incr=@Increment(ref=@Local("x")), > block=[ > @Call(ref=@Deref(ref=@Global("System"), id="out"), name="println", > values=[ > @StringConstant("Hello, world!") > ]) > ]) > > vs: > > for (int x = 10; x < 20; x++) System.out.println("Hello, world!"); > > No keywords, no symbols. Just meta-symbols. Symbols included as things > that > need to be eliminated, because symbols and keywords really do the same > thing > too, and according to your own logic, that means java is a badly designed > language and we should endeavour to make one of the two go away. > > --Reinier Zwitserloot > > NB: Shouldn't we be holding this discussion in closures-dev? > > > On Mon, Nov 23, 2009 at 4:03 PM, wrote: > >> >> > @For >> > @ForInit int x = 10; >> > @ForCond x < 20; >> > @ForIncr x++; >> > @ForBlock { >> > } >> >> This approach would have been ok, if Java was designed with annotations >> instead of keywords. But it was not. And so it is, in my opinion, >> against >> the spirit of the language. >> >> Z. >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> http://kenai.com/projects/refactoringng - refactoring tool for compiler >> guys >> >> >> Reinier Zwitserloot napsal(a): >> > Aside from your other arguments, why would a language have 2 separate >> > constructs for what boils down to doing mostly the same thing? >> > >> > Convenience of course. Annotations are parameterized, pluggable, and >> have >> > their own namespace, and even need to be imported. Keywords have none >> of >> > those things, but they are independent of libraries, appear in >> entirely >> > different places, and are easier to type. Unless you find: >> > >> > @For >> > @ForInit int x = 10; >> > @ForCond x < 20; >> > @ForIncr x++; >> > @ForBlock { >> > } >> > >> > easier to read than for (int x = 10; x < 20; x++) {}, of course. >> > >> > --Reinier Zwitserloot >> > >> > >> > >> > On Mon, Nov 23, 2009 at 1:51 PM, wrote: >> > >> >> Hi Howard, >> >> >> >> I do not understand your arguments. Warning means "be cautious, there >> >> may >> >> be an error" and error means "there is an error". >> >> The @Shared annotation says "be cautious, the variable will be shared >> >> between threads". This warning makes sense because we (programmers) >> are >> >> not used to sharing the local variables. >> >> However, it does not mean anything on the bytecode level. That is, >> the >> >> program is compiled the same way regardless of the annotation. So >> what >> >> error you want to report? >> >> >> >> > I also find the advise that annotations don't change program >> behavior >> >> > a little silly. Half the time your program won't even run without >> the >> >> > correct annotations in many frameworks! >> >> >> >> There is a difference between the Java language and Java frameworks. >> If >> >> you let the annotations change the semantics of the Java language, >> what >> >> would be the difference between annotations and keywords? None, >> except >> >> the >> >> way how they are written. And does it make sense to have two language >> >> categories for the same? >> >> It may seem that annotations can help in adding new features. To some >> >> extent, it is true. But it violates the language consistency. >> >> >> >> Zdenek >> >> -- >> >> Zdenek Tronicek >> >> FIT CTU in Prague >> >> http://kenai.com/projects/refactoringng - refactoring tool for >> compiler >> >> guys >> >> >> >> >> >> Howard Lovatt napsal(a): >> >> > Sure for BGGA it suppresses a warning, but there would be nothing >> to >> >> stop >> >> > inner classes been changed to the same mechanism (I think CISE >> >> proposed >> >> > something similar). For a library as opposed to a language feature >> you >> >> > could >> >> > change the @Shared to provide automatic wrapping in a holder. This >> is >> >> not >> >> > quite the same, in that you would get an error as opposed to a >> warning >> >> if >> >> > @Shared was absent. >> >> > >> >> > However, I prefer the error since I am not a fan of warning >> messages >> >> and >> >> > thought Java was better before warnings and I am therefore not >> fazed >> >> by >> >> > this. I also find the advise that annotations don't change program >> >> > behavior >> >> > a little silly. Half the time your program won't even run without >> the >> >> > correct annotations in many frameworks! >> >> > >> >> > -- Howard. >> >> > >> >> > 2009/11/22 Neal Gafter >> >> > >> >> >> On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt >> >> >> wrote: >> >> >> >> >> >>> I agree with your point that it really only captures finals >> (which >> >> as >> >> >>> you >> >> >>> say are simple values of an expression in the LamdaJ 'closure'), >> but >> >> to >> >> >>> me >> >> >>> this is a secondary issue. A @Shared annotation could be >> introduced >> >> >>> that >> >> >>> works with inner classes and with LamdaJ closures. >> >> >>> >> >> >> >> >> >> @Shared in BGGA just suppresses a warning; it has no effect on the >> >> >> semantics of the code. I have no idea what specification for an >> >> >> annotation >> >> >> you have in mind that could affect the way lambdaj works. >> >> >> >> >> >> >> ______________________________________________________________________ >> >> >> This email has been scanned by the MessageLabs Email Security >> System. >> >> >> For more information please visit http://www.messagelabs.com/email >> >> >> >> ______________________________________________________________________ >> >> >> >> >> > >> >> > >> >> > >> >> > -- >> >> > -- Howard. >> >> > >> >> > >> >> > >> >> > -- >> >> > -- Howard. >> >> > >> >> > >> >> >> >> >> >> >> > >> >> > From tronicek at fit.cvut.cz Mon Nov 23 07:58:40 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 16:58:40 +0100 Subject: Closures, too much or too little? In-Reply-To: <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> Message-ID: <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> Hi Howard, you can argue similarly for example in case of method overriding and overloading and suggest to add the "override" and "overload" keywords. I do not mind if the "shared" or "public" keyword is mandatory in this case. However, mandatory annotation is odd for me. Z. -- Zdenek Tronicek FIT CTU in Prague http://kenai.com/projects/refactoringng - refactoring tool for compiler guys Howard Lovatt napsal(a): > Hi Zdenek, > > The following example from Josh Bloch illustrates why I would rather > writable captured variables generate an error if you miss off @Shared: > > public class Test { > > private static final int N = 10; > > public static void main(String[] args) { > > List<{ => int}> closures = new ArrayList<{ => int}>(); > > for (int i = 0; i < N; i++) > > closures.add( { => i } ); > > int total = 0; > > for ({ => int} closure : closures) > > total += closure.invoke(); > > System.out.println(total); > > } > > } > > This example is almost certainly an error; therefore I feel a warning is > insufficient, much like "int i = 2.0;" is almost certainly an error and I > would find a warning insufficient for this too. To me the warnings that > are > in Java currently are all dubious; they are just a fudge because of some > other problem, e.g. erasure. > > With regard to annotations, if people really like the concept that an > annotation should not be like a keyword then make shared a keyword (I am > happy either way). I think Josh Bloch has suggested reusing public, but I > would prefer either shared or @Shared. > > -- Howard. > From jjb at google.com Mon Nov 23 08:18:00 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 23 Nov 2009 08:18:00 -0800 Subject: Closures, too much or too little? In-Reply-To: <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> Message-ID: <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> I'm still not convinced that it's a good idea to allow closure to capture shared local variables. I do (still) like the idea of "auto-finalization" (i.e., it's OK for a closure or anonymous class instance creation expression) to reference a local variable that's not explicitly labeled final if DU/DA-style analysis shows it to be effectively final. I suspect this is the sweet spot. Josh On Mon, Nov 23, 2009 at 7:58 AM, wrote: > Hi Howard, > > you can argue similarly for example in case of method overriding and > overloading and suggest to add the "override" and "overload" keywords. I > do not mind if the "shared" or "public" keyword is mandatory in this case. > However, mandatory annotation is odd for me. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > http://kenai.com/projects/refactoringng - refactoring tool for compiler > guys > > > Howard Lovatt napsal(a): > > Hi Zdenek, > > > > The following example from Josh Bloch illustrates why I would rather > > writable captured variables generate an error if you miss off @Shared: > > > > public class Test { > > > > private static final int N = 10; > > > > public static void main(String[] args) { > > > > List<{ => int}> closures = new ArrayList<{ => int}>(); > > > > for (int i = 0; i < N; i++) > > > > closures.add( { => i } ); > > > > int total = 0; > > > > for ({ => int} closure : closures) > > > > total += closure.invoke(); > > > > System.out.println(total); > > > > } > > > > } > > > > This example is almost certainly an error; therefore I feel a warning is > > insufficient, much like "int i = 2.0;" is almost certainly an error and I > > would find a warning insufficient for this too. To me the warnings that > > are > > in Java currently are all dubious; they are just a fudge because of some > > other problem, e.g. erasure. > > > > With regard to annotations, if people really like the concept that an > > annotation should not be like a keyword then make shared a keyword (I am > > happy either way). I think Josh Bloch has suggested reusing public, but I > > would prefer either shared or @Shared. > > > > -- Howard. > > > > > From reinier at zwitserloot.com Mon Nov 23 09:34:26 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 18:34:26 +0100 Subject: Closures, too much or too little? In-Reply-To: <2f3845d37771cc23e7d33f32440e4158.squirrel@imap.fit.cvut.cz> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <91d39f5e86b82c9f701eb7a3e136b3e2.squirrel@imap.fit.cvut.cz> <560fb5ed0911230608r7dd0dd3ej854e9966434cb7c5@mail.gmail.com> <560fb5ed0911230718i3840c4f3s32d60da9710464e3@mail.gmail.com> <2f3845d37771cc23e7d33f32440e4158.squirrel@imap.fit.cvut.cz> Message-ID: <560fb5ed0911230934i18287ac7ia0816a9e5be39be4@mail.gmail.com> I just explained at length why stating that 'annotations and keywords SHOULD do different things' cannot be applied to just the things you want. They are different in keywords being global and non-parameterized, and annotations being things you import, which can have parameters. In that they are different. That's as far as the difference needs to go. Any further semantic arguments that they should be MORE different somehow, are not valid unless you explain why this would be a good or bad thing. Hint: "because they should be different" is not a good argument. Strawman comparisons aren't a good argument. Stop making them. On Mon, Nov 23, 2009 at 4:48 PM, wrote: > Not at all. Both, keywords and annotations, are useful in Java. But for > different purposes. Keywords define what the program should do (the > semantics) and annotations add some extra information which serve, for > example, for static analysis. > > What would you think about the language where the while loop is written by > the "while" keyword and the for loop is expressed by the annotation? > Although I do not have any strong argument against such approach, it is > very unnatural and illogical for me. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > http://kenai.com/projects/refactoringng - refactoring tool for compiler > guys > > > Reinier Zwitserloot napsal(a): > > That was not the right response. The right response was: That looks > > ridiculous. But, I see I screwed up; that wasn't the right snippet. This > > is > > closer to the mark: > > > > @For(init=@Declare(type=@Primitive(type=INTEGER), name="x", > > value=@IntConstant(10)), > > cond=@Lesser(left=@Local("x"), right=@Constant(20)), > > incr=@Increment(ref=@Local("x")), > > block=[ > > @Call(ref=@Deref(ref=@Global("System"), id="out"), > name="println", > > values=[ > > @StringConstant("Hello, world!") > > ]) > > ]) > > > > vs: > > > > for (int x = 10; x < 20; x++) System.out.println("Hello, world!"); > > > > No keywords, no symbols. Just meta-symbols. Symbols included as things > > that > > need to be eliminated, because symbols and keywords really do the same > > thing > > too, and according to your own logic, that means java is a badly designed > > language and we should endeavour to make one of the two go away. > > > > --Reinier Zwitserloot > > > > NB: Shouldn't we be holding this discussion in closures-dev? > > > > > > On Mon, Nov 23, 2009 at 4:03 PM, wrote: > > > >> > >> > @For > >> > @ForInit int x = 10; > >> > @ForCond x < 20; > >> > @ForIncr x++; > >> > @ForBlock { > >> > } > >> > >> This approach would have been ok, if Java was designed with annotations > >> instead of keywords. But it was not. And so it is, in my opinion, > >> against > >> the spirit of the language. > >> > >> Z. > >> -- > >> Zdenek Tronicek > >> FIT CTU in Prague > >> http://kenai.com/projects/refactoringng - refactoring tool for compiler > >> guys > >> > >> > >> Reinier Zwitserloot napsal(a): > >> > Aside from your other arguments, why would a language have 2 separate > >> > constructs for what boils down to doing mostly the same thing? > >> > > >> > Convenience of course. Annotations are parameterized, pluggable, and > >> have > >> > their own namespace, and even need to be imported. Keywords have none > >> of > >> > those things, but they are independent of libraries, appear in > >> entirely > >> > different places, and are easier to type. Unless you find: > >> > > >> > @For > >> > @ForInit int x = 10; > >> > @ForCond x < 20; > >> > @ForIncr x++; > >> > @ForBlock { > >> > } > >> > > >> > easier to read than for (int x = 10; x < 20; x++) {}, of course. > >> > > >> > --Reinier Zwitserloot > >> > > >> > > >> > > >> > On Mon, Nov 23, 2009 at 1:51 PM, wrote: > >> > > >> >> Hi Howard, > >> >> > >> >> I do not understand your arguments. Warning means "be cautious, there > >> >> may > >> >> be an error" and error means "there is an error". > >> >> The @Shared annotation says "be cautious, the variable will be shared > >> >> between threads". This warning makes sense because we (programmers) > >> are > >> >> not used to sharing the local variables. > >> >> However, it does not mean anything on the bytecode level. That is, > >> the > >> >> program is compiled the same way regardless of the annotation. So > >> what > >> >> error you want to report? > >> >> > >> >> > I also find the advise that annotations don't change program > >> behavior > >> >> > a little silly. Half the time your program won't even run without > >> the > >> >> > correct annotations in many frameworks! > >> >> > >> >> There is a difference between the Java language and Java frameworks. > >> If > >> >> you let the annotations change the semantics of the Java language, > >> what > >> >> would be the difference between annotations and keywords? None, > >> except > >> >> the > >> >> way how they are written. And does it make sense to have two language > >> >> categories for the same? > >> >> It may seem that annotations can help in adding new features. To some > >> >> extent, it is true. But it violates the language consistency. > >> >> > >> >> Zdenek > >> >> -- > >> >> Zdenek Tronicek > >> >> FIT CTU in Prague > >> >> http://kenai.com/projects/refactoringng - refactoring tool for > >> compiler > >> >> guys > >> >> > >> >> > >> >> Howard Lovatt napsal(a): > >> >> > Sure for BGGA it suppresses a warning, but there would be nothing > >> to > >> >> stop > >> >> > inner classes been changed to the same mechanism (I think CISE > >> >> proposed > >> >> > something similar). For a library as opposed to a language feature > >> you > >> >> > could > >> >> > change the @Shared to provide automatic wrapping in a holder. This > >> is > >> >> not > >> >> > quite the same, in that you would get an error as opposed to a > >> warning > >> >> if > >> >> > @Shared was absent. > >> >> > > >> >> > However, I prefer the error since I am not a fan of warning > >> messages > >> >> and > >> >> > thought Java was better before warnings and I am therefore not > >> fazed > >> >> by > >> >> > this. I also find the advise that annotations don't change program > >> >> > behavior > >> >> > a little silly. Half the time your program won't even run without > >> the > >> >> > correct annotations in many frameworks! > >> >> > > >> >> > -- Howard. > >> >> > > >> >> > 2009/11/22 Neal Gafter > >> >> > > >> >> >> On Sun, Nov 22, 2009 at 12:20 PM, Howard Lovatt > >> >> >> wrote: > >> >> >> > >> >> >>> I agree with your point that it really only captures finals > >> (which > >> >> as > >> >> >>> you > >> >> >>> say are simple values of an expression in the LamdaJ 'closure'), > >> but > >> >> to > >> >> >>> me > >> >> >>> this is a secondary issue. A @Shared annotation could be > >> introduced > >> >> >>> that > >> >> >>> works with inner classes and with LamdaJ closures. > >> >> >>> > >> >> >> > >> >> >> @Shared in BGGA just suppresses a warning; it has no effect on the > >> >> >> semantics of the code. I have no idea what specification for an > >> >> >> annotation > >> >> >> you have in mind that could affect the way lambdaj works. > >> >> >> > >> >> >> > >> ______________________________________________________________________ > >> >> >> This email has been scanned by the MessageLabs Email Security > >> System. > >> >> >> For more information please visit > http://www.messagelabs.com/email > >> >> >> > >> ______________________________________________________________________ > >> >> >> > >> >> > > >> >> > > >> >> > > >> >> > -- > >> >> > -- Howard. > >> >> > > >> >> > > >> >> > > >> >> > -- > >> >> > -- Howard. > >> >> > > >> >> > > >> >> > >> >> > >> >> > >> > > >> > >> > > > > From markmahieu at googlemail.com Mon Nov 23 09:35:35 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 23 Nov 2009 17:35:35 +0000 Subject: Closures, too much or too little? In-Reply-To: <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> Message-ID: <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> On 23 Nov 2009, at 16:18, Joshua Bloch wrote: > I'm still not convinced that it's a good idea to allow closure to capture > shared local variables. I do (still) like the idea of "auto-finalization" > (i.e., it's OK for a closure or anonymous class instance creation > expression) to reference a local variable that's not explicitly labeled > final if DU/DA-style analysis shows it to be effectively final. I suspect > this is the sweet spot. > > Josh A good proportion of the annoying cases I encounter with anonymous classes accessing local variables look like this: int total = 0; for (...) { total += something; } // done with updating total final int finalTotal = total; // annoying doSomething(new Whatever() { public void execute() { // read finalTotal } }); So for me, a more practical variation of "auto-finalization" would be that the variable only 'becomes' final at the point in the code where the closure appears. In the above example, I'd even consider it an improvement if I had to (and could) explicitly redeclare 'total' as final. The other thorny side to all this occurs when the closure actually does want to update the local variable, as you know. If we don't go some way to making that less awkward, people will continue to use the same workarounds they always have, which also have their costs. Personally, I quite liked the way that public/@Shared called out the variables as deserving special attention. Regards, Mark From reinier at zwitserloot.com Mon Nov 23 09:40:43 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 18:40:43 +0100 Subject: Closures, too much or too little? In-Reply-To: <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> Message-ID: <560fb5ed0911230940s608f3d6cx6a6d4c971cd790ed@mail.gmail.com> auto-final can be combined with @Shared (with @Shared being one option when you access a mutating variable from outer scope), though once auto-final is in place, I don't think @Shared is a make-or-break kind of issue with closures. As mark mentioned, it DOES happen though (probably will happen a lot more, when closures are added in JDK7), and people use a number of different solutions to get around this. This is a bad thing. I've seen arrays, I've seen AtomicReference and friends, and I've seen hand-rolled Pointer classes. I've even used all 3, though I've standardized myself on always using an Atomic* for it, whether or not I actually need the atomicity. Is there any pragmatic argument AGAINST adding @Shared to the language, other than "Any feature should prove why we have to add it, not why we shouldn't", and hazy concerns about keywordishness, which seems like a taste fight, not an actual discussion, not to mention solvable by replacing "@Shared" with public. My personal preference lies in auto-final *AND* @Shared. --Reinier Zwitserloot On Mon, Nov 23, 2009 at 5:18 PM, Joshua Bloch wrote: > I'm still not convinced that it's a good idea to allow closure to capture > shared local variables. I do (still) like the idea of "auto-finalization" > (i.e., it's OK for a closure or anonymous class instance creation > expression) to reference a local variable that's not explicitly labeled > final if DU/DA-style analysis shows it to be effectively final. I suspect > this is the sweet spot. > > Josh > > On Mon, Nov 23, 2009 at 7:58 AM, wrote: > > > Hi Howard, > > > > you can argue similarly for example in case of method overriding and > > overloading and suggest to add the "override" and "overload" keywords. I > > do not mind if the "shared" or "public" keyword is mandatory in this > case. > > However, mandatory annotation is odd for me. > > > > Z. > > -- > > Zdenek Tronicek > > FIT CTU in Prague > > http://kenai.com/projects/refactoringng - refactoring tool for compiler > > guys > > > > > > Howard Lovatt napsal(a): > > > Hi Zdenek, > > > > > > The following example from Josh Bloch illustrates why I would rather > > > writable captured variables generate an error if you miss off @Shared: > > > > > > public class Test { > > > > > > private static final int N = 10; > > > > > > public static void main(String[] args) { > > > > > > List<{ => int}> closures = new ArrayList<{ => int}>(); > > > > > > for (int i = 0; i < N; i++) > > > > > > closures.add( { => i } ); > > > > > > int total = 0; > > > > > > for ({ => int} closure : closures) > > > > > > total += closure.invoke(); > > > > > > System.out.println(total); > > > > > > } > > > > > > } > > > > > > This example is almost certainly an error; therefore I feel a warning > is > > > insufficient, much like "int i = 2.0;" is almost certainly an error and > I > > > would find a warning insufficient for this too. To me the warnings that > > > are > > > in Java currently are all dubious; they are just a fudge because of > some > > > other problem, e.g. erasure. > > > > > > With regard to annotations, if people really like the concept that an > > > annotation should not be like a keyword then make shared a keyword (I > am > > > happy either way). I think Josh Bloch has suggested reusing public, but > I > > > would prefer either shared or @Shared. > > > > > > -- Howard. > > > > > > > > > > > From jjb at google.com Mon Nov 23 09:42:48 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 23 Nov 2009 09:42:48 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <3dd3f56a0911230514k2c88e52et429cd9686b1803f4@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <108fcdeb0911111206m4c23bd3cpb564fb2fc8649f37@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> <3dd3f56a0911230514k2c88e52et429cd9686b1803f4@mail.gmail.com> Message-ID: <17b2302a0911230942o4c78e9b2v2e730ebd2c72fb1d@mail.gmail.com> Howard, I'm not sure if we want a Closeable-enabled version of a for-each loop in Java. I discussed this topic with the guy who added the using statement to C# (Peter Hallam, now at Google), and he agreed that the Closeable for-each hybrid didn't really mesh with Java. Josh P.S. Peter just loves the using statement in C#, and is enthusiastic about ARM blocks in Java. On Mon, Nov 23, 2009 at 5:14 AM, Howard Lovatt wrote: > If you have interfaces I think you can add a Closeable version of a > for-each > loop; without the "RandomAccess hell", e.g.: > > interface SafeCloseable { void close(); } > > interface SafeCloseableIterator extends Iterator, SafeCloseable {} > > interface SafeCloseableIterable extends Iterable > { SafeCloseableIterator safeCloseableIterator(); } > > class Source implements SafeCloseableIterable { > public SafeCloseableIterator safeCloseableIterator() { return new > SourceIterator(); } > > public Iterator iterator() { return new SourceIterator(); } > } > > class SourceIterator implements SafeCloseableIterator { > private static final String[] out = { "Hello", "Hello", "World", "World" > }; > > private int index = 0; > > public boolean hasNext() { return ( index >= 0 ) && ( index < out.length > ); } > > public String next() { return out[ index++ ]; } > > public void remove() { throw new UnsupportedOperationException( "Not > supported." ); } > > public void close() { index = -1; } > } > > class FilterIterator implements SafeCloseableIterator { > private final SafeCloseableIterator source; > > public FilterIterator( final Source source ) { this.source = > source.safeCloseableIterator(); } > > public boolean hasNext() { > if ( source.hasNext() ) { source.next(); } > return source.hasNext(); > } > > public String next() { return source.next(); } > > public void remove() { source.remove(); } > > public void close() { source.close(); } > } > > class Filter implements SafeCloseableIterable { > private final Source source; > > public Filter( final Source source ) { this.source = source; } > > public SafeCloseableIterator safeCloseableIterator() { return new > FilterIterator( source ); } > > public Iterator iterator() { return new FilterIterator( source ); } > } > > public class Main { > public static void main( final String[] notUsed ) { > final Filter filter = new Filter( new Source() ); > for ( final String s : filter ) { System.out.println( s ); } > final SafeCloseableIterator i = filter.safeCloseableIterator(); > try { > while ( i.hasNext() ) { > final String s = i.next(); > System.out.println( s ); > } > } finally { i.close(); } > } > } > > From reinier at zwitserloot.com Mon Nov 23 09:44:56 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 18:44:56 +0100 Subject: closures after all? In-Reply-To: <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <997cab100911201530m137e2c8eoe578c9f46922e211@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> Message-ID: <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> I'll readily admit that any change that is bound to give you more options in API design is likely to tickle (in a bad way) the sense of perfection of any API designer, in that they'll want to revisit their existing stuff. But that's an entirely different beast from complicating or simplifying the work of someone building new API -from scratch-. Unless we want to replay that old bitty of 'java is like cobol' (which annoys me to no end. I was rather glad to hear Mark Reinhold publically slaughter that silly notion at devoxx), a certain amount of pain today is worth it for a better tomorrow. However, some concern for how feasible it would be for the main IDEs to come up with fancy refactor scripts to make your job easier, that would be nice. Generics was rather hard to refactor. I'm guessing this may be a bit easier. --Reinier Zwitserloot On Mon, Nov 23, 2009 at 4:43 PM, Tim Peierls wrote: > On Sat, Nov 21, 2009 at 6:46 PM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> Maybe. Knowing how to use 86 features normally is probably easier than >> knowing how to use 85 features very creatively, so, I still don't really >> agree with your reasoning. > > > That's because for a very smart person like you the complexity is linear in > the number of features. You probably didn't endure months of frustration > converting your code to use generics -- all along thinking, "I know this is > good for me. Look at all that lovely additional type-checking. Now why won't > this compile?" You probably didn't race to replace all your uses of > synchronized with Lock/Condition even when it was completely unnecessary. > > Well, I did those things -- the latter especially embarrassing given my > presence on the JSR 166 EG -- and much more! If you say, "Well, Tim, in that > case you probably shouldn't be coding in Java," I'll say, "Maybe not, but > there are many, many Java developers like me in that respect." > > For people like me any new feature, no matter how compelling and desirable > in theory, affects the usability of the language in dramatically non-linear > ways. An API designer has to take such people into account. > > I'm not saying a complex new feature is never worth it, only that it > definitely does make API design harder because of the need to balance the > virtues of using the feature in the API against its effect on the "masses". > > --tim > > > On Sat, Nov 21, 2009 at 10:52 PM, Tim Peierls wrote: >> >>> On Sat, Nov 21, 2009 at 11:44 AM, Reinier Zwitserloot < >>> reinier at zwitserloot.com> wrote: >>> >>>> On Sat, Nov 21, 2009 at 6:24 AM, Tim Peierls wrote: >>>> [in response to Neal's argument that writing libraries is hard already] >>>> >>>> >>>>> The addition of function types would raise the threshold of expertise >>>>> required to do a good job, making that small percentage even smaller. >>>> >>>> >>>> I'm not sure that argument actually works in practice. One of the skills >>>> needed when writing libraries is making sure that the library tries to make >>>> the job that HAS to be done by the user of the library as easy as possible. >>>> Sometimes this requires some _very_ creative design, such as coming up with >>>> something like the builder pattern. Having the ability to use function types >>>> may actually alleviate the need to come up with, say, the 80 hook interfaces >>>> that ParallelArrays defines, making the job easier instead of harder. >>>> >>> >>> Adding a language feature *does* open the door to new possibilities, but >>> the designer's job *is* harder because now you have to evaluate the benefits >>> and costs of using existing features in creative ways vs. taking advantage >>> of these new possibilities. It's not enough to observe that an approach >>> based on new features is more appealing to expert users (more elegant, say, >>> or more compact) than one that is not -- a feature wouldn't get far if it >>> didn't appeal to experts. But the API designer has to be sensitive to the >>> consequences of using new language features for all users, not just the >>> experts. The pool of good designers possessing that kind of sensitivity is >>> necessarily smaller than the one that doesn't have to worry about new >>> language features; the latter have less to do. >>> >>> How do you know if you belong to that smaller pool? I don't know (and I >>> don't claim membership), but I bet self-nomination is not a guarantee. ;-) >>> >>> And again, I think too many folks are taking it on faith that >>> ParallelArray with function types would be vastly superior to ParallelArray >>> with named interfaces. I'm not at all convinced -- in fact, my limited >>> experience suggests otherwise. A year (two years?) ago, I had what I >>> (naturally) thought was an efficient and externally attractive way to >>> drastically reduce the number of named interfaces needed for ParallelArray. >>> Doug Lea didn't like it, but it's possible I didn't describe it well to him. >>> :-) Maybe I can dust it off and try again. >>> >>> --tim >>> >> >> > From neal at gafter.com Mon Nov 23 10:40:56 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 23 Nov 2009 10:40:56 -0800 Subject: ARM Blocks: ease of use and for loops In-Reply-To: <17b2302a0911230942o4c78e9b2v2e730ebd2c72fb1d@mail.gmail.com> References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> <3dd3f56a0911230514k2c88e52et429cd9686b1803f4@mail.gmail.com> <17b2302a0911230942o4c78e9b2v2e730ebd2c72fb1d@mail.gmail.com> Message-ID: <15e8b9d20911231040o7729fe6bl8b56c8e2996f0a76@mail.gmail.com> On Mon, Nov 23, 2009 at 9:42 AM, Joshua Bloch wrote: > I'm not sure if we want a Closeable-enabled version of a for-each loop in > Java. I discussed this topic with the guy who added the using statement to > C# (Peter Hallam, now at Google), and he agreed that the Closeable for-each > hybrid didn't really mesh with Java. > It would be interesting to hear Peter's own comments, rather than having the hearsay filtered. From howard.lovatt at iee.org Mon Nov 23 11:26:57 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 20:26:57 +0100 Subject: ARM Blocks: ease of use and for loops In-Reply-To: References: <3dd3f56a0910210515u51d78ee3i1099230114abc95d@mail.gmail.com> <15e8b9d20911111240p13eeb19bx321056b8dcb5cbf3@mail.gmail.com> <560fb5ed0911111313q4b73cf63q1a4479f2d9472480@mail.gmail.com> <15e8b9d20911111317m285f0686m9f6967e2334c9b34@mail.gmail.com> <560fb5ed0911111321y166fa29aiad2dba800b7fe2db@mail.gmail.com> <15e8b9d20911111330j4824b690vbb8b0b66510a80e7@mail.gmail.com> <560fb5ed0911111334m4d1cdb85j536444e4e4aa2b0d@mail.gmail.com> <3dd3f56a0911120155h6d8552d6k9475e7f18ffcdbf6@mail.gmail.com> <3dd3f56a0911230514k2c88e52et429cd9686b1803f4@mail.gmail.com> Message-ID: <3dd3f56a0911231126n100ea94bj18d3f5a4c6f1c03@mail.gmail.com> An ARM-enabled-for-each loop definitely isn't as important as the standard ARM block, but I would find it useful. The purpose of the post was to demonstrate that using distinct interfaces and a different syntax for an ARM-enabled-for-each loop the combinational explosion problem, RandomAccess hell, that Kevin Bourrillion raise could be avoided. Whether people think it is worthwhile or not is a separate issue to the technical issue raised. What do people think, are distinct interfaces plus a distinct syntax worth while for an ARM-enabled-for-each loop? -- Howard. 2009/11/23 Joshua Bloch > Howard, > > I'm not sure if we want a Closeable-enabled version of a for-each loop in > Java. I discussed this topic with the guy who added the using statement to > C# (Peter Hallam, now at Google), and he agreed that it didn't really mesh > with Java. > > Josh > > > On Mon, Nov 23, 2009 at 5:14 AM, Howard Lovatt wrote: > >> If you have interfaces I think you can add a Closeable version of a >> for-each loop; without the "RandomAccess hell", e.g.: >> >> interface SafeCloseable { void close(); } >> >> interface SafeCloseableIterator extends Iterator, SafeCloseable {} >> >> interface SafeCloseableIterable extends Iterable >> { SafeCloseableIterator safeCloseableIterator(); } >> >> class Source implements SafeCloseableIterable { >> public SafeCloseableIterator safeCloseableIterator() { return new >> SourceIterator(); } >> >> public Iterator iterator() { return new SourceIterator(); } >> } >> >> class SourceIterator implements SafeCloseableIterator { >> private static final String[] out = { "Hello", "Hello", "World", "World" >> }; >> >> private int index = 0; >> >> public boolean hasNext() { return ( index >= 0 ) && ( index < out.length >> ); } >> >> public String next() { return out[ index++ ]; } >> >> public void remove() { throw new UnsupportedOperationException( "Not >> supported." ); } >> >> public void close() { index = -1; } >> } >> >> class FilterIterator implements SafeCloseableIterator { >> private final SafeCloseableIterator source; >> >> public FilterIterator( final Source source ) { this.source = >> source.safeCloseableIterator(); } >> >> public boolean hasNext() { >> if ( source.hasNext() ) { source.next(); } >> return source.hasNext(); >> } >> >> public String next() { return source.next(); } >> >> public void remove() { source.remove(); } >> >> public void close() { source.close(); } >> } >> >> class Filter implements SafeCloseableIterable { >> private final Source source; >> >> public Filter( final Source source ) { this.source = source; } >> >> public SafeCloseableIterator safeCloseableIterator() { return new >> FilterIterator( source ); } >> >> public Iterator iterator() { return new FilterIterator( source ); } >> } >> >> public class Main { >> public static void main( final String[] notUsed ) { >> final Filter filter = new Filter( new Source() ); >> for ( final String s : filter ) { System.out.println( s ); } >> final SafeCloseableIterator i = >> filter.safeCloseableIterator(); >> try { >> while ( i.hasNext() ) { >> final String s = i.next(); >> System.out.println( s ); >> } >> } finally { i.close(); } >> } >> } >> >> >> 2009/11/12 Howard Lovatt >> >>> Reinier has raised a good point that you start with a CloseableIterable >>> and end up with just an Iterable, this loosing of the Cloaseable type hasn't >>> happened in my code (because I am looking for the problem). I can see that >>> it would happen in other peoples code and also by mistake. I think this >>> problem is solved by using: >>> >>> try(final String line : iterableFile) { >>> ... >>> } >>> >>> The above try-for-each block will fail at compile time if iterableFile >>> isn't of type CloseableIterable. >>> >>> Secondly, and more controversially, the for-each loop could fail at >>> compile time if given a CloseableIteratable as opposed to a normal Iterable. >>> >>> 2009/11/11 Reinier Zwitserloot >>> >>>> The problem is: If you forget to retrofit a filter, or you're just using >>>> one written with java6 or below in mind, then there's no obvious sign that >>>> your resource is not being closed. No compiler error or warning. Not even a >>>> pattern in the code you can detect. You'll notice a month later, when you've >>>> released your product to your customers, who are starting to call in with >>>> strange errors involving full DB pools and such. The fix is to write up a >>>> custom findbugs plugin, or something similar. Given the way findbugs is not >>>> even close to universally used, let alone used with custom plugins, that is >>>> not at all a satisfactory answer. >>>> >>>> That's a very serious problem. >>>> >>>> --Reinier Zwitserloot >>>> >>>> >>>> >>>> >>>> On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter wrote: >>>> >>>>> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot < >>>>> reinier at zwitserloot.com> wrote: >>>>> >>>>>> Unless all existing filters are rewritten to support Closeable, and >>>>>> their close methods do an instanceof check on the contained Iterator and >>>>>> pass on the close call if they are also ClosableIterators, I don't see how >>>>>> that's going to work. >>>>> >>>>> >>>>> That sounds like a workable approach. >>>>> >>>>> >>>> >>>> ______________________________________________________________________ >>>> This email has been scanned by the MessageLabs Email Security System. >>>> For more information please visit http://www.messagelabs.com/email >>>> ______________________________________________________________________ >>>> >>> >>> >>> >>> -- >>> -- Howard. >>> >> >> >> >> -- >> -- Howard. >> > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. From howard.lovatt at iee.org Mon Nov 23 11:30:10 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 20:30:10 +0100 Subject: Closures, too much or too little? In-Reply-To: <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> Message-ID: <3dd3f56a0911231130r2a0d8dc4mbcad422fdd4e4954@mail.gmail.com> I would support override as a mandatory keyword, it works well for me in Scala. However I doubt that this will ever be a big enough priority. 2009/11/23 > Hi Howard, > > you can argue similarly for example in case of method overriding and > overloading and suggest to add the "override" and "overload" keywords. I > do not mind if the "shared" or "public" keyword is mandatory in this case. > However, mandatory annotation is odd for me. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > http://kenai.com/projects/refactoringng - refactoring tool for compiler > guys > > > Howard Lovatt napsal(a): > > Hi Zdenek, > > > > The following example from Josh Bloch illustrates why I would rather > > writable captured variables generate an error if you miss off @Shared: > > > > public class Test { > > > > private static final int N = 10; > > > > public static void main(String[] args) { > > > > List<{ => int}> closures = new ArrayList<{ => int}>(); > > > > for (int i = 0; i < N; i++) > > > > closures.add( { => i } ); > > > > int total = 0; > > > > for ({ => int} closure : closures) > > > > total += closure.invoke(); > > > > System.out.println(total); > > > > } > > > > } > > > > This example is almost certainly an error; therefore I feel a warning is > > insufficient, much like "int i = 2.0;" is almost certainly an error and I > > would find a warning insufficient for this too. To me the warnings that > > are > > in Java currently are all dubious; they are just a fudge because of some > > other problem, e.g. erasure. > > > > With regard to annotations, if people really like the concept that an > > annotation should not be like a keyword then make shared a keyword (I am > > happy either way). I think Josh Bloch has suggested reusing public, but I > > would prefer either shared or @Shared. > > > > -- Howard. > > > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. From howard.lovatt at iee.org Mon Nov 23 11:36:30 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Nov 2009 20:36:30 +0100 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911230940s608f3d6cx6a6d4c971cd790ed@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <560fb5ed0911230940s608f3d6cx6a6d4c971cd790ed@mail.gmail.com> Message-ID: <3dd3f56a0911231136w37243265wc67609c642a057ae@mail.gmail.com> I would support @Shared either as a keyword of annotation to be adding to the whole language so that the current inner classes and any new inner class/closure construct could use it. I wouldn't support adding @Shared just for a new construct and not including current inner classes. As for auto-final, no strong feelings (I almost exclusively use final anyway). -- Howard. 2009/11/23 Reinier Zwitserloot > auto-final can be combined with @Shared (with @Shared being one option when > you access a mutating variable from outer scope), though once auto-final is > in place, I don't think @Shared is a make-or-break kind of issue with > closures. > > > As mark mentioned, it DOES happen though (probably will happen a lot more, > when closures are added in JDK7), and people use a number of different > solutions to get around this. This is a bad thing. I've seen arrays, I've > seen AtomicReference and friends, and I've seen hand-rolled Pointer classes. > I've even used all 3, though I've standardized myself on always using an > Atomic* for it, whether or not I actually need the atomicity. > > Is there any pragmatic argument AGAINST adding @Shared to the language, > other than "Any feature should prove why we have to add it, not why we > shouldn't", and hazy concerns about keywordishness, which seems like a taste > fight, not an actual discussion, not to mention solvable by replacing > "@Shared" with public. > > My personal preference lies in auto-final *AND* @Shared. > > --Reinier Zwitserloot > > On Mon, Nov 23, 2009 at 5:18 PM, Joshua Bloch wrote: > >> I'm still not convinced that it's a good idea to allow closure to capture >> shared local variables. I do (still) like the idea of "auto-finalization" >> (i.e., it's OK for a closure or anonymous class instance creation >> expression) to reference a local variable that's not explicitly labeled >> final if DU/DA-style analysis shows it to be effectively final. I suspect >> this is the sweet spot. >> >> Josh >> >> >> On Mon, Nov 23, 2009 at 7:58 AM, wrote: >> >> > Hi Howard, >> > >> > you can argue similarly for example in case of method overriding and >> > overloading and suggest to add the "override" and "overload" keywords. I >> > do not mind if the "shared" or "public" keyword is mandatory in this >> case. >> > However, mandatory annotation is odd for me. >> > >> > Z. >> > -- >> > Zdenek Tronicek >> > FIT CTU in Prague >> > http://kenai.com/projects/refactoringng - refactoring tool for compiler >> > guys >> > >> > >> > Howard Lovatt napsal(a): >> > > Hi Zdenek, >> > > >> > > The following example from Josh Bloch illustrates why I would rather >> > > writable captured variables generate an error if you miss off @Shared: >> > > >> > > public class Test { >> > > >> > > private static final int N = 10; >> > > >> > > public static void main(String[] args) { >> > > >> > > List<{ => int}> closures = new ArrayList<{ => int}>(); >> > > >> > > for (int i = 0; i < N; i++) >> > > >> > > closures.add( { => i } ); >> > > >> > > int total = 0; >> > > >> > > for ({ => int} closure : closures) >> > > >> > > total += closure.invoke(); >> > > >> > > System.out.println(total); >> > > >> > > } >> > > >> > > } >> > > >> > > This example is almost certainly an error; therefore I feel a warning >> is >> > > insufficient, much like "int i = 2.0;" is almost certainly an error >> and I >> > > would find a warning insufficient for this too. To me the warnings >> that >> > > are >> > > in Java currently are all dubious; they are just a fudge because of >> some >> > > other problem, e.g. erasure. >> > > >> > > With regard to annotations, if people really like the concept that an >> > > annotation should not be like a keyword then make shared a keyword (I >> am >> > > happy either way). I think Josh Bloch has suggested reusing public, >> but I >> > > would prefer either shared or @Shared. >> > > >> > > -- Howard. >> > > >> > >> > >> > >> >> > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > -- -- Howard. From tronicek at fit.cvut.cz Mon Nov 23 11:37:59 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 20:37:59 +0100 Subject: Closures, too much or too little? In-Reply-To: <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> Message-ID: <6f1a14d95bf3f5a706992a598a18e637.squirrel@imap.fit.cvut.cz> > So for me, a more practical variation of "auto-finalization" would be that > the variable only 'becomes' final at the point in the code where the > closure appears. What you mean by "becoming final"? Do you propose to flush all the (non-final) variables, which are used in the closure, to the shared memory at the point where this closure is declared? Z. -- Zdenek Tronicek FIT CTU in Prague http://kenai.com/projects/refactoringng - refactoring tool for compiler guys Mark Mahieu napsal(a): > On 23 Nov 2009, at 16:18, Joshua Bloch wrote: > >> I'm still not convinced that it's a good idea to allow closure to >> capture >> shared local variables. I do (still) like the idea of >> "auto-finalization" >> (i.e., it's OK for a closure or anonymous class instance creation >> expression) to reference a local variable that's not explicitly labeled >> final if DU/DA-style analysis shows it to be effectively final. I >> suspect >> this is the sweet spot. >> >> Josh > > > A good proportion of the annoying cases I encounter with anonymous classes > accessing local variables look like this: > > int total = 0; > for (...) { > total += something; > } > // done with updating total > > final int finalTotal = total; // annoying > doSomething(new Whatever() { > public void execute() { > // read finalTotal > } > }); > > > So for me, a more practical variation of "auto-finalization" would be that > the variable only 'becomes' final at the point in the code where the > closure appears. In the above example, I'd even consider it an > improvement if I had to (and could) explicitly redeclare 'total' as final. > > > The other thorny side to all this occurs when the closure actually does > want to update the local variable, as you know. If we don't go some way > to making that less awkward, people will continue to use the same > workarounds they always have, which also have their costs. > > Personally, I quite liked the way that public/@Shared called out the > variables as deserving special attention. > > > Regards, > > Mark > > > > > From tim at peierls.net Mon Nov 23 12:02:06 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 23 Nov 2009 15:02:06 -0500 Subject: closures after all? In-Reply-To: <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201547t5e731d16w1d409d08de73cd5d@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> Message-ID: <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> On Mon, Nov 23, 2009 at 12:44 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > I'll readily admit that any change that is bound to give you more options > in API design is likely to tickle (in a bad way) the sense of perfection of > any API designer, in that they'll want to revisit their existing stuff. But > that's an entirely different beast from complicating or simplifying the work > of someone building new API -from scratch-. The benefits of having more options are obvious. The problem with having more options is that the would-be designer of a new, from-scratch API now has to evaluate more alternatives during the design process: Do I use function types here? Do I use interfaces? Should I do it all with abstract classes? Serious evaluation of an approach probably involves sketching it out, presenting it to a few people and getting feedback, or at least having extended conversations about it. A designer who says, "Clearly using whizbang feature X here is far superior to any other approach, so I won't waste my time considering anything else," is not thinking about the users and might as well be saying, "Users? I understand users so well that I don't have to talk to them." Here's an imperfect but suggestive analogy: More options in the treatment of a disease might offer hope to millions, but the physician's job is harder because she has to evaluate more options in the context of each patient. She might be glad to be able to offer her patients a promising new therapy, but she is working longer hours (or seeing fewer patients). Here's another: The addition of a new instrument when scoring a musical theater piece broadens the palette of available colors. The orchestrator is probably pleased when the producers cough up the extra dough for the player, because now he can achieve certain effects more easily, but he also knows that he'll be working harder -- it's another part to write. (But he's getting paid more, so he's not going to object. :-)) --tim From neal at gafter.com Mon Nov 23 12:35:59 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 23 Nov 2009 12:35:59 -0800 Subject: closures after all? In-Reply-To: <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> Message-ID: <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> On Mon, Nov 23, 2009 at 12:02 PM, Tim Peierls wrote: > Here's an imperfect but suggestive analogy: More options in the treatment > of a disease might offer hope to millions, but the physician's job is harder > because she has to evaluate more options in the context of each patient. She > might be glad to be able to offer her patients a promising new therapy, but > she is working longer hours (or seeing fewer patients). > Doctors can do better by their patients by investing more time, with or without new techniques. On the other hand, she may be able to save more lives with the same effort by taking advantage of the new techniques. That seems to be the way it works in practice. Here's another: The addition of a new instrument when scoring a musical > theater piece broadens the palette of available colors. The orchestrator is > probably pleased when the producers cough up the extra dough for the player, > because now he can achieve certain effects more easily, but he also knows > that he'll be working harder -- it's another part to write. (But he's > getting paid more, so he's not going to object. :-)) > The ochestrator can do a better job by investing more time with or without new instruments. On the other hand, he may be able to better achieve his goals with the same cost and effort by taking advantage of a new instrument in place of a more traditional one. Cheers, Neal From markmahieu at googlemail.com Mon Nov 23 12:36:47 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 23 Nov 2009 20:36:47 +0000 Subject: Closures, too much or too little? In-Reply-To: <6f1a14d95bf3f5a706992a598a18e637.squirrel@imap.fit.cvut.cz> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> <6f1a14d95bf3f5a706992a598a18e637.squirrel@imap.fit.cvut.cz> Message-ID: On 23 Nov 2009, at 19:37, tronicek at fit.cvut.cz wrote: > >> So for me, a more practical variation of "auto-finalization" would be that >> the variable only 'becomes' final at the point in the code where the >> closure appears. > > What you mean by "becoming final"? Do you propose to flush all the > (non-final) variables, which are used in the closure, to the shared memory > at the point where this closure is declared? More musing on than proposing, but I'm suggesting that it's common for the local variable to only initially want to be mutable, whilst I'm in the process of setting up its value. After that's done with, I'd currently need to assign it to a final variable if I want to use its value in an anonymous class, which is annoying, even though (in my 'common' example) I make no attempt to assign to it again in the method, nor in any anonymous class (or closure) that references it. So I'm wondering whether there's a sensible (and clear) rule which would allow the compiler to do that 'annoying part' for me when necessary, such that: int count = 0; count++; // ok, obviously // count 'becomes' final about here Runnable r = #() { doSomethingWith(count); }; // still ok, not trying to assign to it count++; // compiler error - "Can't assign to variable 'count' after use in closure blah blah" It's kinda like the "auto-finalization" that Josh referred to, but deferring the "finalization" part until it's actually needed ('needed' being highly subjective, admittedly). Dunno. Mark From tronicek at fit.cvut.cz Mon Nov 23 12:38:46 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 23 Nov 2009 21:38:46 +0100 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911230940s608f3d6cx6a6d4c971cd790ed@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <142ab2eb-f3fa-4999-927b-92f3faef4788@p35g2000yqh.googlegroups.com> <4650e4ba-c71f-4a65-a9b7-1a81d7a04609@u1g2000pre.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <560fb5ed0911230940s608f3d6cx6a6d4c971cd790ed@mail.gmail.com> Message-ID: <4aa318ec60b8d99a01e19c78cd3db4fd.squirrel@imap.fit.cvut.cz> Hi Reinier, you are asking for logical arguments where there are rarely any. Design of a new language feature (or a new language) is always a matter of taste. For example, if I propose to extend operator = for array so that int[] p = []42; initializes all the elements to 42, will you find any "pragmatic argument" against? We can discuss if it useful or not. Then Josh may say "yeah, we need it! we have many arrays at Google", Joseph "I like the for loop more" and Howard may ask for annotation @Expensive. And you, as a designer, you either like it or not. But "pragmatic arguments" against? Z. -- Zdenek Tronicek FIT CTU in Prague http://kenai.com/projects/refactoringng - refactoring tool for compiler guys Reinier Zwitserloot napsal(a): > auto-final can be combined with @Shared (with @Shared being one option > when > you access a mutating variable from outer scope), though once auto-final > is > in place, I don't think @Shared is a make-or-break kind of issue with > closures. > > > As mark mentioned, it DOES happen though (probably will happen a lot more, > when closures are added in JDK7), and people use a number of different > solutions to get around this. This is a bad thing. I've seen arrays, I've > seen AtomicReference and friends, and I've seen hand-rolled Pointer > classes. > I've even used all 3, though I've standardized myself on always using an > Atomic* for it, whether or not I actually need the atomicity. > > Is there any pragmatic argument AGAINST adding @Shared to the language, > other than "Any feature should prove why we have to add it, not why we > shouldn't", and hazy concerns about keywordishness, which seems like a > taste > fight, not an actual discussion, not to mention solvable by replacing > "@Shared" with public. > > My personal preference lies in auto-final *AND* @Shared. > > --Reinier Zwitserloot > > On Mon, Nov 23, 2009 at 5:18 PM, Joshua Bloch wrote: > >> I'm still not convinced that it's a good idea to allow closure to >> capture >> shared local variables. I do (still) like the idea of >> "auto-finalization" >> (i.e., it's OK for a closure or anonymous class instance creation >> expression) to reference a local variable that's not explicitly labeled >> final if DU/DA-style analysis shows it to be effectively final. I >> suspect >> this is the sweet spot. >> >> Josh >> >> On Mon, Nov 23, 2009 at 7:58 AM, wrote: >> >> > Hi Howard, >> > >> > you can argue similarly for example in case of method overriding and >> > overloading and suggest to add the "override" and "overload" keywords. >> I >> > do not mind if the "shared" or "public" keyword is mandatory in this >> case. >> > However, mandatory annotation is odd for me. >> > >> > Z. >> > -- >> > Zdenek Tronicek >> > FIT CTU in Prague >> > http://kenai.com/projects/refactoringng - refactoring tool for >> compiler >> > guys >> > >> > >> > Howard Lovatt napsal(a): >> > > Hi Zdenek, >> > > >> > > The following example from Josh Bloch illustrates why I would rather >> > > writable captured variables generate an error if you miss off >> @Shared: >> > > >> > > public class Test { >> > > >> > > private static final int N = 10; >> > > >> > > public static void main(String[] args) { >> > > >> > > List<{ => int}> closures = new ArrayList<{ => int}>(); >> > > >> > > for (int i = 0; i < N; i++) >> > > >> > > closures.add( { => i } ); >> > > >> > > int total = 0; >> > > >> > > for ({ => int} closure : closures) >> > > >> > > total += closure.invoke(); >> > > >> > > System.out.println(total); >> > > >> > > } >> > > >> > > } >> > > >> > > This example is almost certainly an error; therefore I feel a >> warning >> is >> > > insufficient, much like "int i = 2.0;" is almost certainly an error >> and >> I >> > > would find a warning insufficient for this too. To me the warnings >> that >> > > are >> > > in Java currently are all dubious; they are just a fudge because of >> some >> > > other problem, e.g. erasure. >> > > >> > > With regard to annotations, if people really like the concept that >> an >> > > annotation should not be like a keyword then make shared a keyword >> (I >> am >> > > happy either way). I think Josh Bloch has suggested reusing public, >> but >> I >> > > would prefer either shared or @Shared. >> > > >> > > -- Howard. >> > > >> > >> > >> > >> >> > > From tim at peierls.net Mon Nov 23 13:30:03 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 23 Nov 2009 16:30:03 -0500 Subject: closures after all? In-Reply-To: <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> Message-ID: <63b4e4050911231330l5e906d89wdaba5a05b07aaaee@mail.gmail.com> On Mon, Nov 23, 2009 at 3:35 PM, Neal Gafter wrote: > On Mon, Nov 23, 2009 at 12:02 PM, Tim Peierls wrote: > >> Here's an imperfect but suggestive analogy: More options in the treatment >> of a disease might offer hope to millions, but the physician's job is harder >> because she has to evaluate more options in the context of each patient. She >> might be glad to be able to offer her patients a promising new therapy, but >> she is working longer hours (or seeing fewer patients). >> > > Doctors can do better by their patients by investing more time, with or > without new techniques. On the other hand, she may be able to save more > lives with the same effort by taking advantage of the new techniques. That > seems to be the way it works in practice. > Not the way the physicians I know talk about it. A new technique can be a great boon, but in practice it means more work for physicians. My wife, a physician, reacts to each new development with deep ambivalence: it's wonderful to have that new option, but now she has more to learn, and her list of things to check off for each patient just got that much longer. OTOH, she's terrible at API design. :-) > Here's another: The addition of a new instrument when scoring a musical >> theater piece broadens the palette of available colors. The orchestrator is >> probably pleased when the producers cough up the extra dough for the player, >> because now he can achieve certain effects more easily, but he also knows >> that he'll be working harder -- it's another part to write. (But he's >> getting paid more, so he's not going to object. :-)) >> > > The ochestrator can do a better job by investing more time with or without > new instruments. On the other hand, he may be able to better achieve his > goals with the same cost and effort by taking advantage of a new instrument > in place of a more traditional one. > Another part to write is another part to write, no matter how desirable the resulting sound. Much as I love being able to add drums to a plain piano part, because it makes it easier to get the rhythms across to the actors in performance, it's a *lot* of work, so much that every time I do it I think, "Hmm, how badly do I want drums in this song?" But getting back to the point: Neal and Reinier, you're working very hard to argue something general and hard to support -- that new language features don't mean more work for API designers -- when you should be arguing that a particular feature is *worth* the extra work. That's the important question. It's hard to engage in a meaningful discussion of costs and benefits if you don't acknowledge the possibility of costs. And while I don't think ParallelArray is a compelling case for function types over named interfaces based on my experience, I'm interested in hearing about other people's experiences with it, and I certainly think it's worth investigating other applications of function types that might prove more compelling. --tim From kevinb at google.com Mon Nov 23 14:36:47 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Mon, 23 Nov 2009 14:36:47 -0800 Subject: closures after all? In-Reply-To: <63b4e4050911231330l5e906d89wdaba5a05b07aaaee@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> <15e8b9d20911231235v7bc56d1dp614da379e2189133@mail.gmail.com> <63b4e4050911231330l5e906d89wdaba5a05b07aaaee@mail.gmail.com> Message-ID: <108fcdeb0911231436h7790ea65l48e9388afe1a42e7@mail.gmail.com> Hello everyone, I have a particular interest in the current debate (over the potential deleterious effects of closures on APIs) as the person who, a few years ago, introduced the Function and Predicate interfaces into Google's internal codebase. To be sure, these have been useful, and we've found many great uses for them. I've also seen too many completely appalling usages of them to count. To give just one example, I once came across a class whose constructor required two Functions and Predicate, on various types, storing those in fields, and whose documentation (of course) quite glossed over the finer details of their semantics. So I asked the author, "why do it this way -- wouldn't it be more natural to just define three abstract methods, with regular old javadoc and the whole bit -- or define an interface with these three methods, to be passed in? Logically, it could be named Xxx, and that helps users understand what it's really all about." His response? "Oh, I hadn't thought of that! You're right, it's totally better that way." ::headdesk:: I think I went home early that day. But this wasn't an isolated incident. This kind of thing happens a LOT. Most developers, by FAR, do not really put conscious thought into the art of API design. Their job is usually to implement a feature, which requires them to make small changes at many different layers of the system -- so every API boundary they touch is one where they are both the implementor and the consumer. It doesn't feel too important to them how exactly they choose to talk to *themselves*. So they walk the path of least resistance. If their first thought is, "I need a way to get from a Foo to a Bar," then their second thought is, "ahh, that's a Function then!" When you consider how bloated and boilerplate-laden these Function and Predicate incantations are, then you can only conclude that this will be happening at a much greater scale once closures are here. Give me a shiny new hammer, and suddenly everything I see looks like a nail! Is potential for abuse alone ever a sufficient argument for killing a feature? Definitely not. And I'm not even opposed to this new closures proposal (such as I understand it); I think it will probably make a lot of code better. I do, however, think it is easily within the realm of possibility that it will make even more code worse. Lawrence is explaining some the reasons very well in this thread. My two cents. On Mon, Nov 23, 2009 at 1:30 PM, Tim Peierls wrote: > On Mon, Nov 23, 2009 at 3:35 PM, Neal Gafter wrote: > > > On Mon, Nov 23, 2009 at 12:02 PM, Tim Peierls wrote: > > > >> Here's an imperfect but suggestive analogy: More options in the > treatment > >> of a disease might offer hope to millions, but the physician's job is > harder > >> because she has to evaluate more options in the context of each patient. > She > >> might be glad to be able to offer her patients a promising new therapy, > but > >> she is working longer hours (or seeing fewer patients). > >> > > > > Doctors can do better by their patients by investing more time, with or > > without new techniques. On the other hand, she may be able to save more > > lives with the same effort by taking advantage of the new techniques. > That > > seems to be the way it works in practice. > > > > Not the way the physicians I know talk about it. A new technique can be a > great boon, but in practice it means more work for physicians. My wife, a > physician, reacts to each new development with deep ambivalence: it's > wonderful to have that new option, but now she has more to learn, and her > list of things to check off for each patient just got that much longer. > > OTOH, she's terrible at API design. :-) > > > > > Here's another: The addition of a new instrument when scoring a musical > >> theater piece broadens the palette of available colors. The orchestrator > is > >> probably pleased when the producers cough up the extra dough for the > player, > >> because now he can achieve certain effects more easily, but he also > knows > >> that he'll be working harder -- it's another part to write. (But he's > >> getting paid more, so he's not going to object. :-)) > >> > > > > The ochestrator can do a better job by investing more time with or > without > > new instruments. On the other hand, he may be able to better achieve his > > goals with the same cost and effort by taking advantage of a new > instrument > > in place of a more traditional one. > > > > Another part to write is another part to write, no matter how desirable the > resulting sound. Much as I love being able to add drums to a plain piano > part, because it makes it easier to get the rhythms across to the actors in > performance, it's a *lot* of work, so much that every time I do it I think, > "Hmm, how badly do I want drums in this song?" > > But getting back to the point: Neal and Reinier, you're working very hard > to > argue something general and hard to support -- that new language features > don't mean more work for API designers -- when you should be arguing that a > particular feature is *worth* the extra work. That's the important > question. > It's hard to engage in a meaningful discussion of costs and benefits if you > don't acknowledge the possibility of costs. > > And while I don't think ParallelArray is a compelling case for function > types over named interfaces based on my experience, I'm interested in > hearing about other people's experiences with it, and I certainly think > it's > worth investigating other applications of function types that might prove > more compelling. > > --tim > > -- Kevin Bourrillion @ Google internal: http://go/javalibraries external: guava-libraries.googlecode.com From reinier at zwitserloot.com Mon Nov 23 14:51:10 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Nov 2009 23:51:10 +0100 Subject: closures after all? In-Reply-To: <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <997cab100911201635o3e682401k81ca9c9340a5aa37@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> Message-ID: <560fb5ed0911231451o335c408bmc8ee2f3d7d3680a2@mail.gmail.com> We should invent a new rule: When you start equating language design to random real-world contrived examples, you lose. I can come up with a zillion analogies in favour of any programming language design argument. Let's instead agree not to foist such analogies on each other. Can you perhaps contribute something of more useful substance? I mentioned that having to use existing techniques in rather creative ways in order to force your API to be somewhat more usable is far inferior and far more complicated compared to using existing + new techniques in their standard, designed for, fashion, in order to get an API which is even more usable, and where your API users don't have to first figure out what kind of creative insanity you've uncovered. So far you've done nothing to counter this particular argument aside from repeating your previous argument but this time with frivolous analogy attached. Unless you want to argue that there are actual alternatives to offering a SAM type or closure in API design, I suggest we drop this notion that adding closures is somehow going to complicate API design. It's codifying a practice we already have. Like Runnable.run, and ActionListener.onAction. We're not inventing rocket science here. On Mon, Nov 23, 2009 at 9:02 PM, Tim Peierls wrote: > On Mon, Nov 23, 2009 at 12:44 PM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > >> I'll readily admit that any change that is bound to give you more options >> in API design is likely to tickle (in a bad way) the sense of perfection of >> any API designer, in that they'll want to revisit their existing stuff. But >> that's an entirely different beast from complicating or simplifying the work >> of someone building new API -from scratch-. > > > The benefits of having more options are obvious. The problem with having > more options is that the would-be designer of a new, from-scratch API now > has to evaluate more alternatives during the design process: Do I use > function types here? Do I use interfaces? Should I do it all with abstract > classes? Serious evaluation of an approach probably involves sketching it > out, presenting it to a few people and getting feedback, or at least having > extended conversations about it. A designer who says, "Clearly using > whizbang feature X here is far superior to any other approach, so I won't > waste my time considering anything else," is not thinking about the users > and might as well be saying, "Users? I understand users so well that I don't > have to talk to them." > > Here's an imperfect but suggestive analogy: More options in the treatment > of a disease might offer hope to millions, but the physician's job is harder > because she has to evaluate more options in the context of each patient. She > might be glad to be able to offer her patients a promising new therapy, but > she is working longer hours (or seeing fewer patients). > > Here's another: The addition of a new instrument when scoring a musical > theater piece broadens the palette of available colors. The orchestrator is > probably pleased when the producers cough up the extra dough for the player, > because now he can achieve certain effects more easily, but he also knows > that he'll be working harder -- it's another part to write. (But he's > getting paid more, so he's not going to object. :-)) > > --tim > From tim at peierls.net Mon Nov 23 14:59:25 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 23 Nov 2009 17:59:25 -0500 Subject: closures after all? In-Reply-To: <560fb5ed0911231451o335c408bmc8ee2f3d7d3680a2@mail.gmail.com> References: <855b507d0911180747o3b4f9099icb6e0aa79ca36ce4@mail.gmail.com> <15e8b9d20911201650o1d0375dau9d5ae7998e5e8474@mail.gmail.com> <63b4e4050911202124p584ba562pbfb856cc8e37c5d@mail.gmail.com> <560fb5ed0911210844v93e7830t71d6136bcfe30c61@mail.gmail.com> <63b4e4050911211352pefb9cdaid9d6574d885fa95f@mail.gmail.com> <560fb5ed0911211546q78addf6w96ddb9df9e0525d5@mail.gmail.com> <63b4e4050911230743w51ad619clb78d3b5621210f84@mail.gmail.com> <560fb5ed0911230944j52f0cfc2g5692386ee537e2d3@mail.gmail.com> <63b4e4050911231202x3454427fk3d088adb20e62743@mail.gmail.com> <560fb5ed0911231451o335c408bmc8ee2f3d7d3680a2@mail.gmail.com> Message-ID: <63b4e4050911231459i4c055156y5b1c60adf7e08e71@mail.gmail.com> I think the one of the existing rules is not to be nasty. Care to rephrase? --tim On Mon, Nov 23, 2009 at 5:51 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > We should invent a new rule: When you start equating language design to > random real-world contrived examples, you lose. I can come up with a zillion > analogies in favour of any programming language design argument. Let's > instead agree not to foist such analogies on each other. > > Can you perhaps contribute something of more useful substance? I mentioned > that having to use existing techniques in rather creative ways in order to > force your API to be somewhat more usable is far inferior and far more > complicated compared to using existing + new techniques in their standard, > designed for, fashion, in order to get an API which is even more usable, and > where your API users don't have to first figure out what kind of creative > insanity you've uncovered. So far you've done nothing to counter this > particular argument aside from repeating your previous argument but this > time with frivolous analogy attached. > > Unless you want to argue that there are actual alternatives to offering a > SAM type or closure in API design, I suggest we drop this notion that adding > closures is somehow going to complicate API design. It's codifying a > practice we already have. Like Runnable.run, and ActionListener.onAction. > We're not inventing rocket science here. > > On Mon, Nov 23, 2009 at 9:02 PM, Tim Peierls wrote: > >> On Mon, Nov 23, 2009 at 12:44 PM, Reinier Zwitserloot < >> reinier at zwitserloot.com> wrote: >> >>> I'll readily admit that any change that is bound to give you more options >>> in API design is likely to tickle (in a bad way) the sense of perfection of >>> any API designer, in that they'll want to revisit their existing stuff. But >>> that's an entirely different beast from complicating or simplifying the work >>> of someone building new API -from scratch-. >> >> >> The benefits of having more options are obvious. The problem with having >> more options is that the would-be designer of a new, from-scratch API now >> has to evaluate more alternatives during the design process: Do I use >> function types here? Do I use interfaces? Should I do it all with abstract >> classes? Serious evaluation of an approach probably involves sketching it >> out, presenting it to a few people and getting feedback, or at least having >> extended conversations about it. A designer who says, "Clearly using >> whizbang feature X here is far superior to any other approach, so I won't >> waste my time considering anything else," is not thinking about the users >> and might as well be saying, "Users? I understand users so well that I don't >> have to talk to them." >> >> Here's an imperfect but suggestive analogy: More options in the treatment >> of a disease might offer hope to millions, but the physician's job is harder >> because she has to evaluate more options in the context of each patient. She >> might be glad to be able to offer her patients a promising new therapy, but >> she is working longer hours (or seeing fewer patients). >> >> Here's another: The addition of a new instrument when scoring a musical >> theater piece broadens the palette of available colors. The orchestrator is >> probably pleased when the producers cough up the extra dough for the player, >> because now he can achieve certain effects more easily, but he also knows >> that he'll be working harder -- it's another part to write. (But he's >> getting paid more, so he's not going to object. :-)) >> >> --tim >> > > From reinier at zwitserloot.com Mon Nov 23 15:40:34 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 24 Nov 2009 00:40:34 +0100 Subject: Closures, too much or too little? In-Reply-To: References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> <6f1a14d95bf3f5a706992a598a18e637.squirrel@imap.fit.cvut.cz> Message-ID: <560fb5ed0911231540u7fcc5514m4d2308a176758338@mail.gmail.com> Mark, spec-wise, "turning final" is effectively equivalent to the compiler desugaring your source code snippet to: int count = 0; final int count0; count++; count0 = count; //generated Runnable r = #() {doSomethingWith(count0);}; I haven't done an exhaustive analysis, but it seems that, if such a desugaring results in legal code (e.g. the DA/DU rules don't cause an error on usage or assignment of count0), it boils down to the same thing. The key is to switch over to count0 at the right time. Neither right before closure usage, nor right after last mutation, will be suitable. Presuming a simple spec and implementation for this feature is possible, I like it. However, as far as these things go, this change doesn't seem to have all that much impact on the concept of @Shared/public variables for closures. It won't get rid of needing to mutate outer scope - plenty of closures where the closure is run inline (some sort of withLock construct, for example), and the closure needs to communicate a result back to the outer scope. Neal's basic approach is not a bad idea, though the warning should not be generated if the gist of the warning can't actually happen, and the compiler can figure this out: So, that would mean, auto-final, and probably this concept of turning final just in time for the closure as well. A bonus here is that the static analysis of code to ascertain if lack of @Shared warrants a warning/error can be deferred until JDK8 if there's time pressure. It won't be backwards incompatible to stop generating frivolous warnings. --Reinier Zwitserloot NB: Mark, does closures-dev know about auto-final and not generating warning/error if there is no mutation after the closure is defined? On Mon, Nov 23, 2009 at 9:36 PM, Mark Mahieu wrote: > On 23 Nov 2009, at 19:37, tronicek at fit.cvut.cz wrote: > > > > >> So for me, a more practical variation of "auto-finalization" would be > that > >> the variable only 'becomes' final at the point in the code where the > >> closure appears. > > > > What you mean by "becoming final"? Do you propose to flush all the > > (non-final) variables, which are used in the closure, to the shared > memory > > at the point where this closure is declared? > > More musing on than proposing, but I'm suggesting that it's common for the > local variable to only initially want to be mutable, whilst I'm in the > process of setting up its value. After that's done with, I'd currently need > to assign it to a final variable if I want to use its value in an anonymous > class, which is annoying, even though (in my 'common' example) I make no > attempt to assign to it again in the method, nor in any anonymous class (or > closure) that references it. > > So I'm wondering whether there's a sensible (and clear) rule which would > allow the compiler to do that 'annoying part' for me when necessary, such > that: > > int count = 0; > count++; // ok, obviously > > // count 'becomes' final about here > Runnable r = #() { doSomethingWith(count); }; // still ok, not trying to > assign to it > > count++; // compiler error - "Can't assign to variable 'count' after use > in closure blah blah" > > > It's kinda like the "auto-finalization" that Josh referred to, but > deferring the "finalization" part until it's actually needed ('needed' being > highly subjective, admittedly). > > Dunno. > > Mark > > > From reinier at zwitserloot.com Mon Nov 23 15:47:11 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 24 Nov 2009 00:47:11 +0100 Subject: Closures, too much or too little? In-Reply-To: <4aa318ec60b8d99a01e19c78cd3db4fd.squirrel@imap.fit.cvut.cz> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <3dd3f56a0911221220i1575ea62x3e57fa1d7c1b67ca@mail.gmail.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <560fb5ed0911230940s608f3d6cx6a6d4c971cd790ed@mail.gmail.com> <4aa318ec60b8d99a01e19c78cd3db4fd.squirrel@imap.fit.cvut.cz> Message-ID: <560fb5ed0911231547j4d6ecf3ewcdb960fdf7ffb827@mail.gmail.com> Plenty of pragmatic counter arguments to your hypothetical: 1. It looks confusing. Testable empirically by showing random programmers off the street "int[] p = []42;" and asking them if they have any idea about what that could possibly do. 2. It's meaningless; arrays in java need a size, and = assigns a new one to the left hand side, so where's the total capacity of this thing? I presume you meant to write "int[] p = new [100]42; instead. 3. A search through existing code bases will probably reveal initializing an array with the same value throughout is a rather rare thing to do. Thus, the above code would rarely be used, which doesn't just mean it's a bad value for effort deal, but also that many programmers will be stymied when they do see this code somewhere. See C# Coalesce operator, which about 80% of all C# coders I interview don't know about. 4. A library can easily do this. In fact, a library already does: Arrays.fill! That's 4 pragmatic arguments. So, lets keep pushing for pragmatic arguments. They clearly exist. On the topic of taste: Yes, taste happens. But please recognize when you have a taste preference, and just say so: "I like using FOO as syntax here. Personal taste." - don't try to dress it up. I know most of us fail to live up to this standard, myself included, but I at least will endeavour to more rigidly apply this principle. --Reinier Zwitserloot On Mon, Nov 23, 2009 at 9:38 PM, wrote: > Hi Reinier, > > you are asking for logical arguments where there are rarely any. > Design of a new language feature (or a new language) is always a matter of > taste. For example, if I propose to extend operator = for array so that > int[] p = []42; initializes all the elements to 42, will you find any > "pragmatic argument" against? > We can discuss if it useful or not. Then Josh may say "yeah, we need it! > we have many arrays at Google", Joseph "I like the for loop more" and > Howard may ask for annotation @Expensive. And you, as a designer, you > either like it or not. But "pragmatic arguments" against? > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > http://kenai.com/projects/refactoringng - refactoring tool for compiler > guys > > > Reinier Zwitserloot napsal(a): > > auto-final can be combined with @Shared (with @Shared being one option > > when > > you access a mutating variable from outer scope), though once auto-final > > is > > in place, I don't think @Shared is a make-or-break kind of issue with > > closures. > > > > > > As mark mentioned, it DOES happen though (probably will happen a lot > more, > > when closures are added in JDK7), and people use a number of different > > solutions to get around this. This is a bad thing. I've seen arrays, I've > > seen AtomicReference and friends, and I've seen hand-rolled Pointer > > classes. > > I've even used all 3, though I've standardized myself on always using an > > Atomic* for it, whether or not I actually need the atomicity. > > > > Is there any pragmatic argument AGAINST adding @Shared to the language, > > other than "Any feature should prove why we have to add it, not why we > > shouldn't", and hazy concerns about keywordishness, which seems like a > > taste > > fight, not an actual discussion, not to mention solvable by replacing > > "@Shared" with public. > > > > My personal preference lies in auto-final *AND* @Shared. > > > > --Reinier Zwitserloot > > > > On Mon, Nov 23, 2009 at 5:18 PM, Joshua Bloch wrote: > > > >> I'm still not convinced that it's a good idea to allow closure to > >> capture > >> shared local variables. I do (still) like the idea of > >> "auto-finalization" > >> (i.e., it's OK for a closure or anonymous class instance creation > >> expression) to reference a local variable that's not explicitly labeled > >> final if DU/DA-style analysis shows it to be effectively final. I > >> suspect > >> this is the sweet spot. > >> > >> Josh > >> > >> On Mon, Nov 23, 2009 at 7:58 AM, wrote: > >> > >> > Hi Howard, > >> > > >> > you can argue similarly for example in case of method overriding and > >> > overloading and suggest to add the "override" and "overload" keywords. > >> I > >> > do not mind if the "shared" or "public" keyword is mandatory in this > >> case. > >> > However, mandatory annotation is odd for me. > >> > > >> > Z. > >> > -- > >> > Zdenek Tronicek > >> > FIT CTU in Prague > >> > http://kenai.com/projects/refactoringng - refactoring tool for > >> compiler > >> > guys > >> > > >> > > >> > Howard Lovatt napsal(a): > >> > > Hi Zdenek, > >> > > > >> > > The following example from Josh Bloch illustrates why I would rather > >> > > writable captured variables generate an error if you miss off > >> @Shared: > >> > > > >> > > public class Test { > >> > > > >> > > private static final int N = 10; > >> > > > >> > > public static void main(String[] args) { > >> > > > >> > > List<{ => int}> closures = new ArrayList<{ => int}>(); > >> > > > >> > > for (int i = 0; i < N; i++) > >> > > > >> > > closures.add( { => i } ); > >> > > > >> > > int total = 0; > >> > > > >> > > for ({ => int} closure : closures) > >> > > > >> > > total += closure.invoke(); > >> > > > >> > > System.out.println(total); > >> > > > >> > > } > >> > > > >> > > } > >> > > > >> > > This example is almost certainly an error; therefore I feel a > >> warning > >> is > >> > > insufficient, much like "int i = 2.0;" is almost certainly an error > >> and > >> I > >> > > would find a warning insufficient for this too. To me the warnings > >> that > >> > > are > >> > > in Java currently are all dubious; they are just a fudge because of > >> some > >> > > other problem, e.g. erasure. > >> > > > >> > > With regard to annotations, if people really like the concept that > >> an > >> > > annotation should not be like a keyword then make shared a keyword > >> (I > >> am > >> > > happy either way). I think Josh Bloch has suggested reusing public, > >> but > >> I > >> > > would prefer either shared or @Shared. > >> > > > >> > > -- Howard. > >> > > > >> > > >> > > >> > > >> > >> > > > > > > From markmahieu at googlemail.com Mon Nov 23 16:31:12 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 24 Nov 2009 00:31:12 +0000 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911231540u7fcc5514m4d2308a176758338@mail.gmail.com> References: <334c4f38-9971-486c-8708-949ef3855ceb@j14g2000yqm.googlegroups.com> <15e8b9d20911221222g731735c8u28b067677ed42a3d@mail.gmail.com> <3dd3f56a0911221251m66ba7983h1789212a5c9cf47c@mail.gmail.com> <3dd3f56a0911230339w3572fe5el8ee35172f9b2ac8@mail.gmail.com> <3dd3f56a0911230644n4561202fpa5427d43f9f736aa@mail.gmail.com> <20e52370558774d23721da73fc41d661.squirrel@imap.fit.cvut.cz> <17b2302a0911230818w6715f7dcr882a82fe1f30ba37@mail.gmail.com> <4E140E62-15DD-4BB5-8262-9D4F2FC73583@googlemail.com> <6f1a14d95bf3f5a706992a598a18e637.squirrel@imap.fit.cvut.cz> <560fb5ed0911231540u7fcc5514m4d2308a176758338@mail.gmail.com> Message-ID: <04141A6C-F886-48E1-AD76-509A2CBF70CE@googlemail.com> IIRC, in javac desugaring happens after DA/DU analysis, so I imagine it'd require changes to both phases. Also, flow analysis understands things like loops which would be important here. I haven't put any real thought into it though, it just feels like a slightly more comfortable half-way house for the read-only cases. But I agree it doesn't help with closures that actually want to mutate the locals, so to speak. Mark On 23 Nov 2009, at 23:40, Reinier Zwitserloot wrote: > Mark, spec-wise, "turning final" is effectively equivalent to the compiler desugaring your source code snippet to: > > int count = 0; > final int count0; > count++; > > count0 = count; //generated > Runnable r = #() {doSomethingWith(count0);}; > > > I haven't done an exhaustive analysis, but it seems that, if such a desugaring results in legal code (e.g. the DA/DU rules don't cause an error on usage or assignment of count0), it boils down to the same thing. The key is to switch over to count0 at the right time. Neither right before closure usage, nor right after last mutation, will be suitable. > > > Presuming a simple spec and implementation for this feature is possible, I like it. However, as far as these things go, this change doesn't seem to have all that much impact on the concept of @Shared/public variables for closures. It won't get rid of needing to mutate outer scope - plenty of closures where the closure is run inline (some sort of withLock construct, for example), and the closure needs to communicate a result back to the outer scope. Neal's basic approach is not a bad idea, though the warning should not be generated if the gist of the warning can't actually happen, and the compiler can figure this out: So, that would mean, auto-final, and probably this concept of turning final just in time for the closure as well. > > A bonus here is that the static analysis of code to ascertain if lack of @Shared warrants a warning/error can be deferred until JDK8 if there's time pressure. It won't be backwards incompatible to stop generating frivolous warnings. > > --Reinier Zwitserloot > > NB: Mark, does closures-dev know about auto-final and not generating warning/error if there is no mutation after the closure is defined? > > > > On Mon, Nov 23, 2009 at 9:36 PM, Mark Mahieu wrote: > On 23 Nov 2009, at 19:37, tronicek at fit.cvut.cz wrote: > > > > >> So for me, a more practical variation of "auto-finalization" would be that > >> the variable only 'becomes' final at the point in the code where the > >> closure appears. > > > > What you mean by "becoming final"? Do you propose to flush all the > > (non-final) variables, which are used in the closure, to the shared memory > > at the point where this closure is declared? > > More musing on than proposing, but I'm suggesting that it's common for the local variable to only initially want to be mutable, whilst I'm in the process of setting up its value. After that's done with, I'd currently need to assign it to a final variable if I want to use its value in an anonymous class, which is annoying, even though (in my 'common' example) I make no attempt to assign to it again in the method, nor in any anonymous class (or closure) that references it. > > So I'm wondering whether there's a sensible (and clear) rule which would allow the compiler to do that 'annoying part' for me when necessary, such that: > > int count = 0; > count++; // ok, obviously > > // count 'becomes' final about here > Runnable r = #() { doSomethingWith(count); }; // still ok, not trying to assign to it > > count++; // compiler error - "Can't assign to variable 'count' after use in closure blah blah" > > > It's kinda like the "auto-finalization" that Josh referred to, but deferring the "finalization" part until it's actually needed ('needed' being highly subjective, admittedly). > > Dunno. > > Mark > > > From markmahieu at googlemail.com Tue Nov 24 03:04:28 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 24 Nov 2009 11:04:28 +0000 Subject: Closures, too much or too little? In-Reply-To: References: Message-ID: <4DB9307E-E910-4053-8363-2C3A28424B59@googlemail.com> Yep, that's what I meant by the variable (count) 'becoming final'; the second count++ would cause a compiler error. Same deal here, as flow analysis would indicate that n is mutated 'after' being used in the closure: for (int n = 1; n <= 10; n++) { someList.add(#() n); // compile error } Mark On 24 Nov 2009, at 09:56, Roel Spilker wrote: > One more thing. If there is a write to count after the assignment to count0, the compiler should give at least a warning. Otherwise the reader of this code could thing the closure would see the modification if the closure is used after the modification. > > int count = 0; > count++; > Runnable r = #() {doSomethingWith(count);}; > count++; > r.run(); > > would desugar to > > int count = 0; > count++; > final int count0 = count; // generated > Runnable r = #() {doSomethingWith(count0);}; > count++; > r.run(); > > In this scenario, I'd like to get an error or at least a warning that count is modified after the final variable has been assigned. > > Roel > > > -----Oorspronkelijk bericht----- > Van: reinier at zwitserloot.com [mailto:coin-dev-bounces at openjdk.java.net] Namens Reinier Zwitserloot > Verzonden: dinsdag 24 november 2009 0:41 > Aan: Mark Mahieu > CC: coin-dev > Onderwerp: Re: Closures, too much or too little? > > Mark, spec-wise, "turning final" is effectively equivalent to the compiler desugaring your source code snippet to: > > int count = 0; > final int count0; > count++; > > count0 = count; //generated > Runnable r = #() {doSomethingWith(count0);}; > > From R.Spilker at topdesk.com Tue Nov 24 01:56:30 2009 From: R.Spilker at topdesk.com (=?windows-1252?Q?Roel_Spilker?=) Date: Tue, 24 Nov 2009 10:56:30 +0100 Subject: Closures, too much or too little? In-Reply-To: <560fb5ed0911231540u7fcc5514m4d2308a176758338@mail.gmail.com> References: Message-ID: One more thing. If there is a write to count after the assignment to count0, the compiler should give at least a warning. Otherwise the reader of this code could thing the closure would see the modification if the closure is used after the modification. int count = 0; count++; Runnable r = #() {doSomethingWith(count);}; count++; r.run(); would desugar to int count = 0; count++; final int count0 = count; // generated Runnable r = #() {doSomethingWith(count0);}; count++; r.run(); In this scenario, I'd like to get an error or at least a warning that count is modified after the final variable has been assigned. Roel -----Oorspronkelijk bericht----- Van: reinier at zwitserloot.com [mailto:coin-dev-bounces at openjdk.java.net] Namens Reinier Zwitserloot Verzonden: dinsdag 24 november 2009 0:41 Aan: Mark Mahieu CC: coin-dev Onderwerp: Re: Closures, too much or too little? Mark, spec-wise, "turning final" is effectively equivalent to the compiler desugaring your source code snippet to: int count = 0; final int count0; count++; count0 = count; //generated Runnable r = #() {doSomethingWith(count0);}; From pbenedict at apache.org Tue Nov 24 17:44:51 2009 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 24 Nov 2009 19:44:51 -0600 Subject: Multi-catch: Explanation of final Message-ID: I have some difficulty understanding why "final" is necessary in the multi-catch proposal. Can anyone help me understand better? I know it revolves around limiting the scope of disjunctive types, but it's not clear to me. Paul From Joe.Darcy at Sun.COM Tue Nov 24 17:48:25 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Nov 2009 17:48:25 -0800 Subject: Multi-catch: Explanation of final In-Reply-To: References: Message-ID: <4B0C8CE9.3090205@sun.com> Paul Benedict wrote: > I have some difficulty understanding why "final" is necessary in the > multi-catch proposal. Can anyone help me understand better? I know it > revolves around limiting the scope of disjunctive types, but it's not > clear to me. > "final" tells the compiler the catch variable does not change; therefore if the value of variable is rethrown, the compiler knows that the set of exceptions throwable by the rethrow is exactly the same as the exception that could be caught by that block. -Joe From neal at gafter.com Tue Nov 24 18:45:28 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 24 Nov 2009 18:45:28 -0800 Subject: Multi-catch: Explanation of final In-Reply-To: <4B0C8CE9.3090205@sun.com> References: <4B0C8CE9.3090205@sun.com> Message-ID: <15e8b9d20911241845wf1e861by220f81bfe88698b9@mail.gmail.com> On Tue, Nov 24, 2009 at 5:48 PM, Joseph D. Darcy wrote: > Paul Benedict wrote: > > I have some difficulty understanding why "final" is necessary in the > > multi-catch proposal. Can anyone help me understand better? I know it > > revolves around limiting the scope of disjunctive types, but it's not > > clear to me. > > > > "final" tells the compiler the catch variable does not change; therefore > if the value of variable is rethrown, the compiler knows that the set of > exceptions throwable by the rethrow is exactly the same as the exception > that could be caught by that block. > Right. To expand on that, if it were not final in a catch (IOException|SQLException ex) the type of ex inside the block would be Exception (their common supertype). So you could assign an InstantiationException to ex and then rethrow it. To preserve type safety, then, throwing ex must be considered the same as throwing Exception. By requiring ex be final, throwing ex can only possibly rethrow the exceptions that the catch clause can catch, which include only IOException and SQLException (two catch table entries are generated for this catch clause). However, if support for exception transparency (disjunctive types) is added for closures, then the final requirement could be lifted. Cheers, Neal From pbenedict at apache.org Tue Nov 24 20:51:35 2009 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 24 Nov 2009 22:51:35 -0600 Subject: Multi-catch: Explanation of final In-Reply-To: <15e8b9d20911241845wf1e861by220f81bfe88698b9@mail.gmail.com> References: <4B0C8CE9.3090205@sun.com> <15e8b9d20911241845wf1e861by220f81bfe88698b9@mail.gmail.com> Message-ID: Wouldn't this be an acceptable conclusion to lifting the final variable? catch(IOException|SQLException ex) { ex = new IllegalArgumentException(); // error since ex is not one of the disjunctive supertypes ex = new IOException(); // ok ex = new SQLException(); // ok } Paul On Tue, Nov 24, 2009 at 8:45 PM, Neal Gafter wrote: > On Tue, Nov 24, 2009 at 5:48 PM, Joseph D. Darcy wrote: >> >> Paul Benedict wrote: >> > I have some difficulty understanding why "final" is necessary in the >> > multi-catch proposal. Can anyone help me understand better? I know it >> > revolves around limiting the scope of disjunctive types, but it's not >> > clear to me. >> > >> >> "final" tells the compiler the catch variable does not change; therefore >> if the value of variable is rethrown, the compiler knows that the set of >> exceptions throwable by the rethrow is exactly the same as the exception >> that could be caught by that block. > > Right.? To expand on that, if it were not final in a > > catch (IOException|SQLException ex) > > the type of ex inside the block would be Exception (their common > supertype).? So you could assign an InstantiationException to ex and then > rethrow it.? To preserve type safety, then, throwing ex must be considered > the same as throwing Exception.? By requiring ex be final, throwing ex can > only possibly rethrow the exceptions that the catch clause can catch, which > include only IOException and SQLException (two catch table entries are > generated for this catch clause). > > However, if support for exception transparency (disjunctive types) is added > for closures, then the final requirement could be lifted. > > Cheers, > Neal > From reinier at zwitserloot.com Tue Nov 24 20:58:11 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Nov 2009 05:58:11 +0100 Subject: Multi-catch: Explanation of final In-Reply-To: References: <4B0C8CE9.3090205@sun.com> <15e8b9d20911241845wf1e861by220f81bfe88698b9@mail.gmail.com> Message-ID: <560fb5ed0911242058h766ab71bvb7981ebbf7581b27@mail.gmail.com> Possibly, but reassigning the exception variable in a catch block happens, well, never. Seems silly to put that much effort into something that is a once in a blue moon occurrence. If the 'final' is bothersome (and I admit it kind of annoys me as well), isn't it simpler (for java programmers, some of which will find sticking 'final' onto a catch clause variable odd, no doubt) to make them auto-final? In other words, if there's ANY assignment in the catch block to the variable, and the variable is a disjunctive type, generate an error, saying that you can't do that. If not, well, it's as good as final. Won't break backwards compatibility. This is easy for disjunctive types, but a bit harder for the secondary aim of the work on exceptions in JDK7: Rethrowing general types. We can keep the requirement to add 'final' for those. --Reinier Zwitserloot On Wed, Nov 25, 2009 at 5:51 AM, Paul Benedict wrote: > Wouldn't this be an acceptable conclusion to lifting the final variable? > > catch(IOException|SQLException ex) { > ex = new IllegalArgumentException(); // error since ex is not one > of the disjunctive supertypes > ex = new IOException(); // ok > ex = new SQLException(); // ok > } > > Paul > > On Tue, Nov 24, 2009 at 8:45 PM, Neal Gafter wrote: > > On Tue, Nov 24, 2009 at 5:48 PM, Joseph D. Darcy > wrote: > >> > >> Paul Benedict wrote: > >> > I have some difficulty understanding why "final" is necessary in the > >> > multi-catch proposal. Can anyone help me understand better? I know it > >> > revolves around limiting the scope of disjunctive types, but it's not > >> > clear to me. > >> > > >> > >> "final" tells the compiler the catch variable does not change; therefore > >> if the value of variable is rethrown, the compiler knows that the set of > >> exceptions throwable by the rethrow is exactly the same as the exception > >> that could be caught by that block. > > > > Right. To expand on that, if it were not final in a > > > > catch (IOException|SQLException ex) > > > > the type of ex inside the block would be Exception (their common > > supertype). So you could assign an InstantiationException to ex and then > > rethrow it. To preserve type safety, then, throwing ex must be > considered > > the same as throwing Exception. By requiring ex be final, throwing ex > can > > only possibly rethrow the exceptions that the catch clause can catch, > which > > include only IOException and SQLException (two catch table entries are > > generated for this catch clause). > > > > However, if support for exception transparency (disjunctive types) is > added > > for closures, then the final requirement could be lifted. > > > > Cheers, > > Neal > > > > From neal at gafter.com Wed Nov 25 00:16:44 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 25 Nov 2009 00:16:44 -0800 Subject: Multi-catch: Explanation of final In-Reply-To: References: <4B0C8CE9.3090205@sun.com> <15e8b9d20911241845wf1e861by220f81bfe88698b9@mail.gmail.com> Message-ID: <15e8b9d20911250016m4aba19d8l284791e503d71e3a@mail.gmail.com> On Tue, Nov 24, 2009 at 8:51 PM, Paul Benedict wrote: > Wouldn't this be an acceptable conclusion to lifting the final variable? > > catch(IOException|SQLException ex) { > ex = new IllegalArgumentException(); // error since ex is not one > of the disjunctive supertypes > Um, the premise here is how to do it without adding disjunctive types to the type system. Cheers, Neal From pbenedict at apache.org Wed Nov 25 08:28:55 2009 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 25 Nov 2009 10:28:55 -0600 Subject: Multi-catch: Explanation of final In-Reply-To: <15e8b9d20911250016m4aba19d8l284791e503d71e3a@mail.gmail.com> References: <4B0C8CE9.3090205@sun.com> <15e8b9d20911241845wf1e861by220f81bfe88698b9@mail.gmail.com> <15e8b9d20911250016m4aba19d8l284791e503d71e3a@mail.gmail.com> Message-ID: >> Wouldn't this be an acceptable conclusion to lifting the final variable? >> >> catch(IOException|SQLException ex) { >> ? ex = new IllegalArgumentException(); // error since ex is not one >> of the disjunctive supertypes > > Um, the premise here is how to do it without adding disjunctive types to the > type system. > Neal, which of course means the use of "final" would prevent such re-assignment. Got it. Paul From jonty.lawson at gmail.com Thu Nov 26 06:31:21 2009 From: jonty.lawson at gmail.com (Jonathan Lawson) Date: Thu, 26 Nov 2009 15:31:21 +0100 Subject: ARM syntax and new keywords Message-ID: A pretty long post I'm afraid, but I hope it is contributing something of value. I've been following the discussions about ARM and a question about the syntax has been niggling at me: wouldn't it be better using a new keyword? Now as I understand it there is considerable resistance to the idea of new keywords, and with reason, but I feel that the associated problems have a reasonable solution and that it is a mistake to refuse to at least consider using keywords. If the resulting feature is much simpler and clearer using a keyword then why introduce some new syntax? As a motivation, consider ARM if we allow new keywords. Create, say, a new keyword 'autoclose'. This would be a new modifier on local variable declarations with much the same semantics as the current proposal; in particular that when the variable goes out of scope there will be a suitably exception protected call to a close routine. In general the keyword would take a 'parameter' giving the name of the close routine, thus: autoclose(close) InputStreamReader in = new FileReader("filename"); The declared type must have a method of the given name that can be called with no args. This would be desugared in much the same way as: try (InputStreamReader in = new FileReader("filename")) { statements_to_the_end_of_scope_of_in } in the current proposal would be. There should also be a simplified form without the (close) for the common cases. There are different ways that this could be defined: either using marker interfaces as currently envisaged, or using a name based scheme. For example, if the declared type has exactly one method with name "close", "dispose", "free", "release" or "unlock" that can be called with no args, use that, otherwise it's an error not to specify the name explicitly. This is slightly nasty in that it puts those names into the language spec, but then again only as defaults, and it has the advantages that it is simple to understand, simple to use and will do what's expected. It would create the restriction that it would be a breaking change to add a second method from the set to an existing library class, but to me that doesn't seem much of a burden. It wouldn't require any reworking of the library at all - no new marker interfaces etc. So the above example would become: autoclose InputStreamReader in = new FileReader("filename"); This feature could also be used simply for user defined types, for example: autoclose(bin) UserBinnable ub = new UserBinnable(); To my eyes it is much clearer than the proposed syntax (not that I find that unacceptable, but I think this is better). It's so simple to use that it will become second nature to use it every time, even in throwaway code. It even has a good chance of being correctly interpreted by someone who doesn't know the feature - surely an indication of a good syntax. It has the difference relative to the proposed syntax that the programmer isn't forced to explicitly show the end of scope via {}, though there is nothing to stop it (by putting the declaration at the start of a new block). The presence of the word 'try' can also be considered an advantage of the current approach (reminding you that there is some exception magic going on), but personally I don't find this compelling. It could be extended to the foreach case that has been recently discussed. If you allow its use just after the : to indicate that the created iterator needs closing: for (Object o: autoclose somethingIterable)... which would be expanded as detailed in the current JLS but with autoclose added to the iterator declaration. This would require somethingIterable.iterator() to return a subtype of Iterator that had a close, dispose etc method, otherwise it's an error. The fact that it is explicit and compiler checked strikes me as a big advantage over the previously discussed idea of just quietly doing it if the passed type permits it. Additionally, if the passed type is changed to no longer support closing then the code no longer compiles, rather than quietly changing its functionality. Anyway, enough of the ARM case. On to the subject of new keywords. Obviously, the above syntax is only worthwhile if the cost of introducing new keywords isn't too high. At the moment it famously is, of course. So, 'source' revisited, but source light. I totally agree that having the meaning of syntax change so that you can't tell what code is doing without looking at the file header is only to be tolerated in extreme cases. However, I don't think this applies with new keywords. If you are looking at source code in an IDE then you get syntax highlighting. This will tell you right away if a name is being treated as an identifier or as a keyword. If you type the name into your code then you will know you that you haven't written an identifier but a keyword (or vice versa). So, the suggested solution is that a contextual keyword called 'keywords' should be permitted as the first thing in a file, in which case it is followed by a version string which must correspond to a version of the JLS (or possibly java version - TBD). The meaning of this is that the list of keywords should be that from the referenced version of the JLS. If a name which is a keyword in the latest version of the language (eg 'autoclose') appears in the source, but is not present in the version of the JLS given in the keywords specification, then it will be treated as an ordinary identifier rather than a keyword for this file. If no keywords specification appears at the start of the source file then "keywords 3.0;" is assumed. This provides many of the advantages of 'source' without most of the downsides. The JSL doesn't need to maintain multiple versions. If you add 'autoclose' say, then you specify what it does and add it to the new list of keywords. The functionality is still, in some senses, always present in the language, it is simply that if a source file specifies a version preceding the version it was added to then the name autoclose refers to an identifier rather than the new feature. It doesn't present language designers with the temptation to modify its behaviour later. The keywords version merely tells you if it is in or out, it doesn't give you information about how to interpret it. IDEs should be able to refactor this relatively easily (just checking that no new keywords are currently used as identifiers in the file when altering the 'keywords' specifier). They should be able to do the syntax highlighting pretty straightforwardly as well. It does create one problem that I can see: if you are writing code using the new keywords how do you access a member called, for example, autoclose, in an existing class? I suppose one answer could be to require the creation of a glue class to rename access to the member, but this isn't very elegant (but then again if new keywords are chosen carefully there shouldn't be very many of these cases). Another possibility would be to allow individual blocks to be reverted to earlier keyword version by tagging them with a local 'keywords' specifier, but this seems a bit heavy handed. Probably the best way would be if current proposals to create a syntax for non-standard identifiers are implemented. Then this could be used to force the new keyword to be treated as an identifier in the given context. Independently of whether the ideas above concerning ARM get any support, I feel that discussions about the language would benefit from the freedom to at least consider new keywords. I hope this post will encourage this by pointing out that the compatibility problems of introducing new keywords can be easily eliminated. Jonty From neal at gafter.com Thu Nov 26 09:37:57 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Nov 2009 09:37:57 -0800 Subject: ARM syntax and new keywords In-Reply-To: References: Message-ID: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> On Thu, Nov 26, 2009 at 6:31 AM, Jonathan Lawson wrote: > A pretty long post I'm afraid, but I hope it is contributing something of > value. > > I've been following the discussions about ARM and a question about the > syntax has been niggling at me: wouldn't it be better using a new keyword? > Now that jdk7 will include a syntax for using names that are otherwise keywords (the syntax is #"name"), the backward-compatibility breakage of adding a new keyword is much less severe. Also, context-sensitive keywords are a true-and-tried technique, just not used yet in Java. From jjb at google.com Thu Nov 26 09:53:34 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 26 Nov 2009 09:53:34 -0800 Subject: ARM syntax and new keywords In-Reply-To: References: Message-ID: <17b2302a0911260953m2dde28cdl8f291af8e3785f8a@mail.gmail.com> Jonathan, Actually I quite like the "try" syntax. Sun is in possession of a protocol, and as soon as we think it's in shape for public consumption, we'll get it out there and you can play with it. Happy Thanksgiving, Josh On Thu, Nov 26, 2009 at 6:31 AM, Jonathan Lawson wrote: > A pretty long post I'm afraid, but I hope it is contributing something of > value. > > I've been following the discussions about ARM and a question about the > syntax has been niggling at me: wouldn't it be better using a new keyword? > > Now as I understand it there is considerable resistance to the idea of new > keywords, and with reason, but I feel that the associated problems have a > reasonable solution and that it is a mistake to refuse to at least consider > using keywords. If the resulting feature is much simpler and clearer using > a > keyword then why introduce some new syntax? > > As a motivation, consider ARM if we allow new keywords. > > Create, say, a new keyword 'autoclose'. This would be a new modifier on > local variable declarations with much the same semantics as the current > proposal; in particular that when the variable goes out of scope there will > be a suitably exception protected call to a close routine. In general the > keyword would take a 'parameter' giving the name of the close routine, > thus: > > autoclose(close) InputStreamReader in = new FileReader("filename"); > > The declared type must have a method of the given name that can be called > with no args. This would be desugared in much the same way as: > > try (InputStreamReader in = new FileReader("filename")) { > statements_to_the_end_of_scope_of_in } > > in the current proposal would be. > > There should also be a simplified form without the (close) for the common > cases. There are different ways that this could be defined: either using > marker interfaces as currently envisaged, or using a name based scheme. For > example, if the declared type has exactly one method with name "close", > "dispose", "free", "release" or "unlock" that can be called with no args, > use that, otherwise it's an error not to specify the name explicitly. This > is slightly nasty in that it puts those names into the language spec, but > then again only as defaults, and it has the advantages that it is simple to > understand, simple to use and will do what's expected. It would create the > restriction that it would be a breaking change to add a second method from > the set to an existing library class, but to me that doesn't seem much of a > burden. It wouldn't require any reworking of the library at all - no new > marker interfaces etc. So the above example would become: > > autoclose InputStreamReader in = new FileReader("filename"); > > This feature could also be used simply for user defined types, for example: > > autoclose(bin) UserBinnable ub = new UserBinnable(); > > To my eyes it is much clearer than the proposed syntax (not that I find > that > unacceptable, but I think this is better). It's so simple to use that it > will become second nature to use it every time, even in throwaway code. It > even has a good chance of being correctly interpreted by someone who > doesn't > know the feature - surely an indication of a good syntax. > > It has the difference relative to the proposed syntax that the programmer > isn't forced to explicitly show the end of scope via {}, though there is > nothing to stop it (by putting the declaration at the start of a new > block). > The presence of the word 'try' can also be considered an advantage of the > current approach (reminding you that there is some exception magic going > on), but personally I don't find this compelling. > > It could be extended to the foreach case that has been recently discussed. > If you allow its use just after the : to indicate that the created iterator > needs closing: > > for (Object o: autoclose somethingIterable)... > > which would be expanded as detailed in the current JLS but with autoclose > added to the iterator declaration. This would require > somethingIterable.iterator() to return a subtype of Iterator that had a > close, dispose etc method, otherwise it's an error. The fact that it is > explicit and compiler checked strikes me as a big advantage over the > previously discussed idea of just quietly doing it if the passed type > permits it. Additionally, if the passed type is changed to no longer > support > closing then the code no longer compiles, rather than quietly changing its > functionality. > > > > Anyway, enough of the ARM case. On to the subject of new keywords. > > Obviously, the above syntax is only worthwhile if the cost of introducing > new keywords isn't too high. At the moment it famously is, of course. So, > 'source' revisited, but source light. > > I totally agree that having the meaning of syntax change so that you can't > tell what code is doing without looking at the file header is only to be > tolerated in extreme cases. However, I don't think this applies with new > keywords. If you are looking at source code in an IDE then you get syntax > highlighting. This will tell you right away if a name is being treated as > an > identifier or as a keyword. If you type the name into your code then you > will know you that you haven't written an identifier but a keyword (or vice > versa). > > So, the suggested solution is that a contextual keyword called 'keywords' > should be permitted as the first thing in a file, in which case it is > followed by a version string which must correspond to a version of the JLS > (or possibly java version - TBD). The meaning of this is that the list of > keywords should be that from the referenced version of the JLS. If a name > which is a keyword in the latest version of the language (eg 'autoclose') > appears in the source, but is not present in the version of the JLS given > in > the keywords specification, then it will be treated as an ordinary > identifier rather than a keyword for this file. If no keywords > specification > appears at the start of the source file then "keywords 3.0;" is assumed. > > This provides many of the advantages of 'source' without most of the > downsides. The JSL doesn't need to maintain multiple versions. If you add > 'autoclose' say, then you specify what it does and add it to the new list > of > keywords. The functionality is still, in some senses, always present in the > language, it is simply that if a source file specifies a version preceding > the version it was added to then the name autoclose refers to an identifier > rather than the new feature. It doesn't present language designers with the > temptation to modify its behaviour later. The keywords version merely tells > you if it is in or out, it doesn't give you information about how to > interpret it. > > IDEs should be able to refactor this relatively easily (just checking that > no new keywords are currently used as identifiers in the file when altering > the 'keywords' specifier). They should be able to do the syntax > highlighting > pretty straightforwardly as well. > > It does create one problem that I can see: if you are writing code using > the > new keywords how do you access a member called, for example, autoclose, in > an existing class? I suppose one answer could be to require the creation of > a glue class to rename access to the member, but this isn't very elegant > (but then again if new keywords are chosen carefully there shouldn't be > very > many of these cases). Another possibility would be to allow individual > blocks to be reverted to earlier keyword version by tagging them with a > local 'keywords' specifier, but this seems a bit heavy handed. Probably the > best way would be if current proposals to create a syntax for non-standard > identifiers are implemented. Then this could be used to force the new > keyword to be treated as an identifier in the given context. > > > Independently of whether the ideas above concerning ARM get any support, I > feel that discussions about the language would benefit from the freedom to > at least consider new keywords. I hope this post will encourage this by > pointing out that the compatibility problems of introducing new keywords > can > be easily eliminated. > > Jonty > > From jjb at google.com Thu Nov 26 09:57:21 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 26 Nov 2009 09:57:21 -0800 Subject: ARM syntax and new keywords In-Reply-To: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> Message-ID: <17b2302a0911260957h14f4b05eh4cc082d96ea44e10@mail.gmail.com> Neal, On Thu, Nov 26, 2009 at 9:37 AM, Neal Gafter wrote: > > Now that jdk7 will include a syntax for using names that are otherwise > keywords (the syntax is #"name"), the backward-compatibility breakage of > adding a new keyword is much less severe. Let's not jump the gun! Sun's recently announced closures effort has barely gotten underway, and no syntax has been chosen. Mark made it clear that syntax he presented at Devoxx was a hastily constructed straw man. Happy Thanksgiving, Josh From neal at gafter.com Thu Nov 26 10:04:45 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Nov 2009 10:04:45 -0800 Subject: ARM syntax and new keywords In-Reply-To: <17b2302a0911260957h14f4b05eh4cc082d96ea44e10@mail.gmail.com> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> <17b2302a0911260957h14f4b05eh4cc082d96ea44e10@mail.gmail.com> Message-ID: <15e8b9d20911261004v2f6e12bekf7521b09cbc6828d@mail.gmail.com> On Thu, Nov 26, 2009 at 9:57 AM, Joshua Bloch wrote: > On Thu, Nov 26, 2009 at 9:37 AM, Neal Gafter wrote: > >> >> Now that jdk7 will include a syntax for using names that are otherwise >> keywords (the syntax is #"name"), the backward-compatibility breakage of >> adding a new keyword is much less severe. > > > Let's not jump the gun! Sun's recently announced closures effort has > barely gotten underway, and no syntax has been chosen. Mark made it clear > that syntax he presented at Devoxx was a hastily constructed straw man. > What do closures have to do with it? Support for exotic identifiers is already in openjdk7. Cheers, Neal From david.goodenough at linkchoose.co.uk Thu Nov 26 10:30:08 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 26 Nov 2009 18:30:08 +0000 Subject: ARM syntax and new keywords Message-ID: <200911261830.09021.david.goodenough@linkchoose.co.uk> On Thursday 26 November 2009, Joshua Bloch wrote: > Neal, > > On Thu, Nov 26, 2009 at 9:37 AM, Neal Gafter wrote: > > Now that jdk7 will include a syntax for using names that are otherwise > > keywords (the syntax is #"name"), the backward-compatibility breakage of > > adding a new keyword is much less severe. > > Let's not jump the gun! Sun's recently announced closures effort has > barely gotten underway, and no syntax has been chosen. Mark made it clear > that syntax he presented at Devoxx was a hastily constructed straw man. > > Happy Thanksgiving, > > Josh > It will be interesting to see how they go about doing that choosing. Will it be a Coin like process, or are Sun going into a closed room and then produce a result on their own? David From david.goodenough at linkchoose.co.uk Thu Nov 26 10:30:20 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 26 Nov 2009 18:30:20 +0000 Subject: ARM syntax and new keywords Message-ID: <200911261830.20223.david.goodenough@linkchoose.co.uk> On Thursday 26 November 2009, Neal Gafter wrote: > On Thu, Nov 26, 2009 at 6:31 AM, Jonathan Lawson wrote: > > A pretty long post I'm afraid, but I hope it is contributing something of > > value. > > > > I've been following the discussions about ARM and a question about the > > syntax has been niggling at me: wouldn't it be better using a new > > keyword? > > Now that jdk7 will include a syntax for using names that are otherwise > keywords (the syntax is #"name"), the backward-compatibility breakage of > adding a new keyword is much less severe. Also, context-sensitive keywords > are a true-and-tried technique, just not used yet in Java. > I hope that the # operator will be available for both methods and fields. This was discussed early on in the Coin process, in my lightweight properties proposal. It is really the only bit of that proposal that is needed, the rest can be done in other ways. Actually it is a little more complicated than for methods. For the simple case of Class#field you can return a java.lang.reflect.Field object, but if you have a chain of # operators you would need a Field[], and if you wish to bind it to an object you need to remember that object, then the result will been to be wrapped in a new object (FieldRef is the best name I have seen). The compilation requirement is simple, object[#field] becomes new FieldRef(object[,"field"]) where object can be an object or a class, and [] means repeated as necessary with at least one present. The compiler would need to check that field exists in object (and on down the chain) regardless of whether this is a private/protected/public field. David From forax at univ-mlv.fr Thu Nov 26 13:04:16 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 26 Nov 2009 22:04:16 +0100 Subject: ARM syntax and new keywords In-Reply-To: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> Message-ID: <4B0EED50.2060905@univ-mlv.fr> Le 26/11/2009 18:37, Neal Gafter a ?crit : > On Thu, Nov 26, 2009 at 6:31 AM, Jonathan Lawsonwrote: > > >> A pretty long post I'm afraid, but I hope it is contributing something of >> value. >> >> I've been following the discussions about ARM and a question about the >> syntax has been niggling at me: wouldn't it be better using a new keyword? >> >> > Now that jdk7 will include a syntax for using names that are otherwise > keywords (the syntax is #"name"), the backward-compatibility breakage of > adding a new keyword is much less severe. Also, context-sensitive keywords > are a true-and-tried technique, just not used yet in Java. > > Exotic identifier doesn't solve the whole problem. Using a new keyword as the name of a package still hold. R?mi From neal at gafter.com Thu Nov 26 12:48:48 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Nov 2009 12:48:48 -0800 Subject: ARM syntax and new keywords In-Reply-To: <200911261830.20223.david.goodenough@linkchoose.co.uk> References: <200911261830.20223.david.goodenough@linkchoose.co.uk> Message-ID: <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> On Thu, Nov 26, 2009 at 10:30 AM, David Goodenough < david.goodenough at linkchoose.co.uk> wrote: > On Thursday 26 November 2009, Neal Gafter wrote: > > Now that jdk7 will include a syntax for using names that are otherwise > > keywords (the syntax is #"name"), the backward-compatibility breakage of > > adding a new keyword is much less severe. Also, context-sensitive > keywords > > are a true-and-tried technique, just not used yet in Java. > > > I hope that the # operator will be available for both methods and fields. > This was discussed early on in the Coin process, in my lightweight > properties > proposal. It is really the only bit of that proposal that is needed, the > rest > can be done in other ways. > This has nothing to do with closures (there is a separate email list for that anyway). The #"name" syntax was added to give a way of using "exotic" identifiers that would otherwise be disallowed. For example, if you have a method pre jdk7 int foobar(int x) { return x + 1; } and then we add a keyword "foobar" to the language in jdk7, you can still use the identifier "foobar" by modifying the source as following int #"foobar"(int x) { return x + 1; } This is even possible for package names, though a bit awkward package #"foobar"; Cheers, Neal From forax at univ-mlv.fr Thu Nov 26 13:09:44 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 26 Nov 2009 22:09:44 +0100 Subject: ARM syntax and new keywords In-Reply-To: <4B0EED50.2060905@univ-mlv.fr> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> <4B0EED50.2060905@univ-mlv.fr> Message-ID: <4B0EEE98.9000105@univ-mlv.fr> Le 26/11/2009 22:04, R?mi Forax a ?crit : > Le 26/11/2009 18:37, Neal Gafter a ?crit : > >> On Thu, Nov 26, 2009 at 6:31 AM, Jonathan Lawsonwrote: >> >> >> >>> A pretty long post I'm afraid, but I hope it is contributing something of >>> value. >>> >>> I've been following the discussions about ARM and a question about the >>> syntax has been niggling at me: wouldn't it be better using a new keyword? >>> >>> >>> >> Now that jdk7 will include a syntax for using names that are otherwise >> keywords (the syntax is #"name"), the backward-compatibility breakage of >> adding a new keyword is much less severe. Also, context-sensitive keywords >> are a true-and-tried technique, just not used yet in Java. >> >> >> > Exotic identifier doesn't solve the whole problem. > Using a new keyword as the name of a package still hold. > > R?mi > > oups, sorry. It seems to work with package name. R?mi From jjb at google.com Thu Nov 26 13:41:01 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 26 Nov 2009 13:41:01 -0800 Subject: ARM syntax and new keywords In-Reply-To: <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> References: <200911261830.20223.david.goodenough@linkchoose.co.uk> <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> Message-ID: <17b2302a0911261341j42bdb70akc98bfab583a883e3@mail.gmail.com> Neal, On Thu, Nov 26, 2009 at 12:48 PM, Neal Gafter wrote: > > This has nothing to do with closures (there is a separate email list for > that anyway). Not yet there isn't. But I hope there will be soon. > The #"name" syntax was added to give a way of using "exotic" > identifiers that would otherwise be disallowed. For example, if you have a > method pre jdk7 > > int foobar(int x) { return x + 1; } > > and then we add a keyword "foobar" to the language in jdk7, you can still > use the identifier "foobar" by modifying the source as following > > int #"foobar"(int x) { return x + 1; } > > This is even possible for package names, though a bit awkward > > package #"foobar"; > Bit this is hideous! Worse than explicit type parameters. We must not do anything that actually makes people do this sort of thing. Josh From mohamed at bana.org.uk Thu Nov 26 13:51:51 2009 From: mohamed at bana.org.uk (Mohamed Bana) Date: Thu, 26 Nov 2009 21:51:51 +0000 Subject: ARM syntax and new keywords In-Reply-To: <17b2302a0911261341j42bdb70akc98bfab583a883e3@mail.gmail.com> References: <200911261830.20223.david.goodenough@linkchoose.co.uk> <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> <17b2302a0911261341j42bdb70akc98bfab583a883e3@mail.gmail.com> Message-ID: <66f12d2d0911261351k79f24736xc50484cdc85e741a@mail.gmail.com> Scala does this using `type` You can use a keyword as an identifier if you place it between `. ?Mohamed On Thu, Nov 26, 2009 at 9:41 PM, Joshua Bloch wrote: > Neal, > > On Thu, Nov 26, 2009 at 12:48 PM, Neal Gafter wrote: > > > > > This has nothing to do with closures (there is a separate email list for > > that anyway). > > > Not yet there isn't. But I hope there will be soon. > > > > The #"name" syntax was added to give a way of using "exotic" > > identifiers that would otherwise be disallowed. For example, if you have > a > > method pre jdk7 > > > > int foobar(int x) { return x + 1; } > > > > and then we add a keyword "foobar" to the language in jdk7, you can still > > use the identifier "foobar" by modifying the source as following > > > > int #"foobar"(int x) { return x + 1; } > > > > This is even possible for package names, though a bit awkward > > > > package #"foobar"; > > > > Bit this is hideous! Worse than explicit type parameters. We must not do > anything that actually makes people do this sort of thing. > > Josh > > From abies at adres.pl Thu Nov 26 14:39:31 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Thu, 26 Nov 2009 23:39:31 +0100 Subject: ARM syntax and new keywords In-Reply-To: <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> References: <200911261830.20223.david.goodenough@linkchoose.co.uk> <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> Message-ID: <4B0F03A3.5030009@adres.pl> Neal Gafter wrote: > This has nothing to do with closures (there is a separate email list for > that anyway). The #"name" syntax was added to give a way of using "exotic" > identifiers that would otherwise be disallowed. We will have to answer questions about closures relation to identifier-like variables for next 10 years if #"abc" syntax is chosen and closures also use # syntax. What is wrong with Scala approach of using backticks? Looks reasonable and won't be confused with possible closures. It is a pain to enter on certain keyboard settings, but it is going to be needed only in exceptional cases. With best regards, Artur Biesiadowski From neal at gafter.com Thu Nov 26 15:05:07 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Nov 2009 15:05:07 -0800 Subject: ARM syntax and new keywords In-Reply-To: <4B0F03A3.5030009@adres.pl> References: <200911261830.20223.david.goodenough@linkchoose.co.uk> <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> <4B0F03A3.5030009@adres.pl> Message-ID: <15e8b9d20911261505t287c9674if654ebe8324aec73@mail.gmail.com> I agree. Backticks would be a much better syntax for exotic identifiers. As far as I can tell, the jsr292 changes that got folded into javac have not been influenced by feedback from the coin mailing list. On Thu, Nov 26, 2009 at 2:39 PM, Artur Biesiadowski wrote: > Neal Gafter wrote: > > This has nothing to do with closures (there is a separate email list for > > that anyway). The #"name" syntax was added to give a way of using > "exotic" > > identifiers that would otherwise be disallowed. > We will have to answer questions about closures relation to > identifier-like variables for next 10 years if #"abc" syntax is chosen > and closures also use # syntax. > > What is wrong with Scala approach of using backticks? Looks reasonable > and won't be confused with possible closures. It is a pain to enter on > certain keyboard settings, but it is going to be needed only in > exceptional cases. > > With best regards, > Artur Biesiadowski > > From markmahieu at googlemail.com Thu Nov 26 16:48:19 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 27 Nov 2009 00:48:19 +0000 Subject: Bug reports Message-ID: Hi Joe, Is there any particular process you'd prefer Coin bug reports to go through, or should they just be filed at the usual place? Mark From reinier at zwitserloot.com Fri Nov 27 03:21:44 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 27 Nov 2009 12:21:44 +0100 Subject: ARM syntax and new keywords In-Reply-To: <15e8b9d20911261505t287c9674if654ebe8324aec73@mail.gmail.com> References: <200911261830.20223.david.goodenough@linkchoose.co.uk> <15e8b9d20911261248y14c6c723re7c5b00784815a2d@mail.gmail.com> <4B0F03A3.5030009@adres.pl> <15e8b9d20911261505t287c9674if654ebe8324aec73@mail.gmail.com> Message-ID: <560fb5ed0911270321x3152799dy69d4db0d3fdda627@mail.gmail.com> +1 on the backticks. Looks better (no need for subsequent string quotes), doesn't use up an extremely valuable symbol (pretty much the last easily typable one that has no current meaning in java code), is the same as other JVM languages that have this feature (well, mostly scala, but then that's a pretty big one, as far as non-java languages on the VM go), which is extra relevant because a major reason to use the identifier escape is for multi-language interop. Not to mention the confusion with closure syntax. Please please pretty please, change it? --Reinier Zwitserloot On Fri, Nov 27, 2009 at 12:05 AM, Neal Gafter wrote: > I agree. Backticks would be a much better syntax for exotic identifiers. > As far as I can tell, the jsr292 changes that got folded into javac have > not > been influenced by feedback from the coin mailing list. > > On Thu, Nov 26, 2009 at 2:39 PM, Artur Biesiadowski > wrote: > > > Neal Gafter wrote: > > > This has nothing to do with closures (there is a separate email list > for > > > that anyway). The #"name" syntax was added to give a way of using > > "exotic" > > > identifiers that would otherwise be disallowed. > > We will have to answer questions about closures relation to > > identifier-like variables for next 10 years if #"abc" syntax is chosen > > and closures also use # syntax. > > > > What is wrong with Scala approach of using backticks? Looks reasonable > > and won't be confused with possible closures. It is a pain to enter on > > certain keyboard settings, but it is going to be needed only in > > exceptional cases. > > > > With best regards, > > Artur Biesiadowski > > > > > > From reinier at zwitserloot.com Fri Nov 27 03:31:01 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 27 Nov 2009 12:31:01 +0100 Subject: ARM syntax and new keywords In-Reply-To: References: Message-ID: <560fb5ed0911270331r2376f5bfrfffb8eab6ce913e2@mail.gmail.com> Jonathan, replace "autoclose" with "@Cleanup", and you've got the _EXACT_ implementation of resource management from Project Lombok (projectlombok.org ). The one difference is that instead of a bunch of default names, lombok has only one: close. @Cleanup is by far my favourite lombok annotation. Experience working with it in real code has led me to the conclusion that having cleanup work on a variable until it runs out of scope, instead of introducing a new block, is a considerably more natural way to do this. There's far less syntax involved (just 1 simple marker on a variable declaration, nothing else, and no new blocks), which really says it all. If using annotations to change code is not okay (and, lombok notwithstanding, it won't be, at least not for a coin proposal), and if introducing a new keyword is not okay (identifier literals notwithstanding, I doubt it will be for coin), there's still a way: try InputStream in = new FileInputStream(file); Method to call for closing is 'close' by default, and can be changed via: try (dispose) InputStream in =.... similar to Jonathan's proposal and project lombok's @Cleanup, and exception handling goes equivalent to the existing ARM proposal. As a practical matter you'll virtually always stick a try-guard statement inside a try/catch block to handle the exception(s) that can occur in your resource operation, so, practically speaking, you end up with something like: try { try InputStream in = new FileInputStream(input); try OutputStream out = new FileOutputStream(output); byte[] b = new byte[65536]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } } catch (IOException e) { System.err.println("File copy failed: " + e.getMessage()); } NB: If 'close' as a default is not considered acceptable, all the considerations of ARM can be used here instead, so, instead of generating an X.close() in the finally block, it can check if the type of the variable declaration is an instance of AutoClosable, etc. --Reinier Zwitserloot On Thu, Nov 26, 2009 at 3:31 PM, Jonathan Lawson wrote: > A pretty long post I'm afraid, but I hope it is contributing something of > value. > > I've been following the discussions about ARM and a question about the > syntax has been niggling at me: wouldn't it be better using a new keyword? > > Now as I understand it there is considerable resistance to the idea of new > keywords, and with reason, but I feel that the associated problems have a > reasonable solution and that it is a mistake to refuse to at least consider > using keywords. If the resulting feature is much simpler and clearer using > a > keyword then why introduce some new syntax? > > As a motivation, consider ARM if we allow new keywords. > > Create, say, a new keyword 'autoclose'. This would be a new modifier on > local variable declarations with much the same semantics as the current > proposal; in particular that when the variable goes out of scope there will > be a suitably exception protected call to a close routine. In general the > keyword would take a 'parameter' giving the name of the close routine, > thus: > > autoclose(close) InputStreamReader in = new FileReader("filename"); > > The declared type must have a method of the given name that can be called > with no args. This would be desugared in much the same way as: > > try (InputStreamReader in = new FileReader("filename")) { > statements_to_the_end_of_scope_of_in } > > in the current proposal would be. > > There should also be a simplified form without the (close) for the common > cases. There are different ways that this could be defined: either using > marker interfaces as currently envisaged, or using a name based scheme. For > example, if the declared type has exactly one method with name "close", > "dispose", "free", "release" or "unlock" that can be called with no args, > use that, otherwise it's an error not to specify the name explicitly. This > is slightly nasty in that it puts those names into the language spec, but > then again only as defaults, and it has the advantages that it is simple to > understand, simple to use and will do what's expected. It would create the > restriction that it would be a breaking change to add a second method from > the set to an existing library class, but to me that doesn't seem much of a > burden. It wouldn't require any reworking of the library at all - no new > marker interfaces etc. So the above example would become: > > autoclose InputStreamReader in = new FileReader("filename"); > > This feature could also be used simply for user defined types, for example: > > autoclose(bin) UserBinnable ub = new UserBinnable(); > > To my eyes it is much clearer than the proposed syntax (not that I find > that > unacceptable, but I think this is better). It's so simple to use that it > will become second nature to use it every time, even in throwaway code. It > even has a good chance of being correctly interpreted by someone who > doesn't > know the feature - surely an indication of a good syntax. > > It has the difference relative to the proposed syntax that the programmer > isn't forced to explicitly show the end of scope via {}, though there is > nothing to stop it (by putting the declaration at the start of a new > block). > The presence of the word 'try' can also be considered an advantage of the > current approach (reminding you that there is some exception magic going > on), but personally I don't find this compelling. > > It could be extended to the foreach case that has been recently discussed. > If you allow its use just after the : to indicate that the created iterator > needs closing: > > for (Object o: autoclose somethingIterable)... > > which would be expanded as detailed in the current JLS but with autoclose > added to the iterator declaration. This would require > somethingIterable.iterator() to return a subtype of Iterator that had a > close, dispose etc method, otherwise it's an error. The fact that it is > explicit and compiler checked strikes me as a big advantage over the > previously discussed idea of just quietly doing it if the passed type > permits it. Additionally, if the passed type is changed to no longer > support > closing then the code no longer compiles, rather than quietly changing its > functionality. > > > > Anyway, enough of the ARM case. On to the subject of new keywords. > > Obviously, the above syntax is only worthwhile if the cost of introducing > new keywords isn't too high. At the moment it famously is, of course. So, > 'source' revisited, but source light. > > I totally agree that having the meaning of syntax change so that you can't > tell what code is doing without looking at the file header is only to be > tolerated in extreme cases. However, I don't think this applies with new > keywords. If you are looking at source code in an IDE then you get syntax > highlighting. This will tell you right away if a name is being treated as > an > identifier or as a keyword. If you type the name into your code then you > will know you that you haven't written an identifier but a keyword (or vice > versa). > > So, the suggested solution is that a contextual keyword called 'keywords' > should be permitted as the first thing in a file, in which case it is > followed by a version string which must correspond to a version of the JLS > (or possibly java version - TBD). The meaning of this is that the list of > keywords should be that from the referenced version of the JLS. If a name > which is a keyword in the latest version of the language (eg 'autoclose') > appears in the source, but is not present in the version of the JLS given > in > the keywords specification, then it will be treated as an ordinary > identifier rather than a keyword for this file. If no keywords > specification > appears at the start of the source file then "keywords 3.0;" is assumed. > > This provides many of the advantages of 'source' without most of the > downsides. The JSL doesn't need to maintain multiple versions. If you add > 'autoclose' say, then you specify what it does and add it to the new list > of > keywords. The functionality is still, in some senses, always present in the > language, it is simply that if a source file specifies a version preceding > the version it was added to then the name autoclose refers to an identifier > rather than the new feature. It doesn't present language designers with the > temptation to modify its behaviour later. The keywords version merely tells > you if it is in or out, it doesn't give you information about how to > interpret it. > > IDEs should be able to refactor this relatively easily (just checking that > no new keywords are currently used as identifiers in the file when altering > the 'keywords' specifier). They should be able to do the syntax > highlighting > pretty straightforwardly as well. > > It does create one problem that I can see: if you are writing code using > the > new keywords how do you access a member called, for example, autoclose, in > an existing class? I suppose one answer could be to require the creation of > a glue class to rename access to the member, but this isn't very elegant > (but then again if new keywords are chosen carefully there shouldn't be > very > many of these cases). Another possibility would be to allow individual > blocks to be reverted to earlier keyword version by tagging them with a > local 'keywords' specifier, but this seems a bit heavy handed. Probably the > best way would be if current proposals to create a syntax for non-standard > identifiers are implemented. Then this could be used to force the new > keyword to be treated as an identifier in the given context. > > > Independently of whether the ideas above concerning ARM get any support, I > feel that discussions about the language would benefit from the freedom to > at least consider new keywords. I hope this post will encourage this by > pointing out that the compatibility problems of introducing new keywords > can > be easily eliminated. > > Jonty > > From david.goodenough at btconnect.com Thu Nov 26 10:09:23 2009 From: david.goodenough at btconnect.com (David Goodenough) Date: Thu, 26 Nov 2009 18:09:23 +0000 Subject: ARM syntax and new keywords In-Reply-To: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> Message-ID: <200911261809.24150.david.goodenough@btconnect.com> On Thursday 26 November 2009, Neal Gafter wrote: > On Thu, Nov 26, 2009 at 6:31 AM, Jonathan Lawson wrote: > > A pretty long post I'm afraid, but I hope it is contributing something of > > value. > > > > I've been following the discussions about ARM and a question about the > > syntax has been niggling at me: wouldn't it be better using a new > > keyword? > > Now that jdk7 will include a syntax for using names that are otherwise > keywords (the syntax is #"name"), the backward-compatibility breakage of > adding a new keyword is much less severe. Also, context-sensitive keywords > are a true-and-tried technique, just not used yet in Java. > I hope that the # operator will be available for both methods and fields. This was discussed early on in the Coin process, in my lightweight properties proposal. It is really the only bit of that proposal that is needed, the rest can be done in other ways. Actually it is a little more complicated than for methods. For the simple case of Class#field you can return a java.lang.reflect.Field object, but if you have a chain of # operators you would need a Field[], and if you wish to bind it to an object you need to remember that object, then the result will been to be wrapped in a new object (FieldRef is the best name I have seen). The compilation requirement is simple, object[#field] becomes new FieldRef(object[,"field"]) where object can be an object or a class, and [] means repeated as necessary with at least one present. The compiler would need to check that field exists in object (and on down the chain) regardless of whether this is a private/protected/public field. David From david.goodenough at btconnect.com Thu Nov 26 10:10:36 2009 From: david.goodenough at btconnect.com (David Goodenough) Date: Thu, 26 Nov 2009 18:10:36 +0000 Subject: ARM syntax and new keywords In-Reply-To: <17b2302a0911260957h14f4b05eh4cc082d96ea44e10@mail.gmail.com> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> <17b2302a0911260957h14f4b05eh4cc082d96ea44e10@mail.gmail.com> Message-ID: <200911261810.36115.david.goodenough@btconnect.com> On Thursday 26 November 2009, Joshua Bloch wrote: > Neal, > > On Thu, Nov 26, 2009 at 9:37 AM, Neal Gafter wrote: > > Now that jdk7 will include a syntax for using names that are otherwise > > keywords (the syntax is #"name"), the backward-compatibility breakage of > > adding a new keyword is much less severe. > > Let's not jump the gun! Sun's recently announced closures effort has > barely gotten underway, and no syntax has been chosen. Mark made it clear > that syntax he presented at Devoxx was a hastily constructed straw man. > > Happy Thanksgiving, > > Josh > It will be interesting to see how they go about doing that choosing. Will it be a Coin like process, or are Sun going into a closed room and then produce a result on their own? David From Joe.Darcy at Sun.COM Fri Nov 27 05:52:48 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 27 Nov 2009 05:52:48 -0800 Subject: ARM syntax and new keywords In-Reply-To: <200911261810.36115.david.goodenough@btconnect.com> References: <15e8b9d20911260937n10f26fe5pda14bb992aa72d72@mail.gmail.com> <17b2302a0911260957h14f4b05eh4cc082d96ea44e10@mail.gmail.com> <200911261810.36115.david.goodenough@btconnect.com> Message-ID: <4B0FD9B0.8010305@sun.com> David Goodenough wrote: > On Thursday 26 November 2009, Joshua Bloch wrote: > >> Neal, >> >> On Thu, Nov 26, 2009 at 9:37 AM, Neal Gafter wrote: >> >>> Now that jdk7 will include a syntax for using names that are otherwise >>> keywords (the syntax is #"name"), the backward-compatibility breakage >>> > of > >>> adding a new keyword is much less severe. >>> >> Let's not jump the gun! Sun's recently announced closures effort has >> barely gotten underway, and no syntax has been chosen. Mark made it >> > clear > >> that syntax he presented at Devoxx was a hastily constructed straw man. >> >> Happy Thanksgiving, >> >> Josh >> >> > It will be interesting to see how they go about doing that choosing. Will it > be a Coin like process, or are Sun going into a closed room and then produce > a result on their own? > > Quoting from Mark Reinhold initial blog entry about closures (http://blogs.sun.com/mr/entry/closures): > Sun will initiate the design and implementation of a simple closures > feature, as outlined above, and add it to JDK 7 > so as to enable broad > experimentation. If all goes well then we?ll later submit a > language-change JSR which would, in turn, be proposed as a component > of the eventual Java SE 7 JSR. > > Revising a programming language that?s in active use by millions of > developers is no small task. Sun neither can nor should do it alone, > so I hereby invite everyone who participated in the earlier closures > conversations?as well as anyone else with an informed opinion?to join us. > -Joe From pbenedict at apache.org Fri Nov 27 15:08:14 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 27 Nov 2009 17:08:14 -0600 Subject: ARM syntax and new keywords Message-ID: Artur, Right on! Backticks are a pretty common escape mechanism in some parts of the computering world (like exotic table names in SQL). I hope the JSR-292 people listen in on your feedback. Paul From hjohn at xs4all.nl Fri Nov 27 16:50:03 2009 From: hjohn at xs4all.nl (John Hendrikx) Date: Sat, 28 Nov 2009 01:50:03 +0100 Subject: ARM syntax and new keywords In-Reply-To: <560fb5ed0911270331r2376f5bfrfffb8eab6ce913e2@mail.gmail.com> References: <560fb5ed0911270331r2376f5bfrfffb8eab6ce913e2@mail.gmail.com> Message-ID: <4B1073BB.4060701@xs4all.nl> Reinier Zwitserloot wrote: > @Cleanup is by far my favourite lombok annotation. Experience working with > it in real code has led me to the conclusion that having cleanup work on a > variable until it runs out of scope, instead of introducing a new block, is > a considerably more natural way to do this. There's far less syntax involved > (just 1 simple marker on a variable declaration, nothing else, and no new > blocks), which really says it all. > Yes, I'm actually a bit surprised that the ARM syntax currently favors the try syntax. Why not simply call a method on any object going out of scope if it implements a certain interface? It would be like finalize, except it would have clearly defined semantics making it useful for automatically cleaning up your resources (ie, it would be called as soon as it goes out of scope). Exceptions being thrown from such a close method should in my opinion simply be disallowed. If your auto cleanup block can't do it's thing without throwing exceptions, then use something else. All this fooling around with annotations, keywords and resource blocks when a decent implementation of finalize could do the trick far easier seems odd to me. From hjohn at xs4all.nl Fri Nov 27 16:53:33 2009 From: hjohn at xs4all.nl (John Hendrikx) Date: Sat, 28 Nov 2009 01:53:33 +0100 Subject: ARM syntax and new keywords In-Reply-To: References: Message-ID: <4B10748D.6080509@xs4all.nl> Paul Benedict wrote: > Artur, > > Right on! Backticks are a pretty common escape mechanism in some parts > of the computering world (like exotic table names in SQL). I hope the > JSR-292 people listen in on your feedback. > > Paul > > To be honest, I see no reason to include such a feature at all, backticks or otherwise. Both look hideously ugly, and if I'm going to have to go through code to add backticks because a new keyword was introduced, I will just rename it instead to avoid using such syntax. Not looking forward to: public T createInstance(Class `class`); Let's just keep: public T createInstance(Class cls); public T createInstance(Class clazz); public T createInstance(Class c); From pbenedict at apache.org Fri Nov 27 17:08:38 2009 From: pbenedict at apache.org (Paul Benedict) Date: Fri, 27 Nov 2009 19:08:38 -0600 Subject: ARM syntax and new keywords In-Reply-To: <4B10748D.6080509@xs4all.nl> References: <4B10748D.6080509@xs4all.nl> Message-ID: John, The backticks are really intended for dynamic languages where they must not be constrainted by Java's identifier lexigram. I sure hope *no one* ever uses it otherwise. Too bad there is no way to turn off that feature unless code is being generated. Paul On Fri, Nov 27, 2009 at 6:53 PM, John Hendrikx wrote: > Paul Benedict wrote: >> >> Artur, >> >> Right on! Backticks are a pretty common escape mechanism in some parts >> of the computering world (like exotic table names in SQL). I hope the >> JSR-292 people listen in on your feedback. >> >> Paul >> >> > > To be honest, I see no reason to include such a feature at all, backticks or > otherwise. ?Both look hideously ugly, and if I'm going to have to go through > code to add backticks because a new keyword was introduced, I will just > rename it instead to avoid using such syntax. > > Not looking forward to: > > public T createInstance(Class `class`); > > Let's just keep: > > public T createInstance(Class cls); > public T createInstance(Class clazz); > public T createInstance(Class c); > > > From tronicek at fit.cvut.cz Sat Nov 28 00:32:10 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Sat, 28 Nov 2009 09:32:10 +0100 Subject: ARM syntax and new keywords In-Reply-To: <4B1073BB.4060701@xs4all.nl> References: <560fb5ed0911270331r2376f5bfrfffb8eab6ce913e2@mail.gmail.com> <4B1073BB.4060701@xs4all.nl> Message-ID: <5a9183018a59633edf369437fb98d5bd.squirrel@imap.fit.cvut.cz> Hi John, how do you want to find out whether the object is accessible at the end of the block? You want to run the garbage collector at each closing brace? Z. -- Zdenek Tronicek FIT CTU in Prague John Hendrikx napsal(a): > Yes, I'm actually a bit surprised that the ARM syntax currently favors > the try syntax. Why not simply call a method on any object going out of > scope if it implements a certain interface? It would be like finalize, > except it would have clearly defined semantics making it useful for > automatically cleaning up your resources (ie, it would be called as soon > as it goes out of scope). > > Exceptions being thrown from such a close method should in my opinion > simply be disallowed. If your auto cleanup block can't do it's thing > without throwing exceptions, then use something else. > > All this fooling around with annotations, keywords and resource blocks > when a decent implementation of finalize could do the trick far easier > seems odd to me. > > > From mthornton at optrak.co.uk Sat Nov 28 00:58:24 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Sat, 28 Nov 2009 08:58:24 +0000 Subject: ARM syntax and new keywords In-Reply-To: <4B10748D.6080509@xs4all.nl> References: <4B10748D.6080509@xs4all.nl> Message-ID: <4B10E630.9060001@optrak.co.uk> John Hendrikx wrote: > Paul Benedict wrote: > >> Artur, >> >> Right on! Backticks are a pretty common escape mechanism in some parts >> of the computering world (like exotic table names in SQL). I hope the >> JSR-292 people listen in on your feedback. >> >> Paul >> >> >> > To be honest, I see no reason to include such a feature at all, > backticks or otherwise. Both look hideously ugly, and if I'm going to > have to go through code to add backticks because a new keyword was > introduced, I will just rename it instead to avoid using such syntax. > > Not looking forward to: > > public T createInstance(Class `class`); > > Let's just keep: > > public T createInstance(Class cls); > public T createInstance(Class clazz); > public T createInstance(Class c); > > > > The main point of the proposal is to allow access to classes, methods, etc written in other languages which have different rules for identifiers. That it also allows people to write silly Java is an unavoidable side effect. Mark Thornton From cowwoc at bbs.darktech.org Sat Nov 28 20:30:29 2009 From: cowwoc at bbs.darktech.org (Gili-2) Date: Sat, 28 Nov 2009 20:30:29 -0800 (PST) Subject: Will Project Coin accept more candidates? Message-ID: <1259469029156-42766.post@n3.nabble.com> Hi, Do you plan on accepting more candidates for Project Coin now that JDK7's schedule has been pushed back by a year? I'd personally like to see multi-catch make it into JDK7. Thank you, Gili -- View this message in context: http://n3.nabble.com/Will-Project-Coin-accept-more-candidates-tp42766p42766.html Sent from the coin-dev mailing list archive at Nabble.com. From reinier at zwitserloot.com Sun Nov 29 01:47:30 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 29 Nov 2009 10:47:30 +0100 Subject: Will Project Coin accept more candidates? In-Reply-To: <1259469029156-42766.post@n3.nabble.com> References: <1259469029156-42766.post@n3.nabble.com> Message-ID: <560fb5ed0911290147x2919bf3el7639a41aeaeef5ad@mail.gmail.com> During the BOF on java language changes at devoxx, closures and multi-catch were both named explicitly as the two things to try to do with the extra time, actually. --Reinier Zwitserloot On Sun, Nov 29, 2009 at 5:30 AM, Gili-2 wrote: > > Hi, > > Do you plan on accepting more candidates for Project Coin now that JDK7's > schedule has been pushed back by a year? > > I'd personally like to see multi-catch make it into JDK7. > > Thank you, > Gili > -- > View this message in context: > http://n3.nabble.com/Will-Project-Coin-accept-more-candidates-tp42766p42766.html > Sent from the coin-dev mailing list archive at Nabble.com. > > From Joe.Darcy at Sun.COM Sun Nov 29 09:47:22 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Nov 2009 09:47:22 -0800 Subject: Will Project Coin accept more candidates? In-Reply-To: <560fb5ed0911290147x2919bf3el7639a41aeaeef5ad@mail.gmail.com> References: <1259469029156-42766.post@n3.nabble.com> <560fb5ed0911290147x2919bf3el7639a41aeaeef5ad@mail.gmail.com> Message-ID: <4B12B3AA.5000908@sun.com> Reinier Zwitserloot wrote: > During the BOF on java language changes at devoxx, closures and multi-catch > were both named explicitly as the two things to try to do with the extra > time, actually. > Yes, while multi-catch is now a possibility for JDK 7, we will *not* be having another Project Coin call for proposals for JDK 7. -Joe > --Reinier Zwitserloot > > > > On Sun, Nov 29, 2009 at 5:30 AM, Gili-2 wrote: > > >> Hi, >> >> Do you plan on accepting more candidates for Project Coin now that JDK7's >> schedule has been pushed back by a year? >> >> I'd personally like to see multi-catch make it into JDK7. >> >> Thank you, >> Gili >> -- >> View this message in context: >> http://n3.nabble.com/Will-Project-Coin-accept-more-candidates-tp42766p42766.html >> Sent from the coin-dev mailing list archive at Nabble.com. >> >> >> > > From pbenedict at apache.org Sun Nov 29 12:58:25 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sun, 29 Nov 2009 14:58:25 -0600 Subject: The philosophy of Nothing In-Reply-To: <7d7138c10911291241v1f0b1ab6o521b3febaa97f583@mail.gmail.com> References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <7d7138c10911291241v1f0b1ab6o521b3febaa97f583@mail.gmail.com> Message-ID: Yes, I understand that the the empty set is a subset of any other set. I looked it up just to refresh myself: http://en.wikipedia.org/wiki/Empty_set But what does an "empty set" (not java.uitl.Set) mean to Java? I perceive "Nothing" as pure .. well, nothingness. I liken such a type to be like NULL in SQL which has no equality -- even to itself. So I have a difficult time accepting that nothing is somehow the set of, or even the type of, something else. Paul On Sun, Nov 29, 2009 at 2:41 PM, Dimitris Andreou wrote: > But you *do* understand that the empty set is a subset of any other set, right? > > 2009/11/29 Paul Benedict : >> Yes, I do have it flipped around. Thank you. I shouldn't enjoy making >> big blunders in public so much. :-) >> >> So let me ask the opposite: >> How can nothing be a type of something? >> >> Paul >> >> On Sun, Nov 29, 2009 at 2:26 PM, Reinier Zwitserloot >> wrote: >>> You've got it flipped around. >>> Nothing is a subtype of Object. (and of String, and of Number, and of >>> Integer, etc). >>> --Reinier Zwitserloot >> > From pbenedict at apache.org Sun Nov 29 13:06:06 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sun, 29 Nov 2009 15:06:06 -0600 Subject: The philosophy of Nothing In-Reply-To: <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> Message-ID: Neal, can clarify this: > There are no elements of the type Nothing. Therefore all of the elements > of the type Nothing are elements of the type T, for every T. The first statement says there are no elements, but the second says there are elements. Paul On Sun, Nov 29, 2009 at 2:57 PM, Neal Gafter wrote: > On Sun, Nov 29, 2009 at 12:33 PM, Paul Benedict > wrote: >> >> Yes, I do have it flipped around. Thank you. I shouldn't enjoy making >> big blunders in public so much. :-) >> >> So let me ask the opposite: >> How can nothing be a type of something? > > A type T is a subtype of a type S iff all of the elements of the type T are > elements of the type S. > > For example, String is a subtype of Object because all of the elements of > the type String are elements of the type Object. > > There are no elements of the type Nothing.? Therefore all of the elements of > the type Nothing are elements of the type T, for every T.? Therefore Nothing > is a subtype of the type T, for every T. > > Cheers, > Neal > From neal at gafter.com Sun Nov 29 13:46:58 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Nov 2009 13:46:58 -0800 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> Message-ID: <15e8b9d20911291346l2186f50cl8cba9cd6567d076a@mail.gmail.com> On Sun, Nov 29, 2009 at 1:06 PM, Paul Benedict wrote: > Neal, can clarify this: > > > There are no elements of the type Nothing. Therefore all of the elements > > of the type Nothing are elements of the type T, for every T. > > The first statement says there are no elements, but the second says > there are elements. > No it doesn't. It is a (vacuously) true statement that does not require the existence of any elements. From neal at gafter.com Sun Nov 29 13:49:40 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Nov 2009 13:49:40 -0800 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <7d7138c10911291241v1f0b1ab6o521b3febaa97f583@mail.gmail.com> Message-ID: <15e8b9d20911291349q20a94975p26160f5cfa59eb1e@mail.gmail.com> On Sun, Nov 29, 2009 at 12:58 PM, Paul Benedict wrote: > Yes, I understand that the the empty set is a subset of any other set. > I looked it up just to refresh myself: > http://en.wikipedia.org/wiki/Empty_set > > But what does an "empty set" (not java.uitl.Set) mean to Java? I > perceive "Nothing" as pure .. well, nothingness. I liken such a type > to be like NULL in SQL which has no equality -- even to itself. > Not the same as NULL. NULL is a value. You can put it in a variable. Nothing, on the other hand, you can't ever get one of. If you try to construct a program that computes an expression of type Nothing then every way yu try to do it you'll find that the program necessarily can't get to the point where the value of type Nothing is present. Such a program must necessarily (by the structure of the type system) transfer control elsewhere before getting to that point, for example by throwing an exception, or "return"ing. Cheers, Neal From reinier at zwitserloot.com Sun Nov 29 13:50:27 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 29 Nov 2009 22:50:27 +0100 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> Message-ID: <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> What neal meant was, anytime the compiler must reason about elements by way of that elements' type, it can reason with safety that any element of type 'Nothing' must clearly be a subtype of everything, and can thus be an acceptable thing in place of any other type. In practice, of course, there are no instances of Nothing. it's a compiler crutch* which helps mark off boundaries where there is nothing but the compiler doesn't know about it. Here's a simple hypothetical example: public ? doSomething() { while (true); } There's no point in writing a return statement in this method. It would be dead code. I could make it return 'void', but my intention is to use this somewhere as a pluggable 'do nothing, forever, except suck down CPU cycles' closure, so being able to fill the return type with something would be useful. What type should it return? "Nothing", of course. A bit more useful: What does this method return? public ? doSomething() { throw new RuntimeException(); } This is where Nothing shines: By having a Nothing type, we can tell the compiler that, well, literally, _nothing_ will be returned. When I call doSomething() from other code, all java has is the signature of this method. It doesn't know that the method will never return normally and always exit with a RuntimeException. By making the return type of doSomething() "Nothing", we let the compiler know that: Q something = doSomething(); is always legal, regardless of Q. It makes doSomething more generic (as in: more generally usable. If doSomething returned "Object", for example, I could NOT pass it into a List's add method! Going even further: List list; list.add(methodCall()); What kind of return type would be legal here for methodCall()? There's no current type that works; Lists of the form ? extends X cannot be added to. But if methodCall never actually returns, then - this would be 'safe' in that the add method never even fires. Nothing lets us tell the type system that all will be well, in a type safe manner. Also, as there can be no instances of Nothing, if you declare that your method returns Nothing, then the compiler will flag an error on every return statement in it. You are FORCED to actually never return from this thing, so, basically, loop endlessly, or throw something. Pragmatically speaking, java isn't functional and doesn't always NEED to return something. We have void. Thus, 'throw' is a statement and not an expression (because if it was, surely the type of a throw expression would be Nothing), System.exit() returns void, etcetera. Hence why java doesn't have a Nothing right now. Languages like haskell and scala have had it since day 1. With generics, java is moving a bit closer to that world. Type-wise, it might help to clearly define what a return type means. It does NOT mean: "This method returns a value that is a T". What it actually means is: "This method will not return something which is not a T." That's because not returning at all (not halting) is always an option. The halting problem says that no type system in the world can verify that you actually return something (that you halt). Well, not in turing complete languages, which java certainly is. Thus, all it can verify is that you NOT return something which is NOT a T. Finally, on the semantics of the word "Nothing" - it's just a word. It was chosen because of precedent; Scala uses it. If you want to know WHY Nothing was chosen, ask Martin Odersky. Or, look at the pragmatic usage, as in the examples I've used here. "Nothing" seems to work out kinda nice: public Nothing throwMe(RuntimeException t) { throw t; } What does that method return? Answer: Nothing - it never returns (normally). *) Perhaps crutch is the wrong word. Give me some leeway while I explain this :) --Reinier Zwitserloot On Sun, Nov 29, 2009 at 10:06 PM, Paul Benedict wrote: > Neal, can clarify this: > > > There are no elements of the type Nothing. Therefore all of the elements > > of the type Nothing are elements of the type T, for every T. > > The first statement says there are no elements, but the second says > there are elements. > > Paul > > On Sun, Nov 29, 2009 at 2:57 PM, Neal Gafter wrote: > > On Sun, Nov 29, 2009 at 12:33 PM, Paul Benedict > > wrote: > >> > >> Yes, I do have it flipped around. Thank you. I shouldn't enjoy making > >> big blunders in public so much. :-) > >> > >> So let me ask the opposite: > >> How can nothing be a type of something? > > > > A type T is a subtype of a type S iff all of the elements of the type T > are > > elements of the type S. > > > > For example, String is a subtype of Object because all of the elements of > > the type String are elements of the type Object. > > > > There are no elements of the type Nothing. Therefore all of the elements > of > > the type Nothing are elements of the type T, for every T. Therefore > Nothing > > is a subtype of the type T, for every T. > > > > Cheers, > > Neal > > > > From pbenedict at apache.org Sun Nov 29 18:14:59 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sun, 29 Nov 2009 20:14:59 -0600 Subject: The philosophy of Nothing In-Reply-To: <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> Message-ID: Thanks Neal. Reiner, your explanation was very good. So basically Nothing can be used outside of closures: public Nothing throwMe(RuntimeException t) { throw t; } 1) Does the Java compiler have to prove a method can never return normally? 2) What is the benefit of telling the compiler the method *must* throw an Exception? Don't say read the spec :-) I did, but it's sparse on the purpose 3) For a method that returns Nothing, if a class transformer alters the method body and actually issues a return, what happens? is a JVM Error thrown? Paul From per at bothner.com Sun Nov 29 18:34:42 2009 From: per at bothner.com (Per Bothner) Date: Sun, 29 Nov 2009 18:34:42 -0800 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> Message-ID: <4B132F42.6000105@bothner.com> On 11/29/2009 06:14 PM, Paul Benedict wrote: 1) Does the Java compiler have to prove a method can never return normally? It should be (and can easily be) integrated with unreachable-code analysis. > 2) What is the benefit of telling the compiler the method *must* throw > an Exception? The useful case, I believe, is specifying that a method never returns "normally" - i.e. it either throws an exception *or* loops forever. Thus any code following a call to such a method is by definition unreachable. public Nothing throwMe(RuntimeException t) { throw t; } public void doit() { throwMe(...); // unreachable here do_something(); // hence this is an error } -- --Per Bothner per at bothner.com http://per.bothner.com/ From tronicek at fit.cvut.cz Sun Nov 29 21:25:33 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 30 Nov 2009 06:25:33 +0100 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> Message-ID: Hi Paul, as far as I know, Nothing is used only by compiler. And I do not see any benifits if I was allowed to use it as an ordinary type in my code. What is the primary purpose of Nothing? Look at closure #() { throw new AssertionError(); } Compiler must infer the return type here. But what it should be? It can be anything because the closure never returns normally. So, compiler will use Nothing which is a subclass of any type. Z. -- Zdenek Tronicek FIT CTU in Prague Paul Benedict napsal(a): > Thanks Neal. Reiner, your explanation was very good. > > So basically Nothing can be used outside of closures: > public Nothing throwMe(RuntimeException t) { > throw t; > } > > 1) Does the Java compiler have to prove a method can never return > normally? > > 2) What is the benefit of telling the compiler the method *must* throw > an Exception? Don't say read the spec :-) I did, but it's sparse on > the purpose > > 3) For a method that returns Nothing, if a class transformer alters > the method body and actually issues a return, what happens? is a JVM > Error thrown? > > Paul > > From pbenedict at apache.org Sun Nov 29 21:53:22 2009 From: pbenedict at apache.org (Paul Benedict) Date: Sun, 29 Nov 2009 23:53:22 -0600 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> Message-ID: Zdenek, Is a problem present if the compiler were to infer it as void? When I put these side-by-side, I don't see any particular issue. closure #() { throw new AssertionError(); } public void something() { throw new AssertionError(); } You can write code today that never returns -- my second example. Paul On Sun, Nov 29, 2009 at 11:25 PM, wrote: > Hi Paul, > > as far as I know, Nothing is used only by compiler. And I do not see any > benifits if I was allowed to use it as an ordinary type in my code. > > What is the primary purpose of Nothing? > Look at closure #() { throw new AssertionError(); } > Compiler must infer the return type here. But what it should be? > It can be anything because the closure never returns normally. > So, compiler will use Nothing which is a subclass of any type. > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > > > Paul Benedict napsal(a): >> Thanks Neal. Reiner, your explanation was very good. >> >> So basically Nothing can be used outside of closures: >> public Nothing throwMe(RuntimeException t) { >> ? ? throw t; >> } >> >> 1) Does the Java compiler have to prove a method can never return >> normally? >> >> 2) What is the benefit of telling the compiler the method *must* throw >> an Exception? Don't say read the spec :-) I did, but it's sparse on >> the purpose >> >> 3) For a method that returns Nothing, if a class transformer alters >> the method body and actually issues a return, what happens? is a JVM >> Error thrown? >> >> Paul >> >> > > From tronicek at fit.cvut.cz Sun Nov 29 22:01:37 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 30 Nov 2009 07:01:37 +0100 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> Message-ID: <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> Yes! Compiler infers the return type to be able to do type checking. And both of these must be correct: Integer i = (#() { throw new AssertionError(); }).invoke(); String s = (#() { throw new AssertionError(); }).invoke(); Z. -- Zdenek Tronicek FIT CTU in Prague Paul Benedict napsal(a): > Zdenek, > > Is a problem present if the compiler were to infer it as void? > > When I put these side-by-side, I don't see any particular issue. > closure #() { throw new AssertionError(); } > public void something() { throw new AssertionError(); } > > You can write code today that never returns -- my second example. > > Paul > > On Sun, Nov 29, 2009 at 11:25 PM, wrote: >> Hi Paul, >> >> as far as I know, Nothing is used only by compiler. And I do not see any >> benifits if I was allowed to use it as an ordinary type in my code. >> >> What is the primary purpose of Nothing? >> Look at closure #() { throw new AssertionError(); } >> Compiler must infer the return type here. But what it should be? >> It can be anything because the closure never returns normally. >> So, compiler will use Nothing which is a subclass of any type. >> >> Z. >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> >> >> Paul Benedict napsal(a): >>> Thanks Neal. Reiner, your explanation was very good. >>> >>> So basically Nothing can be used outside of closures: >>> public Nothing throwMe(RuntimeException t) { >>> ? ? throw t; >>> } >>> >>> 1) Does the Java compiler have to prove a method can never return >>> normally? >>> >>> 2) What is the benefit of telling the compiler the method *must* throw >>> an Exception? Don't say read the spec :-) I did, but it's sparse on >>> the purpose >>> >>> 3) For a method that returns Nothing, if a class transformer alters >>> the method body and actually issues a return, what happens? is a JVM >>> Error thrown? >>> >>> Paul >>> >>> >> >> > From pbenedict at apache.org Sun Nov 29 22:17:08 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 30 Nov 2009 00:17:08 -0600 Subject: The philosophy of Nothing In-Reply-To: <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> Message-ID: Zdenk, In both cases, void or Nothing, there is no return value. So what is the problem you are seeing? Both examples you provided shouldn't compile. Paul On Mon, Nov 30, 2009 at 12:01 AM, wrote: > Yes! Compiler infers the return type to be able to do type checking. And > both of these must be correct: > > Integer i = (#() { throw new AssertionError(); }).invoke(); > String s = (#() { throw new AssertionError(); }).invoke(); > > Z. > -- > Zdenek Tronicek > FIT CTU in Prague > > > Paul Benedict napsal(a): >> Zdenek, >> >> Is a problem present if the compiler were to infer it as void? >> >> When I put these side-by-side, I don't see any particular issue. >> closure #() { throw new AssertionError(); } >> public void something() { throw new AssertionError(); } >> >> You can write code today that never returns -- my second example. >> >> Paul >> >> On Sun, Nov 29, 2009 at 11:25 PM, ? wrote: >>> Hi Paul, >>> >>> as far as I know, Nothing is used only by compiler. And I do not see any >>> benifits if I was allowed to use it as an ordinary type in my code. >>> >>> What is the primary purpose of Nothing? >>> Look at closure #() { throw new AssertionError(); } >>> Compiler must infer the return type here. But what it should be? >>> It can be anything because the closure never returns normally. >>> So, compiler will use Nothing which is a subclass of any type. >>> >>> Z. >>> -- >>> Zdenek Tronicek >>> FIT CTU in Prague >>> >>> >>> Paul Benedict napsal(a): >>>> Thanks Neal. Reiner, your explanation was very good. >>>> >>>> So basically Nothing can be used outside of closures: >>>> public Nothing throwMe(RuntimeException t) { >>>> ? ? throw t; >>>> } >>>> >>>> 1) Does the Java compiler have to prove a method can never return >>>> normally? >>>> >>>> 2) What is the benefit of telling the compiler the method *must* throw >>>> an Exception? Don't say read the spec :-) I did, but it's sparse on >>>> the purpose >>>> >>>> 3) For a method that returns Nothing, if a class transformer alters >>>> the method body and actually issues a return, what happens? is a JVM >>>> Error thrown? >>>> >>>> Paul >>>> >>>> >>> >>> >> > > From tronicek at fit.cvut.cz Sun Nov 29 22:33:41 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 30 Nov 2009 07:33:41 +0100 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> Message-ID: They should compile because Nothing (the type inferred) is a subtype of Integer and String. If the type inferred was void, they should not have compiled. So, Nothing enables the compiler to check types as it does in any other cases. Another example: static T m(#T() p) { return p.invoke(); } Integer i = m(#() { throw new AssertionError(); }); String s = m(#() { throw new AssertionError(); }); new ArrayList().add(#() { throw new AssertionError(); }); Z. -- Zdenek Tronicek FIT CTU in Prague Paul Benedict napsal(a): > Zdenk, > > In both cases, void or Nothing, there is no return value. So what is > the problem you are seeing? Both examples you provided shouldn't > compile. > > Paul > > On Mon, Nov 30, 2009 at 12:01 AM, wrote: >> Yes! Compiler infers the return type to be able to do type checking. And >> both of these must be correct: >> >> Integer i = (#() { throw new AssertionError(); }).invoke(); >> String s = (#() { throw new AssertionError(); }).invoke(); >> >> Z. >> -- >> Zdenek Tronicek >> FIT CTU in Prague >> >> >> Paul Benedict napsal(a): >>> Zdenek, >>> >>> Is a problem present if the compiler were to infer it as void? >>> >>> When I put these side-by-side, I don't see any particular issue. >>> closure #() { throw new AssertionError(); } >>> public void something() { throw new AssertionError(); } >>> >>> You can write code today that never returns -- my second example. >>> >>> Paul >>> >>> On Sun, Nov 29, 2009 at 11:25 PM, ? wrote: >>>> Hi Paul, >>>> >>>> as far as I know, Nothing is used only by compiler. And I do not see >>>> any >>>> benifits if I was allowed to use it as an ordinary type in my code. >>>> >>>> What is the primary purpose of Nothing? >>>> Look at closure #() { throw new AssertionError(); } >>>> Compiler must infer the return type here. But what it should be? >>>> It can be anything because the closure never returns normally. >>>> So, compiler will use Nothing which is a subclass of any type. >>>> >>>> Z. >>>> -- >>>> Zdenek Tronicek >>>> FIT CTU in Prague >>>> >>>> >>>> Paul Benedict napsal(a): >>>>> Thanks Neal. Reiner, your explanation was very good. >>>>> >>>>> So basically Nothing can be used outside of closures: >>>>> public Nothing throwMe(RuntimeException t) { >>>>> ? ? throw t; >>>>> } >>>>> >>>>> 1) Does the Java compiler have to prove a method can never return >>>>> normally? >>>>> >>>>> 2) What is the benefit of telling the compiler the method *must* >>>>> throw >>>>> an Exception? Don't say read the spec :-) I did, but it's sparse on >>>>> the purpose >>>>> >>>>> 3) For a method that returns Nothing, if a class transformer alters >>>>> the method body and actually issues a return, what happens? is a JVM >>>>> Error thrown? >>>>> >>>>> Paul >>>>> >>>>> >>>> >>>> >>> >> >> > From pbenedict at apache.org Sun Nov 29 22:41:33 2009 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 30 Nov 2009 00:41:33 -0600 Subject: The philosophy of Nothing In-Reply-To: References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> Message-ID: <4B13691D.4090805@apache.org> Zdenek, Thank you for your patience. Is this use case any different than reflection or dynamic languages? It sounds like the "Nothing" type returns an Object and automatic casting is performed. So why don't we just use Object as the return value and force a cast? Paul On 11/30/2009 12:33 AM, tronicek at fit.cvut.cz wrote: > They should compile because Nothing (the type inferred) is a subtype of > Integer and String. > If the type inferred was void, they should not have compiled. > So, Nothing enables the compiler to check types as it does in any other > cases. > > Another example: > > static T m(#T() p) { > return p.invoke(); > } > > Integer i = m(#() { throw new AssertionError(); }); > String s = m(#() { throw new AssertionError(); }); > > new ArrayList().add(#() { throw new AssertionError(); }); > > Z. > From tronicek at fit.cvut.cz Sun Nov 29 23:08:03 2009 From: tronicek at fit.cvut.cz (tronicek at fit.cvut.cz) Date: Mon, 30 Nov 2009 08:08:03 +0100 Subject: The philosophy of Nothing In-Reply-To: <4B13691D.4090805@apache.org> References: <560fb5ed0911291226u12ab8729t3d434d70f0fb14bf@mail.gmail.com> <15e8b9d20911291257r78afdae9n2da958b9bf79fb56@mail.gmail.com> <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> <4B13691D.4090805@apache.org> Message-ID: <4f7b9a00f5bac55f3ac06ee99f2220f4.squirrel@imap.fit.cvut.cz> Minor clarification: type is inferred so that the closure can be converted to an interface type. For example: #() { throw new NullPointerException(); } is converted to interface X { Nothing invoke() { throw new NullPointerException(); } } The type checking is done after the conversion. As for the type inferred "Object", it can be done this way. Then, the closure would have been converted to interface Y { Object invoke() { throw new NullPointerException(); } } The original motivation for Nothing (Unreachable then) was to enable passing a closure which returns void as argument to the method like static T withLock(Lock lock, #T() block) Z. -- Zdenek Tronicek FIT CTU in Prague Paul Benedict napsal(a): > Zdenek, > > Thank you for your patience. Is this use case any different than > reflection or dynamic languages? It sounds like the "Nothing" type > returns an Object and automatic casting is performed. So why don't we > just use Object as the return value and force a cast? > > Paul > > On 11/30/2009 12:33 AM, tronicek at fit.cvut.cz wrote: >> They should compile because Nothing (the type inferred) is a subtype of >> Integer and String. >> If the type inferred was void, they should not have compiled. >> So, Nothing enables the compiler to check types as it does in any other >> cases. >> >> Another example: >> >> static T m(#T() p) { >> return p.invoke(); >> } >> >> Integer i = m(#() { throw new AssertionError(); }); >> String s = m(#() { throw new AssertionError(); }); >> >> new ArrayList().add(#() { throw new AssertionError(); }); >> >> Z. >> > > From neal at gafter.com Mon Nov 30 00:54:03 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 00:54:03 -0800 Subject: The philosophy of Nothing In-Reply-To: <4B13691D.4090805@apache.org> References: <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> <4B13691D.4090805@apache.org> Message-ID: <15e8b9d20911300054p6679534bv9281beecb5884cbe@mail.gmail.com> On Sun, Nov 29, 2009 at 10:41 PM, Paul Benedict wrote: > Thank you for your patience. Is this use case any different than > reflection or dynamic languages? It sounds like the "Nothing" type > returns an Object and automatic casting is performed. So why don't we > just use Object as the return value and force a cast? > No cast should be required, as there is no type error. Moreover, the compiler should never allow the code to reach a point at which such a cast could be executed, as a value of type Nothing cannot occur normally (there are no values of type Nothing). Cheers, Neal From reinier at zwitserloot.com Mon Nov 30 02:23:13 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 30 Nov 2009 11:23:13 +0100 Subject: The philosophy of Nothing In-Reply-To: <4B13691D.4090805@apache.org> References: <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> <4B13691D.4090805@apache.org> Message-ID: <560fb5ed0911300223g43a5edecvfd0c6c4bb453e0dd@mail.gmail.com> The need for Nothing is really quite simple. If I have the sort method: Collections.sort(someStringList, some instance of Comparator) and I wish to call it like so: Collections.sort(someStringList, #(String a, String b) { throw new IStillNeedToImplementThisException(); }); then I should be able to. Do you wish to argue that the java compiler should REFUSE to compile this code? If so - why? It's legal just about everywhere else. However, without resorting to target typing, which BGGA/CFJ aren't based on, the compiler cannot figure out that this closure returns 'int'. It never returns, so, as return type means: "I guarantee that this method will NOT return something that is NOT [my return type]", it can infer absolute any type, and that rule will hold, because the method never returns. If I inferred void, then you'd get an error that #(String, String)void is not compatible with the required Comparator, and that would be cryptic. That's bad, so, the compiler would refuse to compile this with an error saying that it can't figure out what you're trying to return. Given that this it doesn't even matter, this is even more cryptic. That's bad, so BGGA/CFJ needs a Nothing type so it can first consider this a closure of #(String, String)Nothing, and then automatically 'box' this closure into the required Comparator (required signature: #(String, String)int), as Nothing is a valid alternative for anything else. Including void. --Reinier Zwitserloot NB: Of course, *WITH* target typing, lack of the Nothing type is not nearly as painful. On Mon, Nov 30, 2009 at 7:41 AM, Paul Benedict wrote: > Zdenek, > > Thank you for your patience. Is this use case any different than > reflection or dynamic languages? It sounds like the "Nothing" type > returns an Object and automatic casting is performed. So why don't we > just use Object as the return value and force a cast? > > Paul > > On 11/30/2009 12:33 AM, tronicek at fit.cvut.cz wrote: > > They should compile because Nothing (the type inferred) is a subtype of > > Integer and String. > > If the type inferred was void, they should not have compiled. > > So, Nothing enables the compiler to check types as it does in any other > > cases. > > > > Another example: > > > > static T m(#T() p) { > > return p.invoke(); > > } > > > > Integer i = m(#() { throw new AssertionError(); }); > > String s = m(#() { throw new AssertionError(); }); > > > > new ArrayList().add(#() { throw new AssertionError(); }); > > > > Z. > > > > > From Joe.Darcy at Sun.COM Mon Nov 30 08:13:52 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Nov 2009 08:13:52 -0800 Subject: Post-Devoxx Project Coin update, closures off-topic for coin-dev Message-ID: <4B13EF40.2090408@sun.com> Hello. As has been announced recently at Devoxx and covered in various places, including previous threads on this list, Mark Reinhold made several announcements about JDK 7 at this year's Devoxx: 1) JDK 7 will have a form of closures. 2) The JDK 7 schedule is being extended to roughly fall 2010. On the first announcement, the coin-dev list is not the appropriate forum to discuss closures in Java. Closures are hereby decreed as off-topic for coin-dev. Mark's blog entry "Closures for Java" (http://blogs.sun.com/mr/entry/closures) invites those with an informed opinion to participate in the current discussion; watch Mark's blog for news about creation of a new list or project, etc., to host this closures effort. On the second announcement, while the JDK 7 schedule has been extended, many of the current final five (or so) Project Coin features have not yet been fully implemented, specified, and tested. Therefore, there will *not* be a general reassessment of Project Coin feature selection or another call for proposals in JDK 7. The final five (or so) proposals remain selected for inclusion in JDK 7 and work will continue to complete those features. However, given its technical merit and the possibility of providing useful infrastructure for ARM, improved exception handling is now being reconsidered for inclusion in JDK 7. No other "for further consideration" proposal is under reconsideration. -Joe From neal at gafter.com Mon Nov 30 08:15:17 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Nov 2009 08:15:17 -0800 Subject: The philosophy of Nothing In-Reply-To: <560fb5ed0911300223g43a5edecvfd0c6c4bb453e0dd@mail.gmail.com> References: <560fb5ed0911291350i4465f1f9n25f4ebb18508cea4@mail.gmail.com> <9f5c28201d5a4206fa4e59ab4881382e.squirrel@imap.fit.cvut.cz> <4B13691D.4090805@apache.org> <560fb5ed0911300223g43a5edecvfd0c6c4bb453e0dd@mail.gmail.com> Message-ID: <15e8b9d20911300815l14c04b46r63bb2d512182fed@mail.gmail.com> On Mon, Nov 30, 2009 at 2:23 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > The need for Nothing is really quite simple. If I have the sort method: > > Collections.sort(someStringList, some instance of Comparator) > > and I wish to call it like so: > > Collections.sort(someStringList, #(String a, String b) { > throw new IStillNeedToImplementThisException(); > }); > > then I should be able to. Do you wish to argue that the java compiler > should > REFUSE to compile this code? If so - why? It's legal just about everywhere > else. However, without resorting to target typing, which BGGA/CFJ aren't > based on, the compiler cannot figure out that this closure returns 'int'. Reinier- The type Nothing plays no role in the process by which the language determines that this code is legal in those specifications. Cheers, Neal