From rssh at gradsoft.com.ua Wed Apr 1 00:16:19 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 1 Apr 2009 10:16:19 +0300 (EEST) Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> Message-ID: > > On Mar 30, 2009, at 10:37 PM, rssh at gradsoft.com.ua wrote: > >>> On Mar 20, 2009, at 1:50 PM, John Rose wrote: >>> >> 3. COMPABILITY - this breaks all code with use $ in string literals. >> (Or I >> read something incorrectly ?) So better prefix such string with >> something. (may be yet one '$' or '@' ?) > > You read incorrectly. Template constructor expressions are distinct > from string literals. They are prefixed with the token "new". > Thanks, I reread you proposal and see that I missed too many during first reading. With explicit compile, I see that - we already have analogical JSR223 mechanism in language, which would be nice to reuse. >> 4. Why just not call this parser from some method ? I. e. what >> arguments >> for including string templates in language itself, instead library >> call ? > > The usual: Sugar like that can help API designers build APIs whose > code is more maintainable: Less noisy. Template-based systems are > popular for a reason. > This would be difference between new "template-text" and new MyCompiler("template-text") // i. e. main magic is in assigned template-expression to appendable. Thanks, now I understand. Hope will be change implement this in (E x: x>=7): Java x > -- John > From Ulf.Zibis at gmx.de Wed Apr 1 01:39:23 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Wed, 01 Apr 2009 10:39:23 +0200 Subject: Proposal and updates OVERSEEN Message-ID: <49D3283B.4040709@gmx.de> Hi Joe, in the last update of your blog, you have overseen my proposal: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001163.html and it's update: Extend switch .. case statement for all types and simple expressions Also you've overseen this update: Simply implicit method invocation chaining Hopefully you will update your blog :-) -Ulf From tim.lebedkov at googlemail.com Wed Apr 1 02:00:06 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Wed, 1 Apr 2009 11:00:06 +0200 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: <28bca0ff0903310658k15b0c9abk45270080ab7cf7af@mail.gmail.com> References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> <28bca0ff0903302340s3aa480a4h3f675ca5e1a00741@mail.gmail.com> <28bca0ff0903310658k15b0c9abk45270080ab7cf7af@mail.gmail.com> Message-ID: Hello Marek, now it's more clear to me why you use 'final'. Thanks Tim On Tue, Mar 31, 2009 at 3:58 PM, Marek Kozie? wrote: > W dniu 31 marca 2009 15:43 u?ytkownik Tim Lebedkov > napisa?: >> Hello Marek, >> >> my proposal (http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001055.html) >> is very similar to yours (it just uses 'auto' instead of 'final'). >> >> Does yours declare variables as final (I mean here 'constant') only >> because you try to avoid introducing a new keyword? Or is there >> another motivation? >> >> Tim >> > > First of all I want Java to have clear separation on variables and values. > And then: > - variables should have explicit type. > - values should have clear context; > > While now people use variables even if they need value, it's because > cost using value is higher than using variable. This provide worse > code, more bugs, and provoke reusing variables. > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From tim.lebedkov at googlemail.com Wed Apr 1 02:02:53 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Wed, 1 Apr 2009 11:02:53 +0200 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> <28bca0ff0903302340s3aa480a4h3f675ca5e1a00741@mail.gmail.com> Message-ID: Hello Reinier, 2009/3/31 Reinier Zwitserloot : > FWIW, I'm -strongly- in favour of implicit typing for final local method > variables, and opposed to extending this for non-finals, not just because > its hard to come up with a syntax for it, due to there being no readily > available keywords or operators to do it with. := comes to mind, but that's > about it. > > NB2: If you want to push forward with this proposal anyway, I strongly > suggest you rewrite it to this, which would be far more backwards > compatible: > > foo := expression; > > instead of: > > auto foo = expression; Thank you for the suggestion, but I think 'auto' is better and fits better in the current language. Regards --Tim From Ulf.Zibis at gmx.de Wed Apr 1 02:17:30 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Wed, 01 Apr 2009 11:17:30 +0200 Subject: Extend switch .. case statement for all types and simple expressions In-Reply-To: <49D14427.5070105@gmx.de> References: <49D14427.5070105@gmx.de> Message-ID: <49D33129.2090600@gmx.de> I would like to add, that the MAJOR ADVANTAGE of my proposal is, that the numerous grades/levels of this proposal could be implemented step by step, depending on the complexity of changes, which could be done for JDK 7. More sophisticated grades/levels could be seamlessly added later. This would be impossible, if the concurring syntax of "Strings in switch", which only compares for equality, comes to account. Also Multiple switch expressions and case ranges could seamlessly be integrated in my proposal. As I argued more detailed before, default semantic of "switch..case" should stay on determining the cases by IDENTITY. Strings, which are equal, could simply be made identical by String#intern(). Example: switch (myStringFromElsewere.intern()) { case STRING1 : ...; // all constants are interned by definition case STRING2 : ...; // " " case "foo" : ...; // automatically interned case "bar" : ...; // " " ... } -Ulf Am 31.03.2009 00:13, Ulf Zibis schrieb: > AUTHOR(S): Ulf Zibis, Cologne, Germany > > OVERVIEW > FEATURE SUMMARY: Extend switch .. case statement for all types and simple expressions. > MAJOR ADVANTAGE: > - Increases readability of source in concurrence to if .. else if .. else syntax. > - Sophisticated jumps. > - maybe in some cases javac and hotspot has chance to compute better optimized code. > MAJOR BENEFIT: > Stop some programmers escaping to some modern scripting language. > MAJOR DISADVANTAGE: > Programmers from other languages, especially C, may be confused about such rich syntax. > > EXAMPLES > SIMPLE EXAMPLE: > (1): > switch( myObject) { > case CONSTANT1 : doSomething(); break; > case CONSTANT2 : doSomethingElse(); break; > default : doSomethingDefault(); > } > (2): > switch( myString) { > case equals("red") : stop(); break; > case equals("green") : go(); break; > default : openYourEyesForCrossingTraffic(); > } > (3): > switch( myString) { > case equalsIgnoreCase("RED") : sureStop(); break; > case equalsIgnoreCase("GREEN") : sureGo(); break; > default : beAwareOfPoliceWachtingYou(); > } > > ADVANCED EXAMPLE: > (4): > switch( primitiveInt) { > case == 10 : doOnlyIf10(); // alternative syntax for 'case 10:' > case < 10 : > case >= 20 : break; > default : doOnlyInRange(); > } > (5): > switch( primitiveInt) { > case (>= 10 && < 20) : doOnlyInRange(); > default : throw new Exception("Out of range"); > } > (6): > switch( myString) { > case contains("foo") : doSomething(); break; > case regionMatches(true, 2, otherString, 4, 6) : doSomethingElse(); break; > default : doSomethingDefault(); > } > (7): > switch( myString.equals()) { // alternative: myString.equals(..) > case "foo" : foo(); break; > case "bar" : bar(); break; > default : dontCare(); > } > (8): > switch( className.startsWith("String", ..)) { // alternative: className.startsWith("String", ?) > case 0 : doForSimpleName(); break; > case 9 : doForFullName(); break; > default : canNotDecide(); > } > (9): > switch( anyObjectOrPrimitive instanceof) { // note, that casting is solved implicit > case boolean, byte, ... float : break; // Don't do anything > case double : forDouble(anyObjectOrPrimitive); > case HashMap : > case TreeMap : forPlattformMap(anyObjectOrPrimitive); break; > case Map : forOtherMap(anyObjectOrPrimitive); break; > default : forObject(anyObjectOrPrimitive); > } > (10): (minimizee chance for NPE) > switch( .equals(myString)) { // alternative: ?.equals(myString) > case "foo" : foo(); break; > case "bar" : bar(); break; > default : dontCare(); > } > (11): > switch( some_lethargic_function_we_cant_call_much().equals(..) ) { > case "this": > case "that": this_or_that(); break; > case "bigjump": big(); // fall > case "jump": jump(); break; > case "secondlastchance": > case "lastchance": last_chance(); break; > default: do_default(); > } > .. as replacement for: > String sSomeString = some_lethargic_function_we_cant_call_much(); > if( sSomeString.equals( "this" ) || sSomeString.equals( "that" ) ) > this_or_that(); > else if( sSomeString.equals( "jump" ) || sSomeString.equals( "bigjump" ) ) > { > if( sSomeString.equals( "bigjump" ) ) > big(); > jump(); > } else if( sSomeString.equals( "secondlastchance" ) || > sSomeString.equals( "lastchance" ) ) > { > last_chance(); > } else do_default(); > > ALTERNATIVES: > (12): > switch( myString) { // note the '.', I personally would prefer this alternative! > case .equals("red") : stop(); break; > case .equals("green") : go(); break; > default : openYourEyesForCrossingTraffic(); > } > (13): > switch( primitiveInt) { // note the '.' > case (. >= 10 && . < 20) : doOnlyInRange(); > // case (? >= 10 && ? < 20) : doOnlyInRange(); // alternative > default : throw new Exception("Out of range"); > } > > > DETAILS > SPECIFICATION: > The new syntax should be interpreted as > switch ( leftExpressionPart ) { > case rightExpressionPart1 : > case rightExpressionPart2 : > ... > default : > } > The result of entire expression should be boolean type. > There is shortcut for: > leftExpressionPart: intVariable > rightExpressionPart: == intLiteral > (the '==' could be ommitted.) > > COMPILATION: > Compiler could first pre-compile to appropriate if..then..else syntax. > Bytecode would not be affected, but in special cases it could be more compact, if noted > pre-compilation would be replaced by sophisticated optimization. > TESTING: > Compiler byte-code results for new syntax should be same than from equivalent hand-coded legacy > if..then..else syntax > . Exception: sophisticated optimization. > LIBRARY SUPPORT: No supporting libraries are needed for the feature? > REFLECTIVE APIS: There should not be any affection to reflection API. > OTHER CHANGES: No. > MIGRATION: > No refactoring is needed to stay compatible. > > COMPATIBILITY > BREAKING CHANGES: > No previously valid programs are now invalid. > ... but ATTENTION: > If proposals from some other guys regarding "Strings in switch" would be taken into JDK 7, there > won't be any compatible way to implement my more general proposal in future version of JDK !!! > --> So switch .. case statement should compare for IDENTITY if not syntactically determined otherwise. > --> compare for EQUALITY would also break semantic of existing switch .. case statement. > Another reason, why I'm against comparing for equality by default syntax, is, that it is good > practice to use String constants instead of widely spreaded String literals with same signature for > numerous reasons (performance, error prone, ...). The "only-for-String" syntax would lead > programmers to stay on widely spreaded String literals of same value. > If constant is not available for switch variable (e.g. if read from stream), variable could be > internalized before, so it's instance becomes identical to the existing constant. > ===>> If just "Strings in switch" is taken over for JDK 7, there is NO NEED, to compare for equality. > EXISTING PROGRAMS: > Source and class files of earlier platform versions interact with the feature without any notice. > > REFERENCES > http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000213.html > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000855.html > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001089.html > http://forums.java.net/jive/thread.jspa?messageID=27781沅 > http://forums.java.net/jive/thread.jspa?messageID=15769㶙 > http://forums.java.net/jive/thread.jspa?messageID=27773汽 > http://forums.java.net/jive/thread.jspa?messageID=11393ⲁ > http://lasu2string.blogspot.com/2008/12/string-switch-small-language-changes-on.html > EXISTING BUGS: > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5012262 > URL FOR PROTOTYPE (optional): > > > > > > > > From jl0235 at yahoo.com Wed Apr 1 06:21:39 2009 From: jl0235 at yahoo.com (james lowden) Date: Wed, 1 Apr 2009 06:21:39 -0700 (PDT) Subject: Opportunity Cost and Proposal Selection In-Reply-To: <49D2CA2F.1040401@sun.com> Message-ID: <751882.88756.qm@web63706.mail.re1.yahoo.com> Joe- I noticed that the version of the "large arrays" linked from your blog is the older (and messier) one; I updated it to this one: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000869.html --- On Tue, 3/31/09, Joe Darcy wrote: > From: Joe Darcy > Subject: Opportunity Cost and Proposal Selection > To: "coin-dev at openjdk.java.net" > Date: Tuesday, March 31, 2009, 8:58 PM > Hello. > > There has been some traffic on the list about criteria for > proposal > selection (and non-selection) and I wanted to discuss that > briefly. > > First, a reminder from some earlier blog entries describing > the context > for Project Coin: > > "Especially with the maturity of the Java platform, > the onus is on the > proposer to convince that a language change should go in; > the onus is > not to prove the change should stay out." > http://blogs.sun.com/darcy/entry/criteria_for_desirable_small_language > December 23, 2008 > > "Given the rough timeline for JDK 7 and other on-going > efforts to change > the language, such as modules and annotations on types, > only a limited > number of small changes can be considered for JDK 7." > http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > December 11, 2008 > > With nearly 70 proposals submitted to the mailing list and > the Sun bug > database having well over 100 open "requests for > enhancements" (rfe's) > for the language, the large majority of those proposals and > rfe's will > *not* be included in JDK 7 as part of Project Coin or any > other effort. > > Project Coin will be limited to around 5 proposals total. > That's it. > > Therefore for Project Coin, in addition to determining > whether a > proposal to change the language is in and of itself > appropriate, a > determination also has to be made as to whether the change > is more > compelling than all but four or so other proposals. > > In economic terms, there an an opportunity cost in the > proposal > selection; that is, because of finite resources, choosing > to have a > particular proposal in the platform removes the opportunity > to do other > proposals. > > There will be good, compelling proposals that would improve > the language > *not* selected for Project Coin because there are a full > set of better, > more compelling proposals that are more useful to include > instead. > > Having available prototypes for proposals, running the > existing tests, > and writing new tests can only better inform the > forthcoming proposal > evaluation and selection. > > -Joe From glenn.a.marshall at gmail.com Wed Apr 1 07:12:40 2009 From: glenn.a.marshall at gmail.com (Glenn A. Marshall) Date: Wed, 1 Apr 2009 10:12:40 -0400 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <15e8b9d20903310751m2da11e10q97ea59c4ffed1bd2@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <980366fa0903310522u31ac7641r6a1554c188122175@mail.gmail.com> <15e8b9d20903310751m2da11e10q97ea59c4ffed1bd2@mail.gmail.com> Message-ID: <980366fa0904010712r5ce024c6xaf0185cf923dc068@mail.gmail.com> I understand that the grammar to handle this, if it was implemented in the obvious way (analogous to the dangling else) is hackish and thus not preferred. I sympathize and agree with this. I agree that this increases the effort/cost to implement this proposal, as well as make the grammar more hackish on an ongoing basis. Part of the assessment is to consider the cost, thus this is a relevant point. This proposal is still in an early state, and does not have an prototype implementation, nor a proposed grammar, both of which would reduce the cost to implement this proposal. I understand that some implementation questions will be resolved if the grammar component of the implementation was available, and it was unambiguous, from a grammar perspective. But you seem to be saying something else - that, conceptually, from a code perspective this proposal isn't clear. Can you elaborate please? I believe the code snippet you originally provided is handled. Tom: you seemed to be saying that you thought this was clear, originally, then later you also raised questions - have your questions been answered? On Tue, Mar 31, 2009 at 10:51 AM, Neal Gafter wrote: > On Tue, Mar 31, 2009 at 5:22 AM, Glenn A. Marshall > wrote: > > Indeed, the grammar would change. It was my hope that this proposal was > > sufficiently detailed that the grammar changes needed would be clear, > > conceptually. Are they? > > Not to me. Seeing the (unambiguous) grammar for your proposal would > clear up a bunch of questions. > From glenn.a.marshall at gmail.com Wed Apr 1 07:33:35 2009 From: glenn.a.marshall at gmail.com (Glenn A. Marshall) Date: Wed, 1 Apr 2009 10:33:35 -0400 Subject: Opportunity Cost and Proposal Selection Message-ID: <980366fa0904010733o5655fe5di10aa2c44883f7a6e@mail.gmail.com> Will the details of the proposal evaluations be published? The thinking here is that for proposals that almost made the cut, perhaps the evaluations would reveal where a bit more work might push them over the line for the next round - increase benefit/decrease cost. This is assuming there will be a next round. Any thoughts on round II? It would seem to be worth considering, given the level of interest. It would, of course, have to wait until Java 8, but why not start early? Surely you're busy with round I for now, but perhaps there could be a parallel effort, with the initial effort primarily around email. thanks for doing all of this, Glenn From neal at gafter.com Wed Apr 1 07:39:57 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 1 Apr 2009 07:39:57 -0700 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <980366fa0904010712r5ce024c6xaf0185cf923dc068@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <980366fa0903310522u31ac7641r6a1554c188122175@mail.gmail.com> <15e8b9d20903310751m2da11e10q97ea59c4ffed1bd2@mail.gmail.com> <980366fa0904010712r5ce024c6xaf0185cf923dc068@mail.gmail.com> Message-ID: <15e8b9d20904010739w3d877199k2846e84cb7cb47b@mail.gmail.com> On Wed, Apr 1, 2009 at 7:12 AM, Glenn A. Marshall wrote: > But you seem to be saying something else - that, conceptually, from a code > perspective this proposal isn't clear.? Can you elaborate please?? I believe > the code snippet you originally provided is handled. The usual technique for handling the dangling else problem is to rewrite the grammar so that it is no longer ambiguous. In other words, programs that under an ambiguous grammar would have more than one interpretation will, under the rewritten grammar, get a single interpretation. I gave an example that is ambiguous in your proposal. Instead of suggesting that it would be handled in one way or another, you said that it would be illegal. That's not the same solution normally applied to the dangling-else problem. A more precise specification in the form of a grammar would help us better understand what you have in mind. However, I believe the question is moot because I don't believe this proposal has any chance of being considered. Besides lacking a specification, it doesn't address a common pain point for Java programmers or add to the expressive power of the language. From fw at deneb.enyo.de Wed Apr 1 08:56:27 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 01 Apr 2009 17:56:27 +0200 Subject: PROPOSAL: 'final' without explicit type References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> <28bca0ff0903291422s77f11c44j4ddf6ea45ec0b669@mail.gmail.com> Message-ID: <87zlf0pduc.fsf@mid.deneb.enyo.de> * Marek Kozie?: > void noInterection(T t,K k){ > if (boo)t=k; // Type mismatch: cannot convert from K to T > ... > } The assignment is not type-safe anyway, as the following modification shows: T noInterection(T t,K k){ if (boo)t=k; // Type mismatch: cannot convert from K to T return t; } This would allow to convert values of any type which implements I1 and I2 to any other type which implements the two interfaces, which is clearly bogus. Consequently, I think your snippet doesn't show what you claim. From alexandre.makarenko at free.fr Wed Apr 1 10:16:54 2009 From: alexandre.makarenko at free.fr (alexandre.makarenko at free.fr) Date: Wed, 1 Apr 2009 19:16:54 +0200 (CEST) Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <28bca0ff0903310631o2cb0b4dey19e857514cece0e8@mail.gmail.com> Message-ID: <14413946.4511781238606214731.JavaMail.root@spooler2-g27.priv.proxad.net> Hi Marek, could you comment this please Read: class Bar { public String name; public Bar right; } class Root { public Bar right; public Bar left; public Root(Bar right, Bar left) { this.left = this.// left is set here right = right; } } alex ----- Original Message ----- From: "Marek Kozie?" To: "Derek Foster" Cc: coin-dev at openjdk.java.net Sent: Tuesday, March 31, 2009 3:31:13 PM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna Subject: Re: Naked dot - accessing object fields through unqualified "." [C1] 2009/3/29 Derek Foster : > The major problem I have with this proposal is that it does not address the point of why I use a prefix on field names. As such, I would still continue to use a prefix even if this proposal were implemented. > > In short, I use a prefix to avoid typographical mistakes, like this one: > > void setFoo(Thing foob) { // Typo! > ? ?this.foo = foo; > } > > This will compile, and no warnings are produced, but it ends up assigning foo to itself, which is not what was intended. > > Your proposal has exactly the same problem: > > void setFoo(Thing foob) { // Typo! > ? ?.foo = foo; > } > > It therefore does not substitute for a field prefix, which WILL fix the problem: > > void setFoo(Thing foob) { // Typo! > ? ?_foo = foo; // ERROR! Undefined variable 'foo'. > } > You can use: Eclipse -> Java -> Code Style -> Edit -> Member Access -> Use 'this' qualifier for field access. (Always) > So unless you had some way to make use of the dot prefix mandatory and the only legal way to access fields (which I would like, but which would be an extremely backwards-incompatible change that will never happen in Java), I don't see that adding an optional dot prefix helps the situation except to reduce typing in constructor and setter methods slightly. > > (Note: I would love a "self-assignment is forbidden" change to Java. If I have time after my other proposals, I might write one up. (Anyone else want to volunteer? This one is easy!) I might be willing to forego prefixes and use the "this.foo = foo" approach, or even the ".foo = foo" approach, if I was sure it wouldn't cause me to fall into the self-assignment trap.) > > Derek > > > Read: class Bar { public String name; public Bar right; } class Root { public Bar right; public Bar left; public Root(Bar right, Bar left) { this.left = left// left is set here .right = right; } } Did you noticed missing semicolon? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From christian at fi12.de Wed Apr 1 11:03:14 2009 From: christian at fi12.de (Christian Fischer) Date: Wed, 1 Apr 2009 20:03:14 +0200 (CEST) Subject: Proposal: Sameness operators In-Reply-To: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.n et> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: These $-operators doesn't seem intuitive to me, but replacing equal-calls sounds interesting. Maybe a better solution would be something like this: if (a eq b) // equals if (a ne b) // not equal if (a lt b) // lesser than if (a le b) // lesser or equal .... From Thomas.Hawtin at Sun.COM Wed Apr 1 11:26:43 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Wed, 01 Apr 2009 19:26:43 +0100 Subject: Proposal: Sameness operators In-Reply-To: References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <49D3B1E3.8070109@sun.com> Christian Fischer wrote: > These $-operators doesn't seem intuitive to me, but replacing equal-calls > sounds interesting. > > Maybe a better solution would be something like this: > if (a eq b) // equals > if (a ne b) // not equal > if (a lt b) // lesser than > if (a le b) // lesser or equal Along with other concerns, four new keywords?! Theoretically they could be context sensitive, but then we are boxing in the grammar. If something like this were to be done (and let's face it, operator overloading ain't gonna happen in JDK7), then I think there needs to be to changes in fundamental direction of the proposal. * We need new symbols. .<. and the like were proposed in another similar proposal. So long as the symbol is a sequence of characters which is not valid in an existing Java program (outside of comments and literal strings). * I think it's clear that we can't use Comparable.compareTo and Object.equals. It requires a new method for each operator. Tom From Joe.Darcy at Sun.COM Wed Apr 1 11:54:40 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 01 Apr 2009 11:54:40 -0700 Subject: Opportunity Cost and Proposal Selection In-Reply-To: <751882.88756.qm@web63706.mail.re1.yahoo.com> References: <751882.88756.qm@web63706.mail.re1.yahoo.com> Message-ID: <49D3B870.7030601@sun.com> james lowden wrote: > Joe- > > I noticed that the version of the "large arrays" linked from your blog is the older (and messier) one; I updated it to this one: > > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000869.html > Hello. I added a link to the revised version. -Joe From Joe.Darcy at Sun.COM Wed Apr 1 12:55:14 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 01 Apr 2009 12:55:14 -0700 Subject: Proposal and updates OVERSEEN In-Reply-To: <49D3283B.4040709@gmx.de> References: <49D3283B.4040709@gmx.de> Message-ID: <49D3C6A2.2040505@sun.com> Ulf Zibis wrote: > Hi Joe, > > in the last update of your blog, you have overseen my proposal: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001163.html > and it's update: > Extend switch .. case statement for all types and simple expressions > > > Also you've overseen this update: > Simply implicit method invocation chaining > > > Hopefully you will update your blog :-) > > -Ulf > > Blog updated accordingly. Thanks, -Joe From howard.lovatt at iee.org Wed Apr 1 13:34:07 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 2 Apr 2009 07:34:07 +1100 Subject: Proposal idea - generators In-Reply-To: <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> References: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> Message-ID: <3dd3f56a0904011334n50b17e59rd2ffaab5985b018a@mail.gmail.com> Hi Neal, I couldn't see in your blog where the problem is. Note I am not proposing, and I don't believe the original poster was either, a continuation style yield. More a Scala and other non-lazy functional language style were the results are stored in a Map and the Map is returned, i.e. like applying (mapping) a function to each element of a list but with more control (in particular break and continue functionality). Maybe you read the original post differently to me. -- Howard. 2009/4/1 Neal Gafter : > On Tue, Mar 31, 2009 at 4:14 AM, Howard Lovatt wrote: >> You can write a library to do this and also have break/continue >> control and parallel processing if needed: >> >> ? ? ? http://www.artima.com/weblogs/viewpost.jsp?thread=240412 > > Howard- > > Your library does not "do this". ?See > http://gafter.blogspot.com/2007/07/internal-versus-external-iterators.html > for an explanation of why not. > > Regards, > Neal > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From neal at gafter.com Wed Apr 1 14:41:34 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 1 Apr 2009 14:41:34 -0700 Subject: Proposal idea - generators In-Reply-To: <3dd3f56a0904011334n50b17e59rd2ffaab5985b018a@mail.gmail.com> References: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> <3dd3f56a0904011334n50b17e59rd2ffaab5985b018a@mail.gmail.com> Message-ID: <15e8b9d20904011441l3736b6b4me3ac78808bb9f450@mail.gmail.com> On Wed, Apr 1, 2009 at 1:34 PM, Howard Lovatt wrote: > Note I am not > proposing, and I don't believe the original poster was either, a > continuation style yield. More a Scala and other non-lazy functional > language style were the results are stored in a Map and the Map is > returned, i.e. like applying (mapping) a function to each element of a > list but with more control (in particular break and continue > functionality). Scala's comprehensions using their standard libraries are lazy. See, for example, Iterator.range. C#'s iterator methods are translated into a state machine (i.e. coroutines) and are inherently lazy. F# and OCaml are the most widely used non-lazy functional languages, but their comprehensions are lazy too. So I'm not sure what you're saying your proposal is comparable to. From neal at gafter.com Wed Apr 1 14:56:34 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 1 Apr 2009 14:56:34 -0700 Subject: Proposal idea - generators In-Reply-To: <15e8b9d20904011441l3736b6b4me3ac78808bb9f450@mail.gmail.com> References: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> <3dd3f56a0904011334n50b17e59rd2ffaab5985b018a@mail.gmail.com> <15e8b9d20904011441l3736b6b4me3ac78808bb9f450@mail.gmail.com> Message-ID: <15e8b9d20904011456r8084a0dsf4f6878c1fa4a5a8@mail.gmail.com> On Wed, Apr 1, 2009 at 2:41 PM, Neal Gafter wrote: > On Wed, Apr 1, 2009 at 1:34 PM, Howard Lovatt wrote: >> Note I am not >> proposing, and I don't believe the original poster was either, a >> continuation style yield. More a Scala and other non-lazy functional >> language style were the results are stored in a Map and the Map is >> returned, i.e. like applying (mapping) a function to each element of a >> list but with more control (in particular break and continue >> functionality). > > Scala's comprehensions using their standard libraries are lazy. ?See, > for example, Iterator.range. ?C#'s iterator methods are translated > into a state machine (i.e. coroutines) and are inherently lazy. ?F# > and OCaml are the most widely used non-lazy functional languages, but > their comprehensions are lazy too. ?So I'm not sure what you're saying > your proposal is comparable to. I may be wrong about OCaml's generators. From develop4lasu at gmail.com Wed Apr 1 15:28:15 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 00:28:15 +0200 Subject: Proposal and updates OVERSEEN In-Reply-To: <49D3C6A2.2040505@sun.com> References: <49D3283B.4040709@gmx.de> <49D3C6A2.2040505@sun.com> Message-ID: <28bca0ff0904011528p1041b241yc1d41bcb546bc2ad@mail.gmail.com> 2009/4/1 Joseph D. Darcy : > > Blog updated accordingly. > > Thanks, > > -Joe > Hi. I'll add my: Updated proposals: - Return 'this' http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001185.html - 'final' without explicit type http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001178.html Can be removed: - 'This' type - while it require from generics to have tagged types it's not possible to introduce it into language. - Enhanced while statement - It was created only to show complex problems with loops. Missed: - Delegation proposal http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000477.html - 'forget' keyword http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001093.html Even if they were missed by reason I would like to know that. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Wed Apr 1 16:05:38 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 01:05:38 +0200 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <14413946.4511781238606214731.JavaMail.root@spooler2-g27.priv.proxad.net> References: <28bca0ff0903310631o2cb0b4dey19e857514cece0e8@mail.gmail.com> <14413946.4511781238606214731.JavaMail.root@spooler2-g27.priv.proxad.net> Message-ID: <28bca0ff0904011605x6d65fd7cqf87d058ae0d3724d@mail.gmail.com> 2009/4/1 : > Hi Marek, > could you comment this please > > Read: > ? ? class Bar { > ? ? ? ? ?public String ? ? name; > ? ? ? ? ?public Bar ? ? ? ? ?right; > ? ? } > > ? ? class Root { > ? ? ? ? ?public Bar ? ? right; > ? ? ? ? ?public Bar ? ? left; > > ? ? ? ? ?public Root(Bar right, Bar left) { > ? ? ? ? ? ? ? this.left = this.// left is set here > ? ? ? ? ? ? ? right = right; > ? ? ? ? ?} > > ? ? } > > > alex > Hi. This was measured that if you split expresion into more lines operator should be placed at start: Operator(s) (during splitting exprestion into two lines) should be placed in a new line, like: String s = "could you comment this please " // + "\n\nRead:"; This is easier to read, bacause it shows directly that previous line need to be checked to understand this one. What's more, operator placed in the end of the line can be over the screen. So, this line: this.left = this.// left is set here is consider to be bad style. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Wed Apr 1 17:20:43 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 1 Apr 2009 17:20:43 -0700 Subject: Proposal idea - generators In-Reply-To: <5090A08F-7225-477B-A390-D3A73A62823E@gmail.com> References: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> <3dd3f56a0904011334n50b17e59rd2ffaab5985b018a@mail.gmail.com> <15e8b9d20904011441l3736b6b4me3ac78808bb9f450@mail.gmail.com> <15e8b9d20904011456r8084a0dsf4f6878c1fa4a5a8@mail.gmail.com> <5090A08F-7225-477B-A390-D3A73A62823E@gmail.com> Message-ID: <15e8b9d20904011720t349fd2e4x98ee29b16328cd86@mail.gmail.com> On Wed, Apr 1, 2009 at 4:13 PM, Howard Lovatt wrote: > My reading of the Scala Language Specification, page 83, is that the for > loop is translated into a map call (or similar). Therefore whether this is > lazy or not is an implementation detail. So I think it is valid to eagerly > evaluate the loop and store the results in a hash map. After all, the > current Java for loop evaluates eagerly. Whether a given Iterator used in a Java for-each loop produces its values eagerly or lazily is an implementation detail of that iterator. Requiring it to be eager reduces the flexibility. From howard.lovatt at gmail.com Wed Apr 1 16:13:08 2009 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Thu, 2 Apr 2009 10:13:08 +1100 Subject: Proposal idea - generators In-Reply-To: <15e8b9d20904011456r8084a0dsf4f6878c1fa4a5a8@mail.gmail.com> References: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> <3dd3f56a0904011334n50b17e59rd2ffaab5985b018a@mail.gmail.com> <15e8b9d20904011441l3736b6b4me3ac78808bb9f450@mail.gmail.com> <15e8b9d20904011456r8084a0dsf4f6878c1fa4a5a8@mail.gmail.com> Message-ID: <5090A08F-7225-477B-A390-D3A73A62823E@gmail.com> My reading of the Scala Language Specification, page 83, is that the for loop is translated into a map call (or similar). Therefore whether this is lazy or not is an implementation detail. So I think it is valid to eagerly evaluate the loop and store the results in a hash map. After all, the current Java for loop evaluates eagerly. Functional languages like Mathematica, which are extensively used in Science and maths, eagerly evalate and store the results. In fact this is a common array generation means. -- Howard On 02/04/2009, at 8:56 AM, Neal Gafter wrote: > On Wed, Apr 1, 2009 at 2:41 PM, Neal Gafter wrote: >> On Wed, Apr 1, 2009 at 1:34 PM, Howard Lovatt >> wrote: >>> Note I am not >>> proposing, and I don't believe the original poster was either, a >>> continuation style yield. More a Scala and other non-lazy functional >>> language style were the results are stored in a Map and the Map is >>> returned, i.e. like applying (mapping) a function to each element >>> of a >>> list but with more control (in particular break and continue >>> functionality). >> >> Scala's comprehensions using their standard libraries are lazy. See, >> for example, Iterator.range. C#'s iterator methods are translated >> into a state machine (i.e. coroutines) and are inherently lazy. F# >> and OCaml are the most widely used non-lazy functional languages, but >> their comprehensions are lazy too. So I'm not sure what you're >> saying >> your proposal is comparable to. > > I may be wrong about OCaml's generators. > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ From markmahieu at googlemail.com Wed Apr 1 23:05:17 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 2 Apr 2009 07:05:17 +0100 Subject: Proposal and updates OVERSEEN In-Reply-To: <28bca0ff0904011528p1041b241yc1d41bcb546bc2ad@mail.gmail.com> References: <49D3283B.4040709@gmx.de> <49D3C6A2.2040505@sun.com> <28bca0ff0904011528p1041b241yc1d41bcb546bc2ad@mail.gmail.com> Message-ID: One more :) The 'Rethrows Clause' proposal was also updated with JLS references, here: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001198.html (The proposal and prototype linked to at http://slm888.com/javac/coin-rethrows.html has a further minor adjustment to simplify the rules around exception type constructors which themselves throw checked exceptions). Mark 2009/4/1 Marek Kozie? > 2009/4/1 Joseph D. Darcy : > > > > Blog updated accordingly. > > > > Thanks, > > > > -Joe > > > > Hi. > I'll add my: > > > Updated proposals: > - Return 'this' > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001185.html > > - 'final' without explicit type > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001178.html > > > > Can be removed: > - 'This' type - while it require from generics to have tagged types > it's not possible to introduce it into language. > - Enhanced while statement - It was created only to show complex > problems with loops. > > > > Missed: > - Delegation proposal > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000477.html > > - 'forget' keyword > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001093.html > > Even if they were missed by reason I would like to know that. > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From scolebourne at joda.org Thu Apr 2 04:39:56 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 2 Apr 2009 12:39:56 +0100 Subject: Helping to find the usefulness of a proposal Message-ID: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> All, One possible way I'd like to suggest that the coin evaluation could be helped would be to write a script to find out how frequently the specific issue comes up in real code. It should be possible to devise, write and run a script to find the number of LOCs affected by many of the proposals. For example: - strings in switch (find if else on constant strings) - multi-catch (find duplicate catch blocks) - elvis operator (find ternary and if else defaulting) - for each where the iterator remove can be accessed (% of loops that access iterator) - for each where index is needed (% of loops that use int looping) - method and field literals - byte and short literals and probably many others (I've just listed some proposals I remember) Ideally, any script would be ASM/BCEL based, but grep style might work too. I mention all this because I don't have the spare time to write such a script, but if you do, then I'm sure we'd all like to run it and discuss the results ;-) Stephen From markmahieu at googlemail.com Thu Apr 2 04:44:21 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 2 Apr 2009 12:44:21 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: Definitely. I did that for the Auto-assigned Parameters proposal actually, but I chose to use javac's parser and then did my own analysis based on the AST. There might be something generically useful I can split out from that hacked-up code, if people want to use the same technique. Mark 2009/4/2 Stephen Colebourne > All, > One possible way I'd like to suggest that the coin evaluation could be > helped would be to write a script to find out how frequently the > specific issue comes up in real code. > > It should be possible to devise, write and run a script to find the > number of LOCs affected by many of the proposals. For example: > > - strings in switch (find if else on constant strings) > - multi-catch (find duplicate catch blocks) > - elvis operator (find ternary and if else defaulting) > - for each where the iterator remove can be accessed (% of loops that > access iterator) > - for each where index is needed (% of loops that use int looping) > - method and field literals > - byte and short literals > and probably many others (I've just listed some proposals I remember) > > Ideally, any script would be ASM/BCEL based, but grep style might work too. > > I mention all this because I don't have the spare time to write such a > script, but if you do, then I'm sure we'd all like to run it and > discuss the results ;-) > > Stephen > > From reinier at zwitserloot.com Thu Apr 2 04:46:30 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 13:46:30 +0200 Subject: Proposal: Sameness operators In-Reply-To: <49D3B1E3.8070109@sun.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> Message-ID: <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> Why can't we use compareTo and equals? .<. syntax had severe problems that disqualified them - see the archive of this mailing list. 'is' has slightly more precedence than 'eq' and the set 'eq', 'ne', 'lt', and 'le' need 'gt' and 'ge' as well, which makes them rather unwieldy. You can reduce a thing or two by going with just 'eq', 'lt' and 'gt', filling the holes with && and ! as usual (not equal becomes ! (a eq b)), or even a !eq b, but this is all devolving into way too much slap-dash language design unless those become global, non-context sensitive keywords. I'm okay with that, but Joe Darcy definitely isn't, so that's right out, at least for now. More symbols is similarly unwieldy; there are no appropriate symbols for these operations available. It would be an even greater mistake to come up with some non-standard and unwieldly syntax for them, such as $=. That way lies perl cartoon-swearing craziness and nobody wants that. Wholesale operator overloading would be far preferable to that situation. ":=" for some sort of inference typing would make some sense and is still free, but that's about where it ends. The cleanest solution to me remains a cleaning of the slate, so to speak, and an explicit demarkation in your source file that you're on 'new java', such as with "source 1.8". With that at the top, "a == b" is compiled the same way as old java's "a == null ? b == null : a.equals(b)" for non-boxable objects (for unboxables and primitives, Unbox everything you can, then do a numeric comparison, or if it's primitive v. object, error), "a < b" and its ilk translate to .compareTo for non-unboxable Comparables, lead to unboxing for unboxables, no change for primitives, and error otherwise. Past mistakes are rectified, blahblahblah. We've been over this before, I'm sure most coin-dev readers have a good idea about how such a thing would work and the decade+ timerift it would cause between code bases that (stubbornly?) stay with non-new java. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Apr 1, 2009, at 20:26, Tom Hawtin wrote: > Christian Fischer wrote: >> These $-operators doesn't seem intuitive to me, but replacing equal- >> calls >> sounds interesting. >> >> Maybe a better solution would be something like this: >> if (a eq b) // equals >> if (a ne b) // not equal >> if (a lt b) // lesser than >> if (a le b) // lesser or equal > > Along with other concerns, four new keywords?! Theoretically they > could > be context sensitive, but then we are boxing in the grammar. > > If something like this were to be done (and let's face it, operator > overloading ain't gonna happen in JDK7), then I think there needs to > be > to changes in fundamental direction of the proposal. > > * We need new symbols. .<. and the like were proposed in another > similar proposal. So long as the symbol is a sequence of characters > which is not valid in an existing Java program (outside of comments > and > literal strings). > > * I think it's clear that we can't use Comparable.compareTo and > Object.equals. It requires a new method for each operator. > > Tom > From peter.levart at gmail.com Thu Apr 2 04:59:25 2009 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 2 Apr 2009 13:59:25 +0200 Subject: Proposal: Automatic Resource Management Message-ID: Hello Coiners! The debate about ARM proposal has calmed down lately and I was thinking about it last few days. Initially I submitted a comment that got lost by list processor and was about using a "marker" interface as a supertype of sigle-method disposable interfaces like this: package java.lang; public interface AutomaticResource {} ... and for example, retroffiting java.io.Closeable: package java.io; public interface Closeable extends AutomaticResource { void close() throws IOException; } ... this way even the name of the method would not be "coined". There would have to be some rules that compiler will enforce to make sure it can uniquely identify the method to be called on resource disposal (for example: the static type of the resource should not directly or indirectly implement or extend two different single-method interfaces marked with AutomaticResource marker superinterface). But then I thought. Why would this language feature even have to be tied to a particular interface. The "foreach" loop did take this approach with java.lang.Iterable, but this had nothing to do with exceptions and catching them and ignoring them silently. A language construct that hides this often cited "bad practice" under the carpet is no good! For example, this snippet of code, written to the proposed ARM spec., submited by Bob Lee in this thread a month ago, asking Neal Gafter to demonstrate how the equivalent BGGA version would look like: try (InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest)) { byte[] buf = new byte[8 * 1024]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } catch (IOException e) { showDialog("Copy failed."); } ... is flawed. This code does not guarantee that in the absence of shown exception the file has been copied in it's intirety. Ignoring exception thrown on an InputStream.close() might be desireable, but ignoring exception thrown on OutputStream.close() migh mean that you don't mind missing writing some final bytes into the file. Closing OutputStream should not be part of automatic resource disposal but part of main code block. This brings us to the question how is ARM supposed to be able do differentiate InputStream from OutputStream if both implement Closeable? So I thought how to circumvent these two weeknesses. My take on this is something like the following: try (InputStream in = new FileInputStream("inputFile"); OutputStream out = new FileOutputStream("outputFile")) { // try body } catch (IOException e) { // catch body } finally (IOException e1 : in.close(); IOException e2 : out.close()) { // finally body } ... would be translated to ... { IOException e1 = null; IOException e2 = null; try { InputStream in = new FileInputStream("inputFile"); try { OutputStream out = new FileOutputStream("outputFile"); try { // try body } finally { try { out.close(); } catch (IOException $$e) { e2 = $$e; } } } finally { try { in.close(); } catch (IOException $$e) { e1 = $$e; } } } catch (IOException e) { // catch body } finally { // finally body } } ... no special interfaces are used here. The code to dispose of resources is clearly visible (it has to be writen, yes, but that also means that it can be read, which is a good thing). The above example is the "full monty" version. The thing to note is that a try (...; ...; ...) construct is to be matched by an optional finally (...; ...; ...) construct in that both, if the second is specified, must have an equal number of semicolons. Each "statement" in the try construct gets it's own slot that must be matched by the coresponding slot in the finally (...; ...; ...) construct. Any slot in finally construct can be left empty (like any of the 3 slots in the for (;;) statement). The following minimal version is also possible (in this example no catching of exceptions on resource cleanup is attempted): int i, j; ReadWriteLock iLock = ...; ReadWriteLock jLock = ...; // ... try (jLock.readLock().lock(); iLock.writeLock().lock()) { i += j; } finally (jLock.readLock().unlock(); iLock.writeLock().unlock()) ... gets translated to: { jLock.readLock().lock(); try { iLock.writeLock().lock(); try { i += j; } finally { iLock.writeLock().unlock(); } } finally { jLock.readLock().unlock(); } } All this will have to be formalized. This is just an idea to keep the debate going. Regards, Peter From rssh at gradsoft.com.ua Thu Apr 2 05:03:33 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 2 Apr 2009 15:03:33 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <9ca625bf5b892e4a94f495a155f66e6f.squirrel@wmail.gradsoft.ua> > All, > One possible way I'd like to suggest that the coin evaluation could be > helped would be to write a script to find out how frequently the > specific issue comes up in real code. > > It should be possible to devise, write and run a script to find the > number of LOCs affected by many of the proposals. For example: > Clever idea. If I would know, that one will used, I will wrote one during next week-end. > - strings in switch (find if else on constant strings) > - multi-catch (find duplicate catch blocks) > - elvis operator (find ternary and if else defaulting) > - for each where the iterator remove can be accessed (% of loops that > access iterator) > - for each where index is needed (% of loops that use int looping) > - method and field literals > - byte and short literals > and probably many others (I've just listed some proposals I remember) > > Ideally, any script would be ASM/BCEL based, but grep style might work > too. > > I mention all this because I don't have the spare time to write such a > script, but if you do, then I'm sure we'd all like to run it and > discuss the results ;-) > > Stephen > > From pdoubleya at gmail.com Thu Apr 2 05:15:35 2009 From: pdoubleya at gmail.com (Patrick Wright) Date: Thu, 2 Apr 2009 14:15:35 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <64efa1ba0904020515m679910b4n1be9cce0034e474d@mail.gmail.com> This would be useful. One might be able to start by building on the infrastructure in Checkstyle, PMD or FindBugs for some of these. I don't know about FindBugs, but the other two allow you to write your own matching rules. Jackpot could be used as well, but it's no longer maintained as an independent project (now part of NB refactoring infrastructure). One would have to use a slightly older version of it. Patrick From scolebourne at joda.org Thu Apr 2 05:24:32 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 2 Apr 2009 13:24:32 +0100 Subject: Proposal: Sameness operators In-Reply-To: <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> Message-ID: <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> The best alternative operator symbols I've come up with yet are bracketed ones: a (==) b a (<) b I don't think that the symbols are ideal, but they do look reasonably readable, and its way better than .equals(). Do I expect anything to happen here? No. There is a long history of "operator overloading" being frowned on in the Java language. The net result is more of an argument to use Groovy, Scala, Fan etc. Stephen 2009/4/2 Reinier Zwitserloot : > Why can't we use compareTo and equals? > > .<. syntax had severe problems that disqualified them - see the > archive of this mailing list. > > 'is' has slightly more precedence than 'eq' and the set 'eq', 'ne', > 'lt', and 'le' need 'gt' and 'ge' as well, which makes them rather > unwieldy. You can reduce a thing or two by going with just 'eq', 'lt' > and 'gt', filling the holes with && and ! as usual (not equal becomes ! > (a eq b)), or even a !eq b, but this is all devolving into way too > much slap-dash language design unless those become global, non-context > sensitive keywords. I'm okay with that, but Joe Darcy definitely > isn't, so that's right out, at least for now. > > More symbols is similarly unwieldy; there are no appropriate symbols > for these operations available. It would be an even greater mistake to > come up with some non-standard and unwieldly syntax for them, such as > $=. That way lies perl cartoon-swearing craziness and nobody wants > that. Wholesale operator overloading would be far preferable to that > situation. ":=" for some sort of inference typing would make some > sense and is still free, but that's about where it ends. > > > The cleanest solution to me remains a cleaning of the slate, so to > speak, and an explicit demarkation in your source file that you're on > 'new java', such as with "source 1.8". With that at the top, "a == b" > is compiled the same way as old java's "a == null ? b == null : > a.equals(b)" for non-boxable objects (for unboxables and primitives, > Unbox everything you can, then do a numeric comparison, or if it's > primitive v. object, error), "a < b" and its ilk translate > to .compareTo for non-unboxable Comparables, lead to unboxing for > unboxables, no change for primitives, and error otherwise. Past > mistakes are rectified, blahblahblah. We've been over this before, I'm > sure most coin-dev readers have a good idea about how such a thing > would work and the decade+ timerift it would cause between code bases > that (stubbornly?) stay with non-new java. > > > > ?--Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On Apr 1, 2009, at 20:26, Tom Hawtin wrote: > >> Christian Fischer wrote: >>> These $-operators doesn't seem intuitive to me, but replacing equal- >>> calls >>> sounds interesting. >>> >>> Maybe a better solution would be something like this: >>> if (a eq b) // equals >>> if (a ne b) // not equal >>> if (a lt b) // lesser than >>> if (a le b) // lesser or equal >> >> Along with other concerns, four new keywords?! Theoretically they >> could >> be context sensitive, but then we are boxing in the grammar. >> >> If something like this were to be done (and let's face it, operator >> overloading ain't gonna happen in JDK7), then I think there needs to >> be >> to changes in fundamental direction of the proposal. >> >> ?* We need new symbols. .<. and the like were proposed in another >> similar proposal. So long as the symbol is a sequence of characters >> which is not valid in an existing Java program (outside of comments >> and >> literal strings). >> >> ?* I think it's clear that we can't use Comparable.compareTo and >> Object.equals. It requires a new method for each operator. >> >> Tom >> > > > From reinier at zwitserloot.com Thu Apr 2 05:24:42 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 14:24:42 +0200 Subject: Proposal: Automatic Resource Management In-Reply-To: References: Message-ID: <370F8DB1-A374-43B4-9F83-ABCD5A925D93@zwitserloot.com> I remember quite a bit of discussion on that. Some of the problems no one really solved: - What if one object ends up implementing multiple interfaces that are all AutomaticResource subtypes? Call all of them? Compile-time error? What if that situation happens at runtime due to updating a library? Class Validation? Close all of them in that case, but compile- time error if the compiler detects such a situation? Runtime exception? - What if one implements AutomaticResource but has multiple methods? Who is responsible for warning? Compiler? What if I construct a class file with this 'bug' in it? Its easy even without ASM: Use jruby, jython, or just an older version of javac. Piece of pie. The JVM can't just up and crash when it encounters such a type, so some sort of behaviour must be specified. You also seem to mistaken about the ARM proposal's 'exception hiding' principle. As I understand it, this is relevant ONLY if the guarded scope (=contents of the try block) threw an exception of its own. You can't throw 2 exceptions simultaneously in java, so one of them has to win out. Normally, in try/finally blocks, whatever the finally block does wins, but for ARM, the idea is that the try block's exception wins, because often .close() will fail if some method on the resource itself also failed, and the problem is probably better described with a more useful stack trace on the original. If a try block ends normally, but during resource cleanup the .close() causes an exception, that exception will propagate out, it will NOT be ignored! There is no need to catch exceptions wafting off of InputStream.close() because they basically never happen. The thing that is strongly preferable is to take the annoyance of having to worry about InputStream.close() away from the programmer, which ARM essentially does. The problem isn't IOExceptions being thrown by close(), the problem is InputStream.close()'s declaration that it throws this exception, which forces you to handle it. This isn't the only erroneous checked exception in java (new String(somebytes, "UTF-8") declares that it can throw the checked UnsupportedEncodingException, eventhough it actually cant, because UTF-8 is guaranteed by the JVM spec to exist. The appropriate way to handle this is to catch the UEncEx, and rethrow it as an InternalError("JVM Bug"). But I digress - at any rate, InputStream.close() in practice doesn't throw exceptions unless there's a good reason for it, whereas the UEncEx from String. is *defined* that it MUST NOT throw that exception, which puts it in a different ballpark). Your proposal is vague to me: What, exactly, are e1 and e2? Will one of them be non-null if there is an exception? What happens if I leave my finally body empty, which is what I imagine most people who are in a hurry will do? Just get ignored? That would be very bad. Having to remember the order of the try-block's parameters because these are applied to the finally parameters also strikes me as particularly bad design; making mistakes in ordering seems like a great way to make a puzzler. --Reinier Zwitserloot On Apr 2, 2009, at 13:59, Peter Levart wrote: > Hello Coiners! > > The debate about ARM proposal has calmed down lately and I was > thinking > about it last few days. Initially I submitted a comment that got > lost by > list processor and was about using a "marker" interface as a > supertype of > sigle-method disposable interfaces like this: > > > package java.lang; > > public interface AutomaticResource {} > > > ... and for example, retroffiting java.io.Closeable: > > > package java.io; > > public interface Closeable extends AutomaticResource { > void close() throws IOException; > } > > > ... this way even the name of the method would not be "coined". > There would > have to be some rules that compiler will enforce to make sure it can > uniquely identify the method to be called on resource disposal (for > example: > the static type of the resource should not directly or indirectly > implement > or extend two different single-method interfaces marked with > AutomaticResource marker superinterface). > > But then I thought. Why would this language feature even have to be > tied to > a particular interface. The "foreach" loop did take this approach with > java.lang.Iterable, but this had nothing to do with exceptions and > catching > them and ignoring them silently. A language construct that hides > this often > cited "bad practice" under the carpet is no good! > > For example, this snippet of code, written to the proposed ARM spec., > submited by Bob Lee in this thread a month ago, asking Neal Gafter to > demonstrate how the equivalent BGGA version would look like: > > try (InputStream in = new FileInputStream(src); > OutputStream out = new FileOutputStream(dest)) { > byte[] buf = new byte[8 * 1024]; > int n; > while ((n = in.read(buf)) >= 0) > out.write(buf, 0, n); > } catch (IOException e) { > showDialog("Copy failed."); > } > > ... is flawed. This code does not guarantee that in the absence of > shown > exception the file has been copied in it's intirety. > > Ignoring exception thrown on an InputStream.close() might be > desireable, but > ignoring exception thrown on OutputStream.close() migh mean that you > don't > mind missing writing some final bytes into the file. Closing > OutputStream > should not be part of automatic resource disposal but part of main > code > block. This brings us to the question how is ARM supposed to be able > do > differentiate InputStream from OutputStream if both implement > Closeable? > > So I thought how to circumvent these two weeknesses. My take on this > is > something like the following: > > > try (InputStream in = new FileInputStream("inputFile"); > OutputStream out = new FileOutputStream("outputFile")) > { > // try body > } > catch (IOException e) > { > // catch body > } > finally (IOException e1 : in.close(); > IOException e2 : out.close()) > { > // finally body > } > > > ... would be translated to ... > > > { > IOException e1 = null; > IOException e2 = null; > > try > { > InputStream in = new FileInputStream("inputFile"); > > try > { > OutputStream out = new > FileOutputStream("outputFile"); > > try > { > // try body > } > finally > { > try > { > out.close(); > } > catch (IOException $$e) > { > e2 = $$e; > } > } > } > finally > { > try > { > in.close(); > } > catch (IOException $$e) > { > e1 = $$e; > } > } > } > catch (IOException e) > { > // catch body > } > finally > { > // finally body > } > } > > > > ... no special interfaces are used here. The code to dispose of > resources is > clearly visible (it has to be writen, yes, but that also means that > it can > be read, which is a good thing). > > The above example is the "full monty" version. The thing to note is > that a > try (...; ...; ...) construct is to be matched by an optional > finally (...; > ...; ...) construct in that both, if the second is specified, must > have an > equal number of semicolons. Each "statement" in the try construct > gets it's > own slot that must be matched by the coresponding slot in the > finally (...; > ...; ...) construct. Any slot in finally construct can be left empty > (like > any of the 3 slots in the for (;;) statement). > > The following minimal version is also possible (in this example no > catching > of exceptions on resource cleanup is attempted): > > int i, j; > ReadWriteLock iLock = ...; > ReadWriteLock jLock = ...; > > // ... > > try (jLock.readLock().lock(); iLock.writeLock().lock()) { > i += j; > } > finally (jLock.readLock().unlock(); iLock.writeLock().unlock()) > > > ... gets translated to: > > > { > jLock.readLock().lock(); > try { > iLock.writeLock().lock(); > try { > i += j; > } > finally { > iLock.writeLock().unlock(); > } > } > finally { > jLock.readLock().unlock(); > } > } > > > All this will have to be formalized. This is just an idea to keep > the debate > going. > > Regards, Peter > From reinier at zwitserloot.com Thu Apr 2 05:25:38 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 14:25:38 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: <64efa1ba0904020515m679910b4n1be9cce0034e474d@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <64efa1ba0904020515m679910b4n1be9cce0034e474d@mail.gmail.com> Message-ID: <8FD8F030-FE9E-4225-ABD0-40E043B6F1ED@zwitserloot.com> ... or resurrect it by ripping it out of netbeans. I love the idea of jackpot and am saddened that it is no longer a stand-alone thing. --Reinier Zwitserloot On Apr 2, 2009, at 14:15, Patrick Wright wrote: > This would be useful. > > One might be able to start by building on the infrastructure in > Checkstyle, PMD or FindBugs for some of these. I don't know about > FindBugs, but the other two allow you to write your own matching > rules. Jackpot could be used as well, but it's no longer maintained as > an independent project (now part of NB refactoring infrastructure). > One would have to use a slightly older version of it. > > > > Patrick > From develop4lasu at gmail.com Thu Apr 2 05:28:13 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 14:28:13 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> 2009/4/2 Stephen Colebourne : > All, > One possible way I'd like to suggest that the coin evaluation could be > helped would be to write a script to find out how frequently the > specific issue comes up in real code. > > It should be possible to devise, write and run a script to find the > number of LOCs affected by many of the proposals. For example: > > - strings in switch (find if else on constant strings) > - multi-catch (find duplicate catch blocks) > - elvis operator (find ternary and if else defaulting) > - for each where the iterator remove can be accessed (% of loops that > access iterator) > - for each where index is needed (% of loops that use int looping) > - method and field literals > - byte and short literals > and probably many others (I've just listed some proposals I remember) > > Ideally, any script would be ASM/BCEL based, but grep style might work too. > > I mention all this because I don't have the spare time to write such a > script, but if you do, then I'm sure we'd all like to run it and > discuss the results ;-) > > Stephen > > We may list all proposals and write opinions & statistics (as we think). -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Thomas.Hawtin at Sun.COM Thu Apr 2 05:29:17 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Thu, 02 Apr 2009 13:29:17 +0100 Subject: Proposal: Sameness operators In-Reply-To: <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> Message-ID: <49D4AF9D.9090407@sun.com> Reinier Zwitserloot wrote: > Why can't we use compareTo and equals? * compareTo may well be unreasonably inefficient. * equals handles nulls (asymmetrically), compareTo does not * equals does test-and-cast (event for generic types - urgh), compareTo uses generics * equals does not throw ClassCastException, compareTo does (but probably shouldn't with generics) Therefore, new methods please. I'm sure you are aware the whole subject of operator overloading in general is a minefield. > .<. syntax had severe problems that disqualified them - see the > archive of this mailing list. Other than reminding me of the F-language, as a lexical token it is perfectly upstanding. The IDE behaviour is a bonus (well I find menus popping up as I type almost as annoying as Flash adverts and b***king cursors, but you get what I mean). > The cleanest solution to me remains a cleaning of the slate, so to Making a slight change wouldn't be an effective cleaning of the slate, IMO. Lots of downsides (not necessarily to you in particular) and not enough upsides. Anyway, I think we all knew which way the wind was blowing on proposals like this one from the start of the process. Tom Hawtin From reinier at zwitserloot.com Thu Apr 2 05:36:24 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 14:36:24 +0200 Subject: Proposal: Sameness operators In-Reply-To: <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> Message-ID: <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> It's certainly the best backwards compatible alternative that I have ever seen, but they are still FAR from ideal. Take your average programmer who is just reading some code. He first sees: a == b He rightly assumes this is some sort of equality check, though he would probably be surprised to learn that in java, it's object pointer identity, not object equality, if a and b are objects. Still, that's one sort of (mostly useless) equality, and it is the same as C's meaning for this operation, which is not an unimportant benefit, because many things in java that look indistinguishable from C code do roughly the same thing. Then he sees: a (==) b a few lines down, and now he's just confused and will need to hit the books to figure any of this out. I'll grant you that the readability of the current situation is not very good either, and I will certainly grant that the practical nature of the == operator is very bad indeed (In fact, when this comes up in discussion, I always suggest just dropping support for object identity altogether in the language, and moving that to System.identicalPointers(a, b) or some such. Who needs to know about this stuff? Nobody. It's like copying arrays quickly. Yes, java should be capable of doing it, but not even close to useful enough to warrant an operator!) Crazy idea: We can get a little closer to ideal by creating a class in java lang with useful static methods which you can then import, like: public static void is(Object x, Object y) { if ( x == null ) return y == null; return x.equals(y); } public static void is(Object x, int y) { // Yes, you'd need a few gazillion is methods to cover all the primitives on either side, but 1 static import will grab all of them } ... loads more is methods Then same with lt, gt, le, ge. Then you could write: if ( is(a, b) ) { //doStuff } Which is a small improvement. Add an ability to specify 'as infix' in static imports, and you have pretty much what we all want without backwards compatibility issues: import static java.lang.Equality.is infix; if ( a is b ) { //do something } I'd consider that a large improvement. In my perfect world: ':=' is assignment, assignment to a boolean is no longer an expression but just a statement to avoid bugs, '=' is equality, and '==' is a deprecated syntax for System.identicalPointer, or just '=' for primitives/unboxables. That would no longer be even remotely compatible with java as is, though. --Reinier Zwitserloot On Apr 2, 2009, at 14:24, Stephen Colebourne wrote: > The best alternative operator symbols I've come up with yet are > bracketed ones: > > a (==) b > a (<) b > > I don't think that the symbols are ideal, but they do look reasonably > readable, and its way better than .equals(). > > Do I expect anything to happen here? No. There is a long history of > "operator overloading" being frowned on in the Java language. The net > result is more of an argument to use Groovy, Scala, Fan etc. > > Stephen > > > 2009/4/2 Reinier Zwitserloot : >> Why can't we use compareTo and equals? >> >> .<. syntax had severe problems that disqualified them - see the >> archive of this mailing list. >> >> 'is' has slightly more precedence than 'eq' and the set 'eq', 'ne', >> 'lt', and 'le' need 'gt' and 'ge' as well, which makes them rather >> unwieldy. You can reduce a thing or two by going with just 'eq', 'lt' >> and 'gt', filling the holes with && and ! as usual (not equal >> becomes ! >> (a eq b)), or even a !eq b, but this is all devolving into way too >> much slap-dash language design unless those become global, non- >> context >> sensitive keywords. I'm okay with that, but Joe Darcy definitely >> isn't, so that's right out, at least for now. >> >> More symbols is similarly unwieldy; there are no appropriate symbols >> for these operations available. It would be an even greater mistake >> to >> come up with some non-standard and unwieldly syntax for them, such as >> $=. That way lies perl cartoon-swearing craziness and nobody wants >> that. Wholesale operator overloading would be far preferable to that >> situation. ":=" for some sort of inference typing would make some >> sense and is still free, but that's about where it ends. >> >> >> The cleanest solution to me remains a cleaning of the slate, so to >> speak, and an explicit demarkation in your source file that you're on >> 'new java', such as with "source 1.8". With that at the top, "a == b" >> is compiled the same way as old java's "a == null ? b == null : >> a.equals(b)" for non-boxable objects (for unboxables and primitives, >> Unbox everything you can, then do a numeric comparison, or if it's >> primitive v. object, error), "a < b" and its ilk translate >> to .compareTo for non-unboxable Comparables, lead to unboxing for >> unboxables, no change for primitives, and error otherwise. Past >> mistakes are rectified, blahblahblah. We've been over this before, >> I'm >> sure most coin-dev readers have a good idea about how such a thing >> would work and the decade+ timerift it would cause between code bases >> that (stubbornly?) stay with non-new java. >> >> >> >> --Reinier Zwitserloot >> Like it? Tip it! >> http://tipit.to >> >> >> >> On Apr 1, 2009, at 20:26, Tom Hawtin wrote: >> >>> Christian Fischer wrote: >>>> These $-operators doesn't seem intuitive to me, but replacing >>>> equal- >>>> calls >>>> sounds interesting. >>>> >>>> Maybe a better solution would be something like this: >>>> if (a eq b) // equals >>>> if (a ne b) // not equal >>>> if (a lt b) // lesser than >>>> if (a le b) // lesser or equal >>> >>> Along with other concerns, four new keywords?! Theoretically they >>> could >>> be context sensitive, but then we are boxing in the grammar. >>> >>> If something like this were to be done (and let's face it, operator >>> overloading ain't gonna happen in JDK7), then I think there needs to >>> be >>> to changes in fundamental direction of the proposal. >>> >>> * We need new symbols. .<. and the like were proposed in another >>> similar proposal. So long as the symbol is a sequence of characters >>> which is not valid in an existing Java program (outside of comments >>> and >>> literal strings). >>> >>> * I think it's clear that we can't use Comparable.compareTo and >>> Object.equals. It requires a new method for each operator. >>> >>> Tom >>> >> >> >> > From mthornton at optrak.co.uk Thu Apr 2 05:48:15 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 02 Apr 2009 13:48:15 +0100 Subject: Proposal: Sameness operators In-Reply-To: <49D4AF9D.9090407@sun.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> Message-ID: <49D4B40F.2010100@optrak.co.uk> Tom Hawtin wrote: > Reinier Zwitserloot wrote: > >> Why can't we use compareTo and equals? >> > > * compareTo may well be unreasonably inefficient. > * equals handles nulls (asymmetrically), compareTo does not > * equals does test-and-cast (event for generic types - urgh), > compareTo uses generics > * equals does not throw ClassCastException, compareTo does (but > probably shouldn't with generics) > > Therefore, new methods please. I'm sure you are aware the whole subject > of operator overloading in general is a minefield. > a.compareTo(b) == 0 and a.equals(b) are not always the same, sometimes for very good reasons. I seem to remember that there is at least one such class in the Java platform. Mark Thornton From rssh at gradsoft.com.ua Thu Apr 2 05:56:20 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 2 Apr 2009 15:56:20 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <64efa1ba0904020515m679910b4n1be9cce0034e474d@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <64efa1ba0904020515m679910b4n1be9cce0034e474d@mail.gmail.com> Message-ID: <7a2038dee31c8246dde1340615ec8b3a.squirrel@wmail.gradsoft.ua> > This would be useful. > > One might be able to start by building on the infrastructure in > Checkstyle, PMD or FindBugs for some of these. I don't know about > FindBugs, but the other two allow you to write your own matching > rules. Jackpot could be used as well, but it's no longer maintained as > an independent project (now part of NB refactoring infrastructure). > One would have to use a slightly older version of it. > With JavaChecker infrastructure (http://redmine.gradsoft.ua/projects/show/javachecker) it's easy to write declarative rules for counting source-code patterns. For example, rule for catching exception with empty catch block look's like: catch($x,Block(NIL)) -> true [ violationDiscovered(EmptyCatchBlock, "empty catch block",$x) ]. And as I know, this is one tool, which contains own Java resolver. (jackport can use javacc resolver, CheckStyle and PMD does not have resolvers yet; FindBugs work with .class files, so it can check only compiled stuff). But I will have time to write rules only during next week-end; if anybody want to write this rules earlier - I recommend use JavaChecker as starting point Reading sources and some introductory article: (for example http://www.gradsoft.ua/eng/whitepapers/secr2008/secr2008-1.html) must be enough for starting hacking. > > > Patrick > > From david.goodenough at linkchoose.co.uk Thu Apr 2 06:07:21 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 2 Apr 2009 14:07:21 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <200904021407.24330.david.goodenough@linkchoose.co.uk> On Thursday 02 April 2009, Stephen Colebourne wrote: > All, > One possible way I'd like to suggest that the coin evaluation could be > helped would be to write a script to find out how frequently the > specific issue comes up in real code. > > It should be possible to devise, write and run a script to find the > number of LOCs affected by many of the proposals. For example: > > - strings in switch (find if else on constant strings) > - multi-catch (find duplicate catch blocks) > - elvis operator (find ternary and if else defaulting) > - for each where the iterator remove can be accessed (% of loops that > access iterator) > - for each where index is needed (% of loops that use int looping) > - method and field literals > - byte and short literals > and probably many others (I've just listed some proposals I remember) > > Ideally, any script would be ASM/BCEL based, but grep style might work too. > > I mention all this because I don't have the spare time to write such a > script, but if you do, then I'm sure we'd all like to run it and > discuss the results ;-) > > Stephen As a matter of interest, how would you go about finding the instances of the problem that my lightweight properties proposal aims to solve, i.e. field names in strings (binding frameworks, SQL and Criteria strings, and PropertyChangeSupport events). You could always just build a list of fields and look for all strings that contained those string values (they might be EL strings, or parts of an SQL statement), but I think you would come up with a large number of false positives. There are plenty of instances of this out there, but I am not at all sure how you would count them accurately. This lack of ability to check them was of course the point of needing a solution. David From rssh at gradsoft.com.ua Thu Apr 2 06:10:39 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 2 Apr 2009 16:10:39 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> Message-ID: Yes, yet one idea - create poll, where each proposal is listed with link and rated from -5 to 5 // -5 - I strongly against this in Java; +5 - I strongly for; 0 - neutral. (by default all is null)) and publish somewhere. // better different instances for controlled and non-controlled auditory. It will be interesting. > 2009/4/2 Stephen Colebourne : >> All, >> One possible way I'd like to suggest that the coin evaluation could be >> helped would be to write a script to find out how frequently the >> specific issue comes up in real code. >> >> It should be possible to devise, write and run a script to find the >> number of LOCs affected by many of the proposals. For example: >> >> - strings in switch (find if else on constant strings) >> - multi-catch (find duplicate catch blocks) >> - elvis operator (find ternary and if else defaulting) >> - for each where the iterator remove can be accessed (% of loops that >> access iterator) >> - for each where index is needed (% of loops that use int looping) >> - method and field literals >> - byte and short literals >> and probably many others (I've just listed some proposals I remember) >> >> Ideally, any script would be ASM/BCEL based, but grep style might work >> too. >> >> I mention all this because I don't have the spare time to write such a >> script, but if you do, then I'm sure we'd all like to run it and >> discuss the results ;-) >> >> Stephen >> >> > > We may list all proposals and write opinions & statistics (as we think). > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie?? > > http://lasu2string.blogspot.com/ > > From mthornton at optrak.co.uk Thu Apr 2 06:14:24 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 02 Apr 2009 14:14:24 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <200904021407.24330.david.goodenough@linkchoose.co.uk> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <200904021407.24330.david.goodenough@linkchoose.co.uk> Message-ID: <49D4BA30.8070702@optrak.co.uk> David Goodenough wrote: > On Thursday 02 April 2009, Stephen Colebourne wrote: > >> All, >> One possible way I'd like to suggest that the coin evaluation could be >> helped would be to write a script to find out how frequently the >> specific issue comes up in real code. >> >> It should be possible to devise, write and run a script to find the >> number of LOCs affected by many of the proposals. For example: >> >> - strings in switch (find if else on constant strings) >> - multi-catch (find duplicate catch blocks) >> - elvis operator (find ternary and if else defaulting) >> - for each where the iterator remove can be accessed (% of loops that >> access iterator) >> - for each where index is needed (% of loops that use int looping) >> - method and field literals >> - byte and short literals >> and probably many others (I've just listed some proposals I remember) >> >> Ideally, any script would be ASM/BCEL based, but grep style might work too. >> >> I mention all this because I don't have the spare time to write such a >> script, but if you do, then I'm sure we'd all like to run it and >> discuss the results ;-) >> >> Stephen >> > > As a matter of interest, how would you go about finding the instances of > the problem that my lightweight properties proposal aims to solve, i.e. > There are a number of types of change which are hard to verify or quantify using existing code. For example escape analysis may fail to show benefits from eliminating allocation because the programmers have already done it manually. In particular they might have used integer loops instead of an iterator when looping over an ArrayList. I still have quite a few old style loops simply because there hasn't been a sufficiently good reason to change them yet. Mark Thornton From rssh at gradsoft.com.ua Thu Apr 2 06:14:44 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 2 Apr 2009 16:14:44 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <200904021407.24330.david.goodenough@linkchoose.co.uk> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <200904021407.24330.david.goodenough@linkchoose.co.uk> Message-ID: <2d40714ad6407ff97935bcf5acf6b1fc.squirrel@wmail.gradsoft.ua> > As a matter of interest, how would you go about finding the instances of > the problem that my lightweight properties proposal aims to solve, i.e. .... afraid none = scripts will works only for simple proposals. From markmahieu at googlemail.com Thu Apr 2 06:25:15 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 2 Apr 2009 14:25:15 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: Wow. http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png Here are the important bits from my quick hack. Took under half an hour to get it finding cases where Auto-assignment Parameters would and wouldn't work across large source trees. Of course, javac makes much more than parsing available if you need it... import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.parser.JavacParser; import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; ... // create a TreeScanner to do your analysis TreeScanner scanner = new TreeScanner() { @Override public void visitMethodDef(JCMethodDecl tree) { // look at a method's parameters for (List l = params; l.nonEmpty(); l = l.tail) { JCVariableDecl param = l.head; // examine param or whatever } // continue recursively scanning the method body etc super.visitMethodDef(tree); } }; ... Context context = new Context(); JavacFileManager.preRegister(context); ParserFactory factory = ParserFactory.instance(context); String sourceCode = readSourceFromFile(...); JavacParser parser = (JavacParser) factory.newParser(sourceCode, false, false, false); JCCompilationUnit cu = parser.parseCompilationUnit(); // do your analysis scanner.scan(cu); From misterm at gmail.com Thu Apr 2 06:34:05 2009 From: misterm at gmail.com (Michael Nascimento) Date: Thu, 2 Apr 2009 10:34:05 -0300 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <389b9d740904020634u321941d0l9c61c56d9d7ea295@mail.gmail.com> Using JDK 6, you can write an annotation processor for all sources that uses the Tree API for that. Regards, Michael Nascimento Santos https://genesis.dev.java.net/ https://jsr-310.dev.java.net/ On Thu, Apr 2, 2009 at 10:25 AM, Mark Mahieu wrote: > Wow. > > http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png > > > Here are the important bits from my quick hack. ?Took under half an hour to > get it finding cases where Auto-assignment Parameters would and wouldn't > work across large source trees. > > Of course, javac makes much more than parsing available if you need it... > > > > import com.sun.tools.javac.file.JavacFileManager; > import com.sun.tools.javac.parser.JavacParser; > import com.sun.tools.javac.parser.ParserFactory; > import com.sun.tools.javac.tree.TreeScanner; > import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; > import com.sun.tools.javac.tree.JCTree.JCMethodDecl; > import com.sun.tools.javac.tree.JCTree.JCVariableDecl; > import com.sun.tools.javac.util.Context; > import com.sun.tools.javac.util.List; > > ... > > // create a TreeScanner to do your analysis > TreeScanner scanner = new TreeScanner() { > > @Override > public void visitMethodDef(JCMethodDecl tree) { > ?// look at a method's parameters > for (List l = params; l.nonEmpty(); l = l.tail) { > JCVariableDecl param = l.head; > ?// examine param or whatever > } > ?// continue recursively scanning the method body etc > super.visitMethodDef(tree); > } > }; > > ... > > Context context = new Context(); > JavacFileManager.preRegister(context); > ParserFactory factory = ParserFactory.instance(context); > > String sourceCode = readSourceFromFile(...); > > JavacParser parser = (JavacParser) factory.newParser(sourceCode, false, > false, false); > JCCompilationUnit cu = parser.parseCompilationUnit(); > > // do your analysis > scanner.scan(cu); > > From markmahieu at googlemail.com Thu Apr 2 06:47:26 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 2 Apr 2009 14:47:26 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <389b9d740904020634u321941d0l9c61c56d9d7ea295@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <389b9d740904020634u321941d0l9c61c56d9d7ea295@mail.gmail.com> Message-ID: Yep, which is a better option if the code is going to be more than a quick throwaway. The advantage with using the javac versions of those types is that you get familiarity with other APIs you need to interact with when building an actual prototype... Mark 2009/4/2 Michael Nascimento > Using JDK 6, you can write an annotation processor for all sources > that uses the Tree API for that. > > Regards, > Michael Nascimento Santos > https://genesis.dev.java.net/ > https://jsr-310.dev.java.net/ > > On Thu, Apr 2, 2009 at 10:25 AM, Mark Mahieu > wrote: > > Wow. > > > > > http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png > > > > > > Here are the important bits from my quick hack. Took under half an hour > to > > get it finding cases where Auto-assignment Parameters would and wouldn't > > work across large source trees. > > > > Of course, javac makes much more than parsing available if you need it... > > > > > > > > import com.sun.tools.javac.file.JavacFileManager; > > import com.sun.tools.javac.parser.JavacParser; > > import com.sun.tools.javac.parser.ParserFactory; > > import com.sun.tools.javac.tree.TreeScanner; > > import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; > > import com.sun.tools.javac.tree.JCTree.JCMethodDecl; > > import com.sun.tools.javac.tree.JCTree.JCVariableDecl; > > import com.sun.tools.javac.util.Context; > > import com.sun.tools.javac.util.List; > > > > ... > > > > // create a TreeScanner to do your analysis > > TreeScanner scanner = new TreeScanner() { > > > > @Override > > public void visitMethodDef(JCMethodDecl tree) { > > // look at a method's parameters > > for (List l = params; l.nonEmpty(); l = l.tail) { > > JCVariableDecl param = l.head; > > // examine param or whatever > > } > > // continue recursively scanning the method body etc > > super.visitMethodDef(tree); > > } > > }; > > > > ... > > > > Context context = new Context(); > > JavacFileManager.preRegister(context); > > ParserFactory factory = ParserFactory.instance(context); > > > > String sourceCode = readSourceFromFile(...); > > > > JavacParser parser = (JavacParser) factory.newParser(sourceCode, false, > > false, false); > > JCCompilationUnit cu = parser.parseCompilationUnit(); > > > > // do your analysis > > scanner.scan(cu); > > > > > > From david.goodenough at linkchoose.co.uk Thu Apr 2 06:28:25 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 2 Apr 2009 14:28:25 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <2d40714ad6407ff97935bcf5acf6b1fc.squirrel@wmail.gradsoft.ua> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <200904021407.24330.david.goodenough@linkchoose.co.uk> <2d40714ad6407ff97935bcf5acf6b1fc.squirrel@wmail.gradsoft.ua> Message-ID: <200904021428.26371.david.goodenough@linkchoose.co.uk> On Thursday 02 April 2009, rssh at gradsoft.com.ua wrote: > > As a matter of interest, how would you go about finding the instances of > > the problem that my lightweight properties proposal aims to solve, i.e. > > .... afraid none = scripts will works only for simple proposals. Well I suppose a first pass would simply be to count all occurences of String values who's value matched a field name, but how deep do you go looking for fields - probably just in the user's code not the libraries even though you would then miss lots of PropertyChange fires and all the named properties inside Swing. Could your code do the simple string == fieldname scan? That would under-count, but it would be a start. David From rssh at gradsoft.com.ua Thu Apr 2 07:18:26 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 2 Apr 2009 17:18:26 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <200904021428.26371.david.goodenough@linkchoose.co.uk> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <200904021407.24330.david.goodenough@linkchoose.co.uk> <2d40714ad6407ff97935bcf5acf6b1fc.squirrel@wmail.gradsoft.ua> <200904021428.26371.david.goodenough@linkchoose.co.uk> Message-ID: <69bcb3eed8382ed8d1ca39bc49797501.squirrel@wmail.gradsoft.ua> > On Thursday 02 April 2009, rssh at gradsoft.com.ua wrote: >> > As a matter of interest, how would you go about finding the instances >> of >> > the problem that my lightweight properties proposal aims to solve, >> i.e. >> >> .... afraid none = scripts will works only for simple proposals. > > Well I suppose a first pass would simply be to count all occurences of > String values who's value matched a field name, but how deep do you > go looking for fields - probably just in the user's code not the libraries > even though you would then miss lots of PropertyChange fires and > all the named properties inside Swing. > > Could your code do the simple string == fieldname scan? That would > under-count, but it would be a start. > Yes, this is possible. But if we have class X with field "fx", than String "fx" somewhere in class Y - how count this ? This can be undercount or overcount. Knowledge about Y import (i. e. X is accessible from X or not) also give us nothing, because exists possibility, that this is something generic in Y. So, we can receive some counts and they would have some correlation with property access, but all with some level of 'vagueness' in interpretation. > David > > From david.goodenough at linkchoose.co.uk Thu Apr 2 07:29:27 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 2 Apr 2009 15:29:27 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <69bcb3eed8382ed8d1ca39bc49797501.squirrel@wmail.gradsoft.ua> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <200904021428.26371.david.goodenough@linkchoose.co.uk> <69bcb3eed8382ed8d1ca39bc49797501.squirrel@wmail.gradsoft.ua> Message-ID: <200904021529.29938.david.goodenough@linkchoose.co.uk> On Thursday 02 April 2009, rssh at gradsoft.com.ua wrote: > > On Thursday 02 April 2009, rssh at gradsoft.com.ua wrote: > >> > As a matter of interest, how would you go about finding the instances > >> > >> of > >> > >> > the problem that my lightweight properties proposal aims to solve, > >> > >> i.e. > >> > >> .... afraid none = scripts will works only for simple proposals. > > > > Well I suppose a first pass would simply be to count all occurences of > > String values who's value matched a field name, but how deep do you > > go looking for fields - probably just in the user's code not the > > libraries even though you would then miss lots of PropertyChange fires > > and all the named properties inside Swing. > > > > Could your code do the simple string == fieldname scan? That would > > under-count, but it would be a start. > > Yes, this is possible. But if we have class X with field "fx", than String > "fx" somewhere in class Y - how count this ? > This can be undercount or overcount. > Knowledge about Y import (i. e. X is accessible from X or not) also give > us nothing, because exists possibility, that this is something generic in > Y. > > So, we can receive some counts and they would have some correlation with > property access, but all with some level of 'vagueness' in interpretation. It would be a start I suppose. It would probably overcount, but then this test is also missing all the field names embedded in Criteria or similar APIs and in SQL and related beasts. David > > > David From peter.levart at gmail.com Thu Apr 2 07:33:49 2009 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 2 Apr 2009 16:33:49 +0200 Subject: Proposal: Automatic Resource Management In-Reply-To: <370F8DB1-A374-43B4-9F83-ABCD5A925D93@zwitserloot.com> References: <370F8DB1-A374-43B4-9F83-ABCD5A925D93@zwitserloot.com> Message-ID: I apologise! The code snipped submitted by Bob Lee is not flawed at all as I have suggested in my previous message. I did not read ARM specification correctly. Nevertheless with increasing number of resources managed by a single ARM construct, the track of which method has thrown exception and why is lost. This is also true if to many statements that can throw the same exception are written in a single try block. Ideally all thrown exceptions should be individually accessible together within a single block (being catch or finally block I don't know which). This way any additional logic can act on the whole failure context. So in this respect my proposed construct is no better because it separates exception thrown in initialization and try block from exceptions thrown in clean-up code which are accessible in finally block. I understand that sometimes one just wants to be passed a single variable that holds the "most meaningful" exception thrown among several and that is what ARM proposal is trying to solve. A programmer using ARM construct will have to evaluate whether ARM is the correct tool for the particular problem and not blindly accept it because it is the correct tool for most problems (and it is so easy to use). On the other hand the try-catch-finally statement as we have now in Java is always the right tool (if used correctly) but it unfortunately can too easily be used incorrectly. Regards, Peter From reinier at zwitserloot.com Thu Apr 2 08:18:25 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 17:18:25 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> Message-ID: <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> Polling has many, many problems associated with it: 1. It does not reliably measure impact. Let's say generics gets a 9.0 in the polls, and the foreach loop gets only an 8.0. The right answer is to implement foreach, eventhough it scored lower. It's easier and has less impact. implementing difficulty can be decided by an expert group, but there's also the concept of impact. A nice case in point: Almost everyone rated operator support for BigDecimal and BigInteger as very low in Stephen Colebourne's polls, but is that reflective? I don't think so. It's just the one with the lowest impact - no body cares about that a lot, and some care about it not at all. It is, however, hard to see how operator support for BigDecimal/BigInteger can break, well, anything. The value of any proposal is its positive impact divided by its negative impact, and dividing by a very small number gives you a very large number. 2. Not all know about intricacies. For example, with generics, I bet many who vocally supported them did not know the details about reification, the sheer complexity of co/contra-variance (which just cannot be simplified, the core concept is difficult, period), etcetera. By not being aware of the weight put on future expansions and patchy stopgaps in the proposal itself, some proposals that are technically (but not obviously) complex get an unfairly inflated poll score. Perhaps a fairer way would be to first reduce the list to a manageable number, and then to poll, but only amongst those who have attempted to read and fully grok all proposals on the list, and can be expected to know enough repercussions to make a fair analysis, and to poll not just on 'how much would you like this in java?' but also on 'how much would you NOT like this in java?' - in order to give the simpler stuff like e.g. operators for BigDecimal/Integer a fighting chance. How do you determine that someone is both skilled enough to understand AND has attempted to grok all proposals on the short-list? I have no idea. --Reinier Zwitserloot On Apr 2, 2009, at 15:10, rssh at gradsoft.com.ua wrote: > > > Yes, yet one idea - create poll, where each proposal is listed with > link > and rated from -5 to 5 > // -5 - I strongly against this in Java; +5 - I strongly for; 0 - > neutral. > (by default all is null)) and publish somewhere. > // better different instances for controlled and non-controlled > auditory. > > It will be interesting. > > > >> 2009/4/2 Stephen Colebourne : >>> All, >>> One possible way I'd like to suggest that the coin evaluation >>> could be >>> helped would be to write a script to find out how frequently the >>> specific issue comes up in real code. >>> >>> It should be possible to devise, write and run a script to find the >>> number of LOCs affected by many of the proposals. For example: >>> >>> - strings in switch (find if else on constant strings) >>> - multi-catch (find duplicate catch blocks) >>> - elvis operator (find ternary and if else defaulting) >>> - for each where the iterator remove can be accessed (% of loops >>> that >>> access iterator) >>> - for each where index is needed (% of loops that use int looping) >>> - method and field literals >>> - byte and short literals >>> and probably many others (I've just listed some proposals I >>> remember) >>> >>> Ideally, any script would be ASM/BCEL based, but grep style might >>> work >>> too. >>> >>> I mention all this because I don't have the spare time to write >>> such a >>> script, but if you do, then I'm sure we'd all like to run it and >>> discuss the results ;-) >>> >>> Stephen >>> >>> >> >> We may list all proposals and write opinions & statistics (as we >> think). >> >> -- >> Pozdrowionka. / Regards. >> Lasu aka Marek Kozie?? >> >> http://lasu2string.blogspot.com/ >> >> > > > From Joe.Darcy at Sun.COM Thu Apr 2 08:27:56 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Thu, 02 Apr 2009 08:27:56 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> Message-ID: <49D4D97C.5090808@sun.com> Reinier Zwitserloot wrote: > Polling has many, many problems associated with it: > I will treat any polling information as strictly informative and in no way binding on the decisions that get made. Polling is the limit case of design by committee and not well-suited to technical decisions. -Joe From rssh at gradsoft.com.ua Thu Apr 2 09:09:28 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 2 Apr 2009 19:09:28 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> Message-ID: > Polling has many, many problems associated with it: > yes. But we have no other ways to know 'meaning of mass'. I. e. 'design by poll' is not good idea, but 'design without any information from real word' is not good idea also. It's well-known problem in sociology, where, unlike computer science, we have no correct instruments at all. Exists some 'non-direct' ways to know how correct is poll: controlled auditories, same poll in different cases, but all this is not panacea. > 1. It does not reliably measure impact. Let's say generics gets a 9.0 > in the polls, and the foreach loop gets only an 8.0. The right answer > is to implement foreach, eventhough it scored lower. It's easier and > has less impact. implementing difficulty can be decided by an expert > group, but there's also the concept of impact. > Yes. I think all understand this. // btw, near all proposals in project coin are easy implementable. > A nice case in point: Almost everyone rated operator support for > BigDecimal and BigInteger as very low in Stephen Colebourne's polls, > but is that reflective? I don't think so. It's just the one with the > lowest impact - no body cares about that a lot, and some care about it > not at all. It is, however, hard to see how operator support for > BigDecimal/BigInteger can break, well, anything. The value of any > proposal is its positive impact divided by its negative impact, and > dividing by a very small number gives you a very large number. > I also have question to Stephen polls: i. e. I can't understand why multiline strings rated so low. Anybody, who works with databases know, that analyzing query plan or copy non-trivial query test in java is a big pain, and most of Java project in corporate sector use non-trivial sql queris". Only one answer, which I can suggest - that auditory which attend Java conferences does not reflect auditory of Java users: most of Java conferences attenders do system programming or research and have nothing with most of database projects which is not so interesting and rare have academics interest. To verify this, possible repeat his poll on some programmer event, which is not so academics. > 2. Not all know about intricacies. For example, with generics, I bet > many who vocally supported them did not know the details about > reification, the sheer complexity of co/contra-variance (which just > cannot be simplified, the core concept is difficult, period), > etcetera. By not being aware of the weight put on future expansions > and patchy stopgaps in the proposal itself, some proposals that are > technically (but not obviously) complex get an unfairly inflated poll > score. > Filtration by proposal size, as I know, already was done. > > > Perhaps a fairer way would be to first reduce the list to a manageable > number, and then to poll, but only amongst those who have attempted to > read and fully grok all proposals on the list, and can be expected to Or just does not touch proposals, which was not readed. (mark as 0, 'neutral') > know enough repercussions to make a fair analysis, and to poll not > just on 'how much would you like this in java?' but also on 'how much > would you NOT like this in java?' - in order to give the simpler stuff > like e.g. operators for BigDecimal/Integer a fighting chance. How do Yes. > you determine that someone is both skilled enough to understand AND > has attempted to grok all proposals on the short-list? I have no idea. > 'Skilled enough', sorry, I think that people, which skilled enough prefer haskell and will poll for haskell-like features, which is not ordinary Java programmer want ;) Also will be wery interested difference between this audience (subscribers of the list) and general audience of Java programmers. Note, that I does not propose use polls as one and only one criteria. I just tell that see result of such poll will be interest. // btw - from other side, all this activity is overkill, I can suggest, // that accepted proposals would be exactly same, which was listed in // project-coin description (before coin was started) // http://blogs.sun.com/darcy/entry/project_coin // +ARM +jsr292 and ... it's already 6, which is more than 5 :) I. e. doing project coin with external auditory was a 'Sun system error', I guess; if they want some feedback from community, correct way was at first implement own stuff, than ask community for something new ;) > > --Reinier Zwitserloot > > > > On Apr 2, 2009, at 15:10, rssh at gradsoft.com.ua wrote: > >> >> >> Yes, yet one idea - create poll, where each proposal is listed with >> link >> and rated from -5 to 5 >> // -5 - I strongly against this in Java; +5 - I strongly for; 0 - >> neutral. >> (by default all is null)) and publish somewhere. >> // better different instances for controlled and non-controlled >> auditory. >> >> It will be interesting. >> >> >> >>> 2009/4/2 Stephen Colebourne : >>>> All, >>>> One possible way I'd like to suggest that the coin evaluation >>>> could be >>>> helped would be to write a script to find out how frequently the >>>> specific issue comes up in real code. >>>> >>>> It should be possible to devise, write and run a script to find the >>>> number of LOCs affected by many of the proposals. For example: >>>> >>>> - strings in switch (find if else on constant strings) >>>> - multi-catch (find duplicate catch blocks) >>>> - elvis operator (find ternary and if else defaulting) >>>> - for each where the iterator remove can be accessed (% of loops >>>> that >>>> access iterator) >>>> - for each where index is needed (% of loops that use int looping) >>>> - method and field literals >>>> - byte and short literals >>>> and probably many others (I've just listed some proposals I >>>> remember) >>>> >>>> Ideally, any script would be ASM/BCEL based, but grep style might >>>> work >>>> too. >>>> >>>> I mention all this because I don't have the spare time to write >>>> such a >>>> script, but if you do, then I'm sure we'd all like to run it and >>>> discuss the results ;-) >>>> >>>> Stephen >>>> >>>> >>> >>> We may list all proposals and write opinions & statistics (as we >>> think). >>> >>> -- >>> Pozdrowionka. / Regards. >>> Lasu aka Marek Kozie????? >>> >>> http://lasu2string.blogspot.com/ >>> >>> >> >> >> > > From reinier at zwitserloot.com Thu Apr 2 09:15:22 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 18:15:22 +0200 Subject: Proposal: Sameness operators In-Reply-To: <49D4B40F.2010100@optrak.co.uk> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> <49D4B40F.2010100@optrak.co.uk> Message-ID: <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> The argument that .compareTo should not be used because it isn't entirely congruent with either the meaning of .equals() or the meanings of all the comparison operators (from == to <) on the primitives, just doesn't hold water, for this simple reason: They make absolutely no sense now, either, and nobody cares about that. Here's some fun facts (all asserts are true): int x = 0/0; //ArithmeticException double x = 0/0.0; //okay, x = NaN double y = 0/0.0; assert x != y; assert ! (x == y); assert Double.valueOf(x).equals(Double.valueOf(y)); //WTF! assert Double.valueOf(x).equals(y); //WTF! Clearly, equals is fundamentally broken. We need a new equals! Oh no! assert ! (x < y); assert ! (x <= y); assert Double.valueOf(x).compareTo(y) == 0; //WTF! So, compareTo is broken as well. Just like equals is. assert x < "foo"; //Compiler Error: Cant compare those two. assert Double.valueOf(x).compareTo("foo"); //With java 1.4: Runtime error. assert Double.valueOf(x).compareTo("foo"); //With java 1.5+: Compile time error. A compiler error is better, but these two results certainly are consistent. In fact, in java 1.5+, you DO get a compiler error. So, if x < "foo" would be rewritten to the version below that after comparison operator support is added that uses compareTo, you get roughly the same situation: A compiler error that tells you that the compiler didn't expect a String there. The exact text of the error is slightly different, but other than that, it's the same. Why is this a problem? The fix to me seems relatively simple: 1. Anything that is legal now needs to stay legal. I would write down the rules for this, except they are totally nuts, as the above samples show. So, just do whatever java 6 does for everything that would have been legal in 6. In particular, this involves unboxing both sides if both sides can be unboxed. And unbox one side if the other side is a numeric primitive. Yes, this leads to crazy puzzlers, such as: Double x = Double.valueOf(Double.NaN); double y = 0; if ( x != y && !(x < y) && !(x > y) ) System.out.println("This line prints? Whoa!"); But that's what we're stuck with. Unless Lovatt's and my crazy idea of breaking backwards compatibility with an explicit source keyword is implemented, this craziness can't go away, we're stuck with it. 2. First unbox whatever can be unboxed, then continue to: 3. If either LHS or RHS implements Comparable, we'll use that. Note that primitives do not implement Comparable. Comparison operations between primitives are hardcoded into the JLS spec. If both sides do implement Comparable, LHS wins. If only the RHS does, the order is mathematically reversed (a > b becomes b < a). If the winning HS is willing to take Number according to the generics bound of Comparable (which means RAW types *DO*, as they take all objects), then numeric primitives are boxed. If neither side implements Comparable, compiler error. If a side does, but the type of the other side isn't compatible with Comparable's bound, or is a non-numeric primitive (boolean - char is actually numeric, because this didn't look quite enough like a Salvador Dali painting yet, go figure) you get a compile-time error, even if the other way around would have worked. 4. BigDecimal and BigInteger are changed to implement Comparable instead. The fact that they currently don't is something I don't really understand would consider filing as a bug if I worked more with mixed BI/BD and primitives math. By doing this, something like: 5 < new BigInteger("10") would work out the way you expect it to (that would return 'true'). BI/BD's comparison methods can't just convert the incoming primitive to a BI/BD, because NaN and the infinities don't convert, yet the answer to this expression: Double.NEGATIVE_INFINITY < BigInteger.ZERO should clearly be true. The above plan can make that happen by adding more logic to BI/BD's compareTo methods. The reason Double and company need to unbox is because their implementations of compareTo can then stay blissfully unaware of BI and BD's existence. There's a problem if you attempt to compare 2 numeric entities that aren't hardcoded into the JVM, but I don't think a perfect solution is possible here. This proposal is not entirely consistent with the primitive's compare operators, but attempting to be consistent with the current mess that is comparison operators between primitives is not a goal that we should aspire to, IMO. The concept of 'I'll give you an answer if there is a mathematical answer, and if there isn't, I will give you a compile-time error if I can, and a runtime error otherwise' seems perfect to me. That's compareTo's current semantics, so, lucky us! NB: Attempting to integrate equality into compareTo is probably a bad idea, eventhough we are stuck with some funny puzzlers where equality and comparison clearly aren't consistent. The real problem is that numeric equality is just different from object equality (numerically, NaN is not equal to NaN, but as objects, they are, and asking if apple == pear makes no sense numerically, but as objects, there's a logical answer: No, they aren't). I don't see us getting out of that one. Possibly use <> as an operator that specifically means: Not Numerically equal, and !<> as numerically equal. Yeah, that doesn't really look too readable to me either. --Reinier Zwitserloot On Apr 2, 2009, at 14:48, Mark Thornton wrote: > Tom Hawtin wrote: >> Reinier Zwitserloot wrote: >> >>> Why can't we use compareTo and equals? >>> >> >> * compareTo may well be unreasonably inefficient. >> * equals handles nulls (asymmetrically), compareTo does not >> * equals does test-and-cast (event for generic types - urgh), >> compareTo uses generics >> * equals does not throw ClassCastException, compareTo does (but >> probably shouldn't with generics) >> >> Therefore, new methods please. I'm sure you are aware the whole >> subject of operator overloading in general is a minefield. >> > a.compareTo(b) == 0 and a.equals(b) are not always the same, > sometimes for very good reasons. I seem to remember that there is at > least one such class in the Java platform. > > Mark Thornton > From develop4lasu at gmail.com Thu Apr 2 10:34:24 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 19:34:24 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> Message-ID: <28bca0ff0904021034w40f2c5d1nfa8b574e99f61a11@mail.gmail.com> As pool I would suggest, while [yes/no] do not give any knowledge: Problem: -> Analyzed(0~5~6) // did you took much time to analyze it? // (0 = no) (5 = a lot) -> IHadSuchProblem(0~5~6) // how often you had such problem ? (0 = no) (5 = often) (6 = almost all time) -> IWouldUseIt(0~5~6) // would you use in new JDK ? (0 = no) (5= a lot) -> Problems(0~5~6[,sample]) // like: to many interactions, to complicated, potential problems .... (0 = none) (5 = a lot) -> OtherSolutionWouldSolveProblem(0~5~6[,SolutionName]) // do you know other solution (0 = do not know any) (5 = in 100%) (6 = 100% and would be better) -> SolutionNotComplete(0~5~6[,description]) // what is missing in yours opinion? (0 = none) (5 = incomplete) -> Except(0~5~6,what) // some parts of this solution should be removed (0 = none) -> Extend(0~5~6,what) // this soultion need to be extended to work correctly (0 = no need) (5 = to weak to solve problem at current version) where (in YOUR opinion): 0 : none ~ 5 : much 6 : very much Like: [Marek Kozie?] StringInSwitch: -> Analyzed(5) -> IHadSuchProblem(3) -> IWouldUseIt(1) -> Problems(3) -> OtherSolutionWouldSolveProblem(6,enum) -> SolutionNotComplete(5,onlyForStaticData) -> Exclude(0) -> Extend(6,dynamicData comparator) NextSolution/Proposal: ... Explanation: -> Analyzed(5) : I took a lot of time to analyze it -> IHadSuchProblem(3) : i had it some times -> IWouldUseIt(1) : I think this solution have no much use for me (to weak = no dynamic data). -> Problems(3) : would cause bad style -> OtherSolutionWouldSolveProblem(6,enum) : can have all those and more -> SolutionNotComplete(5,onlyForStaticData) : -> Exclude(0) : nothing to exclude -> Extend(6,dynamicData asymetricComparator) : should be extended with ... and It would help a lot This could be parsed to bring some critical informations (like potential problem). -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From mthornton at optrak.co.uk Thu Apr 2 10:42:21 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 02 Apr 2009 18:42:21 +0100 Subject: Proposal: Sameness operators In-Reply-To: <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> <49D4B40F.2010100@optrak.co.uk> <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> Message-ID: <49D4F8FD.4080909@optrak.co.uk> Reinier Zwitserloot wrote: > The argument that .compareTo should not be used because it isn't > entirely congruent with either the meaning of .equals() or the > meanings of all the comparison operators (from == to <) on the > primitives, just doesn't hold water, for this simple reason: > I merely meant that if you want to have a set of comparison operators with some of them based on compareTo, then they all must be based on compareTo --- you can't use equals (or ==) for the equality comparisons. Therefore you have three sets of operations ==, System.identityHashCode(), plus for some types <, <=, >, >= Object.equals(), Object.hashCode() Comparable.compareTo() All these need to remain clearly distinct because their existing behaviour is not always compatible. Mark Thornton From Jonathan.Gibbons at Sun.COM Thu Apr 2 11:16:09 2009 From: Jonathan.Gibbons at Sun.COM (Jonathan Gibbons) Date: Thu, 02 Apr 2009 11:16:09 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <49D500E9.3050106@sun.com> For all this sort of analysis, you'd do better to use the combination of javac's annotation processing framework and the javac Tree API, than to use direct access into private javac API. Annotation processing isn't just for processing annotations ;-) You can write a processor that will be called on all types, and you can bridge from the processing world (javax.lang.model.*) to the java Tree API (com.sun.source.*) using com.sun.source.util.Trees. This allows you to write utilities to analyze ASTs without requiring the use of any javac internal API. -- Jon Mark Mahieu wrote: > Wow. > > http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png > > > Here are the important bits from my quick hack. Took under half an hour to > get it finding cases where Auto-assignment Parameters would and wouldn't > work across large source trees. > > Of course, javac makes much more than parsing available if you need it... > > > > import com.sun.tools.javac.file.JavacFileManager; > import com.sun.tools.javac.parser.JavacParser; > import com.sun.tools.javac.parser.ParserFactory; > import com.sun.tools.javac.tree.TreeScanner; > import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; > import com.sun.tools.javac.tree.JCTree.JCMethodDecl; > import com.sun.tools.javac.tree.JCTree.JCVariableDecl; > import com.sun.tools.javac.util.Context; > import com.sun.tools.javac.util.List; > > ... > > // create a TreeScanner to do your analysis > TreeScanner scanner = new TreeScanner() { > > @Override > public void visitMethodDef(JCMethodDecl tree) { > // look at a method's parameters > for (List l = params; l.nonEmpty(); l = l.tail) { > JCVariableDecl param = l.head; > // examine param or whatever > } > // continue recursively scanning the method body etc > super.visitMethodDef(tree); > } > }; > > ... > > Context context = new Context(); > JavacFileManager.preRegister(context); > ParserFactory factory = ParserFactory.instance(context); > > String sourceCode = readSourceFromFile(...); > > JavacParser parser = (JavacParser) factory.newParser(sourceCode, false, > false, false); > JCCompilationUnit cu = parser.parseCompilationUnit(); > > // do your analysis > scanner.scan(cu); > > From mthornton at optrak.co.uk Thu Apr 2 11:31:51 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 02 Apr 2009 19:31:51 +0100 Subject: Proposal: Sameness operators In-Reply-To: <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> <49D4B40F.2010100@optrak.co.uk> <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> Message-ID: <49D50497.4020801@optrak.co.uk> Reinier Zwitserloot wrote: > > BI/BD's comparison methods can't just convert the incoming primitive > to a BI/BD, because NaN and the infinities don't convert, yet the > answer to this expression: > > Double.NEGATIVE_INFINITY < BigInteger.ZERO > > should clearly be true. The above plan can make that happen by adding > more logic to BI/BD's compareTo methods. The 754R decimal format does include NaN and +-infinite, so perhaps the answer here is to modify Java's BigDecimal to match. Joe could probably tell us more about the possibility of such a change. Mark Thornton From Joe.Darcy at Sun.COM Thu Apr 2 11:33:45 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 11:33:45 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D500E9.3050106@sun.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <49D500E9.3050106@sun.com> Message-ID: <49D50509.4020909@sun.com> On 04/02/09 11:16 AM, Jonathan Gibbons wrote: > For all this sort of analysis, you'd do better to use the combination of > javac's > annotation processing framework and the javac Tree API, than to use direct > access into private javac API. > > Annotation processing isn't just for processing annotations ;-) You can > write > a processor that will be called on all types, and you can bridge from the > processing world (javax.lang.model.*) to the java Tree API > (com.sun.source.*) > using com.sun.source.util.Trees. This allows you to write utilities to > analyze ASTs without requiring the use of any javac internal API. > +1 The annotation processing in javac with JSR 269 (and apt before it) is a general purpose meta-programming framework. Combined with the javac tree API, many program analyses can be performed. -Joe > -- Jon > > > > Mark Mahieu wrote: > >> Wow. >> >> http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png >> >> >> Here are the important bits from my quick hack. Took under half an hour to >> get it finding cases where Auto-assignment Parameters would and wouldn't >> work across large source trees. >> >> Of course, javac makes much more than parsing available if you need it... >> >> >> >> import com.sun.tools.javac.file.JavacFileManager; >> import com.sun.tools.javac.parser.JavacParser; >> import com.sun.tools.javac.parser.ParserFactory; >> import com.sun.tools.javac.tree.TreeScanner; >> import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; >> import com.sun.tools.javac.tree.JCTree.JCMethodDecl; >> import com.sun.tools.javac.tree.JCTree.JCVariableDecl; >> import com.sun.tools.javac.util.Context; >> import com.sun.tools.javac.util.List; >> >> ... >> >> // create a TreeScanner to do your analysis >> TreeScanner scanner = new TreeScanner() { >> >> @Override >> public void visitMethodDef(JCMethodDecl tree) { >> // look at a method's parameters >> for (List l = params; l.nonEmpty(); l = l.tail) { >> JCVariableDecl param = l.head; >> // examine param or whatever >> } >> // continue recursively scanning the method body etc >> super.visitMethodDef(tree); >> } >> }; >> >> ... >> >> Context context = new Context(); >> JavacFileManager.preRegister(context); >> ParserFactory factory = ParserFactory.instance(context); >> >> String sourceCode = readSourceFromFile(...); >> >> JavacParser parser = (JavacParser) factory.newParser(sourceCode, false, >> false, false); >> JCCompilationUnit cu = parser.parseCompilationUnit(); >> >> // do your analysis >> scanner.scan(cu); >> >> >> > > > From reinier at zwitserloot.com Thu Apr 2 11:53:18 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 2 Apr 2009 20:53:18 +0200 Subject: Proposal: Sameness operators In-Reply-To: <49D4F8FD.4080909@optrak.co.uk> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> <49D4B40F.2010100@optrak.co.uk> <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> <49D4F8FD.4080909@optrak.co.uk> Message-ID: Why must == also run off of compareTo? (Or, alternatively, why do you - need- an equality-checking operation based on compareTo that isn't ==)? Java cannot enforce contracts in that way; for example, it's perfectly legal syntactically, eventhough you're breaking the API contract, to always "return 1;" in response to a compareTo. Unless an actual compare operation attempts both the stated comparison and the mathematically equivalent reverse (a < b and b > a) and throws an exception if the results aren't equal, there's no guarantee that compareTo makes any sense. The current situation with boxing primitives is that == and <> and extremely inconsistent; new Double(5) vs. new Double(5) isn't == equal, but they are equal as far as compareTo is concerned. Nevertheless, people -do- apply comparisons in java. Making it easier ought to help. To further complicate things, introducing a new Comparable-like interface that doesn't suffer from these problems as badly (for example by wanting an enum back instead of a positive/ negative/zero value) will not be compatible with the existing Comparable, which would be awkard for HashSet. My point is thus: There is a perfect world, and java doesn't have it. And it never will. Either we do this, or we give up and never have any sort of improvement to the comparable situation. If that's the choice, I want comparator operators, even with the glitches. --Reinier Zwitserloot On Apr 2, 2009, at 19:42, Mark Thornton wrote: > Reinier Zwitserloot wrote: >> The argument that .compareTo should not be used because it isn't >> entirely congruent with either the meaning of .equals() or the >> meanings of all the comparison operators (from == to <) on the >> primitives, just doesn't hold water, for this simple reason: >> > I merely meant that if you want to have a set of comparison > operators with some of them based on compareTo, then they all must > be based on compareTo --- you can't use equals (or ==) for the > equality comparisons. Therefore you have three sets of operations > > ==, System.identityHashCode(), plus for some types <, <=, >, >= > > Object.equals(), Object.hashCode() > > Comparable.compareTo() > > All these need to remain clearly distinct because their existing > behaviour is not always compatible. > > Mark Thornton > > > > From mthornton at optrak.co.uk Thu Apr 2 12:18:29 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 02 Apr 2009 20:18:29 +0100 Subject: Proposal: Sameness operators In-Reply-To: References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> <49D4B40F.2010100@optrak.co.uk> <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> <49D4F8FD.4080909@optrak.co.uk> Message-ID: <49D50F85.4040401@optrak.co.uk> Reinier Zwitserloot wrote: > My point is thus: There is a perfect world, and java doesn't have it. > And it never will. Either we do this, or we give up and never have any > sort of improvement to the comparable situation. If that's the choice, > I want comparator operators, even with the glitches. > A new set of operators like (==), (<), etc, all based on compareTo would work, but I don't know how likely such a change is. In their favour, these operators would NOT be overloaded so the usual complaints about operators wouldn't apply. Mark From peter.levart at gmail.com Thu Apr 2 12:30:10 2009 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 2 Apr 2009 21:30:10 +0200 Subject: Proposal: Automatic Resource Management In-Reply-To: <370F8DB1-A374-43B4-9F83-ABCD5A925D93@zwitserloot.com> References: <370F8DB1-A374-43B4-9F83-ABCD5A925D93@zwitserloot.com> Message-ID: Hello Coiners! I played with ARM a little more and also considered Reinier Zwitserloot's remarks to my idea of making ARM more SARM (Semi Automatic Resource Management). I apologise again of accusing Bob Lee's example as flawed. Now that I fully understand Joshua Bloch's ARM proposal, I'm convinced that it's exception suppressing logic is correct for most usage scenarios. One weakness that the ARM spec does not address yet is about how AutomaticResource interface should be handled in obscure situations of multiple inheritance. So I'm still trying to get rid of the need for special interface altogether. Here's my second take: try (InputStream in = new FileInputStream(inputFile); in.close()) { // try block } catch(IOException e) { // catch block } finally { // finally block } ... to be translated into: try { InputStream in = new FileInputStream(inputFile); boolean $$suppress = false; try { // try block } catch (final Throwable $$t) { $$suppress = true; throw $$t; } finally { if ($$suppress) try { in.close(); } catch (Throwable $$ignore) {} else in.close(); } } catch (IOException e) { // catch block } finally { // finally block } ... that's not much different from Joshua's original proposal. In fact it uses the same exception suppressing logic. There are only 3 differences: - does not use a special interface - disposal is explicit (Semi Automatic) - handles only a single resource But with both "catch" and "finally" parts as optional, the following: try (InputStream in = new FileInputStream(inputFile); in.close()) { // try block } ... is translated into: { InputStream in = new FileInputStream(inputFile); boolean $$suppress = false; try { // try block } catch (final Throwable $$t) { $$suppress = true; throw $$t; } finally { if ($$suppress) try { in.close(); } catch (Throwable $$ignore) {} else in.close(); } } ... and so, single-resource SARM constructs can then be nested to construct for example this: try (InputStream in = new FileInputStream(inputFile); in.close()) { try (OutputStream out = new FileOutputStream(outputFile); out.close()) { // try block } } catch(IOException e) { // catch block } ... one more with locking: ReadWriteLock rwl = ... try (rwl.writeLock().lock(); rwl.writeLock().unlock()) { i++; } That's it. What dou you think? Regards, Peter From develop4lasu at gmail.com Thu Apr 2 12:33:10 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 21:33:10 +0200 Subject: Proposal: Automatic Resource Management In-Reply-To: References: Message-ID: <28bca0ff0904021233u2fae0949tb0a9c4171cd9ab1e@mail.gmail.com> 2009/4/2 Peter Levart : > Hello Coiners! > > The debate about ARM proposal has calmed down lately and I was thinking > about it last few days. Initially I submitted a comment that got lost by > list processor and was about using a "marker" interface as a supertype of > sigle-method disposable interfaces like this: > > > package java.lang; > > public interface AutomaticResource {} > > > ... and for example, retroffiting java.io.Closeable: > > > package java.io; > > public interface Closeable extends AutomaticResource { > ? ?void close() throws IOException; > } > > > ... this way even the name of the method would not be "coined". There would > have to be some rules that compiler will enforce to make sure it can > uniquely identify the method to be called on resource disposal (for example: > the static type of the resource should not directly or indirectly implement > or extend two different single-method interfaces marked with > AutomaticResource marker superinterface). > > But then I thought. Why would this language feature even have to be tied to > a particular interface. The "foreach" loop did take this approach with > java.lang.Iterable, but this had nothing to do with exceptions and catching > them and ignoring them silently. A language construct that hides this often > cited "bad practice" under the carpet is no good! > > For example, this snippet of code, written to the proposed ARM spec., > submited by Bob Lee in this thread a month ago, asking Neal Gafter to > demonstrate how the equivalent BGGA version would look like: > > ?try (InputStream in = new FileInputStream(src); > ? ? ?OutputStream out = new FileOutputStream(dest)) { > ? ?byte[] buf = new byte[8 * 1024]; > ? ?int n; > ? ?while ((n = in.read(buf)) >= 0) > ? ? ?out.write(buf, 0, n); > ?} catch (IOException e) { > ? ?showDialog("Copy failed."); > ?} > > ... is flawed. This code does not guarantee that in the absence of shown > exception the file has been copied in it's intirety. > > Ignoring exception thrown on an InputStream.close() might be desireable, but > ignoring exception thrown on OutputStream.close() migh mean that you don't > mind missing writing some final bytes into the file. Closing OutputStream > should not be part of automatic resource disposal but part of main code > block. This brings us to the question how is ARM supposed to be able do > differentiate InputStream from OutputStream if both implement Closeable? > > So I thought how to circumvent these two weeknesses. My take on this is > something like the following: > > > ? ? ? ?try (InputStream in = new FileInputStream("inputFile"); > ? ? ? ? ? ? OutputStream out = new FileOutputStream("outputFile")) > ? ? ? ?{ > ? ? ? ? ?// try body > ? ? ? ?} > ? ? ? ?catch (IOException e) > ? ? ? ?{ > ? ? ? ? ?// catch body > ? ? ? ?} > ? ? ? ?finally (IOException e1 : in.close(); > ? ? ? ? ? ? ? ? IOException e2 : out.close()) > ? ? ? ?{ > ? ? ? ? ?// finally body > ? ? ? ?} > > > ... would be translated to ... > > > ? ? ? ?{ > ? ? ? ? ? ?IOException e1 = null; > ? ? ? ? ? ?IOException e2 = null; > > ? ? ? ? ? ?try > ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ?InputStream in = new FileInputStream("inputFile"); > > ? ? ? ? ? ? ? ?try > ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ?OutputStream out = new FileOutputStream("outputFile"); > > ? ? ? ? ? ? ? ? ? ?try > ? ? ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ? ? ?// try body > ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ?finally > ? ? ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ? ? ?try > ? ? ? ? ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ? ? ? ? ?out.close(); > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ?catch (IOException $$e) > ? ? ? ? ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ? ? ? ? ?e2 = $$e; > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?finally > ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ?try > ? ? ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ? ? ?in.close(); > ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ?catch (IOException $$e) > ? ? ? ? ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ? ? ? ? ?e1 = $$e; > ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ?} > ? ? ? ? ? ?catch (IOException e) > ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ?// catch body > ? ? ? ? ? ?} > ? ? ? ? ? ?finally > ? ? ? ? ? ?{ > ? ? ? ? ? ? ? ?// finally body > ? ? ? ? ? ?} > ? ? ? ?} > > > > ... no special interfaces are used here. The code to dispose of resources is > clearly visible (it has to be writen, yes, but that also means that it can > be read, which is a good thing). > > The above example is the "full monty" version. The thing to note is that a > try (...; ...; ...) construct is to be matched by an optional finally (...; > ...; ...) construct in that both, if the second is specified, must have an > equal number of semicolons. Each "statement" in the try construct gets it's > own slot that must be matched by the coresponding slot in the finally (...; > ...; ...) construct. Any slot in finally construct can be left empty (like > any of the 3 slots in the for (;;) statement). > > The following minimal version is also possible (in this example no catching > of exceptions on resource cleanup is attempted): > > int i, j; > ReadWriteLock iLock = ...; > ReadWriteLock jLock = ...; > > // ... > > try (jLock.readLock().lock(); iLock.writeLock().lock()) { > ?i += j; > } > finally (jLock.readLock().unlock(); iLock.writeLock().unlock()) > > > ... gets translated to: > > > { > ? ?jLock.readLock().lock(); > ? ?try { > ? ? ?iLock.writeLock().lock(); > ? ? ?try { > ? ? ? ?i += j; > ? ? ?} > ? ? ?finally { > ? ? ? ?iLock.writeLock().unlock(); > ? ? ?} > ? ?} > ? ?finally { > ? ? ?jLock.readLock().unlock(); > ? ?} > } > > > All this will have to be formalized. This is just an idea to keep the debate > going. > > Regards, Peter > > If I can I would suggest: try (InputStream in = new FileInputStream("inputFile"); OutputStream out = new FileOutputStream("outputFile")) { // try body } catch (IOException e) { // catch body } finally (IOException e1 : in.close(); IOException e2 : out.close()) { // finally body } change to: catch: catch(variable = Type); catch(variable = Type exceptionVariable){}; catch(Type exceptionVariable){}; allow mix try with new : new try Constructor catch ....; variable would be null is exception occurs. IOException exception = null; InputStream in = new try FileInputStream("inputFile") catch (exception = IOException); if (in == null) return ...; OutputStream out = new try FileOutputStream("outputFile")) catch (exception = IOException); if ( (in != null) && (out != null) ) try{ ... } catch (exception = IOException); if (in != null) try {in.close(); } catch (exception = IOException); if (out != null) try {out.close(); } catch (exception = IOException); if (exception != null) throw exception; ... But I didn't analyzed all interactions. for locks I still think that they should be done by: synchronize.write(lock){} -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Thu Apr 2 12:48:30 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 21:48:30 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <87zlf0pduc.fsf@mid.deneb.enyo.de> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> <28bca0ff0903291422s77f11c44j4ddf6ea45ec0b669@mail.gmail.com> <87zlf0pduc.fsf@mid.deneb.enyo.de> Message-ID: <28bca0ff0904021248t336d38d2tb1b4a7d8a6d51137@mail.gmail.com> 2009/4/1 Florian Weimer : > * Marek Kozie?: > >> ? ? ? void noInterection(T t,K k){ >> ? ? ? ? ? ? ? if (boo)t=k; // Type mismatch: cannot convert from K to T >> ? ? ? ? ? ? ? ... >> ? ? ? } > > The assignment is not type-safe anyway, as the following modification > shows: > > > ? ? ? ? T noInterection(T t,K k){ > ? ? ? ? ? ? ? ?if (boo)t=k; // Type mismatch: cannot convert from K to T > ? ? ? ? ? ? ? ?return t; > ? ? ? ?} > > This would allow to convert values of any type which implements I1 and > I2 to any other type which implements the two interfaces, which is > clearly bogus. > > Consequently, I think your snippet doesn't show what you claim. > I wanted to show when assignment is possible : Intersection : I1 & I2 Bounds : $ extends I1 & I2 Intersection = Bounds // OK Intersection = Intersection // OK Bounds = Intersection // Error Bounds = Bounds // Error -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Thu Apr 2 12:48:54 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 12:48:54 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> Message-ID: <49D516A6.6000404@sun.com> On 04/02/09 09:09 AM, rssh at gradsoft.com.ua wrote: >> Polling has many, many problems associated with it: >> >> > > yes. But we have no other ways to know 'meaning of mass'. I. e. 'design > by poll' is not good idea, but 'design without any information from real > word' is not good idea also. > > It's well-known problem in sociology, where, unlike computer science, we > have no correct instruments at all. Exists some 'non-direct' ways > to know how correct is poll: controlled auditories, same poll in different > cases, but all this is not panacea. > > >> 1. It does not reliably measure impact. Let's say generics gets a 9.0 >> in the polls, and the foreach loop gets only an 8.0. The right answer >> is to implement foreach, eventhough it scored lower. It's easier and >> has less impact. implementing difficulty can be decided by an expert >> group, but there's also the concept of impact. >> >> > > Yes. I think all understand this. > // btw, near all proposals in project coin are easy implementable. > I do not share that opinion. There are no simple language changes in Java. Given the relative scarcity of prototypes, to say nothing of prototypes with a thorough test suite, we can at best make informed estimates of the difficulty of various changes, but I'm certain there will be surprises down the line, as there were for every JDK 5 language change. >> A nice case in point: Almost everyone rated operator support for >> BigDecimal and BigInteger as very low in Stephen Colebourne's polls, >> but is that reflective? I don't think so. It's just the one with the >> lowest impact - no body cares about that a lot, and some care about it >> not at all. It is, however, hard to see how operator support for >> BigDecimal/BigInteger can break, well, anything. The value of any >> proposal is its positive impact divided by its negative impact, and >> dividing by a very small number gives you a very large number. >> >> > > I also have question to Stephen polls: i. e. I can't understand why > multiline strings rated so low. Anybody, who works with databases > know, that analyzing query plan or copy non-trivial query test > in java is a big pain, and most of Java project in corporate sector use > non-trivial sql queris". > Only one answer, which I can suggest - that auditory which attend Java > conferences does not reflect auditory of Java users: most of Java > conferences attenders do system programming or research and have nothing > with most of database projects which is not so interesting and rare > have academics interest. > To verify this, possible repeat his poll on some programmer event, which > is not so academics. > On this point, I've long thought the Java platform is like the elephant in the parable about the blind men and the elephant: http://en.wikipedia.org/wiki/Blind_Men_and_an_Elephant That is, while each of us may know and understand our own usage of Java quite and well and have valid ideas about how Java could be changed to improve programming in our own areas of interest (properties! operator overloading! design by contract! your favorite feature!), evolving the platform with an eye toward optimizing it *as a whole* will mean at least some areas don't get what they want. [snip] > Note, that I does not propose use polls as one and only one criteria. I > just tell that see result of such poll will be interest. > > // btw - from other side, all this activity is overkill, I can suggest, > // that accepted proposals would be exactly same, which was listed in > // project-coin description (before coin was started) > // http://blogs.sun.com/darcy/entry/project_coin > // +ARM +jsr292 and ... it's already 6, which is more than 5 :) > Your own sentence disproves your point since ARM was not listed among the five proposal areas under consideration before Project Coin started. > I. e. doing project coin with external auditory was a 'Sun system error', > I guess; if they want some feedback from community, correct way was at > first implement own stuff, than ask community for something new ;) > The call of proposal phase of Project Coin is an effort both to solicit feedback from the external community and also to invite the external community to participate more directly in evolving the language. That opportunity to participate also implies participating in the large amount of work required to go from "I have this great idea!" to "I have this great idea and here is a carefully considered review of all the implications of the idea, along with a prototype." The blogs I wrote last year and the proposal form itself are part of an effort to explain and expose what this language work entails so more people can get involved. Unfortunately, many of the submitted proposals did not do a credible job of analyzing the true effect the proposal would have, which has a rather strong relation to why many were not chosen for further consideration. For example, let's take the "'This' type" proposal: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000107.html Including a this type/self type notion in a programming language type system is a well-studied problem in type systems; as I sent to the list, papers continue to be written on this topic in the programming language literature. It known to *not* be a simple change to the type system. Let's look at the specification section of the proposal: > SPECIFICATION: > (I did not have time to analyze this completely.) > The analysis is the part that matters most! This proposal appears completely oblivious to and ignorant of the large amount of prior work on this topic. It is not as if the notion of adding a self type to Java is a new idea; there is already a Sun bug for this from several years ago: 6479372 Add self types (type of 'this' aka ThisClass) to the language http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 So in total, this "proposal" added *nothing* to the understanding of what adding a this type to Java would mean and how the change could be done. Those factors weighed quite strongly in why this particular proposal did not more on to "for further consideration." Language design, especially additions to an existing language, is not an endeavor where enthusiasm can overcome lack of diligence and expertise. -Joe From markmahieu at googlemail.com Thu Apr 2 13:53:45 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 2 Apr 2009 21:53:45 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D500E9.3050106@sun.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <49D500E9.3050106@sun.com> Message-ID: Hi Jon, Invoking the parser directly seemed like the quickest way of grabbing some figures at the time, but you (and Michael) are quite right of course. The main point I was trying to get across was there are easily approachable ways that people can attempt to do some of the analysis Stephen mentioned, without ripping components out of Netbeans etc to do it, great though they may be. But I shouldn't be spreading my bad habits around with abandon like that, quick hack or not :) My apologies. Mark 2009/4/2 Jonathan Gibbons > For all this sort of analysis, you'd do better to use the combination of > javac's > annotation processing framework and the javac Tree API, than to use direct > access into private javac API. > > Annotation processing isn't just for processing annotations ;-) You can > write > a processor that will be called on all types, and you can bridge from the > processing world (javax.lang.model.*) to the java Tree API > (com.sun.source.*) > using com.sun.source.util.Trees. This allows you to write utilities to > analyze ASTs without requiring the use of any javac internal API. > > -- Jon > > > > > Mark Mahieu wrote: > >> Wow. >> >> http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png >> >> >> Here are the important bits from my quick hack. Took under half an hour >> to >> get it finding cases where Auto-assignment Parameters would and wouldn't >> work across large source trees. >> >> Of course, javac makes much more than parsing available if you need it... >> >> >> >> import com.sun.tools.javac.file.JavacFileManager; >> import com.sun.tools.javac.parser.JavacParser; >> import com.sun.tools.javac.parser.ParserFactory; >> import com.sun.tools.javac.tree.TreeScanner; >> import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; >> import com.sun.tools.javac.tree.JCTree.JCMethodDecl; >> import com.sun.tools.javac.tree.JCTree.JCVariableDecl; >> import com.sun.tools.javac.util.Context; >> import com.sun.tools.javac.util.List; >> >> ... >> >> // create a TreeScanner to do your analysis >> TreeScanner scanner = new TreeScanner() { >> >> @Override >> public void visitMethodDef(JCMethodDecl tree) { >> // look at a method's parameters >> for (List l = params; l.nonEmpty(); l = l.tail) { >> JCVariableDecl param = l.head; >> // examine param or whatever >> } >> // continue recursively scanning the method body etc >> super.visitMethodDef(tree); >> } >> }; >> >> ... >> >> Context context = new Context(); >> JavacFileManager.preRegister(context); >> ParserFactory factory = ParserFactory.instance(context); >> >> String sourceCode = readSourceFromFile(...); >> >> JavacParser parser = (JavacParser) factory.newParser(sourceCode, false, >> false, false); >> JCCompilationUnit cu = parser.parseCompilationUnit(); >> >> // do your analysis >> scanner.scan(cu); >> >> >> > > From develop4lasu at gmail.com Thu Apr 2 13:59:02 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 2 Apr 2009 22:59:02 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D516A6.6000404@sun.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> <49D516A6.6000404@sun.com> Message-ID: <28bca0ff0904021359v4ea9aa05i1ed7782f60c7e84e@mail.gmail.com> 2009/4/2 Joe Darcy : > On 04/02/09 09:09 AM, rssh at gradsoft.com.ua wrote: >>> Polling has many, many problems associated with it: >>> >>> >> >> ?yes. ?But we have no other ways to know 'meaning of mass'. I. e. 'design >> by poll' is not good idea, but 'design without any information from real >> word' is not good idea also. >> >> It's well-known problem in sociology, where, unlike computer science, we >> ?have no correct instruments at all. Exists some 'non-direct' ways >> ?to know how correct is poll: controlled auditories, same poll in different >> cases, but all this is not panacea. >> >> >>> 1. It does not reliably measure impact. Let's say generics gets a 9.0 >>> in the polls, and the foreach loop gets only an 8.0. The right answer >>> is to implement foreach, eventhough it scored lower. It's easier and >>> has less impact. implementing difficulty can be decided by an expert >>> group, but there's also the concept of impact. >>> >>> >> >> ?Yes. I think all understand this. >> // btw, near all proposals in project coin are easy implementable. >> > > I do not share that opinion. > > There are no simple language changes in Java. > > Given the relative scarcity of prototypes, to say nothing of prototypes > with a thorough test suite, we can at best make informed estimates of > the difficulty of various changes, but I'm certain there will be > surprises down the line, as there were for every JDK 5 language change. > >>> A nice case in point: Almost everyone rated operator support for >>> BigDecimal and BigInteger as very low in Stephen Colebourne's polls, >>> but is that reflective? I don't think so. It's just the one with the >>> lowest impact - no body cares about that a lot, and some care about it >>> not at all. It is, however, hard to see how operator support for >>> BigDecimal/BigInteger can break, well, anything. The value of any >>> proposal is its positive impact divided by its negative impact, and >>> dividing by a very small number gives you a very large number. >>> >>> >> >> I also have question to Stephen polls: i. e. I can't understand why >> multiline strings rated so low. ?Anybody, who works with databases >> ?know, that analyzing query plan or copy non-trivial query test >> ?in java is a big pain, and most of Java project in corporate sector use >> non-trivial sql queris". >> ? Only one answer, which I can suggest - that auditory which attend Java >> conferences does not reflect auditory of Java users: most of Java >> conferences attenders do system programming or research and have nothing >> with most of ?database projects which is not so interesting and rare >> have academics interest. >> ? To verify this, possible repeat his poll on some programmer event, which >> is not so academics. >> > > On this point, I've long thought the Java platform is like the elephant > in the parable about the blind men and the elephant: > > ? ?http://en.wikipedia.org/wiki/Blind_Men_and_an_Elephant > > That is, while each of us may know and understand our own usage of Java > quite and well and have valid ideas about how Java could be changed to > improve programming in our own areas of interest (properties! operator > overloading! design by contract! ?your favorite feature!), evolving the > platform ?with an eye toward optimizing it *as a whole* will ?mean at > least some areas don't get what they want. > > [snip] > >> Note, that I does not propose use polls as one and only one criteria. I >> just tell that see result of such poll will be interest. >> >> // btw - from other side, all this activity is overkill, I can suggest, >> // that ?accepted proposals would be exactly same, which was listed in >> // project-coin description (before coin was started) >> // ? ? http://blogs.sun.com/darcy/entry/project_coin >> // ? +ARM ?+jsr292 ?and ... ?it's already 6, which is more than 5 :) >> > > Your own sentence disproves your point since ARM was not listed among > the five proposal areas under consideration before Project Coin started. > >> I. e. doing project coin with external auditory ?was a 'Sun system error', >> I guess; if they want some feedback from community, correct way was at >> first implement own stuff, than ask community for something new ;) >> > > The call of proposal phase of Project Coin is an effort both to solicit > feedback from the external community and also to invite the external > community to participate more directly in evolving the language. ?That > opportunity to participate also implies participating in the large > amount of work required to go from "I have this great idea!" to "I have > this great idea and here is a carefully considered review of all the > implications of the idea, along with a prototype." ?The blogs I wrote > last year and the proposal form itself are part of an effort to explain > and expose what this language work entails so more people can get involved. > > Unfortunately, many of the submitted proposals did not do a credible job > of analyzing the true effect the proposal would have, which has a rather > strong relation to why many were not chosen for further consideration. > For example, let's take the "'This' type" proposal: > > ? ?http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000107.html > > Including a this type/self type notion in a programming language type > system is a well-studied problem in type systems; as I sent to the list, > papers continue to be written on this topic in the programming language > literature. ?It known to *not* be a simple change to the type system. > Let's look at the specification section of the proposal: > >> SPECIFICATION: >> (I did not have time to analyze this completely.) >> > > The analysis is the part that matters most! ?This proposal appears > completely oblivious to and ignorant of the large amount of prior work > on this topic. > > It is not as if the notion of adding a self type to Java is a new idea; > there is already a Sun bug for this from several years ago: > > ? ?6479372 Add self types (type of 'this' aka ThisClass) to the language > ? ?http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 > > So in total, this "proposal" added *nothing* to the understanding of > what adding a this type to Java would mean and how the change could be done. > > Those factors weighed quite strongly in why this particular proposal did > not more on to "for further consideration." > > Language design, especially additions to an existing language, is not an > endeavor where enthusiasm can overcome lack of diligence and expertise. > > -Joe > > > YES I do make mistakes. You already said that. While I'm against splitting Java into more languages, I'll be happy even if one proposal will make Java better and more frendly. So if you think that i didn't helped at all then remove me from the group. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Jonathan.Gibbons at Sun.COM Thu Apr 2 14:02:54 2009 From: Jonathan.Gibbons at Sun.COM (Jonathan Gibbons) Date: Thu, 02 Apr 2009 14:02:54 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <49D500E9.3050106@sun.com> Message-ID: <49D527FE.3050105@sun.com> Mark, Quick hacks are good. My point was just that once you know the coding pattern, it can be even easier/quicker to hack up an annotation processor to do what you want than to learn the innards of the compiler. The internal API has never been intended for public consumption, and there are often undocumented quirks or constraints about individual specific methods, meaning it is very much a case of "proceed at your own risk". The good news is that is now a goal to support utilities such as you all have been describing, and that JSR 199, JSR 269 and the Tree API, are all part of the formal support for such work. -- Jon Mark Mahieu wrote: > Hi Jon, > > Invoking the parser directly seemed like the quickest way of grabbing > some figures at the time, but you (and Michael) are quite right of course. > > The main point I was trying to get across was there are easily > approachable ways that people can attempt to do some of the analysis > Stephen mentioned, without ripping components out of Netbeans etc to > do it, great though they may be. > > But I shouldn't be spreading my bad habits around with abandon like > that, quick hack or not :) > > My apologies. > > Mark > > > 2009/4/2 Jonathan Gibbons > > > For all this sort of analysis, you'd do better to use the > combination of javac's > annotation processing framework and the javac Tree API, than to > use direct > access into private javac API. > > Annotation processing isn't just for processing annotations ;-) > You can write > a processor that will be called on all types, and you can bridge > from the > processing world (javax.lang.model.*) to the java Tree API > (com.sun.source.*) > using com.sun.source.util.Trees. This allows you to write > utilities to > analyze ASTs without requiring the use of any javac internal API. > > -- Jon > > > > > Mark Mahieu wrote: > > Wow. > > http://www.geekherocomic.com/comics-highres/2009-02-25-coding-overkill.png > > > Here are the important bits from my quick hack. Took under > half an hour to > get it finding cases where Auto-assignment Parameters would > and wouldn't > work across large source trees. > > Of course, javac makes much more than parsing available if you > need it... > > > > import com.sun.tools.javac.file.JavacFileManager; > import com.sun.tools.javac.parser.JavacParser; > import com.sun.tools.javac.parser.ParserFactory; > import com.sun.tools.javac.tree.TreeScanner; > import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; > import com.sun.tools.javac.tree.JCTree.JCMethodDecl; > import com.sun.tools.javac.tree.JCTree.JCVariableDecl; > import com.sun.tools.javac.util.Context; > import com.sun.tools.javac.util.List; > > ... > > // create a TreeScanner to do your analysis > TreeScanner scanner = new TreeScanner() { > > @Override > public void visitMethodDef(JCMethodDecl tree) { > // look at a method's parameters > for (List l = params; l.nonEmpty(); l = l.tail) { > JCVariableDecl param = l.head; > // examine param or whatever > } > // continue recursively scanning the method body etc > super.visitMethodDef(tree); > } > }; > > ... > > Context context = new Context(); > JavacFileManager.preRegister(context); > ParserFactory factory = ParserFactory.instance(context); > > String sourceCode = readSourceFromFile(...); > > JavacParser parser = (JavacParser) > factory.newParser(sourceCode, false, > false, false); > JCCompilationUnit cu = parser.parseCompilationUnit(); > > // do your analysis > scanner.scan(cu); > > > > > From Joe.Darcy at Sun.COM Thu Apr 2 14:28:28 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 14:28:28 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: <28bca0ff0904021359v4ea9aa05i1ed7782f60c7e84e@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> <49D516A6.6000404@sun.com> <28bca0ff0904021359v4ea9aa05i1ed7782f60c7e84e@mail.gmail.com> Message-ID: <49D52DFC.9020306@sun.com> On 04/02/09 01:59 PM, Marek Kozie? wrote: > 2009/4/2 Joe Darcy : > >> On 04/02/09 09:09 AM, rssh at gradsoft.com.ua wrote: >> >>>> Polling has many, many problems associated with it: >>>> >>>> >>>> > > YES I do make mistakes. > You already said that. > The problem is not that you made mistake; the problem is that despite being informed how and why your your proposals were inadequate, you proceed to submit more than half a dozen other proposals of the same character. > While I'm against splitting Java into more languages, I'll be happy > even if one proposal will make Java better and more frendly. > We do not have a deficiency of ideas for proposals; just in Sun's bug database there are dozens of valid ways to improve the language. The analysis of the proposals is the scarce and valuable factor. > So if you think that i didn't helped at all then remove me from the group > As you wish. -Joe From markmahieu at googlemail.com Thu Apr 2 14:53:23 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 2 Apr 2009 22:53:23 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D516A6.6000404@sun.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> <49D516A6.6000404@sun.com> Message-ID: 2009/4/2 Joe Darcy > > Given the relative scarcity of prototypes, to say nothing of prototypes > with a thorough test suite, we can at best make informed estimates of > the difficulty of various changes, but I'm certain there will be > surprises down the line, as there were for every JDK 5 language change. I'd certainly like to see more prototypes, personally; I find them extremely useful for getting to the details of a proposal. However, is there any value in people building test suites even if they can't put together an actual prototype to test them with? I think there may be. Mark From Ulf.Zibis at gmx.de Thu Apr 2 15:02:26 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Fri, 03 Apr 2009 00:02:26 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <49D535F2.6060009@gmx.de> Am 02.04.2009 13:39, Stephen Colebourne schrieb: > All, > One possible way I'd like to suggest that the coin evaluation could be > helped would be to write a script to find out how frequently the > specific issue comes up in real code. > > It should be possible to devise, write and run a script to find the > number of LOCs affected by many of the proposals. For example: > > - strings in switch (find if else on constant strings) > More general: - objects and simple expressions in switch (find repetitive+nested usage of if else constructs) -Ulf > - multi-catch (find duplicate catch blocks) > - elvis operator (find ternary and if else defaulting) > - for each where the iterator remove can be accessed (% of loops that > access iterator) > - for each where index is needed (% of loops that use int looping) > - method and field literals > - byte and short literals > and probably many others (I've just listed some proposals I remember) > > Ideally, any script would be ASM/BCEL based, but grep style might work too. > > I mention all this because I don't have the spare time to write such a > script, but if you do, then I'm sure we'd all like to run it and > discuss the results ;-) > > Stephen > > > From Joe.Darcy at Sun.COM Thu Apr 2 15:19:40 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 15:19:40 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> <49D516A6.6000404@sun.com> Message-ID: <49D539FC.4050005@sun.com> Mark Mahieu wrote: > 2009/4/2 Joe Darcy > > > Given the relative scarcity of prototypes, to say nothing of prototypes > with a thorough test suite, we can at best make informed estimates of > the difficulty of various changes, but I'm certain there will be > surprises down the line, as there were for every JDK 5 language change. > > > I'd certainly like to see more prototypes, personally; I find them > extremely useful for getting to the details of a proposal. Yes; they can help in writing the specification too :-) > However, is there any value in people building test suites even if they > can't put together an actual prototype to test them with? I think there > may be. I was more so thinking of regression style testing in conjunction with developing a prototype, but having a limited number of independent tests might help too. -Joe From forax at univ-mlv.fr Thu Apr 2 15:25:42 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 03 Apr 2009 00:25:42 +0200 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D535F2.6060009@gmx.de> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <49D535F2.6060009@gmx.de> Message-ID: <49D53B66.2000509@univ-mlv.fr> Ulf Zibis a ?crit : > Am 02.04.2009 13:39, Stephen Colebourne schrieb: > >> All, >> One possible way I'd like to suggest that the coin evaluation could be >> helped would be to write a script to find out how frequently the >> specific issue comes up in real code. >> >> It should be possible to devise, write and run a script to find the >> number of LOCs affected by many of the proposals. For example: >> >> - strings in switch (find if else on constant strings) >> >> > > More general: > - objects and simple expressions in switch (find repetitive+nested usage > of if else constructs) > > -Ulf > Stephen, Ulf, Strings can be stored, by example, in a HashMap, so finding if a part of a program can be retrofit or not is far from simple. R?mi From brucechapman at paradise.net.nz Thu Apr 2 15:35:52 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Fri, 03 Apr 2009 11:35:52 +1300 (NZDT) Subject: Helping to find the usefulness of a proposal In-Reply-To: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> Message-ID: <1238711752.49d53dc8e0a4c@www.paradise.net.nz> Good idea, Should they each be evaluated against the same corpus and what would be a suitable corpus? http://en.wikipedia.org/wiki/Corpus_linguistics Bruce Quoting Stephen Colebourne : > All, > One possible way I'd like to suggest that the coin evaluation could be > helped would be to write a script to find out how frequently the > specific issue comes up in real code. > > It should be possible to devise, write and run a script to find the > number of LOCs affected by many of the proposals. For example: > > - strings in switch (find if else on constant strings) > - multi-catch (find duplicate catch blocks) > - elvis operator (find ternary and if else defaulting) > - for each where the iterator remove can be accessed (% of loops that > access iterator) > - for each where index is needed (% of loops that use int looping) > - method and field literals > - byte and short literals > and probably many others (I've just listed some proposals I remember) > > Ideally, any script would be ASM/BCEL based, but grep style might work > too. > > I mention all this because I don't have the spare time to write such a > script, but if you do, then I'm sure we'd all like to run it and > discuss the results ;-) > > Stephen > From Joe.Darcy at Sun.COM Thu Apr 2 16:02:56 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 16:02:56 -0700 Subject: Proposal: Sameness operators In-Reply-To: <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> Message-ID: <49D54420.5090906@sun.com> Reinier Zwitserloot wrote: [snip] > > public static void is(Object x, Object y) { > if ( x == null ) return y == null; > return x.equals(y); > } > > public static void is(Object x, int y) { > // Yes, you'd need a few gazillion is methods to cover all the > primitives on either side, but 1 static import will grab all of them > } > > ... loads more is methods > > > Then same with lt, gt, le, ge. > > Then you could write: > > if ( is(a, b) ) { > //doStuff > } > > Which is a small improvement. > > Add an ability to specify 'as infix' in static imports, and you have > pretty much what we all want without backwards compatibility issues: > > import static java.lang.Equality.is infix; > > if ( a is b ) { > //do something > } > > I'd consider that a large improvement. Yes, in JDK 7 I'd like to see 6797535 Add shared two argument static equals method to the platform http://bugs.sun.com/view_bug.do?bug_id=6797535 addressed in the platform. I was thinking putting it in a place like a new utility class java.util.Object. -Joe From Joe.Darcy at Sun.COM Thu Apr 2 16:13:36 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 16:13:36 -0700 Subject: Proposal: Sameness operators In-Reply-To: <49D50497.4020801@optrak.co.uk> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <49D4AF9D.9090407@sun.com> <49D4B40F.2010100@optrak.co.uk> <27F0EA9D-8936-4330-A5FE-97F522C290F0@zwitserloot.com> <49D50497.4020801@optrak.co.uk> Message-ID: <49D546A0.4010406@sun.com> Mark Thornton wrote: > Reinier Zwitserloot wrote: >> BI/BD's comparison methods can't just convert the incoming primitive >> to a BI/BD, because NaN and the infinities don't convert, yet the >> answer to this expression: >> >> Double.NEGATIVE_INFINITY < BigInteger.ZERO >> >> should clearly be true. The above plan can make that happen by adding >> more logic to BI/BD's compareTo methods. > The 754R decimal format does include NaN and +-infinite, so perhaps the > answer here is to modify Java's BigDecimal to match. Yes, I actually worked on incorporating the decimal changes into the 754R draft while I was editor :-) The "preferred exponent" nomenclature in the new 754 standard came from the JSR 13 BigDecimal specification work in JDK 5. > Joe could probably tell us more about the possibility of such a change. We don't plan to add the non-finite values and negative zero to the set of values recognized by BigDecimal. If someone wanted to do this, I'd recommend creating a wrapper around BigDecimal that supported the new values and otherwise delegated to an internal BigDecimal. -Joe From rssh at gradsoft.com.ua Thu Apr 2 16:30:27 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Fri, 3 Apr 2009 02:30:27 +0300 (EEST) Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D516A6.6000404@sun.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> <49D516A6.6000404@sun.com> Message-ID: >> >> Yes. I think all understand this. >> // btw, near all proposals in project coin are easy implementable. >> > > I do not share that opinion. > > There are no simple language changes in Java. > Of course, word 'simple' is relative ;) // And to be correct, I mean proposals upward some quality point. ....... > > On this point, I've long thought the Java platform is like the elephant > in the parable about the blind men and the elephant: > > http://en.wikipedia.org/wiki/Blind_Men_and_an_Elephant > > That is, while each of us may know and understand our own usage of Java > quite and well and have valid ideas about how Java could be changed to > improve programming in our own areas of interest (properties! operator > overloading! design by contract! your favorite feature!), evolving the > platform with an eye toward optimizing it *as a whole* will mean at > least some areas don't get what they want. > Good point. In parable elephants exists and each blinder can touch his part. In our case, for some blinders, elephant must not exists ;))) Even if it can be 'build' in such direction, but we choose not to grow elephant in all directions, because we can't grow quickly. And also exists many group of blinders, near different points of elephants, some groups are big but silent, some are small but loud. Elephant designers are also blinders and guided listening ;) > [snip] > >> Note, that I does not propose use polls as one and only one criteria. I >> just tell that see result of such poll will be interest. >> >> // btw - from other side, all this activity is overkill, I can suggest, >> // that accepted proposals would be exactly same, which was listed in >> // project-coin description (before coin was started) >> // http://blogs.sun.com/darcy/entry/project_coin >> // +ARM +jsr292 and ... it's already 6, which is more than 5 :) >> > > Your own sentence disproves your point since ARM was not listed among > the five proposal areas under consideration before Project Coin started. > I mean not 'would be exactly same, which was listed in project-coin description (before coin was started)[url]', but 'would be exactly same, which was listed in project-coin description (before coin was started)[url] +ARM +jsr292', sorry for ambiguity. ARM floating around (and widly discussed) from late 2007 or early 2008. And all we know, that if BGGA will not available, than at least ARM must be included. I. e. I can't say that ARM is 'external' and new or not to be generally known be included in Java 7 before project coin start. I have no pretension about judgement process, It's only about information flow: i. e. Sun have all proposals before and call for new proposals with process of selecting 5 from set of newly received and 5 apriory well-known items, for which we know, that they are necessory, it's near the same, that throw away all non-apriory proposals. I. e. I guess, that when people asked to submit new proposals, they expect that exists demand for new proposals, not demand for choosing from five well-known items. When appointment of all new proposals to be thrown away, with role be backgroung for well-known items, people, which invested some time in such activity, usually frustrated. It's why I think, that call for new proposals, whithout real possibility to implement something new (not well-known before) was an error. If we have slot, for example, in summary for 10 proposals to implement (5 well know and 5 new) - then all ok, it's fair game. >> I. e. doing project coin with external auditory was a 'Sun system >> error', >> I guess; if they want some feedback from community, correct way was at >> first implement own stuff, than ask community for something new ;) >> > > The call of proposal phase of Project Coin is an effort both to solicit > feedback from the external community and also to invite the external > community to participate more directly in evolving the language. That > opportunity to participate also implies participating in the large > amount of work required to go from "I have this great idea!" to "I have > this great idea and here is a carefully considered review of all the > implications of the idea, along with a prototype." The blogs I wrote > last year and the proposal form itself are part of an effort to explain > and expose what this language work entails so more people can get > involved. > It would be great, to participate in language evolution in future. For now I does not see general aviable process for future participation: call closed, all new proposal throwed away. Finish. Fire bug reports is useless - they will live in bugzilla for years. One possible solution: is make 'coin project' regular, for example once a year. (May be with entry barrier as 'required implementation in some form') Another - propose some process (may be long) for author, how to push his proposal (whith implementation) into language after JDK7 (or receive official position, that this change is rejected) > Unfortunately, many of the submitted proposals did not do a credible job > of analyzing the true effect the proposal would have, which has a rather > strong relation to why many were not chosen for further consideration. > For example, let's take the "'This' type" proposal: > ... Problem with inaccurate proposals - it's well known problem, the same with publications, wildly used technique is peer review. (Honesly, overall quality of proposals was better that I was expected). Good entry barrier can be requirement to proposal to be implemented in some form. P.S. Project coin involved me to think about Java more close than before. So, despite my criticism, you achieve goal to raise interest to participate in process of Java language evolution ;) From tim.keith at gmail.com Thu Apr 2 16:49:13 2009 From: tim.keith at gmail.com (Tim Keith) Date: Thu, 2 Apr 2009 16:49:13 -0700 Subject: Proposal: Sameness operators In-Reply-To: <49D54420.5090906@sun.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> <49D54420.5090906@sun.com> Message-ID: I would like to suggest calling the class java.lang.Objects, similar to java.util.Collections and java.util.Arrays. And it would be handy to also have in there a null-safe static method to help in implementing hashCode: public static int hashCode(Object o) { return o == null ? 0 : o.hashCode(); } -- Tim On Thu, Apr 2, 2009 at 4:02 PM, Joe Darcy wrote: > Reinier Zwitserloot wrote: > > [snip] > >> >> public static void is(Object x, Object y) { >> if ( x == null ) return y == null; >> return x.equals(y); >> } >> >> public static void is(Object x, int y) { >> // Yes, you'd need a few gazillion is methods to cover all the >> primitives on either side, but 1 static import will grab all of them >> } >> >> ... loads more is methods >> >> >> Then same with lt, gt, le, ge. >> >> Then you could write: >> >> if ( is(a, b) ) { >> //doStuff >> } >> >> Which is a small improvement. >> >> Add an ability to specify 'as infix' in static imports, and you have >> pretty much what we all want without backwards compatibility issues: >> >> import static java.lang.Equality.is infix; >> >> if ( a is b ) { >> //do something >> } >> >> I'd consider that a large improvement. > > Yes, in JDK 7 I'd like to see > > 6797535 Add shared two argument static equals method to the platform > http://bugs.sun.com/view_bug.do?bug_id=6797535 > > addressed in the platform. I was thinking putting it in a place like a > new utility class java.util.Object. > > -Joe > > From scolebourne at joda.org Thu Apr 2 17:28:02 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Fri, 03 Apr 2009 01:28:02 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <1238711752.49d53dc8e0a4c@www.paradise.net.nz> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <1238711752.49d53dc8e0a4c@www.paradise.net.nz> Message-ID: <49D55812.9010809@joda.org> I think that as a first step, any info on the most likely Coins would be beneficial. I'd suggest publishing the script alongside the results. Stephen brucechapman at paradise.net.nz wrote: > Good idea, > > Should they each be evaluated against the same corpus and what would be a > suitable corpus? > > http://en.wikipedia.org/wiki/Corpus_linguistics > > Bruce > > Quoting Stephen Colebourne : > >> All, >> One possible way I'd like to suggest that the coin evaluation could be >> helped would be to write a script to find out how frequently the >> specific issue comes up in real code. >> >> It should be possible to devise, write and run a script to find the >> number of LOCs affected by many of the proposals. For example: >> >> - strings in switch (find if else on constant strings) >> - multi-catch (find duplicate catch blocks) >> - elvis operator (find ternary and if else defaulting) >> - for each where the iterator remove can be accessed (% of loops that >> access iterator) >> - for each where index is needed (% of loops that use int looping) >> - method and field literals >> - byte and short literals >> and probably many others (I've just listed some proposals I remember) >> >> Ideally, any script would be ASM/BCEL based, but grep style might work >> too. >> >> I mention all this because I don't have the spare time to write such a >> script, but if you do, then I'm sure we'd all like to run it and >> discuss the results ;-) >> >> Stephen >> > > From Joe.Darcy at Sun.COM Thu Apr 2 19:08:43 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 19:08:43 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: <1238711752.49d53dc8e0a4c@www.paradise.net.nz> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <1238711752.49d53dc8e0a4c@www.paradise.net.nz> Message-ID: <49D56FAB.8090405@sun.com> brucechapman at paradise.net.nz wrote: > Good idea, > > Should they each be evaluated against the same corpus and what would > be a suitable corpus? > > http://en.wikipedia.org/wiki/Corpus_linguistics On that front, Alex sent me the following: > Analysis of a micro-corpus of your own or your company's code is > unscientific. > > Ewan Tempero and his colleagues at the University of Auckland have > done excellent, peer-reviewed work on how Java language features are > used in real-world code. Their "Qualitas Corpus" consists of over > 100,000 classes - see http://www.cs.auckland.ac.nz/~ewan/corpus/ > > If someone showed that, say, a null check occurs on average every 15 > lines of code in this corpus, and that null-safe operators could > remove those lines without adverse side effects, then that would be a > real contribution to Project Coin. I agree that using a standard, large corpus to empirically examine the utility of the Project Coin proposals would be a fine component of their evaluation. -Joe From Joe.Darcy at Sun.COM Thu Apr 2 19:09:37 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 19:09:37 -0700 Subject: Proposal: Sameness operators In-Reply-To: References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> <49D54420.5090906@sun.com> Message-ID: <49D56FE1.8080601@sun.com> Tim Keith wrote: > I would like to suggest calling the class java.lang.Objects, similar > to java.util.Collections and java.util.Arrays. Since this would be a utility class, I thought it would be better placed in java.util rather than java.lang. > And it would be handy to also have in there a null-safe static method > to help in implementing hashCode: > public static int hashCode(Object o) { > return o == null ? 0 : o.hashCode(); > } I've added this suggestion to the Sun bug. Thanks, -Joe > -- Tim > > On Thu, Apr 2, 2009 at 4:02 PM, Joe Darcy wrote: >> Reinier Zwitserloot wrote: >> >> [snip] >> >>> public static void is(Object x, Object y) { >>> if ( x == null ) return y == null; >>> return x.equals(y); >>> } >>> >>> public static void is(Object x, int y) { >>> // Yes, you'd need a few gazillion is methods to cover all the >>> primitives on either side, but 1 static import will grab all of them >>> } >>> >>> ... loads more is methods >>> >>> >>> Then same with lt, gt, le, ge. >>> >>> Then you could write: >>> >>> if ( is(a, b) ) { >>> //doStuff >>> } >>> >>> Which is a small improvement. >>> >>> Add an ability to specify 'as infix' in static imports, and you have >>> pretty much what we all want without backwards compatibility issues: >>> >>> import static java.lang.Equality.is infix; >>> >>> if ( a is b ) { >>> //do something >>> } >>> >>> I'd consider that a large improvement. >> Yes, in JDK 7 I'd like to see >> >> 6797535 Add shared two argument static equals method to the platform >> http://bugs.sun.com/view_bug.do?bug_id=6797535 >> >> addressed in the platform. I was thinking putting it in a place like a >> new utility class java.util.Object. >> >> -Joe >> >> > From brucechapman at paradise.net.nz Thu Apr 2 20:59:32 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Fri, 03 Apr 2009 16:59:32 +1300 (NZDT) Subject: Helping to find the usefulness of a proposal In-Reply-To: <49D56FAB.8090405@sun.com> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <1238711752.49d53dc8e0a4c@www.paradise.net.nz> <49D56FAB.8090405@sun.com> Message-ID: <1238731172.49d589a4a3575@www.paradise.net.nz> Comments inline Bruce Quoting Joe Darcy : > brucechapman at paradise.net.nz wrote: > > Good idea, > > > > Should they each be evaluated against the same corpus and what would > > be a suitable corpus? > > > > http://en.wikipedia.org/wiki/Corpus_linguistics > > On that front, Alex sent me the following: > > > Analysis of a micro-corpus of your own or your company's code is > > unscientific. > > > > Ewan Tempero and his colleagues at the University of Auckland have > > done excellent, peer-reviewed work on how Java language features are > > used in real-world code. Their "Qualitas Corpus" consists of over > > 100,000 classes - see http://www.cs.auckland.ac.nz/~ewan/corpus/ > > OK, I was aware of that one because the last JUG meeting here was about visualising code and was working with that corpus. The problem then is that the corpus is HUGE. Even the 20090202r version which only has the latest release of each system (and is probably the appopriate one for coin use) is 1.2Gb (my monthly broadband limit is 1Gb - I'd probably sneakernet it from someone locally). Maybe this is one of those cases where it is better to take the analysis tools to the corpus rather than the other way around. For that we'd need someone to host the corpus and run jobs submitted against it. Let me do some further research on that. Bruce > > If someone showed that, say, a null check occurs on average every 15 > > lines of code in this corpus, and that null-safe operators could > > remove those lines without adverse side effects, then that would be a > > real contribution to Project Coin. > > I agree that using a standard, large corpus to empirically examine the > utility of the Project Coin proposals would be a fine component of their > > evaluation. > > -Joe > From Joe.Darcy at Sun.COM Thu Apr 2 21:30:57 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 21:30:57 -0700 Subject: Of knapsacks and language features Message-ID: <49D59101.6070400@sun.com> A quick note on some additional considerations in language feature selection. I view the selection of language proposals to be a kind of knapsack problem: http://en.wikipedia.org/wiki/Knapsack_problem That is, each feature has some discrete size and complexity to implement and confers some improvement to the language. There is a bounded size and complexity budget and the goal is maximizing the value held in the knapset, the value of improvements shipped in a release. Of note is that implementing a language change has much more of a discrete size (or a small selection of possible sizes) rather than a continuous range of possible sizes. In other words, because of the coordinated set of deliverables associated with a language change, it may be reasonable to implement 0% 50% or 100% of a possible feature but no other fraction. And doing 50% of the feature might take 1/4 of the effort of doing the whole thing or 3/4 of that effort. Even when precise costs and improvements can be quantified, because of these discrete sizes the "greedy" algorithm of putting the highest value / cost item in the knapsack first can lead to globally poor results. If nothing else, having a pre-pass to reduce the number of proposals being considered for further review greatly reduces the combinatorial possibilities of subsets of features that could be included in a release. -Joe From Joe.Darcy at Sun.COM Thu Apr 2 21:48:46 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 02 Apr 2009 21:48:46 -0700 Subject: Opportunity Cost and Proposal Selection In-Reply-To: <980366fa0904010733o5655fe5di10aa2c44883f7a6e@mail.gmail.com> References: <980366fa0904010733o5655fe5di10aa2c44883f7a6e@mail.gmail.com> Message-ID: <49D5952E.9040602@sun.com> On 04/01/09 07:33 AM, Glenn A. Marshall wrote: > Will the details of the proposal evaluations be published? In general, no. I plan to write up some general retrospective comments on the proposals that were and were not chosen for further consideration in the coming weeks. However, there will be more detailed analysis and discussion to get the set of "for further consideration" proposals down to the final set of proposals. > The thinking here is that for proposals that almost made the cut, > perhaps the evaluations would reveal where a bit more work might push > them over the line for the next round - increase benefit/decrease cost. > > This is assuming there will be a next round. > > Any thoughts on round II? I think we have to see how round I works out first ;-) > It would seem to be worth considering, given the level of interest. > It would, of course, have to wait until Java 8, but why not start early? > > Surely you're busy with round I for now, but perhaps there could be a > parallel effort, with the initial effort primarily around email. Thinking about and working on possible language is great fun of course, but I think in the near term the Project Coin list needs to focus on JDK 7 related work. > thanks for doing all of this, It's an interesting project! -Joe From vapor1 at teleport.com Thu Apr 2 23:33:14 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 02:33:14 -0400 (EDT) Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax Message-ID: <29484356.1238740394998.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Replies inline. -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 31, 2009 5:59 AM >To: Mark Thornton >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Simplified StringBuffer/StringBuilder syntax > >+ being overloaded to also mean string concatenation was a mistake in >java 1.0*. Let's not enshrine it by making more of them. Actually, I agree with this. I think they should have come up with a new "concatenation" operator instead of trying to reuse an existing one. However, + is what we have, and that's not going to change. However, it is obnoxious because it isn't really "complete" -- it takes care of one trivial use case in concatenating strings, but it doesn't handle the larger issue of what to do when all the concatenation doesn't occur in the same expression, and it isn't consistent in its coverage of the family of related types (String, StringBuffer, and StringBuilder) that are really used in creating strings. My intent wasn't to create new operators -- it was to fix odd holes and (fairly inconvenient) missing features in the behavior of the existing ones. I just want the behavior of +, =, and += to behave consistently and intuitively when used with the classes that are used to generate Strings (StringBuffer, StringBuilder, and String). For anybody who knows that + means concatenation of strings, it's fairly obvious what: StringBuilder foo = "abc"; foo += "def"; is supposed to do. >Also, if '+' will call .append on any appendables, I guarantee you, >the first thing some clown will create is this: > >public class BigInteger2 extends Number implements Appendable { > //I'm a BigInteger that supports +! Oh - and I'm mutable too :/ >} Two observations: 1) If you are programming alongside clowns, it's probably time to find a new job. 2) This is probably the least of the damage that a clown can do when armed with a Java compiler. See observation #1. >Specific problems with the entire concept: > >1. + so far is strictly a 'create new object with result' kind of of >operation. "x + y" is an expression that does not change either the >value of x, or the value of y. It just creates a new value, and that >is the result of the expression. The same thing happens with strings, >but if you apply this to appendables, all of a sudden you get "x + y" >takes y and appends it to x. That is just strange. That's not what the proposal says. It says "x = x + y" takes y and appends it to x, if x is a StringBuilder and y is a String. The append is only done so that this happens efficiently (by eliminating the need to create an unnecessary temporary String object). It's an optimization for an expression in a very common, specific pattern involving multiple operators which is known to be evaluated inefficiently if not treated as a special case. Compilers do this sort of large-scale optimization frequently for a variety of reasons. From the user's point of view, there is no difference in behavior. "x + y" by itself does what it has always done. >2. The whole point of not allowing operator overloading is to make >sure any given snippet of the form 'x + y' serves as an anchor of >sorts: You know nothing too weird is going on in those 3 characters. >If + can mean: Mathematical plus, -OR- string concatenation (utterly >unrelated), -OR- anything anybody may have cooked up by implementing >Appendable, then there's zero conservative anchoring left for the + >symbol. Ergo I assert that doing this is as bad as having full blown >operator overloading. Actually, it's worse - at least full blown >operator overloading has proper names for things ('+' is plus and not >append), and allows one to write proper libraries for it. I personally am not particularly against operator overloading as a general principle. I've used C++ for many years and never really had a problem with someone abusing it. I've never really understood certain parts of the Java community's shock and horror at the concept of having it in a language -- lots of languages have it, and it doesn't really seem to be one of the major problems with any of them. (C++, for instance, has WAY bigger problems than that!) Whether it gets abused or not mostly depends on the culture and training of the average person who uses that particular language, not the features they have available to them. Also, libraries which aren't useful and reasonably intuitive don't tend to become widespread in their use. Operator overloading is only one of many possible ways that an API could be designed either well or poorly. As always, the market decides. In any case, having limited use of operator overloading designed within the platform by the people who maintain it is presumably a lot less likely to lead to abuse than to turn the public at large loose on it, so the general arguments against operator overloading ("Everybody and his dog will define operators to have unintuitive meanings at every opportunity!") don't really seem to apply in this case. Also, having operator overloading based on system interfaces which have defined meanings (and which may well be designed in ways that make them awkward to use in cases where those meanings do not apply) seems far less prone to abuse than the C++ model of "any operator can be redefined by anybody at any time for any purpose, as long as you remember to include the appropriate header file." With regards to "things people cook up using Appendable", presumably those will be things for which appending strings is a meaningful operation, right? Otherwise, they shouldn't be implementing the Appendable interface in the first place (and it would be awkward to do so, since "append(String)" isn't the only method on it, and the others are harder to implement). Since that's what the interface is really defined for, why is it a bad thing for them to be able to use the same syntax for appending strings to something with that mandate as it would be for appending them to other things, like Strings? Note that I'm not really all that sure that I'll add the Appendable concept to the proposal, since I have other concerns about it (such as the fact that append(int) isn't allowed, so there would be a lot of calling of String.valueOf(?) on the arguments). I'll have to think a bit more on that issue. >*) string concat and numeric plus are unrelated to each other. In >fact, numeric plus ought to be commutative, which string concat isn't >(commutative = swapping arguments doesn't change result). It weakens >the information that a raw + sign is capable of telling you. There are >pros and cons to having a strict interpretation of a + sign, but given >that java does not allow operator overloading, the onus appears to be >on those in favour of weakening it to prove why this is acceptable. Operator + is already defined within the language to mean concatenation as well as addition. You may argue that this shouldn't be the case, and I may even agree with you, but the fact remains that it is so, and neither of us can change that fact at this point. Given that we do, in fact, have operator + for strings meaning concatenation, I think that it is logical for us to make sure that the full set of operations that have related semantics all work together in a fashion that makes sense, given that + means concatenation for strings. Otherwise, we have a language that's not just inconsistent in the one detail that + has multiple meanings -- we have a language that's arbitrary and capricious with regards to which apparently similar operations are allowed versus which ones aren't. That's harder for users to learn. "I'm supposed to use StringBuilder to build strings. Why can't I build them with nice syntax like I'm used to with expressions involving Strings? Why does making a small change (building a string in multiple statements versus a single statement) mean I have to use an entirely different syntax to get a similar level of efficiency?". Also, in this case, it leads to a lot of unnecessarily verbose code or unnecessarily inefficient code being written. Derek > --Reinier Zwitserloot > > > >On Mar 28, 2009, at 21:14, Mark Thornton wrote: > >> Derek Foster wrote: >>> >>> CONCATENATION: An expression of the form >>> >>> SB += S >>> >>> where SB is an RValue expression of type StringBuilder, and S is an >>> expression of type String, shall be considered to have meaning as >>> defined below. (Previously, this was a syntax error) >>> >>> SELF-CONCATENATION: >>> >>> An expression of the form >>> >>> SB = SB + S >>> >> Why not allow any Appendable in these cases? >> >> Mark Thornton >> > > From peter.levart at gmail.com Thu Apr 2 23:35:28 2009 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 3 Apr 2009 08:35:28 +0200 Subject: Proposal: Sameness operators In-Reply-To: <49D54420.5090906@sun.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> <49D54420.5090906@sun.com> Message-ID: On Fri, Apr 3, 2009 at 1:02 AM, Joe Darcy wrote: > > Yes, in JDK 7 I'd like to see > > 6797535 Add shared two argument static equals method to the platform > http://bugs.sun.com/view_bug.do?bug_id=6797535 > > addressed in the platform. I was thinking putting it in a place like a > new utility class java.util.Object. > > -Joe > > Maybe not java.util.Object but java.util.Objects. Using the same name as a java.lang class prevents IDEs to suggest the imports since java.lang classes are already in scope. You would have to manually type import statements each time you wanted to use this method. Nobody does this nowadays. It would be very inconvenient. Regards, Peter From Joe.Darcy at Sun.COM Thu Apr 2 23:47:37 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Thu, 02 Apr 2009 23:47:37 -0700 Subject: Proposal: Sameness operators In-Reply-To: References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> <49D54420.5090906@sun.com> Message-ID: <49D5B109.2020007@sun.com> Peter Levart wrote: > > On Fri, Apr 3, 2009 at 1:02 AM, Joe Darcy > wrote: > > > Yes, in JDK 7 I'd like to see > > 6797535 Add shared two argument static equals method to the > platform > http://bugs.sun.com/view_bug.do?bug_id=6797535 > > addressed in the platform. I was thinking putting it in a place > like a > new utility class java.util.Object. > > -Joe > > > Maybe not java.util.Object but java.util.Objects. Using the same name > as a java.lang class prevents IDEs to suggest the imports since > java.lang classes are already in scope. Yes, I meant to type "java.util.Objects" -- having a class other than java.lang.Object named "Object" is just wrong! -Joe From vapor1 at teleport.com Fri Apr 3 00:04:18 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 03:04:18 -0400 (EDT) Subject: Naked dot - accessing object fields through unqualified Message-ID: <19432589.1238742258930.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Replies inline. -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 31, 2009 9:03 AM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: Naked dot - accessing object fields through unqualified "." [C1] > >'Self-assignment is forbidden' would not be backwards compatibile. >Yes, such code would most likely be a bug, but its still an issue. It >would have to be a warning, at best. Personally, I think it should be an error, since there seems to be no valid reason to do it, and it almost certainly indicates a bug. I think that compilers should default to being in a 'strict' mode where things like this that have been found to be bad ideas with virtually no upside are treated as illegal, even if that makes them not fully backwards compatible. For backwards compatibility, there could be a command-line switch to turn off strict mode if necessary for compiling old code. Some other things I'd like to see in this category: * Having an abstract class with a constructor that has 'public' or 'private' access. * Using C-style array declarations. (int x[] instead of int[] x) I could probably think of a few more. >However: > >Every single external java compiler I know of will warn you when you >self-assign. Eclipse does it. So does netbeans. So does IDEA. So does >pmd. So does findbugs. Mere warnings are not enough to stop people from doing this sort of thing, especially when the warning message is buried in 436 other warning messages about code which is less unambiguously broken than this is. (Note: I *HATE* it when people ignore compiler warnings like this, but I am speaking from experience when I say that it usually takes years to convince a company to clean up its act.) Unfortunately, I have worked for lots of companies that routinely ignore warnings. >If you internalize the self-assignment warning, where do you stop? >There are literally hundreds of 'duh, that must be a bug' warnings you >could generate. Not all of them are as obvious, or as non-contentious, >as 'self assignment'. So, where do you stop? Do we use the glacial >nature of the language changes process to set this up? I think that when a practice is almost always problematic, is easy to fix, and has no legitimate purpose (and/or has an easy workaround in the few cases that it is legitimate), it should be made an error (with the caveats above). I don't think that we should carry along every single design mistake in the 1.0 edition of the Java Language Standard with us until the end of time. The ability to achieve backwards compatibility is important (hence the ability to turn off strict mode I described above), but clarity of language design and preventing common errors is too. Otherwise, the amount of code which contains the error in question just keeps growing over time. > I say: No. The >community has done a fine job of addressing these issues by creating >code checkers. In my experience, the community, by and large, does not use code checkers. Relatively few companies do. Again, I wish it were otherwise, but the truth is that most companies assume that if something passes the checks done by the compiler, it's probably fine. Having tried to introduce them into companies a few times, I can report that most software engineers really don't want to be bothered with them (and are convinced that checkers won't find any bugs important enough to justify the time spent learning to use them and cleaning up lots of innocuous warnings just for the sake of the tool). Again, I thoroughly disagree with that philosophy, but that's what I have heard repeatedly in industry. Also, using a code checker is often a painful experience if you are forced to use a framework written by people who don't use them. The other issue is that every code checker checks for a different set of things. Just because your code passes your code checker's rules doesn't mean it will pass mine, or vice versa. The Sun Java compiler as of a specific version, at least, is the same for everybody. > So, I'd instead suggest: >Any improvements to java core in this area should focus on improving >the ability for external tools to integrate better. For example, a way >to extend @SuppressWarnings with additional keywords would be great. A >way to let javac auto-find (via the SPI system) 'warning/error' >plugins would be another fine idea. Having any kind of plugin system >for the official javac to give other tools a go at creating warnings >and errors on the AST that javac's parser is building would be good >already, using SPI to find these automatically is just one way of >doing it. I'm not sure APT is quite right for the job; I don't want to >litter annotations to the gist of '@ExtensivelyCheckMe' all over the >place. I'm certainly in favor of making life easier for code checkers. However, checkers that don't get used are no better than ones that don't exist. Javac (or jikes, etc.) gets used every time someone compiles a program. That means it's going to have far more influence on the correctness of the majority of Java code than any other tool. Derek > > > --Reinier Zwitserloot > > > >On Mar 29, 2009, at 04:42, Derek Foster wrote: > >> The major problem I have with this proposal is that it does not >> address the point of why I use a prefix on field names. As such, I >> would still continue to use a prefix even if this proposal were >> implemented. >> >> In short, I use a prefix to avoid typographical mistakes, like this >> one: >> >> void setFoo(Thing foob) { // Typo! >> this.foo = foo; >> } >> >> This will compile, and no warnings are produced, but it ends up >> assigning foo to itself, which is not what was intended. >> >> Your proposal has exactly the same problem: >> >> void setFoo(Thing foob) { // Typo! >> .foo = foo; >> } >> >> It therefore does not substitute for a field prefix, which WILL fix >> the problem: >> >> void setFoo(Thing foob) { // Typo! >> _foo = foo; // ERROR! Undefined variable 'foo'. >> } >> >> So unless you had some way to make use of the dot prefix mandatory >> and the only legal way to access fields (which I would like, but >> which would be an extremely backwards-incompatible change that will >> never happen in Java), I don't see that adding an optional dot >> prefix helps the situation except to reduce typing in constructor >> and setter methods slightly. >> >> (Note: I would love a "self-assignment is forbidden" change to Java. >> If I have time after my other proposals, I might write one up. >> (Anyone else want to volunteer? This one is easy!) I might be >> willing to forego prefixes and use the "this.foo = foo" approach, or >> even the ".foo = foo" approach, if I was sure it wouldn't cause me >> to fall into the self-assignment trap.) >> >> Derek >> >> > From vapor1 at teleport.com Fri Apr 3 00:21:24 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 03:21:24 -0400 (EDT) Subject: Proposal: Sameness operators Message-ID: <12090747.1238743285109.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> -----Original Message----- >From: Tom Hawtin >Sent: Mar 31, 2009 7:09 AM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: Proposal: Sameness operators > >Derek Foster wrote: >> a $$ b "same as": a==null ? b==null : a.equals(b), or a == b for primitive types. > >$ and $$ are valid identifier in (existing) Java. Not a lot of people >know that. http://jroller.com/tackline/entry/things_i_didn_t_know I, however, do know it. In fact, I mentioned it in the "Breaking Changes" section of my proposal. However, use of generated code is rare in general, and fixing a code generator to comply with a new language version only has to be done once. I considered it a lesser risk than introducing syntax that might break non-generated programs, which are very common indeed. I am open to other operators being used instead of the ones I suggested. I considered >#, <#, ##, and !#, for instance, but I thought that too many people might want to use # for closure-related things. Mostly, I wanted readability and understandability. The idea is you can just replace an = (which means "object identity" aka "equals") with a $ (which means "object equality" aka "sameness") and the related operators tend to mean what you would expect them to. >> a !$ b "not same as": a==null ? b!=null : !a.equals(b), or a != b for primitive types. >> a >$ b "greater than or same": a.compareTo(b) >= 0, or a >= b for primitive types. >> a <$ b "less than or same": a.compareTo(b) <= 0, or a <= b for primitive types. > >That's going to be jolly confusing for BigDecimal users (but I guess >that is not a state change). Personally, I find if (a >$ b) { do stuff } if (a $$ b) { do stuff } a lot less confusing than: if (a.compareTo(b) >= 0) { do stuff } if (a == null ? b == null : a.equals(b)) { do stuff } so I would hope that these would eventually reduce the confusion, not add to it. Really, the confusion is already there in how or if classes like BigDecimal implement interfaces like Comparable. (Which maybe was your point.) Derek From mthornton at optrak.co.uk Fri Apr 3 00:33:34 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Fri, 03 Apr 2009 08:33:34 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <1238731172.49d589a4a3575@www.paradise.net.nz> References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <1238711752.49d53dc8e0a4c@www.paradise.net.nz> <49D56FAB.8090405@sun.com> <1238731172.49d589a4a3575@www.paradise.net.nz> Message-ID: <49D5BBCE.2030102@optrak.co.uk> brucechapman at paradise.net.nz wrote: > OK, > > I was aware of that one because the last JUG meeting here was about visualising > code and was working with that corpus. > > The problem then is that the corpus is HUGE. Even the 20090202r version which > only has the latest release of each system (and is probably the appopriate one > for coin use) is 1.2Gb (my monthly broadband limit is 1Gb - I'd probably > sneakernet it from someone locally). > Ouch, however I'm sure there are quite a few of us with substantially more generous download allowances. Mark Thornton From forax at univ-mlv.fr Fri Apr 3 00:34:20 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 03 Apr 2009 09:34:20 +0200 Subject: Proposal: Sameness operators In-Reply-To: <49D5B109.2020007@sun.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> <49D54420.5090906@sun.com> <49D5B109.2020007@sun.com> Message-ID: <49D5BBFC.7040705@univ-mlv.fr> Joseph D. Darcy a ?crit : > Peter Levart wrote: > >> On Fri, Apr 3, 2009 at 1:02 AM, Joe Darcy > > wrote: >> >> >> Yes, in JDK 7 I'd like to see >> >> 6797535 Add shared two argument static equals method to the >> platform >> http://bugs.sun.com/view_bug.do?bug_id=6797535 >> >> addressed in the platform. I was thinking putting it in a place >> like a >> new utility class java.util.Object. >> >> -Joe >> >> >> Maybe not java.util.Object but java.util.Objects. Using the same name >> as a java.lang class prevents IDEs to suggest the imports since >> java.lang classes are already in scope. >> > > Yes, I meant to type "java.util.Objects" -- having a class other than > java.lang.Object named "Object" is just wrong! > > -Joe > or fun, all programs that use import java.util.* will break. R?mi From vapor1 at teleport.com Fri Apr 3 00:45:56 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 03:45:56 -0400 (EDT) Subject: PROPOSAL: Underscores in numbers Message-ID: <31694231.1238744756544.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> -----Original Message----- >From: Bruce Chapman >Sent: Mar 31, 2009 3:14 AM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Underscores in numbers > >Derek, >thanks for writing this up, it saved me doing it. (and it would >complement my integer literal proposals nicely) You're welcome! Personally, I definitely hope that your type suffixes for bytes and shorts proposal goes through. Lack of that seems a weird omission in the language, and I am tired of casting to bytes. I am not as keen on the other proposal with its "0h52" notation, however. That seems to be mixing radix and type in a way that is not very consistent with how the rest of the language works. >A couple of comments: > >1. I don't really like most of your decimal examples because (apart from >the money one) although we talk about these as numbers, they are not >numbers really, just identifiers whose significant elements consist >solely of digits. As an explanation, prepending 00 to the front of any >of these would yield a different (or invalid) phone/credit card/SS >number, whereas prepending 00 to a number does not (but not in java >where it makes an octal or a compiler error :), similarly add two >together or subtracting them makes no sense. I think that both pure numbers (underscores used for order-of-magnitude grouping of digits) and formatted numbers (underscores used in standard groups) like these are both valid use cases for this feature. They are definitely different use cases, but it is nice that the feature can be used for both. >Real countable number examples that could be useful are populations, >national debt, Long.MAX_VALUE etc, as well as the hex and binary >examples you use later. I'm not averse to adding more examples. I tried to make each existing example show a different likely use of the feature. So I really only needed one example to show the use of underscores to group big numbers in three-digit chunks (as commas would be used, for Americans anyway). >I am not convinced of the utility of multiple consecutive underscore >separators, and I think the example that uses that is confusing and >asking for trouble. IMHO it would add to the value if you removed that >option, but you might have some good use case you are thinking about. >Similarly for underscore at either end seems strange. It might take more >effort to describe it such that these are illegal, but I don't think >anyone would complain at the absence of that form. I left them in because I couldn't see a good reason to exclude them, and it's possible that someone might want to use them for some form of formatting that I haven't thought of. Perhaps someone might want to space the digits out to make a number line up with the characters in a comment field that's above it, for instance: // AreaCode Exchange Number int x = 555______555___1212; int y = 555______857___5309; The question really is whether adding multiples causes actual problems. As far as I can see, it doesn't. If someone is abusing them to write unclear code, then it seems to me that that person is really the problem. I don't think the feature in and of itself particularly encourages abuse. It could be used in ways that make code clearer rather than harder to read. I don't really expect it to be used much, though. >Any reason why in the syntax you didn't just add underscore to the >various XXXXDigits forms (and maybe change the name a little) rather >than the more complex approach, then describe the erasure of the >underscore in the description of each form? Because that would have made things like "0x_" or "_._" be parseable as syntactically legal numbers, which would then become illegal once the underscores were removed. Getting the grammar right for the underscores proposal turned out to be much trickier than I had anticipated. (It probably took me two hours.) I initially did it wrong, and had to revise it once I realized that I couldn't ever allow an underscore to appear if it wasn't next to a digit. Derek >Bruce > >Derek Foster wrote: >> When I posted my Binary Literals proposal, I got feedback from several people stating that they would like to see a proposal regarding underscores in numbers, in the style of Ruby, since that would make numbers of all types (but especially binary ones) easier to read. Here is such a proposal. >> >> AUTHOR(S): Derek Foster >> >> OVERVIEW >> >> In Java, currently, numbers of various types currently are expressed in their pure form, as a long string of digits possibly interspersed with other punctuation (periods, an exponent specifier, etc.) needed to separate distinct sections of the number. While this is easy for a compiler to process, it is often difficult for a human being to visually parse. >> >> The ability of a human to visually separate separate items tops out somewhere near "seven plus or minus two" items. Research done by telephone companies suggests that for many practical purposes, the longest string of numbers an average human can successfully hold in memory at a time is around three or four. Also, it is difficult for the human eye to find common positions in numbers that have no break in their visual structure. >> >> As a result, most numbers that humans deal with in day-to-day life have separators included in them to break the long sequence of digits into manageable chunks that are easy to deal with as separate entities. This includes items such as (apologies to non-USA readers...): >> >> Phone numbers: 555-555-1212 >> Credit card numbers: 1234-5678-9012-3456 >> Social security numbers: 999-99-9999 >> Monetary amounts: $12,345,132.12 >> >> and a wide variety of other types of numbers. >> >> However, Java provides no way to add these kinds of visual separators into a number. Java expects the number to be essentially an unbroken string of digits. >> >> This proposal suggests that Java follow the lead of the Ruby programming language in allowing the underscore character to be inserted into numbers in most positions, for readability purposes. >> >> >> FEATURE SUMMARY: >> >> Java numeric literals will allow underscores to be placed in (nearly) arbitrary positions within the number, at the programmer's discretion, for readability purposes. These underscores shall be ignored by the compiler for the purposes of code generation. >> >> >> MAJOR ADVANTAGE: >> >> Programmers won't have to visually parse long strings of digits (a task humans are quite poor at). The internal digit-oriented structure of many numbers can be made more clear. >> >> >> MAJOR BENEFIT: >> >> Increased readability of code. >> >> >> MAJOR DISADVANTAGE: >> >> The number parsers in the Java compiler would have to be adjusted to parse and ignore the underscores. This is a small amount of effort, but nonzero. There might also be some small performance impact. >> >> If someone were to use this feature inappropriately, it could result in difficult to read code. >> >> >> ALTERNATIVES: >> >> Do without separators in numbers, or use some other character for them. >> >> >> EXAMPLES >> >> >> SIMPLE EXAMPLE: Show the simplest possible program utilizing the new feature. >> >> int phoneNumber = 555_555_1212; >> >> >> ADVANCED EXAMPLE: >> >> long creditCardNumber = 1234_5678_9012_3456L; >> long socialSecurityNumbers = 999_99_9999L; >> float monetaryAmount = 12_345_132.12; >> long hexBytes = 0xFF_EC_DE_5E; >> long hexWords = 0xFFEC_DE5E; >> long maxLong = 0x7fff_ffff_ffff_ffffL; >> long alsoMaxLong = 9_223_372_036_854_775_808L; >> double whyWouldYouEverDoThis = 0x1_.ffff_ffff_ffff_fp10_23; >> >> (Additionally, if binary literals are ever added to the Java language, the following might also be possible... >> byte nybbles = 0b0010_0101; >> long bytes = 0b11010010_01101001_10010100_10010010; >> int weirdBitfields = 0b000_10_101; >> ) >> >> Note that underscores can be placed around and between digits, but that underscores cannot be placed by themselves in positions where a string of digits would normally be expected: >> >> int x1 = _52; // This is an identifier, not a numeric literal. >> int x2 = 5_2; // OK. (decimal literal) >> int x2 = 52_; // OK. (decimal literal) >> int x3 = 5_______2; // OK. (decimal literal.) >> >> int x4 = 0_x52; // Illegal. Can't put underscores in the "0x" radix prefix. >> int x5 = 0x_52; // OK. (hexadecimal literal) >> int x6 = 0x5_2; // OK. (hexadecimal literal) >> int x6 = 0x52_; // OK. (hexadecimal literal) >> int x6 = 0x_; // Illegal. Not a valid hex number with the underscore removed. >> >> int x7 = 0_52; // OK. (octal literal) >> int x7 = 05_2; // OK. (octal literal) >> int x8 = 052_; // OK. (octal literal) >> >> >> DETAILS >> >> SPECIFICATION: >> >> DECIMALS: >> >> Section 3.10.1 ("Integer Literals") of the Java Language Specification 3rd edition shall be modified like so: >> >> Underscores: >> _ >> _ Underscores >> >> DecimalNumeral: >> 0 >> NonZeroDigit DigitsAndUnderscores_opt >> >> DigitsAndUnderscores: >> Underscores_opt Digit Underscores_opt >> DigitsAndUnderscores Digit Underscores_opt >> >> Digit: >> 0 >> NonZeroDigit >> >> NonZeroDigit: one of >> 1 2 3 4 5 6 7 8 9 >> >> HexNumeral: >> 0 x HexDigitsAndUnderscores >> 0 X HexDigitsAndUnderscores >> >> HexDigitsAndUnderscores: >> Underscores_opt HexDigit Underscores_opt >> Underscores_opt HexDigit HexDigitsAndUnderscores >> >> HexDigit: one of >> 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F >> >> OctalNumeral: >> 0 OctalDigitsAndUnderscores >> >> OctalDigitsAndUnderscores: >> Underscores_opt OctalDigit Underscores_opt >> Underscores_opt OctalDigit OctalDigitsAndUnderscores >> >> OctalDigit: one of >> 0 1 2 3 4 5 6 7 >> >> Section 3.10.2 ("Floating-Point Literals") would be modified as follows: >> >> >> FloatingPointLiteral: >> DecimalFloatingPointLiteral >> HexadecimalFloatingPointLiteral >> >> DecimalFloatingPointLiteral: >> Digit DigitsAndUnderscores_opt . DigitsAndUnderscores_opt ExponentPart_opt FloatTypeSuffix_opt >> . DigitsAndUnderscores ExponentPartopt FloatTypeSuffix_opt >> Digit DigitsAndUnderscores_opt ExponentPart FloatTypeSuffix_opt >> Digit DigitsAndUnderscores_opt ExponentPart_opt FloatTypeSuffix >> >> ExponentPart: >> ExponentIndicator SignedInteger >> >> ExponentIndicator: one of >> e E >> >> SignedInteger: >> Sign_opt DigitsAndUnderscores >> >> Sign: one of >> + - >> >> FloatTypeSuffix: one of >> f F d D >> >> HexadecimalFloatingPointLiteral: >> HexSignificand BinaryExponent FloatTypeSuffix_opt >> >> HexSignificand: >> HexNumeral >> HexNumeral . >> 0x HexDigitsAndUnderscores_opt . HexDigitsAndUnderscores >> 0X HexDigitsAndUnderscores_opt . HexDigitsAndUnderscores >> >> BinaryExponent: >> BinaryExponentIndicator SignedInteger >> >> BinaryExponentIndicator:one of >> p P >> >> >> COMPILATION: >> >> Numbers containing underscores are to be parsed and evaluated by the compiler exactly as if the underscores were not present. The above grammar ensures that removing underscores will not result in an unparseable number. >> >> A simple strategy for achieving this is that once a number has been parsed by the compiler lexer and determined to be syntactically valid according to the above grammar, then if the number contains any underscores, then all underscores in it may be removed (by something as simple as numberAsString.replaceAll("_","")) before passing the number on to the code that would normally have parsed the number prior to this proposal. >> >> More performant approaches are certainly possible. >> >> >> TESTING: How can the feature be tested? >> >> A variety of literals may be generated, of the cross product of each of the following radicies: >> >> hex, decimal, octal >> >> with each of the following types: >> >> byte, char, short, int, long, float, double >> >> such that for each possible numeric field in the result, that one or more underscores are inserted at the beginning, in the middle, and at the end of the digits. >> >> Note that the above grammar is specifically designed to disallow any underscores from appearing which are not either preceded by or followed by a digit. >> >> >> LIBRARY SUPPORT: >> >> Methods such as Integer.decode(String) and Long.decode(String) should probably be updated to ignore underscores in their inputs, since these methods attempt to parse according to Java conventions. >> >> I suggest that methods such as Integer.parseInt(), Float.parseFloat(), etc. should probably NOT be updated to ignore underscores, since these methods deal with numbers in their pure form, and are more focused and much more widely used. To alter them to ignore underscores would introduce ambiguity in (and have a performance impact on) various parsing code that uses them. >> >> >> REFLECTIVE APIS: >> >> No changes to reflective APIs are needed. >> >> >> OTHER CHANGES: >> >> No other changes are needed. >> >> >> MIGRATION: >> >> Underscores can be inserted into numbers within an existing code base as desired for readability. >> >> >> COMPATIBILITY >> >> BREAKING CHANGES: >> >> Since use of underscores within numbers was previously a syntax error, this should not break any existing programs. >> >> >> EXISTING PROGRAMS: >> >> This feature does not affect the format of class files. It is purely a notational convenience. Hence, interaction with existing class files would not be affected. >> >> REFERENCES >> >> EXISTING BUGS: >> >> A search of the Bug Database did not find any bug ID's related to this proposal. >> >> URL FOR PROTOTYPE (optional): >> >> None. >> >> >> >> > From vapor1 at teleport.com Fri Apr 3 00:57:06 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 03:57:06 -0400 (EDT) Subject: PROPOSAL: Auto-assignment Parameters Message-ID: <31069284.1238745426303.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 31, 2009 9:05 AM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Auto-assignment Parameters > >Derek, if this proposal will save you a lot of typing, I think you're >doing it wrong. Thare are many tools that will auto-generate POJOs for >you, including whatever setter you prefer. Most IDEs have this in >their 'source' or 'refactor' menu, for example. It wasn't the typing of creating them in the first place that I had in mind, but what comes after that. I would explain more on that point, but it seems you have saved me the trouble: >What annoys me about these tools is that they are one-way operations. > From seeing the multiple pages of POJO auto-generated code (incl. >hashCode, equals, toString, and constructor, and in some cases, the >auto-generated builder as well), I cannot ascertain quickly if this is >'just' the usual auto-generated boilerplate, or if there's a fun >surprise in there someplace (like some field being excluded for equals/ >hashCode purposes, or a missing getter, or some such). This makes >POJOs spectacularly unmaintainable compared to the low impact they >should be having, in java. It's also somewhat difficult (but certainly >not impossible) to change things that were used to auto-generate code, >such as changing the type or name of a field later. You and I are in rabid agreement on that point. I don't like code generation tools that spew forth blocks of code that I then have to maintain. To me, the existence of such tools indicates a deficiency in the language. (If it's easy enough for a tool to generate boilerplate code like that, it should be easy for the language to make that boilerplate code unnecessary by generating it for me as I compile.) >That's why I want a 'data' modifier for class, which will completely >auto-generate everything. If the 'saves me typing' argument holds >water, imagine what this will do for you! We agree on this. I want a data modifier for a class also (or could we just use the 'struct' keyword like C++?). However, the auto-assignment parameters proposal has more general applicability to classes other than data classes as well, so I want those too. I might even use them both together in the same class. > I also don't want such a >feature to spin out of a control into an entirely new programming >definition syntax, so we'll just use java itself to fill in the gaps >and afford us flexibility: If the auto-gen isn't good enough for you, >then don't use it and write it the usual way. You get method-level >granularity for this process, but that's where it ends. Simple and yet >a great boon for code maintainability. I agree with this as well. I think it's perfectly reasonable for there to be shorthand syntax for common cases, with the ability to override it when something more complex is needed. If I just want to return three values from a method, I don't want to have to write a full-blown class complete with a constructor, getters, and setters. Just specifying the fields is enough. A data class will probably do fine. But I want to be able to replace that data class later with the real thing if necessary without having to update all of the uses of it in the code. Derek > > > > --Reinier Zwitserloot > > > >On Mar 28, 2009, at 22:31, Derek Foster wrote: > >> Just to add a few kudos and comments: >> >> I like the proposal a lot. Even in its current form, this would save >> me a lot of typing. Of the proposals so far put forth on Project >> Coin, this is the one I would probably end up using the most often. >> I use a lot of immutable class objects, and this >> >> Some suggestions and things to consider: >> >> 1) I think that having to repeat "this." all over the place is >> perhaps unnecessary. You could use something shorter, like a leading >> dot, or perhaps a leading equals sign: >> >> class Foo { >> final int bar; >> final String baz; >> Foo(int .bar, String .baz) {} >> void setBar(int .bar) {} >> void setBaz(String .baz) {} >> } >> >> 2) I think that allowing the syntax for all method parameters, not >> just constructor parameters, would be nice. >> >> 3) I think that allowing the syntax for return values from methods >> has some potential advantages as well. There are some potential >> advantages with >> Javadoc generation, as I describe below, which would make: >> >> String this.foo getFoo() {} >> >> advantageous in some circumstances even if it isn't much shorter than: >> >> String getFoo() { return this.foo; } >> >> 4) I think you should consider the impact on Javadoc more carefully. >> Particularly in cases where people use a prefix ("_", "m_", etc.) on >> their internal fields, which is very common. It looks as though >> those prefixes would end up being displayed in Javadoc as >> constructor parameter names, which would be less than ideal. >> >> Also, autogeneration of Javadoc for the this. parameters, based on >> Javadoc for the class members they are initialized from would be >> nice. Currently, these often have to be maintained in parallel, >> which can be a significant annoyance. >> >> I often see people write code equivalent to: >> >> class Foo { >> /** This is the name of a famous person which can't be null and >> blah blah blah. */ >> String _bar; >> >> /** >> * Construct a new instance. >> * @param bar This is the name of a famous person which can't be >> null and blah blah blah. >> */ >> Foo(String bar) { >> _bar = bar; >> } >> >> /** >> * Sets the value of bar. >> * @param bar This is the name of a famous person which can't be >> null and blah blah blah. >> */ >> void setBar(String bar) { >> _bar = bar; >> } >> >> /** >> * Gets the value of bar. >> * @return This is the name of a famous person which can't be >> null and blah blah blah. >> */ >> String getBar() { >> return _bar; >> } >> >> } >> >> which essentially reproduces the same JavaDoc comment four times >> (and means it must be maintained in quadruplicate if changes are >> made). It would be nice to replace this with something like: >> >> class Foo { >> /** This is the name of a famous person which can't be null and >> blah blah blah. */ >> String _bar; >> >> /** Construct a new instance. */ >> Foo(String this.bar) {} >> >> /** Sets the value of bar. */ >> void setBar(String this.bar) {} >> >> /** Gets the value of bar. */ >> String this.bar getBar() {} >> } >> >> with the same Javadoc being generated as the prior example. >> >> 5) Being able to omit the type in all of these cases would be a big >> plus. When I have a variable of a type like >> "List>", it would be >> awfully nice to be able to omit having to specify that detail >> redundantly in the constructor, settter, and getter. >> >> Derek >> >> >> >> >> -----Original Message----- >>> From: Mark Mahieu >>> Sent: Mar 26, 2009 2:21 PM >>> To: Marek Kozie? >>> Cc: coin-dev >>> Subject: Re: PROPOSAL: Auto-assignment Parameters >>> >>> 2009/3/26 Marek Kozie? >>> >>>> I see one problem here. >>>> class Some{ >>>> final String name; >>>> public Some(String this.name){} >>>> } >>>> >>>> perform .intern() is impossible now. >>> >>> >>> Correct, you'd have to write it the same way as you'd do now. I >>> actually >>> view that as a Good Thing though: there's a clear, visual distinction >>> between parameters which are just assigned directly to the fields, >>> and those >>> on which we perform some operation first. Only the latter would >>> appear in >>> the body of the constructor, without being cluttered by the former. >>> >>> >>>> But I like the proposition 'much'. >>>> Simple and clear. >>> >>> >>> Glad you like it! >>> >>> >>> Regards, >>> >>> Mark >>> >> >> > From vapor1 at teleport.com Fri Apr 3 01:09:56 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 04:09:56 -0400 (EDT) Subject: PROPOSAL: @OverrideAll annotation Message-ID: <17542308.1238746196681.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> My major problem with this proposal is that it doesn't seem to be straightforward to generate the bodies of methods that have to return something. Particularly for code such as implementations of the Visitor pattern. Having un-overridden methods simply return null or zero is often not the right thing to do. It's OK for generating methods that just take parameters, I suppose. Still, having annotations generate code or otherwise affect the operation of a program is apparently a no-no per Sun's rules. If something like this is going to happen, I think it needs a new keyword or something rather than using an annotation. (Although, personally, I don't think it would be such a bad thing if code generation via annotation existed, but were limited only to certain annotations in a specific package duly designated by the language implementors. Annotations have one nice quality that other ways of extending the language don't: You can create new "keywords" at will with no risk of breaking someone's perfectly-working code. If they don't import the annotation, they won't need to be impacted by it. I sort of wish there was an alternative to annotations (@@Foo instead of @Foo?) which was explicitly for the purpose of telling the compiler to generate boilerplate code of various types. Decorators in Python sort of serve this purpose, for instance.) Derek -----Original Message----- >From: rssh at gradsoft.com.ua >Sent: Mar 31, 2009 10:02 AM >To: Gabriel Belingueres >Cc: coin-dev >Subject: Re: PROPOSAL: @OverrideAll annotation > >> Hi, >> >> I've written a new feature that might be comfortable to use for >> someone. All input is welcomed. >> > >It-is possible to do near same with annotation API (create a superclass > which will override all) > >But -- sometime we really need to say, that all methods 'mus be' >overriden. (For example - when implementing Proxy pattern). >In such case class-level annotation '@OverrideAll' which tell compiler >to check, that all methods must be overriden -- brilliant idea. > > > > > >> Regards, >> Gabriel >> >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): Gabriel Belingueres >> >> OVERVIEW >> >> Add an @OverrideAll annotation to allow a class to override all >> inherited methods with a trivial implementation. The resulting class >> then could be used as the basis for a Null Object pattern (or even a >> basic Mock object.) >> >> >> FEATURE SUMMARY: >> >> The proposed @OverrideAll annotation will allow the class to override >> all methods (from its superclasses and implemented interfaces) with a >> trivial body, but the defined class can choose to implement specific >> methods, replacing those that would be produced automatically by the >> annotation. >> >> >> MAJOR ADVANTAGE: >> >> Less coding for implementing Null Objects, or simple tests. >> >> >> MAJOR BENEFIT: >> >> Let the compiler implement all uninteresting, non relevant behavior by >> automatically providing with a trivial implementation of the inherited >> methods. >> >> >> MAJOR DISADVANTAGE: >> >> Might be a cause of NullPointerException if not used judiciously. >> >> >> ALTERNATIVES: >> >> Implement all uninteresting methods by yourself by providing yourself >> a trivial implementation (though actually popular IDEs can do this >> automatically for you already.) >> >> EXAMPLES >> >> Given: >> >> class B {} >> >> public class A implements I1, I2 { >> >> public static final int VAR = 1; >> >> private B b; >> >> public static Integer getSome() { >> return VAR; >> } >> >> public A() { >> } >> >> public A(B b) { >> this.b=b; >> } >> >> public B getB() { >> return b; >> } >> >> public void setB(B b) { >> this.b=b; >> } >> >> protected void doProtected() { ... } >> >> private void doPrivate() { ... } >> >> A someNewA() { ... } >> >> public synchronized void someSynchronized() { >> } >> >> } >> >> then: >> >> @OverrideAll >> public class NullA extends A { >> } >> >> is equivalent to declare: >> >> public class NullA extends A { >> >> public NullA() {} >> >> public NullA(B b) { >> super(b); >> } >> >> public B getB() { >> return null; >> } >> >> public void setB(B b) { >> } >> >> protected void doProtected() { >> // empty >> } >> >> A someNewA() { >> return null; >> } >> >> public synchronized void someSynchronized() { >> // empty >> } >> >> } >> >> You may not want the default trivial implementation in some methods, >> then you override them as usual: >> >> @OverrideAll >> public class NullA extends A { >> >> @Override >> public B getB() { >> return new B(); >> } >> >> @Override >> public synchronized void someSynchronized() { >> System.out.println("overridden"); >> } >> >> } >> >> EXAMPLE 2 >> >> Implement a trivial Collection interface just to test that adding >> elements will increase the collection size: >> >> Currently: >> >> public class SomeCollection implements Collection { >> >> private int counter; >> >> @Override >> public boolean add(E arg0) { >> counter++; >> return true; >> } >> >> @Override >> public boolean addAll(Collection c) { >> counter += c.size(); >> return true; >> } >> >> @Override >> public void clear() { >> } >> >> @Override >> public boolean contains(Object arg0) { >> return false; >> } >> >> @Override >> public boolean containsAll(Collection arg0) { >> return false; >> } >> >> @Override >> public boolean isEmpty() { >> return false; >> } >> >> @Override >> public Iterator iterator() { >> return null; >> } >> >> @Override >> public boolean remove(Object arg0) { >> return false; >> } >> >> @Override >> public boolean removeAll(Collection arg0) { >> return false; >> } >> >> @Override >> public boolean retainAll(Collection arg0) { >> return false; >> } >> >> @Override >> public int size() { >> return counter; >> } >> >> @Override >> public Object[] toArray() { >> return null; >> } >> >> @Override >> public T[] toArray(T[] arg0) { >> return null; >> } >> >> } >> >> With the annotation: >> >> @OverrideAll >> public class SomeCollection implements Collection { >> >> private int counter; >> >> @Override >> public boolean add(E arg0) { >> counter++; >> return true; >> } >> >> @Override >> public boolean addAll(Collection c) { >> counter += c.size(); >> return true; >> } >> >> >> @Override >> public int size() { >> return counter; >> } >> >> } >> >> >> DETAILS >> >> >> SPECIFICATION: >> >> A preliminary specification follows: >> >> As this feature is proposed as an annotation for code generation, no >> changes to the current JLSv3 are needed. >> >> The annotation will generate "trivial" overridden implementations for >> all methods not specified in the class, for each superclass in the >> hierarchy (except Object) and implemented interface. >> >> - Static methods, private methods, final methods, constructors and >> methods from class Object should never be generated. >> - If some superclass (except Object) has already overridden some >> Object class methods, then do NOT generate an empty overridden method >> (to reuse current behavior.) (for example, if some superclass already >> override toString(), equals() or hashCode().) >> >> - OPTIONAL: add a parameter to the @OverrideAll annotation to indicate >> if @Deprecated methods should not be implemented. >> >> Trivial implementation for generated methods: >> >> - Methods returning void will have an empty body. (OPTIONAL: add a >> parameter to the @OverrideAll annotation to indicate that it should >> throw UnsupportedOperationException instead) >> - Methods returning a primitive type will have a body returning the >> same default value that would have for uninitialized instance >> variables. (JLS section 4.12.5.) >> - Methods returning a reference type will "return null;". (JLS section >> 4.12.5.) >> - The method will never return a covariant return type (because in >> case of implementing a Null object, it should be undistinguished from >> the common case) >> - Methods that throws checked exceptions can be modified to delete the >> throws clause. (ie. the trivial implementation should not throw >> checked exceptions) >> - Synchronized methods should retain that attribute. >> >> >> COMPILATION: >> >> Compilation should proceed as usual, except that the annotation >> processor would generate the code when it encounters an annotated >> class. >> >> No changes to the class file format are needed. >> >> >> TESTING >> >> Test cases should be done, including testing with classes implementing >> several interfaces, classes with generics, inner classes, etc. >> >> >> LIBRARY SUPPORT: >> >> No, except creating the new annotation. >> >> >> REFLECTIVE APIS: >> >> No changes foreseen. >> >> >> OTHER CHANGES: >> >> Output of javadoc tool. >> >> >> MIGRATION: >> >> Just add the annotation to class level, and erase your trivially >> implemented overridden methods. >> >> >> COMPATIBILITY >> >> BREAKING CHANGES: >> All existing programs remain valid. >> >> EXISTING PROGRAMS: >> The semantics of existing class files and legal source files are >> unchanged by this feature. >> >> >> REFERENCES >> >> EXISTING BUGS: >> >> None that I know about. >> >> URL FOR PROTOTYPE: >> >> None at this time. >> >> > > > From vapor1 at teleport.com Fri Apr 3 01:15:25 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 04:15:25 -0400 (EDT) Subject: Proposal: Accepting a subclass as an element type in a for loop Message-ID: <9909880.1238746526010.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> I was leaning somewhat on the side of thinking this would be a nice feature (it is, at least, an elegant one), but I think that Reiner's arguments have convinced me otherwise. The example of the filtering method, in particular, shows that working around this is quite easy. Given that the need for this actually comes up pretty rarely in my experience (I have only ever wanted this once, that I can recall, and it was both easy and intuitive to work around in a manner somewhat similar to but less general than Reiner's suggestion), I think I have come to the conclusion that despite its elegance, this probably isn't worth adding to the language. Derek -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 31, 2009 11:16 AM >To: Jean-Louis Ardoint >Cc: coin-dev at openjdk.java.net >Subject: Re: Proposal: Accepting a subclass as an element type in a for loop > >Why is this worthy of a language change? It's very niche. > >You can solve your problem by writing 1 method, like so: > >for ( Rectangle r : MyUtilityClass.filterOnType(shapes, >Rectangle.class) ) { > drawRectangle(r); >} > > >with: > >public class MyUtilityClass { > public static List filterOnType(Iterable >in, Class outType) { > List list = new ArrayList(); > for ( A a : in ) > if ( outType.isInstance(a) ) list.add(outType.cast(a)); > return list; >} > > > >Even if you disregard for a moment that if you add this, I've got >about a gazillion other niche things that have about as many use cases >and are about as easy to solve with a library for coin,your proposal >has omitted a rather serious issue: > >What would you do if you have something like: > >List> foo = someMethodCall(); >for ( Set set : foo ) { > // You can't do this in java. >} > > > > --Reinier Zwitserloot > > > >On Mar 31, 2009, at 14:55, Jean-Louis Ardoint wrote: > >> I'm maybe a bit too late. Here's my proposal anyway. >> >> >> >> -- Jean-Louis Ardoint >> >> >> >> Accepting a subclass as an element type in a for loop >> >> >> >> AUTHOR(S): Jean-Louis Ardoint >> >> >> >> OVERVIEW >> >> >> >> FEATURE SUMMARY >> >> >> >> Add a filtering and downcast capability to the enhanced for statement >> (a.k.a for each). >> >> >> >> MAJOR ADVANTAGE >> >> >> >> It should reduce the number of lines of code and depth of nesting in >> loops. The resulting code would be more readable that what is done >> currently to achieve the same goal. The meaning of such a loop is >> quite >> obvious. >> >> >> >> MAJOR BENEFIT >> >> >> >> Better readability and expressiveness. >> >> >> >> MAJOR DISADVANTAGE >> >> >> >> More complexity in the compiler to generate a little bit more >> bytecode. >> >> >> >> ALTERNATIVE >> >> >> >> You can currently the same thing, yet it means adding an extra if >> statement and an intermediate variable to be cast. >> >> >> >> EXAMPLES >> >> >> >> Here is a small not very interesting example of such a enhanced for >> loop: >> >> >> >> Shape[] shapes = ...; >> >> for (Shape s : shapes) >> >> drawShape(s); >> >> >> >> If for a reason you would need to draw only the rectangles, you would >> need to write: >> >> >> >> for (Shape s : shapes) { >> >> if (s instanceof Rectangle) >> >> drawRectangle((Rectangle)s); >> >> } >> >> >> >> This is not very aesthetic. If only the for loop would directly >> accept a >> subclass as the element type and do the type checking and downcast, we >> could be able to write: >> >> >> >> for (Rectangle r : shapes) >> >> drawRectangle(r); >> >> >> >> Note that there is a subtlety w.r.t. the handling of nulls. See >> Compilation below for more details >> >> >> >> DETAILS >> >> >> >> SPECIFICATION: >> >> >> >> The grammar is unchanged. The equivalence between an enhanced for loop >> and a regular for loop has to be changed in JLS 14.14.2. >> >> COMPILATION: >> >> >> >> The way enhanced loop are translated into bytecode would change >> depending on whether the loop variable type is a subclass of the >> iterable or array element type. >> >> If the loop variable type is a subclass, then the loop is equivalent >> to: >> >> >> >> For an expression returning Iterable: >> >> Iterable cs... >> >> for (I #i = cs.iterator(); #i.hasNext(); ) { >> >> C #c = #i.next(); >> >> if (#c == null || #c instanceof D) { >> >> D d = (C)#c; >> >> ... >> >> } >> >> } >> >> >> >> For an array: >> >> >> >> C[] ca... >> >> for (int i = 0; i < ca.length; i++) { >> >> C #c = ca[i]; >> >> if (#c == null || #c instanceof D) { >> >> D d = (C)#c; >> >> ... >> >> } >> >> } >> >> >> >> Note that we need to test against null to keep the same behavior as >> the >> regular enhanced for loop. >> >> >> >> TESTING: >> >> >> >> This feature can be tested in the same way the enhanced for loop is >> tested. >> >> >> >> >> >> LIBRARY SUPPORT: >> >> >> >> There is no need for library support. >> >> >> >> >> >> REFLECTIVE APIS: >> >> >> >> No updates to the reflection APIs are needed. >> >> >> >> >> >> OTHER CHANGES: >> >> >> >> No other changes are needed. >> >> >> >> >> >> MIGRATION: >> >> >> >> Migration of existing enhanced for loop can be done if one desires so. >> >> >> >> COMPATIBILITY >> >> >> >> >> >> BREAKING CHANGES: >> >> >> >> This feature would not break any existing programs, since the new >> feature only permits more code to be parsed than before. >> >> >> >> >> >> EXISTING PROGRAMS: >> >> >> >> Class file format does not change, so existing programs can use class >> files compiled with the new feature without problems. >> >> >> >> >> >> >> >> >> >> >> >> >> >> > > From rssh at gradsoft.com.ua Fri Apr 3 01:19:42 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Fri, 3 Apr 2009 11:19:42 +0300 (EEST) Subject: PROPOSAL: @OverrideAll annotation In-Reply-To: <17542308.1238746196681.JavaMail.root@mswamui-thinleaf.atl.sa.earthlin k.net> References: <17542308.1238746196681.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Message-ID: > My major problem with this proposal is that it doesn't seem to be > straightforward to generate the bodies of methods that have to return > something. Particularly for code such as implementations of the Visitor > pattern. > > Having un-overridden methods simply return null or zero is often not the > right thing to do. > > It's OK for generating methods that just take parameters, I suppose. > May be this is not, what author of original proposal mean, but have class annotation @OverrideAll, which does not generate any code, just throw compile-time error when exists non-overridden member functions is helpfull in some situations and prevent from hard to debug errors. > Still, having annotations generate code or otherwise affect the operation > of a program is apparently a no-no per Sun's rules. If something like this > is going to happen, I think it needs a new keyword or something rather > than using an annotation. > > (Although, personally, I don't think it would be such a bad thing if code > generation via annotation existed, but were limited only to certain > annotations in a specific package duly designated by the language > implementors. Annotations have one nice quality that other ways of > extending the language don't: You can create new "keywords" at will with > no risk of breaking someone's perfectly-working code. If they don't import > the annotation, they won't need to be impacted by it. I sort of wish there > was an alternative to annotations (@@Foo instead of @Foo?) which was > explicitly for the purpose of telling the compiler to generate boilerplate > code of various types. Decorators in Python sort of serve this purpose, > for instance.) > > Derek > > -----Original Message----- >>From: rssh at gradsoft.com.ua >>Sent: Mar 31, 2009 10:02 AM >>To: Gabriel Belingueres >>Cc: coin-dev >>Subject: Re: PROPOSAL: @OverrideAll annotation >> >>> Hi, >>> >>> I've written a new feature that might be comfortable to use for >>> someone. All input is welcomed. >>> >> >>It-is possible to do near same with annotation API (create a superclass >> which will override all) >> >>But -- sometime we really need to say, that all methods 'mus be' >>overriden. (For example - when implementing Proxy pattern). >>In such case class-level annotation '@OverrideAll' which tell compiler >>to check, that all methods must be overriden -- brilliant idea. >> >> >> >> >> >>> Regards, >>> Gabriel >>> >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>> >>> AUTHOR(S): Gabriel Belingueres >>> >>> OVERVIEW >>> >>> Add an @OverrideAll annotation to allow a class to override all >>> inherited methods with a trivial implementation. The resulting class >>> then could be used as the basis for a Null Object pattern (or even a >>> basic Mock object.) >>> >>> >>> FEATURE SUMMARY: >>> >>> The proposed @OverrideAll annotation will allow the class to override >>> all methods (from its superclasses and implemented interfaces) with a >>> trivial body, but the defined class can choose to implement specific >>> methods, replacing those that would be produced automatically by the >>> annotation. >>> >>> >>> MAJOR ADVANTAGE: >>> >>> Less coding for implementing Null Objects, or simple tests. >>> >>> >>> MAJOR BENEFIT: >>> >>> Let the compiler implement all uninteresting, non relevant behavior by >>> automatically providing with a trivial implementation of the inherited >>> methods. >>> >>> >>> MAJOR DISADVANTAGE: >>> >>> Might be a cause of NullPointerException if not used judiciously. >>> >>> >>> ALTERNATIVES: >>> >>> Implement all uninteresting methods by yourself by providing yourself >>> a trivial implementation (though actually popular IDEs can do this >>> automatically for you already.) >>> >>> EXAMPLES >>> >>> Given: >>> >>> class B {} >>> >>> public class A implements I1, I2 { >>> >>> public static final int VAR = 1; >>> >>> private B b; >>> >>> public static Integer getSome() { >>> return VAR; >>> } >>> >>> public A() { >>> } >>> >>> public A(B b) { >>> this.b=b; >>> } >>> >>> public B getB() { >>> return b; >>> } >>> >>> public void setB(B b) { >>> this.b=b; >>> } >>> >>> protected void doProtected() { ... } >>> >>> private void doPrivate() { ... } >>> >>> A someNewA() { ... } >>> >>> public synchronized void someSynchronized() { >>> } >>> >>> } >>> >>> then: >>> >>> @OverrideAll >>> public class NullA extends A { >>> } >>> >>> is equivalent to declare: >>> >>> public class NullA extends A { >>> >>> public NullA() {} >>> >>> public NullA(B b) { >>> super(b); >>> } >>> >>> public B getB() { >>> return null; >>> } >>> >>> public void setB(B b) { >>> } >>> >>> protected void doProtected() { >>> // empty >>> } >>> >>> A someNewA() { >>> return null; >>> } >>> >>> public synchronized void someSynchronized() { >>> // empty >>> } >>> >>> } >>> >>> You may not want the default trivial implementation in some methods, >>> then you override them as usual: >>> >>> @OverrideAll >>> public class NullA extends A { >>> >>> @Override >>> public B getB() { >>> return new B(); >>> } >>> >>> @Override >>> public synchronized void someSynchronized() { >>> System.out.println("overridden"); >>> } >>> >>> } >>> >>> EXAMPLE 2 >>> >>> Implement a trivial Collection interface just to test that adding >>> elements will increase the collection size: >>> >>> Currently: >>> >>> public class SomeCollection implements Collection { >>> >>> private int counter; >>> >>> @Override >>> public boolean add(E arg0) { >>> counter++; >>> return true; >>> } >>> >>> @Override >>> public boolean addAll(Collection c) { >>> counter += c.size(); >>> return true; >>> } >>> >>> @Override >>> public void clear() { >>> } >>> >>> @Override >>> public boolean contains(Object arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean containsAll(Collection arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean isEmpty() { >>> return false; >>> } >>> >>> @Override >>> public Iterator iterator() { >>> return null; >>> } >>> >>> @Override >>> public boolean remove(Object arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean removeAll(Collection arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean retainAll(Collection arg0) { >>> return false; >>> } >>> >>> @Override >>> public int size() { >>> return counter; >>> } >>> >>> @Override >>> public Object[] toArray() { >>> return null; >>> } >>> >>> @Override >>> public T[] toArray(T[] arg0) { >>> return null; >>> } >>> >>> } >>> >>> With the annotation: >>> >>> @OverrideAll >>> public class SomeCollection implements Collection { >>> >>> private int counter; >>> >>> @Override >>> public boolean add(E arg0) { >>> counter++; >>> return true; >>> } >>> >>> @Override >>> public boolean addAll(Collection c) { >>> counter += c.size(); >>> return true; >>> } >>> >>> >>> @Override >>> public int size() { >>> return counter; >>> } >>> >>> } >>> >>> >>> DETAILS >>> >>> >>> SPECIFICATION: >>> >>> A preliminary specification follows: >>> >>> As this feature is proposed as an annotation for code generation, no >>> changes to the current JLSv3 are needed. >>> >>> The annotation will generate "trivial" overridden implementations for >>> all methods not specified in the class, for each superclass in the >>> hierarchy (except Object) and implemented interface. >>> >>> - Static methods, private methods, final methods, constructors and >>> methods from class Object should never be generated. >>> - If some superclass (except Object) has already overridden some >>> Object class methods, then do NOT generate an empty overridden method >>> (to reuse current behavior.) (for example, if some superclass already >>> override toString(), equals() or hashCode().) >>> >>> - OPTIONAL: add a parameter to the @OverrideAll annotation to indicate >>> if @Deprecated methods should not be implemented. >>> >>> Trivial implementation for generated methods: >>> >>> - Methods returning void will have an empty body. (OPTIONAL: add a >>> parameter to the @OverrideAll annotation to indicate that it should >>> throw UnsupportedOperationException instead) >>> - Methods returning a primitive type will have a body returning the >>> same default value that would have for uninitialized instance >>> variables. (JLS section 4.12.5.) >>> - Methods returning a reference type will "return null;". (JLS section >>> 4.12.5.) >>> - The method will never return a covariant return type (because in >>> case of implementing a Null object, it should be undistinguished from >>> the common case) >>> - Methods that throws checked exceptions can be modified to delete the >>> throws clause. (ie. the trivial implementation should not throw >>> checked exceptions) >>> - Synchronized methods should retain that attribute. >>> >>> >>> COMPILATION: >>> >>> Compilation should proceed as usual, except that the annotation >>> processor would generate the code when it encounters an annotated >>> class. >>> >>> No changes to the class file format are needed. >>> >>> >>> TESTING >>> >>> Test cases should be done, including testing with classes implementing >>> several interfaces, classes with generics, inner classes, etc. >>> >>> >>> LIBRARY SUPPORT: >>> >>> No, except creating the new annotation. >>> >>> >>> REFLECTIVE APIS: >>> >>> No changes foreseen. >>> >>> >>> OTHER CHANGES: >>> >>> Output of javadoc tool. >>> >>> >>> MIGRATION: >>> >>> Just add the annotation to class level, and erase your trivially >>> implemented overridden methods. >>> >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: >>> All existing programs remain valid. >>> >>> EXISTING PROGRAMS: >>> The semantics of existing class files and legal source files are >>> unchanged by this feature. >>> >>> >>> REFERENCES >>> >>> EXISTING BUGS: >>> >>> None that I know about. >>> >>> URL FOR PROTOTYPE: >>> >>> None at this time. >>> >>> >> >> >> > > From Joe.Darcy at Sun.COM Fri Apr 3 01:25:07 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 03 Apr 2009 01:25:07 -0700 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <6F835C91-A2F2-4050-BD03-DB1B462C2B4F@sun.com> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> <6F835C91-A2F2-4050-BD03-DB1B462C2B4F@sun.com> Message-ID: <49D5C7E3.50801@sun.com> Hello. Some comments interspersed. John Rose wrote: > Here is a text form of the proposal, for the archives. The wiki form > should be equivalent at the moment, but as edits are made the wiki > form will be normative. > > Best wishes, > -- John > > AUTHOR(S): > > John Rose > > OVERVIEW > > Create source-code syntaxes for using new JVM features from JSR 292. > These are invokedynamic instructions, method handle invocation, > certain relaxed conversions, and exotic identifiers. [snip] > 1.3 Any call to a method in Dynamic accepts an optional type parameter > which specifies the return type of the call site's descriptor. The > type parameter may any type whatever, including void or a primitive > type. If it is omitted it defaults to the type java.dyn.Dynamic > itself. (See part 4 for conversion rules involving Dynamic.) > Reiterating a point Neal raised, if Dynamic is not related to Object, what does that mean when Dynamic is used as the format type argument to a type parameter? What do "? extends Dynamic" and "? super Dynamic" mean to the type system? > Dynamic x = Dynamic.myGetCurrentThing(); // type () -> Dynamic > Dynamic.myPutCurrentThing(x); // type (Dynamic) -> void > int y = Dynamic.myHashCode((Object)x); // type (Object) -> > int > boolean z = Dynamic.myEquals(x, y); // type (Dynamic, > int) -> boolean > > (Rationale: Although it is strange for non-references to appear in the > syntactic position of type arguments, this design is far simpler than > inventing a completely new syntax for specifying the return type of > the call site, as some early prototypes did.) > > 1.4 For the purposes of determining the descriptor of the > invokedynamic instruction, null arguments (unless casted to some other > type) are deemed to be of reference type java.lang.Void. This is a > pragmatic choice, compatible with the verifier and partially coherent > with the meaning of the type Void, since it happens to allow only null > reference values. Conversely, void method return values are reflected > as null values. The type Void will appear only to the bootstrap > method, and will serve notice that the call site contains a null, > rather than an explicitly typed reference. > > Dynamic.myPrintLine(null); // type (Void) -> Dynamic > Dynamic.foo((String)null, null); // type (String, Void) -> > void > > 1.5 No checked exceptions are produced by any call to Dynamic. > > try { Dynamic.foo(); } catch (Exception ee) { } // a compile- > time error > Actually there is a special rule that catching Exception is always okay per JLS 11.2.3; this program is legal and compiles fine: public class Test { public static void main(String... args){ try { ; } catch (Exception e) { ; } } } [snip] > 2.2 Any reference of type MethodHandle may be qualified with the > method name "invoke" and invoked on any number and type of arguments. > Only the method named "invoke" is treated this new way. All other > expressions involving MethodHandle are unchanged in meaning, including > selection of members other than "invoke", casting, and instanceof. > > MethodHandle mh = ...; > mh.invoke("foo", 42); // argument types (String, int) > MethodType mtype = mh.type(); // no new rules here; see JSR 292 > javadocs > mh.neverBeforeSeenName(); // no new rules; must raise an error > > In effect, java.dyn.MethodHandle appears to have an infinite number of > non-static methods named "invoke", of every possible signature. > > (In fact, JSR 292 specifies that each individual method handle has a > unique type signature, and may be invoked only under that specific > type. This type is checked on every method handle call. JSR 292 > guarantees runtime type safety by requiring that an exception be > thrown if a method handle caller and callee do not agree exactly on > the argument and return types. The details of this check are not part > of this specification, but rather of the MethodHandle API.) > So what are the notions of identity and equality for method handles? [snip] > 4.1 As specified above, the interface java.dyn.Dynamic has no > supertypes or members. As such, it is a bare reference type. (As an > arbitrary relation, the superclass of Dynamic[] is Object[].) We > Are there any other type building operations besides arrays we need to worry about? [snip] > 4.6 The expression syntaxes with predefined meaning for dynamic sub- > expressions are those which perform the conversions described above. > These are assignment "=" and casts. Dynamic expressions may also be > tested with instanceof. Also, Dynamic values may be declared, > assigned to variables, passed as method or constructor arguments, and > returned from methods. > > But, the Java operators "==" "!=" "+" "+=" on reference types are > clarified to apply only to reference types which are java.lang.Object > or one of its subtypes; they do not have a predefined meaning if > either operand is dynamic. The "synchronized" and "throw" statements > cannot be applied to dynamic expressions. > So if there is no predefined meaning, are those operations illegal? [snip] > REFLECTIVE APIS: > > The method java.lang.Class.getDeclaredMethod must be special-cased to > always succeed for MethodHandle.invoke and for Dynamic (any method > name), regardless of signature. The JSR 292 JVM has this logic > already, but it must be exposed out through the Class API. > > Only single-result reflection lookups need to be changed. Multiple- > method lookups should *not* produce implicitly defined methods. > > The javax.lang.model API (which is used internally by javac) does not > need specialization, because the implicitly defined methods of > MethodHandle and Dynamic do not ever need to mix with other more > normal methods. The static (compile-time) model of Dynamic may not > present any enclosed elemeents, while that of MethodHandle must not > present any methods named "invoke". > > Facilities which compute type relations (such as > javax.lang.model.util.Types) may need to be updated to take Dynamic > into account. Generally speaking, the new Dynamic conversions operate > in parallel to the implicit boxing conversions. That is, they add no > new subtype or supertype relations, but they provide a few more ways > for values to be implicitly converted or casted. > Yes, I would expect a few changes to the type-related APIs. They may also need to be changes to programs that assume Object is the root of the reference type hierarchy. I know I've written annotation processing code like that and Dynamic would need to be special cased in there. -Joe From vapor1 at teleport.com Fri Apr 3 01:26:41 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 04:26:41 -0400 (EDT) Subject: PROPOSAL: 'final' without explicit type (update) Message-ID: <31420118.1238747201155.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 31, 2009 11:28 AM >To: Tim Lebedkov >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: 'final' without explicit type (update) > >Tim: > >This isn't the first time I've read about inferring types, and this >isn't the first time I've seen 'final' used for it. > >It's -not- just to avoid a new keyword. It's quite specifically >because auto-typing should only be done for final variables. The >problem is this: > ... This message had a good explanation of why final is preferred, and an explanation of why not using an interface type is probably OK in this limited circumstance. Probably the best explanations of these issues I've seen. (I've just snipped it away. Read the Reiner's original post for the original description.) >FWIW, I'm -strongly- in favour of implicit typing for final local >method variables, and opposed to extending this for non-finals, not >just because its hard to come up with a syntax for it, due to there >being no readily available keywords or operators to do it with. := >comes to mind, but that's about it. I agree with this, on both points. (I'm perhaps not as "strongly" in favor as Reiner, but I do think that having implicit typing for local variables would be a net positive in readability, despite the lack of an explicit type in the code. I think that implicit typing would probably be a mistake for fields, however, even if they're final. (They're accessed in too many places.) With code that uses generics a lot, the overhead of having to mention long type names multiple times starts to become large. Improved type inference would help a lot. Derek From vapor1 at teleport.com Fri Apr 3 02:13:23 2009 From: vapor1 at teleport.com (Derek Foster) Date: Fri, 3 Apr 2009 05:13:23 -0400 (EDT) Subject: PROPOSAL: Binary Literals Message-ID: <31379447.1238750003379.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> -----Original Message----- >From: Mark Thornton >Sent: Mar 26, 2009 4:54 AM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Binary Literals > >Derek Foster wrote: >> You are not considering the impact of constant folding on compiler optimizations. >> >> Not all constants are created equal. Constants whose values can be determined at compile time can be inlined by the compiler, and arithmetic expressions involving them can often therefore be simplified at compile time. This process is known as "constant folding". The resulting code need not reference the original variable to get the constant at all -- it can just use the inlined result of evaluating the expression. Additional compiler optimizations may then be performed on the basis of these folded constants. For instance, a compiler might decide to compile this code: >> >Perhaps you missed my suggestion that the range of operations permitted >in constant expressions be extended to include the bit munging >operations (and possibly others). We could perhaps have an annotation >that was only permitted on static methods in the java.* name space and >which required the compiler to execute the method at compile time if its >arguments were compile time constants. The compiler could alternatively >have a private list of such methods, the annotation conveniently tells >everyone else what is on the list. I did miss that suggestion, actually. Though now that you've mentioned it: It's not that I would mind that feature in the compiler ("that feature" being compile-time evaluation of common library methods which are passed parameters known at compile time). However, it doesn't sound terribly easy to implement. Especially when you consider the implications of having to do error handling on illegal function arguments at compile time, rather than at runtime. In fact, it sounds a whole lot more intrusive and a lot more work for the compiler team than just being able to parse a simple binary number. Besides that issue, however, and besides the also (substantial!) issue of the readability of (0b11010100 & 0b01001011) ^ (0b01101010 | 0b10010100) vs. (Byte.parseByte("0b11010100",2) & Byte.parseByte("0b01001011",2) ^ (Byte.parseByte("0b01101010",2) | Byte.parseByte("0b10010100",2)) there is also the fact that some Java platforms simply don't HAVE a Byte class. For instance, consider JavaCard: http://java.sun.com/javacard/ A JavaCard, if you weren't aware, is a literally credit-card-sized computer running a very stripped-down JVM that is just capable enough that it can do encryption calculations in order to ensure, for instance, that the card is connecting to an authorized and properly authenticated bank machine. There's no room in a machine that small for the vast majority of standard library classes, most of which would be useless anyway in a computer of those capabilities. For instance, there is no support for java.lang.String, java.lang.Integer, and so forth (since this computer has no need to process Strings, and only needs integers for the purpose of number-crunching math, not nullness checks). Programmers for JavaCard could easily use binary numbers in their encryption algorithms. That's a use case that is easily handled by my proposal. However, importing a library that depends on Byte.parseInt(java.lang.String, int) isn't going to be sufficient for them, because they have neither Byte nor String. When I worked on the massively parallel processor chip I described earlier, our Java didn't have Byte or String classes either. Even if it had had something like String, nobody probably would have used it. Text processing is just not the kind of thing you use a massively parallel number crunching chip to do. Also, when each processor on the chip has around 8Kbytes of ROM to store program code, you don't want to be wasting it on library routines, or calls to them, that you don't really need. Derek >Mark Thornton > From mthornton at optrak.co.uk Fri Apr 3 02:59:52 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Fri, 03 Apr 2009 10:59:52 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: <31379447.1238750003379.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> References: <31379447.1238750003379.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Message-ID: <49D5DE18.3000606@optrak.co.uk> Derek Foster wrote: > > I did miss that suggestion, actually. Though now that you've mentioned it: > > It's not that I would mind that feature in the compiler ("that feature" > being compile-time evaluation of common library > methods which are passed parameters known at compile time). However, > it doesn't sound terribly easy to implement. Especially when you consider > the implications of having to do error handling on illegal function > arguments at compile time, rather than at runtime. In fact, it sounds > a whole lot more intrusive and a lot more work for the compiler team > than just being able to parse a simple binary number. > They already have to handle the exception resulting from integer division by zero, so I don't think this makes much difference to compile time expression evaluation. This is especially true if only methods in the java namespace were permitted (and these could be restricted to 'easy' methods). > there is also the fact that some Java platforms simply don't HAVE a Byte > class. For instance, consider JavaCard: > > http://java.sun.com/javacard/ > > A JavaCard, if you weren't aware, is a literally credit-card-sized computer > I was aware it existed but my Java experience hasn't gone any lower than JavaME. However when expressions are evaluated at compile time the resulting byte code contains no reference to the source of the computation -- only the result appears. Thus the fact that Byte isn't available in the target platform wouldn't matter. For example: class A { public static final String STREET="Mead Lane"; } class B { public static final String TOWN = "Hertford"; } class MyApp { public static final String ADDRESS = A.STREET + "," + B.TOWN; } The byte code for MyApp contains ADDRESS = "Mead Lane, Hertford" and no reference to classes A, or B. I don't like this behaviour, but it is what currently happens. I think it was intended to assist with implementation on restricted environments. Regards, Mark Thornton From reinier at zwitserloot.com Fri Apr 3 03:14:57 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 3 Apr 2009 12:14:57 +0200 Subject: Naked dot - accessing object fields through unqualified In-Reply-To: <19432589.1238742258930.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> References: <19432589.1238742258930.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Message-ID: <763DE2D4-9ADE-40FF-A37A-D8963DCA2CD5@zwitserloot.com> You can think what you want, but that's not likely. Again, a source keyword would open up an opportunity to engage a bunch of strict checks, but you underestimate the amount of code that people have inherited from people that inherited it from people that inherited it, and each added their own little mess to the spaghetti. Them, and a bunch of contractors in between. It was thoroughly tested somewhere in 1999, and nobody even knows how it works, but every so often someone does need to wade into the mess and fix something. You can not force these people to deal with a gazillion 'these are likely bugs' errors. It needs to be opt-in. Your further suggestions are even further off the mark; why is an abstract class with a private constructor bad? It's a matter of style; most people who want utility classes make their constructors final, but some make their class abstract as well, because of the link between 'abstract' classes (cannot be instantiated) and utility classes (should not be instantiated). I believe a programming language should set style as much as possible, but java doesn't do that now, and changing it is a massive turn-around in java dogma that you or I just cannot take. C style array declarations - okay, fine. Yes. Guuuuhhhh, they are making working with the [ and ] symbols in a way that doesn't screw up the parser annoying, to say the least. Yet another argument for a 'source' keyword. If people don't want to listen to or setup their warnings, then more errors is just not going to help. Your suggestion is: Some companies are so boneheaded they won't listen to their IDE's warnings, so we'll just force it on them with a javac change? Nononono. That'll just result in them not updating their java, and that's one of those things sun (rightfully) wants to avoid like the plague without a solid reason to do it (like wiping the slate clean across the board, not just in this niche area). At any rate, there's no way to centralize errors/warnings in javac. Period. They are far too contentious. As I have said before, APT is a good start, but some more support for external warning/error plugins would help (including the ability to add more SuppressWarnings keywords). It would be nice if javac shipped out of the box with an extensive set, sure, but, again, opt-in. --Reinier Zwitserloot On Apr 3, 2009, at 09:04, Derek Foster wrote: > Replies inline. > > -----Original Message----- >> From: Reinier Zwitserloot >> Sent: Mar 31, 2009 9:03 AM >> To: Derek Foster >> Cc: coin-dev at openjdk.java.net >> Subject: Re: Naked dot - accessing object fields through >> unqualified "." [C1] >> >> 'Self-assignment is forbidden' would not be backwards compatibile. >> Yes, such code would most likely be a bug, but its still an issue. It >> would have to be a warning, at best. > > Personally, I think it should be an error, since there seems to be > no valid reason to do it, and it almost certainly indicates a bug. I > think that compilers should default to being in a 'strict' mode > where things like this that have been found to be bad ideas with > virtually no upside are treated as illegal, even if that makes them > not fully backwards compatible. For backwards compatibility, there > could be a command-line switch to turn off strict mode if necessary > for compiling old code. > > Some other things I'd like to see in this category: > > * Having an abstract class with a constructor that has 'public' or > 'private' access. > > * Using C-style array declarations. (int x[] instead of int[] x) > > I could probably think of a few more. > >> However: >> >> Every single external java compiler I know of will warn you when you >> self-assign. Eclipse does it. So does netbeans. So does IDEA. So does >> pmd. So does findbugs. > > Mere warnings are not enough to stop people from doing this sort of > thing, especially when the warning message is buried in 436 other > warning messages about code which is less unambiguously broken than > this is. (Note: I *HATE* it when people ignore compiler warnings > like this, but I am speaking from experience when I say that it > usually takes years to convince a company to clean up its act.) > Unfortunately, I have worked for lots of companies that routinely > ignore warnings. > >> If you internalize the self-assignment warning, where do you stop? >> There are literally hundreds of 'duh, that must be a bug' warnings >> you >> could generate. Not all of them are as obvious, or as non- >> contentious, >> as 'self assignment'. So, where do you stop? Do we use the glacial >> nature of the language changes process to set this up? > > I think that when a practice is almost always problematic, is easy > to fix, and has no legitimate purpose (and/or has an easy workaround > in the few cases that it is legitimate), it should be made an error > (with the caveats above). I don't think that we should carry along > every single design mistake in the 1.0 edition of the Java Language > Standard with us until the end of time. The ability to achieve > backwards compatibility is important (hence the ability to turn off > strict mode I described above), but clarity of language design and > preventing common errors is too. Otherwise, the amount of code which > contains the error in question just keeps growing over time. > >> I say: No. The >> community has done a fine job of addressing these issues by creating >> code checkers. > > In my experience, the community, by and large, does not use code > checkers. Relatively few companies do. Again, I wish it were > otherwise, but the truth is that most companies assume that if > something passes the checks done by the compiler, it's probably > fine. Having tried to introduce them into companies a few times, I > can report that most software engineers really don't want to be > bothered with them (and are convinced that checkers won't find any > bugs important enough to justify the time spent learning to use them > and cleaning up lots of innocuous warnings just for the sake of the > tool). Again, I thoroughly disagree with that philosophy, but that's > what I have heard repeatedly in industry. > > Also, using a code checker is often a painful experience if you are > forced to use a framework written by people who don't use them. > > The other issue is that every code checker checks for a different > set of things. Just because your code passes your code checker's > rules doesn't mean it will pass mine, or vice versa. The Sun Java > compiler as of a specific version, at least, is the same for > everybody. > >> So, I'd instead suggest: >> Any improvements to java core in this area should focus on improving >> the ability for external tools to integrate better. For example, a >> way >> to extend @SuppressWarnings with additional keywords would be >> great. A >> way to let javac auto-find (via the SPI system) 'warning/error' >> plugins would be another fine idea. Having any kind of plugin system >> for the official javac to give other tools a go at creating warnings >> and errors on the AST that javac's parser is building would be good >> already, using SPI to find these automatically is just one way of >> doing it. I'm not sure APT is quite right for the job; I don't want >> to >> litter annotations to the gist of '@ExtensivelyCheckMe' all over the >> place. > > I'm certainly in favor of making life easier for code checkers. > However, checkers that don't get used are no better than ones that > don't exist. Javac (or jikes, etc.) gets used every time someone > compiles a program. That means it's going to have far more influence > on the correctness of the majority of Java code than any other tool. > > Derek > >> >> >> --Reinier Zwitserloot >> >> >> >> On Mar 29, 2009, at 04:42, Derek Foster wrote: >> >>> The major problem I have with this proposal is that it does not >>> address the point of why I use a prefix on field names. As such, I >>> would still continue to use a prefix even if this proposal were >>> implemented. >>> >>> In short, I use a prefix to avoid typographical mistakes, like this >>> one: >>> >>> void setFoo(Thing foob) { // Typo! >>> this.foo = foo; >>> } >>> >>> This will compile, and no warnings are produced, but it ends up >>> assigning foo to itself, which is not what was intended. >>> >>> Your proposal has exactly the same problem: >>> >>> void setFoo(Thing foob) { // Typo! >>> .foo = foo; >>> } >>> >>> It therefore does not substitute for a field prefix, which WILL fix >>> the problem: >>> >>> void setFoo(Thing foob) { // Typo! >>> _foo = foo; // ERROR! Undefined variable 'foo'. >>> } >>> >>> So unless you had some way to make use of the dot prefix mandatory >>> and the only legal way to access fields (which I would like, but >>> which would be an extremely backwards-incompatible change that will >>> never happen in Java), I don't see that adding an optional dot >>> prefix helps the situation except to reduce typing in constructor >>> and setter methods slightly. >>> >>> (Note: I would love a "self-assignment is forbidden" change to Java. >>> If I have time after my other proposals, I might write one up. >>> (Anyone else want to volunteer? This one is easy!) I might be >>> willing to forego prefixes and use the "this.foo = foo" approach, or >>> even the ".foo = foo" approach, if I was sure it wouldn't cause me >>> to fall into the self-assignment trap.) >>> >>> Derek >>> >>> >> > From Thomas.Hawtin at Sun.COM Fri Apr 3 03:24:24 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Fri, 03 Apr 2009 11:24:24 +0100 Subject: Proposal: Sameness operators In-Reply-To: <49D5B109.2020007@sun.com> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D3B1E3.8070109@sun.com> <88885FEA-F3CF-4D47-8379-7571E9E31F76@zwitserloot.com> <4b4f45e00904020524p27741baeo40483e83d71dc768@mail.gmail.com> <275433EA-A420-42C8-891D-3B0C2629222A@zwitserloot.com> <49D54420.5090906@sun.com> <49D5B109.2020007@sun.com> Message-ID: <49D5E3D8.8020901@sun.com> Joseph D. Darcy wrote: > Yes, I meant to type "java.util.Objects" -- having a class other than > java.lang.Object named "Object" is just wrong! But having an interface named "Object" is just CORBA! Tom From reinier at zwitserloot.com Fri Apr 3 03:27:40 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 3 Apr 2009 12:27:40 +0200 Subject: PROPOSAL: @OverrideAll annotation In-Reply-To: <17542308.1238746196681.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> References: <17542308.1238746196681.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Message-ID: <61773C12-3611-452A-B0A1-8B873F0E47E1@zwitserloot.com> What Derek said - this is not a good idea. rssh: The proposal specifically states that each non-overridden method is to be generated with an empty body, or if that isn't possible due to a return type, the default return for that type (0/false/0.0/'\0'/ null). --Reinier Zwitserloot On Apr 3, 2009, at 10:09, Derek Foster wrote: > My major problem with this proposal is that it doesn't seem to be > straightforward to generate the bodies of methods that have to > return something. Particularly for code such as implementations of > the Visitor pattern. > > Having un-overridden methods simply return null or zero is often not > the right thing to do. > > It's OK for generating methods that just take parameters, I suppose. > > Still, having annotations generate code or otherwise affect the > operation of a program is apparently a no-no per Sun's rules. If > something like this is going to happen, I think it needs a new > keyword or something rather than using an annotation. > > (Although, personally, I don't think it would be such a bad thing if > code generation via annotation existed, but were limited only to > certain annotations in a specific package duly designated by the > language implementors. Annotations have one nice quality that other > ways of extending the language don't: You can create new "keywords" > at will with no risk of breaking someone's perfectly-working code. > If they don't import the annotation, they won't need to be impacted > by it. I sort of wish there was an alternative to annotations (@@Foo > instead of @Foo?) which was explicitly for the purpose of telling > the compiler to generate boilerplate code of various types. > Decorators in Python sort of serve this purpose, for instance.) > > Derek > > -----Original Message----- >> From: rssh at gradsoft.com.ua >> Sent: Mar 31, 2009 10:02 AM >> To: Gabriel Belingueres >> Cc: coin-dev >> Subject: Re: PROPOSAL: @OverrideAll annotation >> >>> Hi, >>> >>> I've written a new feature that might be comfortable to use for >>> someone. All input is welcomed. >>> >> >> It-is possible to do near same with annotation API (create a >> superclass >> which will override all) >> >> But -- sometime we really need to say, that all methods 'mus be' >> overriden. (For example - when implementing Proxy pattern). >> In such case class-level annotation '@OverrideAll' which tell >> compiler >> to check, that all methods must be overriden -- brilliant idea. >> >> >> >> >> >>> Regards, >>> Gabriel >>> >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>> >>> AUTHOR(S): Gabriel Belingueres >>> >>> OVERVIEW >>> >>> Add an @OverrideAll annotation to allow a class to override all >>> inherited methods with a trivial implementation. The resulting class >>> then could be used as the basis for a Null Object pattern (or even a >>> basic Mock object.) >>> >>> >>> FEATURE SUMMARY: >>> >>> The proposed @OverrideAll annotation will allow the class to >>> override >>> all methods (from its superclasses and implemented interfaces) >>> with a >>> trivial body, but the defined class can choose to implement specific >>> methods, replacing those that would be produced automatically by the >>> annotation. >>> >>> >>> MAJOR ADVANTAGE: >>> >>> Less coding for implementing Null Objects, or simple tests. >>> >>> >>> MAJOR BENEFIT: >>> >>> Let the compiler implement all uninteresting, non relevant >>> behavior by >>> automatically providing with a trivial implementation of the >>> inherited >>> methods. >>> >>> >>> MAJOR DISADVANTAGE: >>> >>> Might be a cause of NullPointerException if not used judiciously. >>> >>> >>> ALTERNATIVES: >>> >>> Implement all uninteresting methods by yourself by providing >>> yourself >>> a trivial implementation (though actually popular IDEs can do this >>> automatically for you already.) >>> >>> EXAMPLES >>> >>> Given: >>> >>> class B {} >>> >>> public class A implements I1, I2 { >>> >>> public static final int VAR = 1; >>> >>> private B b; >>> >>> public static Integer getSome() { >>> return VAR; >>> } >>> >>> public A() { >>> } >>> >>> public A(B b) { >>> this.b=b; >>> } >>> >>> public B getB() { >>> return b; >>> } >>> >>> public void setB(B b) { >>> this.b=b; >>> } >>> >>> protected void doProtected() { ... } >>> >>> private void doPrivate() { ... } >>> >>> A someNewA() { ... } >>> >>> public synchronized void someSynchronized() { >>> } >>> >>> } >>> >>> then: >>> >>> @OverrideAll >>> public class NullA extends A { >>> } >>> >>> is equivalent to declare: >>> >>> public class NullA extends A { >>> >>> public NullA() {} >>> >>> public NullA(B b) { >>> super(b); >>> } >>> >>> public B getB() { >>> return null; >>> } >>> >>> public void setB(B b) { >>> } >>> >>> protected void doProtected() { >>> // empty >>> } >>> >>> A someNewA() { >>> return null; >>> } >>> >>> public synchronized void someSynchronized() { >>> // empty >>> } >>> >>> } >>> >>> You may not want the default trivial implementation in some methods, >>> then you override them as usual: >>> >>> @OverrideAll >>> public class NullA extends A { >>> >>> @Override >>> public B getB() { >>> return new B(); >>> } >>> >>> @Override >>> public synchronized void someSynchronized() { >>> System.out.println("overridden"); >>> } >>> >>> } >>> >>> EXAMPLE 2 >>> >>> Implement a trivial Collection interface just to test that adding >>> elements will increase the collection size: >>> >>> Currently: >>> >>> public class SomeCollection implements Collection { >>> >>> private int counter; >>> >>> @Override >>> public boolean add(E arg0) { >>> counter++; >>> return true; >>> } >>> >>> @Override >>> public boolean addAll(Collection c) { >>> counter += c.size(); >>> return true; >>> } >>> >>> @Override >>> public void clear() { >>> } >>> >>> @Override >>> public boolean contains(Object arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean containsAll(Collection arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean isEmpty() { >>> return false; >>> } >>> >>> @Override >>> public Iterator iterator() { >>> return null; >>> } >>> >>> @Override >>> public boolean remove(Object arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean removeAll(Collection arg0) { >>> return false; >>> } >>> >>> @Override >>> public boolean retainAll(Collection arg0) { >>> return false; >>> } >>> >>> @Override >>> public int size() { >>> return counter; >>> } >>> >>> @Override >>> public Object[] toArray() { >>> return null; >>> } >>> >>> @Override >>> public T[] toArray(T[] arg0) { >>> return null; >>> } >>> >>> } >>> >>> With the annotation: >>> >>> @OverrideAll >>> public class SomeCollection implements Collection { >>> >>> private int counter; >>> >>> @Override >>> public boolean add(E arg0) { >>> counter++; >>> return true; >>> } >>> >>> @Override >>> public boolean addAll(Collection c) { >>> counter += c.size(); >>> return true; >>> } >>> >>> >>> @Override >>> public int size() { >>> return counter; >>> } >>> >>> } >>> >>> >>> DETAILS >>> >>> >>> SPECIFICATION: >>> >>> A preliminary specification follows: >>> >>> As this feature is proposed as an annotation for code generation, no >>> changes to the current JLSv3 are needed. >>> >>> The annotation will generate "trivial" overridden implementations >>> for >>> all methods not specified in the class, for each superclass in the >>> hierarchy (except Object) and implemented interface. >>> >>> - Static methods, private methods, final methods, constructors and >>> methods from class Object should never be generated. >>> - If some superclass (except Object) has already overridden some >>> Object class methods, then do NOT generate an empty overridden >>> method >>> (to reuse current behavior.) (for example, if some superclass >>> already >>> override toString(), equals() or hashCode().) >>> >>> - OPTIONAL: add a parameter to the @OverrideAll annotation to >>> indicate >>> if @Deprecated methods should not be implemented. >>> >>> Trivial implementation for generated methods: >>> >>> - Methods returning void will have an empty body. (OPTIONAL: add a >>> parameter to the @OverrideAll annotation to indicate that it should >>> throw UnsupportedOperationException instead) >>> - Methods returning a primitive type will have a body returning the >>> same default value that would have for uninitialized instance >>> variables. (JLS section 4.12.5.) >>> - Methods returning a reference type will "return null;". (JLS >>> section >>> 4.12.5.) >>> - The method will never return a covariant return type (because in >>> case of implementing a Null object, it should be undistinguished >>> from >>> the common case) >>> - Methods that throws checked exceptions can be modified to delete >>> the >>> throws clause. (ie. the trivial implementation should not throw >>> checked exceptions) >>> - Synchronized methods should retain that attribute. >>> >>> >>> COMPILATION: >>> >>> Compilation should proceed as usual, except that the annotation >>> processor would generate the code when it encounters an annotated >>> class. >>> >>> No changes to the class file format are needed. >>> >>> >>> TESTING >>> >>> Test cases should be done, including testing with classes >>> implementing >>> several interfaces, classes with generics, inner classes, etc. >>> >>> >>> LIBRARY SUPPORT: >>> >>> No, except creating the new annotation. >>> >>> >>> REFLECTIVE APIS: >>> >>> No changes foreseen. >>> >>> >>> OTHER CHANGES: >>> >>> Output of javadoc tool. >>> >>> >>> MIGRATION: >>> >>> Just add the annotation to class level, and erase your trivially >>> implemented overridden methods. >>> >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: >>> All existing programs remain valid. >>> >>> EXISTING PROGRAMS: >>> The semantics of existing class files and legal source files are >>> unchanged by this feature. >>> >>> >>> REFERENCES >>> >>> EXISTING BUGS: >>> >>> None that I know about. >>> >>> URL FOR PROTOTYPE: >>> >>> None at this time. >>> >>> >> >> >> > > From reinier at zwitserloot.com Fri Apr 3 03:34:47 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 3 Apr 2009 12:34:47 +0200 Subject: PROPOSAL: Binary Literals In-Reply-To: <31379447.1238750003379.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> References: <31379447.1238750003379.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Message-ID: <483055E7-EAC0-4FF0-9B11-2F828F90B917@zwitserloot.com> public static byte b(String in) { return Byte.parseByte(in, 2); } then: (0b11010100 & 0b01001011) ^ (0b01101010 | 0b10010100) vs: import static ByteUtils.b; (b("11010100") & b("01001011")) ^ (b("01101010") | b("10010100")) I can live with that. --Reinier Zwitserloot On Apr 3, 2009, at 11:13, Derek Foster wrote: > > > -----Original Message----- >> From: Mark Thornton >> Sent: Mar 26, 2009 4:54 AM >> To: Derek Foster >> Cc: coin-dev at openjdk.java.net >> Subject: Re: PROPOSAL: Binary Literals >> >> Derek Foster wrote: >>> You are not considering the impact of constant folding on compiler >>> optimizations. >>> >>> Not all constants are created equal. Constants whose values can be >>> determined at compile time can be inlined by the compiler, and >>> arithmetic expressions involving them can often therefore be >>> simplified at compile time. This process is known as "constant >>> folding". The resulting code need not reference the original >>> variable to get the constant at all -- it can just use the inlined >>> result of evaluating the expression. Additional compiler >>> optimizations may then be performed on the basis of these folded >>> constants. For instance, a compiler might decide to compile this >>> code: >>> >> Perhaps you missed my suggestion that the range of operations >> permitted >> in constant expressions be extended to include the bit munging >> operations (and possibly others). We could perhaps have an annotation >> that was only permitted on static methods in the java.* name space >> and >> which required the compiler to execute the method at compile time >> if its >> arguments were compile time constants. The compiler could >> alternatively >> have a private list of such methods, the annotation conveniently >> tells >> everyone else what is on the list. > > > I did miss that suggestion, actually. Though now that you've > mentioned it: > > It's not that I would mind that feature in the compiler ("that > feature" > being compile-time evaluation of common library > methods which are passed parameters known at compile time). However, > it doesn't sound terribly easy to implement. Especially when you > consider > the implications of having to do error handling on illegal function > arguments at compile time, rather than at runtime. In fact, it sounds > a whole lot more intrusive and a lot more work for the compiler team > than just being able to parse a simple binary number. > > Besides that issue, however, and besides the also (substantial!) issue > of the readability of > > (0b11010100 & 0b01001011) ^ (0b01101010 | 0b10010100) > > vs. > > (Byte.parseByte("0b11010100",2) & Byte.parseByte("0b01001011",2) ^ > (Byte.parseByte("0b01101010",2) | Byte.parseByte("0b10010100",2)) > > there is also the fact that some Java platforms simply don't HAVE a > Byte > class. For instance, consider JavaCard: > > http://java.sun.com/javacard/ > > A JavaCard, if you weren't aware, is a literally credit-card-sized > computer > running a very stripped-down JVM that is just capable enough that it > can do encryption calculations in order to ensure, for instance, that > the card is connecting to an authorized and properly authenticated > bank > machine. There's no room in a machine that small for the vast majority > of standard library classes, most of which would be useless anyway in > a computer of those capabilities. For instance, there is no support > for java.lang.String, java.lang.Integer, and so forth (since this > computer has no need to process Strings, and only needs integers > for the purpose of number-crunching math, not nullness checks). > > Programmers for JavaCard could easily use binary numbers in their > encryption algorithms. That's a use case that is easily handled by > my proposal. However, importing a library that depends on > Byte.parseInt(java.lang.String, int) isn't going to be sufficient > for them, because they have neither Byte nor String. > > When I worked on the massively parallel processor chip I described > earlier, our Java didn't have Byte or String classes either. Even > if it had had something like String, nobody probably would have > used it. Text processing is just not the kind of thing you use a > massively parallel number crunching chip to do. Also, when each > processor on the chip has around 8Kbytes of ROM to store program code, > you don't want to be wasting it on library routines, or calls > to them, that you don't really need. > > Derek > > > > > > > > >> Mark Thornton >> > > From mthornton at optrak.co.uk Fri Apr 3 03:48:37 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Fri, 03 Apr 2009 11:48:37 +0100 Subject: Annotation processors Message-ID: <49D5E985.8010408@optrak.co.uk> These have come up several times on this list. I suspect many people have only a vague idea of what they can do. Is there any good documentation or introductory material available? Mark Thornton From pdoubleya at gmail.com Fri Apr 3 04:05:38 2009 From: pdoubleya at gmail.com (Patrick Wright) Date: Fri, 3 Apr 2009 13:05:38 +0200 Subject: Annotation processors In-Reply-To: <49D5E985.8010408@optrak.co.uk> References: <49D5E985.8010408@optrak.co.uk> Message-ID: <64efa1ba0904030405w4d68cec9xbee57f8a9969ec25@mail.gmail.com> Here are some links I found on searching for this yesterday http://today.java.net/pub/a/today/2008/04/10/source-code-analysis-using-java-6-compiler-apis.html http://blogs.sun.com/sundararajan/entry/javac_tree_api_-_check http://scg.unibe.ch/archive/projects/Erni08b.pdf http://java.sun.com/javase/6/docs/technotes/guides/javac/index.html http://smallwiki.unibe.ch/adriankuhn/javacompiler/ HTH Patrick From mthornton at optrak.co.uk Fri Apr 3 04:21:02 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Fri, 03 Apr 2009 12:21:02 +0100 Subject: Annotation processors In-Reply-To: <64efa1ba0904030405w4d68cec9xbee57f8a9969ec25@mail.gmail.com> References: <49D5E985.8010408@optrak.co.uk> <64efa1ba0904030405w4d68cec9xbee57f8a9969ec25@mail.gmail.com> Message-ID: <49D5F11E.9030806@optrak.co.uk> Thanks Patrick Wright wrote: > http://scg.unibe.ch/archive/projects/Erni08b.pdf > I like the section: "How to abuse JSR269 for AST rewriting". I wonder if I can use that to extend the compile time evaluation of constant expressions. Regards, Mark From belingueres at gmail.com Fri Apr 3 08:23:59 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Fri, 3 Apr 2009 12:23:59 -0300 Subject: PROPOSAL: @OverrideAll annotation In-Reply-To: <61773C12-3611-452A-B0A1-8B873F0E47E1@zwitserloot.com> References: <17542308.1238746196681.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> <61773C12-3611-452A-B0A1-8B873F0E47E1@zwitserloot.com> Message-ID: Hi, Thanks for taking the time for reading this. @Derek: My current approach for implementing this feature is to use the reflection API to get the Methods and generate from there the source file. (I'm not very experienced with the annotation API so this may not be the shortest path to do it, but for a first try I think it's OK.) However my mayor problem here is how to generate the concrete class, for example let's say we have: class A { public void method1() {}; public void method2() {}; } @OverrideAll class B extends A { public void method1() { ... } } the easiest way I'm thinking I can generate the code is to create a superclass class A_overrideAll which extends A with all methods overridden, and then make B extends A_overrideAll. However, AFAIK I can't modify the original source file (where class B is declared) so how can now make it a subclass of A_overrideAll? I choose an annotation instead of introducing a new keyword because it was less intrusive than the other, that is, with a new keyword I would need to modify the JLS, which is unnecessary because no language rule changes. If further analysis reveal that a new keyword would be better than an annotation, then it's fine with me. @rssh: no compile time error should be thrown, instead, at runtime the execution of a method should have a default behavior. In terms of the language, the most basic behavior is do nothing/return default values, but in general, the idea was to create a Null Object, meaning that the client code could call methods that do nothing instead of checking for != null. (Hopefully you could avoid some NPEs with this idiom.) Other idiom that apply for @OverrideAll are the AWT/Swing Listeners and Adapters. There are lots of XXXListener interfaces with an associated XXXAdapter abstract class that are used with a (sometimes anonymous) class just to listen to particular events offered in the listener interface. With the @OverrideAll annotation, you could avoid the declaration of the abstract adapter class. Regards, Gabriel 2009/4/3 Reinier Zwitserloot : > What Derek said - this is not a good idea. > > rssh: The proposal specifically states that each non-overridden method > is to be generated with an empty body, or if that isn't possible due > to a return type, the default return for that type (0/false/0.0/'\0'/ > null). > > > > ?--Reinier Zwitserloot > > > > On Apr 3, 2009, at 10:09, Derek Foster wrote: > >> My major problem with this proposal is that it doesn't seem to be >> straightforward to generate the bodies of methods that have to >> return something. Particularly for code such as implementations of >> the Visitor pattern. >> >> Having un-overridden methods simply return null or zero is often not >> the right thing to do. >> >> It's OK for generating methods that just take parameters, I suppose. >> >> Still, having annotations generate code or otherwise affect the >> operation of a program is apparently a no-no per Sun's rules. If >> something like this is going to happen, I think it needs a new >> keyword or something rather than using an annotation. >> >> (Although, personally, I don't think it would be such a bad thing if >> code generation via annotation existed, but were limited only to >> certain annotations in a specific package duly designated by the >> language implementors. Annotations have one nice quality that other >> ways of extending the language don't: You can create new "keywords" >> at will with no risk of breaking someone's perfectly-working code. >> If they don't import the annotation, they won't need to be impacted >> by it. I sort of wish there was an alternative to annotations (@@Foo >> instead of @Foo?) which was explicitly for the purpose of telling >> the compiler to generate boilerplate code of various types. >> Decorators in Python sort of serve this purpose, for instance.) >> >> Derek >> >> -----Original Message----- >>> From: rssh at gradsoft.com.ua >>> Sent: Mar 31, 2009 10:02 AM >>> To: Gabriel Belingueres >>> Cc: coin-dev >>> Subject: Re: PROPOSAL: @OverrideAll annotation >>> >>>> Hi, >>>> >>>> I've written a new feature that might be comfortable to use for >>>> someone. All input is welcomed. >>>> >>> >>> It-is possible to do near same with annotation API (create a >>> superclass >>> which will override all) >>> >>> But -- sometime we really need to say, that all methods 'mus be' >>> overriden. ?(For example - when implementing Proxy pattern). >>> In such case class-level annotation '@OverrideAll' ?which tell >>> compiler >>> to check, that all methods must be overriden -- brilliant idea. >>> >>> >>> >>> >>> >>>> Regards, >>>> Gabriel >>>> >>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>>> >>>> AUTHOR(S): Gabriel Belingueres >>>> >>>> OVERVIEW >>>> >>>> Add an @OverrideAll annotation to allow a class to override all >>>> inherited methods with a trivial implementation. The resulting class >>>> then could be used as the basis for a Null Object pattern (or even a >>>> basic Mock object.) >>>> >>>> >>>> FEATURE SUMMARY: >>>> >>>> The proposed @OverrideAll annotation will allow the class to >>>> override >>>> all methods (from its superclasses and implemented interfaces) >>>> with a >>>> trivial body, but the defined class can choose to implement specific >>>> methods, replacing those that would be produced automatically by the >>>> annotation. >>>> >>>> >>>> MAJOR ADVANTAGE: >>>> >>>> Less coding for implementing Null Objects, or simple tests. >>>> >>>> >>>> MAJOR BENEFIT: >>>> >>>> Let the compiler implement all uninteresting, non relevant >>>> behavior by >>>> automatically providing with a trivial implementation of the >>>> inherited >>>> methods. >>>> >>>> >>>> MAJOR DISADVANTAGE: >>>> >>>> Might be a cause of NullPointerException if not used judiciously. >>>> >>>> >>>> ALTERNATIVES: >>>> >>>> Implement all uninteresting methods by yourself by providing >>>> yourself >>>> a trivial implementation (though actually popular IDEs can do this >>>> automatically for you already.) >>>> >>>> EXAMPLES >>>> >>>> Given: >>>> >>>> class B {} >>>> >>>> public class A implements I1, I2 { >>>> >>>> ?public static final int VAR = 1; >>>> >>>> ?private B b; >>>> >>>> ?public static Integer getSome() { >>>> ? ?return VAR; >>>> ?} >>>> >>>> ?public A() { >>>> ?} >>>> >>>> ?public A(B b) { >>>> ? ?this.b=b; >>>> ?} >>>> >>>> ?public B getB() { >>>> ? ?return b; >>>> ?} >>>> >>>> ?public void setB(B b) { >>>> ? ?this.b=b; >>>> ?} >>>> >>>> ?protected void doProtected() { ... } >>>> >>>> ?private void doPrivate() { ... } >>>> >>>> ?A someNewA() { ... } >>>> >>>> ?public synchronized void someSynchronized() { >>>> ?} >>>> >>>> } >>>> >>>> then: >>>> >>>> @OverrideAll >>>> public class NullA extends A { >>>> } >>>> >>>> is equivalent to declare: >>>> >>>> public class NullA extends A { >>>> >>>> ?public NullA() {} >>>> >>>> ?public NullA(B b) { >>>> ? ?super(b); >>>> ?} >>>> >>>> ?public B getB() { >>>> ? ?return null; >>>> ?} >>>> >>>> ?public void setB(B b) { >>>> ?} >>>> >>>> ?protected void doProtected() { >>>> ? // empty >>>> ?} >>>> >>>> ?A someNewA() { >>>> ? return null; >>>> ?} >>>> >>>> ?public synchronized void someSynchronized() { >>>> ? ?// empty >>>> ?} >>>> >>>> } >>>> >>>> You may not want the default trivial implementation in some methods, >>>> then you override them as usual: >>>> >>>> @OverrideAll >>>> public class NullA extends A { >>>> >>>> ?@Override >>>> ?public B getB() { >>>> ? ?return new B(); >>>> ?} >>>> >>>> ?@Override >>>> ?public synchronized void someSynchronized() { >>>> ? ?System.out.println("overridden"); >>>> ?} >>>> >>>> } >>>> >>>> EXAMPLE 2 >>>> >>>> Implement a trivial Collection interface just to test that adding >>>> elements will increase the collection size: >>>> >>>> Currently: >>>> >>>> public class SomeCollection implements Collection { >>>> >>>> ?private int counter; >>>> >>>> ?@Override >>>> ?public boolean add(E arg0) { >>>> ? ?counter++; >>>> ? ?return true; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean addAll(Collection c) { >>>> ? ?counter += c.size(); >>>> ? ?return true; >>>> ?} >>>> >>>> ?@Override >>>> ?public void clear() { >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean contains(Object arg0) { >>>> ? ?return false; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean containsAll(Collection arg0) { >>>> ? ?return false; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean isEmpty() { >>>> ? ?return false; >>>> ?} >>>> >>>> ?@Override >>>> ?public Iterator iterator() { >>>> ? ?return null; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean remove(Object arg0) { >>>> ? ?return false; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean removeAll(Collection arg0) { >>>> ? ?return false; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean retainAll(Collection arg0) { >>>> ? ?return false; >>>> ?} >>>> >>>> ?@Override >>>> ?public int size() { >>>> ? ?return counter; >>>> ?} >>>> >>>> ?@Override >>>> ?public Object[] toArray() { >>>> ? ?return null; >>>> ?} >>>> >>>> ?@Override >>>> ?public T[] toArray(T[] arg0) { >>>> ? ?return null; >>>> ?} >>>> >>>> } >>>> >>>> With the annotation: >>>> >>>> @OverrideAll >>>> public class SomeCollection implements Collection { >>>> >>>> ?private int counter; >>>> >>>> ?@Override >>>> ?public boolean add(E arg0) { >>>> ? ?counter++; >>>> ? ?return true; >>>> ?} >>>> >>>> ?@Override >>>> ?public boolean addAll(Collection c) { >>>> ? ?counter += c.size(); >>>> ? ?return true; >>>> ?} >>>> >>>> >>>> ?@Override >>>> ?public int size() { >>>> ? ?return counter; >>>> ?} >>>> >>>> } >>>> >>>> >>>> DETAILS >>>> >>>> >>>> SPECIFICATION: >>>> >>>> A preliminary specification follows: >>>> >>>> As this feature is proposed as an annotation for code generation, no >>>> changes to the current JLSv3 are needed. >>>> >>>> The annotation will generate "trivial" overridden implementations >>>> for >>>> all methods not specified in the class, for each superclass in the >>>> hierarchy (except Object) and implemented interface. >>>> >>>> - Static methods, private methods, final methods, constructors and >>>> methods from class Object should never be generated. >>>> - If some superclass (except Object) has already overridden some >>>> Object class methods, then do NOT generate an empty overridden >>>> method >>>> (to reuse current behavior.) (for example, if some superclass >>>> already >>>> override toString(), equals() or hashCode().) >>>> >>>> - OPTIONAL: add a parameter to the @OverrideAll annotation to >>>> indicate >>>> if @Deprecated methods should not be implemented. >>>> >>>> Trivial implementation for generated methods: >>>> >>>> - Methods returning void will have an empty body. (OPTIONAL: add a >>>> parameter to the @OverrideAll annotation to indicate that it should >>>> throw UnsupportedOperationException instead) >>>> - Methods returning a primitive type will have a body returning the >>>> same default value that would have for uninitialized instance >>>> variables. (JLS section 4.12.5.) >>>> - Methods returning a reference type will "return null;". (JLS >>>> section >>>> 4.12.5.) >>>> - The method will never return a covariant return type (because in >>>> case of implementing a Null object, it should be undistinguished >>>> from >>>> the common case) >>>> - Methods that throws checked exceptions can be modified to delete >>>> the >>>> throws clause. (ie. the trivial implementation should not throw >>>> checked exceptions) >>>> - Synchronized methods should retain that attribute. >>>> >>>> >>>> COMPILATION: >>>> >>>> Compilation should proceed as usual, except that the annotation >>>> processor would generate the code when it encounters an annotated >>>> class. >>>> >>>> No changes to the class file format are needed. >>>> >>>> >>>> TESTING >>>> >>>> Test cases should be done, including testing with classes >>>> implementing >>>> several interfaces, classes with generics, inner classes, etc. >>>> >>>> >>>> LIBRARY SUPPORT: >>>> >>>> No, except creating the new annotation. >>>> >>>> >>>> REFLECTIVE APIS: >>>> >>>> No changes foreseen. >>>> >>>> >>>> OTHER CHANGES: >>>> >>>> Output of javadoc tool. >>>> >>>> >>>> MIGRATION: >>>> >>>> Just add the annotation to class level, and erase your trivially >>>> implemented overridden methods. >>>> >>>> >>>> COMPATIBILITY >>>> >>>> BREAKING CHANGES: >>>> All existing programs remain valid. >>>> >>>> EXISTING PROGRAMS: >>>> The semantics of existing class files and legal source files are >>>> unchanged by this feature. >>>> >>>> >>>> REFERENCES >>>> >>>> EXISTING BUGS: >>>> >>>> None that I know about. >>>> >>>> URL FOR PROTOTYPE: >>>> >>>> None at this time. >>>> >>>> >>> >>> >>> >> >> > > > From belingueres at gmail.com Fri Apr 3 08:58:18 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Fri, 3 Apr 2009 12:58:18 -0300 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: <31420118.1238747201155.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> References: <31420118.1238747201155.JavaMail.root@mswamui-thinleaf.atl.sa.earthlink.net> Message-ID: I agree that must be valid just for final, local variables. Regards, Gabriel 2009/4/3 Derek Foster : > > > -----Original Message----- >>From: Reinier Zwitserloot >>Sent: Mar 31, 2009 11:28 AM >>To: Tim Lebedkov >>Cc: coin-dev at openjdk.java.net >>Subject: Re: PROPOSAL: 'final' without explicit type (update) >> >>Tim: >> >>This isn't the first time I've read about inferring types, and this >>isn't the first time I've seen 'final' used for it. >> >>It's -not- just to avoid a new keyword. It's quite specifically >>because auto-typing should only be done for final variables. The >>problem is this: >> ... > > This message had a good explanation of why final is preferred, and an explanation of why not using an interface type is probably OK in this limited circumstance. Probably the best explanations of these issues I've seen. (I've just snipped it away. Read the Reiner's original post for the original description.) > >>FWIW, I'm -strongly- in favour of implicit typing for final local >>method variables, and opposed to extending this for non-finals, not >>just because its hard to come up with a syntax for it, due to there >>being no readily available keywords or operators to do it with. := >>comes to mind, but that's about it. > > I agree with this, on both points. (I'm perhaps not as "strongly" in favor as Reiner, but I do think that having implicit typing for local variables would be a net positive in readability, despite the lack of an explicit type in the code. I think that implicit typing would probably be a mistake for fields, however, even if they're final. (They're accessed in too many places.) With code that uses generics a lot, the overhead of having to mention long type names multiple times starts to become large. Improved type inference would help a lot. > > Derek > > > From Joe.Darcy at Sun.COM Fri Apr 3 10:07:37 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 03 Apr 2009 10:07:37 -0700 Subject: Annotation processors In-Reply-To: <49D5E985.8010408@optrak.co.uk> References: <49D5E985.8010408@optrak.co.uk> Message-ID: <49D64259.1020801@sun.com> Mark Thornton wrote: > These have come up several times on this list. I suspect many people > have only a vague idea of what they can do. Is there any good > documentation or introductory material available? > > Mark Thornton > > The annotation processing in javac provides immutable data structures modeling the types in question. However, much of the power of providing mutable source files can be had by either using an annotation processor to generate subclasses of a class or the *superclass* of a class. Those capabilities are mandated for JSR 269 annotation processing frameworks, as implemented in javac and Eclipse. For example, @MakeMeAPropertyInMySuperclass annotations could be used to automatically generate at build time the desired property structure that could be inherited. It is technically possible (a small matter of programming ;-) to run @MakeMeAPropertyInMySuperclass(name="foo",type=Type.class) class Foo extends ToBeGenerated {} into something like class ToBeGenerated { private Type foo; Type getFoo() { return foo; } Type setFoo(Type type) { this.type = type; return this.type; } } Bruce Chapman has written interesting annotation processors as part of his rapt and hickory projects: https://rapt.dev.java.net/ https://hickory.dev.java.net/ -Joe From howard.lovatt at iee.org Sat Apr 4 21:59:07 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 5 Apr 2009 14:59:07 +1000 Subject: Opportunity Cost and Proposal Selection Message-ID: <3dd3f56a0904042159r741706fdq9e081f4043850950@mail.gmail.com> Hi All, I would like to thanks Sun and particularly Joe for running this process, despite the fact that I think many of my favourites will not make 'the list' :( I think it is a very health process. -- Howard. From markmahieu at googlemail.com Sun Apr 5 04:40:55 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sun, 5 Apr 2009 12:40:55 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49C27E68.7020709@gmail.com> References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> Message-ID: <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> Hi Stephen, Revisiting an email from a couple of weeks ago... On 19 Mar 2009, at 17:18, Stephen Colebourne wrote: > Neal Gafter wrote: >> On Thu, Mar 19, 2009 at 1:26 AM, Jacek Kolodziejczyk >> wrote: >> >>> In my opinion the most obtrusive part in the current state of >>> proposals >>> is assumption that the invocation on null object should always >>> return null. >>> If I understand it correctly the following would break at runtime, >>> because null cannot be assigned to boolean: >>> >>> List list = null; >>> boolean b = list?.isEmpty(); >>> >> >> That would be a compile-time error because of the incompatibility >> between null and boolean. >> > The intention is that you can write a combination to handle this with > the submitted Coin proposal: > > List list = null; > boolean b = list?.isEmpty() ?: true; > > Stephen > I don't understand how that combination is supposed to work, given this part of the proposal: "A null-safe method invocation expression e1?.name(args) ... the type of the result is the same as the type of e1.name(args). It is an error if this is not a reference type." Doesn't that mean that the compiler should reject the expression 'list?.isEmpty()' ? Mark From neal at gafter.com Sun Apr 5 07:11:33 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 5 Apr 2009 07:11:33 -0700 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> Message-ID: <15e8b9d20904050711o124b388etca7847f8a456a45c@mail.gmail.com> On Sun, Apr 5, 2009 at 4:40 AM, Mark Mahieu wrote: >> List list = null; >> boolean b = list?.isEmpty() ?: true; >> >> Stephen >> > > I don't understand how that combination is supposed to work, given > this part of the proposal: > > "A null-safe method invocation expression e1?.name(args) ... the type > of the result is the same as the type of e1.name(args). ?It is an > error if this is not a reference type." > > Doesn't that mean that the compiler should reject the expression > 'list?.isEmpty()' ? Given the spec as written, yes. However, it could be changed so that the result is the same as the result of the rewriting in the "compilation" section of the spec. In that case its result would be Boolean. However, that is likely to result in more runtime null errors, not fewer, if people do things like if (list?.isEmpty()) ... -Neal From markmahieu at googlemail.com Sun Apr 5 10:19:52 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sun, 5 Apr 2009 18:19:52 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <15e8b9d20904050711o124b388etca7847f8a456a45c@mail.gmail.com> References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> <15e8b9d20904050711o124b388etca7847f8a456a45c@mail.gmail.com> Message-ID: 2009/4/5 Neal Gafter > On Sun, Apr 5, 2009 at 4:40 AM, Mark Mahieu > wrote: > > Doesn't that mean that the compiler should reject the expression > > 'list?.isEmpty()' ? > > Given the spec as written, yes. However, it could be changed so that > the result is the same as the result of the rewriting in the > "compilation" section of the spec. In that case its result would be > Boolean. However, that is likely to result in more runtime null > errors, not fewer, if people do things like > > if (list?.isEmpty()) ... > > -Neal > Thanks, Neal. I've started putting a rough implementation of this proposal together, just to aid my own understanding. Are you or Stephen (or anyone else) intending to produce a prototype, or would it be useful if I polish up what I've been doing? Mark From neal at gafter.com Sun Apr 5 10:52:55 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 5 Apr 2009 10:52:55 -0700 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> <15e8b9d20904050711o124b388etca7847f8a456a45c@mail.gmail.com> Message-ID: <15e8b9d20904051052q530820e5m9fcb3441c8cb59d3@mail.gmail.com> On Sun, Apr 5, 2009 at 10:19 AM, Mark Mahieu wrote: > I've started putting a rough implementation of this proposal together, just > to aid my own understanding. ?Are you or Stephen (or anyone else) intending > to produce a prototype, or would it be useful if I polish up what I've been > doing? I'm not planning to prototype this. From jodastephen at gmail.com Sun Apr 5 05:11:57 2009 From: jodastephen at gmail.com (Stephen Colebourne) Date: Sun, 05 Apr 2009 13:11:57 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> Message-ID: <49D8A00D.7040909@gmail.com> Mark Mahieu wrote: >> >> List list = null; >> boolean b = list?.isEmpty() ?: true; >> >> Stephen >> > > I don't understand how that combination is supposed to work, given > this part of the proposal: > > "A null-safe method invocation expression e1?.name(args) ... the type > of the result is the same as the type of e1.name(args). It is an > error if this is not a reference type." > > Doesn't that mean that the compiler should reject the expression > 'list?.isEmpty()' ? I hope Neal can comment as he wrote up the details of the proposal. I did ask him about this when I first read it, and he replied that primitives were handled in the "boxedValue ?: primitive" case. At the time, I assumed that meant that the "list?.isEmpty() ?: false" was also handled, but on re-reading today, you may be right. I'd like the "list?.isEmpty() ?: false" to be handled though. Stephen From stephen at joda.org Sun Apr 5 11:07:51 2009 From: stephen at joda.org (Stephen C) Date: Sun, 05 Apr 2009 19:07:51 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> <15e8b9d20904050711o124b388etca7847f8a456a45c@mail.gmail.com> Message-ID: <49D8F377.4080308@joda.org> Mark Mahieu wrote: > I've started putting a rough implementation of this proposal together, > just to aid my own understanding. Are you or Stephen (or anyone else) > intending to produce a prototype, or would it be useful if I polish up > what I've been doing? I haven't got time to do so, thus it would be great if you do some polishing. Stephen From markmahieu at googlemail.com Sun Apr 5 23:05:24 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 6 Apr 2009 07:05:24 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49D8F377.4080308@joda.org> References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> <49C27E68.7020709@gmail.com> <84A9B0E6-9454-4A74-AFF1-BE92D6694D05@googlemail.com> <15e8b9d20904050711o124b388etca7847f8a456a45c@mail.gmail.com> <49D8F377.4080308@joda.org> Message-ID: 2009/4/5 Stephen C > Mark Mahieu wrote: > > I've started putting a rough implementation of this proposal together, > > just to aid my own understanding. Are you or Stephen (or anyone else) > > intending to produce a prototype, or would it be useful if I polish up > > what I've been doing? > I haven't got time to do so, thus it would be great if you do some > polishing. > Stephen > OK, will do. Mark From alexandre.makarenko at free.fr Mon Apr 6 14:25:23 2009 From: alexandre.makarenko at free.fr (alex) Date: Mon, 6 Apr 2009 23:25:23 +0200 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: References: Message-ID: <200904062325.23836.alexandre.makarenko@free.fr> Hi Tim, a little bit late comment... what if Map> anagrams(); compiled as Map> anagrams = new HashMap>(); ? In more general way for a class C C c( constructor-args ); would be equivalent to C c = new C( constructor-args ); @lex ps: C++ trick ;-) On Saturday 28 March 2009 09:35:46 Tim Lebedkov wrote: > Type inference for variable definition/initialization using the 'auto' > keyword. > > AUTHOR(S): Tim Lebedkov > > OVERVIEW > > Provide a two sentence or shorter description of these five aspects of > the feature: > > FEATURE SUMMARY: Should be suitable as a summary in a language tutorial. > > This proposal addresses the addition of type inference for > variable definitions to the Java programming language using the 'auto' > keyword instead of specific type name. > > For example, consider the following assignment statement: > > Map> anagrams = new HashMap>(); > > This is rather lengthy, so it can be replaced with this: > > auto anagrams = new HashMap>(); > > and anagrams is automatically typed as HashMap> > > MAJOR ADVANTAGE: What makes the proposal a favorable change? > > Generics have had a tremendously positive impact on type safety in the > Java programming language. They have made it possible to provide > static guarantees about the type of instances used by other classes, > preventing entire classes of runtime errors from occurring. However, > generics have added complexity to Java, making the code far more > verbose and occasionally difficult to read. Although solving this > problem is well outside the scope of this proposal, a limited form of > type inference would remove unnecessary redundancy from the language. > Even without generics it seems unnecessary to duplicate type names for > simple variable definitions/assignments like: > > Integer a = new Integer(1023); > > MAJOR BENEFIT: Why is the platform better if the proposal is adopted? > > Less code and no duplication has a positive impact on many things: > - faster typing/faster code changes > - easier code changing without IDE assistance > - code versioning diffs are more clear > > MAJOR DISADVANTAGE: There is always a cost. > > - it could be harder to read the code. > - auto will be a keyword and may break some old code > > ALTERNATIVES: Can the benefits and advantages be had some way without > a language change? > > no > > EXAMPLES > > SIMPLE EXAMPLE: Show the simplest possible program utilizing the new > feature. > > 1. simple assignment > > Map> a = new HashMap>(); > > becomes > > auto a = new HashMap>(); > > 2. auto in for > > List list = ... > for (auto s: list) > ... > > 3. auto for a final variable > > final ArrayList list = new ArrayList(); > > becomes > > final auto list = new ArrayList(); > > 4. class field definition > > class A { > String a = ""; > } > > becomes > > class A { > auto a = ""; > } > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > auto i = 5 + 3; // same as "int i = 5 + 3" > auto i = 5 + 3L; // same as "long i = 5 + 3L" > for (auto entry : (new HashMap>).entrySet()) { } > > DETAILS > > SPECIFICATION: Describe how the proposal affects the grammar, type > system, and meaning of expressions and statements in the Java > Programming Language as well as any other known impacts. > > Informally, the specification adds syntax to replace the type definition > in variable definitions with assignments by 'auto'. The type of the > variable is automatically determined. > > COMPILATION: How would the feature be compiled to class files? Show > how the simple and advanced examples would be compiled. Compilation > can be expressed as at least one of a desugaring to existing source > constructs and a translation down to bytecode. If a new bytecode is > used or the semantics of an existing bytecode are changed, describe > those changes, including how they impact verification. Also discuss > any new class file attributes that are introduced. Note that there are > many downstream tools that consume class files and that they may to be > updated to support the proposal! > > The resulting bytecode would be identical to bytecode generated by the > same code with the types inferred. > > TESTING: How can the feature be tested? > > The proposed construct can be tested by writing a number of statements > that construct instances using > inferred types. These instances can then be assigned to variables and > fields of specific types, and passed to > methods that expect specific types. These tests should compile and run > as expected: > auto set = new SortedSet(); > set.add("A"); > set.add("B"); > set.add("C"); > // verify that set contains "A", "B", "C". > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > > No library support is required, although libraries can be rewritten to > take advantage of the new feature. > > REFLECTIVE APIS: Do any of the various and sundry reflection APIs need > to be updated? This list of reflective APIs includes but is not > limited to core reflection (java.lang.Class and java.lang.reflect.*), > javax.lang.model.*, the doclet API, and JPDA. > > No reflective APIs need to be changed. > > OTHER CHANGES: Do any other parts of the platform need be updated too? > Possibilities include but are not limited to JNI, serialization, and > output of the javadoc tool. > > No other parts of the platform need to be updated. > > MIGRATION: Sketch how a code base could be converted, manually or > automatically, to use the new feature. > > Libraries can be rewritten to take advantage of this feature, but it > is not imperative that they do so. > > COMPATIBILITY > > This change is backwards incompatible on the source code level. > > BREAKING CHANGES: Are any previously valid programs now invalid? If > so, list one. > > All programs that use auto as a name for an identifier would become > invalid. > > EXISTING PROGRAMS: How do source and class files of earlier platform > versions interact with the feature? Can any new overloadings occur? > Can any new overriding occur? > > The feature is completely transparent to the class files. Class files > do not contain > any information about the variables declared using 'auto'. > > REFERENCES > > [1] Thanks to Jeremy Manson (his proposal served as a template for this > one) > http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000009.html > [2] Jaako Jarvi and Bjarne Stroustrup. Decltype and auto (revision 3). > Paper N1607, > JTC1-SC22/WG21, February 17 2004. Online: http://www.open-std.org/jtc1/ > sc22/wg21/docs/papers/2004/n1607.pdf; same as ANSI NCITS/J16 04-0047. > [3] James Gosling, Bill Joy, Guy Steele, and Gilad Bracha. The Java > Language Specification, 3rd Edition. > Addison Wesley, 2004. > > > EXISTING BUGS: Please include a list of any existing Sun bug ids > related to this proposal. > 6242254, 4983159, 6368076 > > URL FOR PROTOTYPE (optional): > none From mthornton at optrak.co.uk Mon Apr 6 14:31:32 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Mon, 06 Apr 2009 22:31:32 +0100 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: <200904062325.23836.alexandre.makarenko@free.fr> References: <200904062325.23836.alexandre.makarenko@free.fr> Message-ID: <49DA74B4.5080304@optrak.co.uk> alex wrote: > Hi Tim, > a little bit late comment... > > what if > > Map> anagrams(); > > compiled as > > Map> anagrams = new HashMap>(); > > Why HashMap and not some other implementation of Map? That approach only works if the LHS specifies a concrete type and not an interface or abstract class. Mark Thornton From rssh at gradsoft.com.ua Mon Apr 6 17:33:12 2009 From: rssh at gradsoft.com.ua (Ruslan Shevchenko) Date: Tue, 7 Apr 2009 03:33:12 +0300 (EEST) Subject: scripts and results (was Helping to find the usefulness of a proposal) Message-ID: <60287e9e1530b3e1ae49976316e8dc57.squirrel@wmail.gradsoft.ua> Good day, Few days ago Stephan give idea about writing simple script, which count amount of possible-optimizations of existing code. So, I wrote few checks for some of such entries. They count low bound of number of code patterns, which can be optimized with some of coin proposal and situated on distinct source lines. I'm afraid that information, which come from count of such code patterns can give incorrect direction: when we have such patterns in code, it's means that problem is not so big and we can easy live with one. Big language problems solved (or not) in non-trivial way, when we have no common (may be ugly) workaround. For example. in Java we rare will see BigDecimal.add() because it is not easy to work with BigDecimals, instead people work with double and have troubles with floating points rounding issues (see http://www.ddj.com/java/184405721)). Yet one example - choosing another language for implementing db-intensive parts of projects. Ok, you warned; data still can be interesting: Checked patterns was: string in switch instanceof switch byte literals multi catch loop by iterator, with call remove inside loop (if you want include other checks, you can add one at etc/checkers_coin.def or ask me [but without any warranty]) Exists one proposal, which I can't find on Joe blog: is change of variable subtype inside 'if instance' statement I. e. patterns look: if (x instanceof something) { something sx = (something)x; } And proposal tell type 'x' as 'something' inside dominate if block. Are anybody remember such proposal or it's was my fantasy ? Some results: For jetty6_11: (web server) byte literal : 52 elvis : 43 instanceof switch : 8 loop with remove : 0 multi catch : 22 string in switch : 19 Files:187 For gwt-user (google ajax library) byte literal : 2 elvis : 30 instanceof switch : 6 loop with remove : 5 multi catch : 9 string in switch : 10 Files:920 For openjdk-jdk part: (system library) byte literal : 1245 elvis : 725 instanceof switch : 252 loop with remove : 61 multi catch : 349 string in switch : 380 Files:7375 If you want to play with checks - most easy way is get special modified source distributive of JavaChecker, which I published as 2.5.0p0 and run it, i.e. (assuming you on Unix console) retrive distributive: wget http://datacenter.gradsoft.ua/public.repository/ua.gradsoft/javachecker/installations/JavaCheckerSourceInstaller-2.5.0p0.jar run installer: java -jar JavaCheckerSourceInstaller-2.5.0p0.jar (install one from UI) cd vi build-check-external.xml, look at few last tasks at end vi check-external.properties add own task and run one, as example: ant -f build-check-external.xml check-coin-openjdk Note, that speed of JavaChecker is far from ideal: openJDK-jdk processed near 50 minutes, so be patient ;) Hope, this information can be useful, as one (and not main) of sources. Regards ! From reinier at zwitserloot.com Mon Apr 6 17:37:18 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 7 Apr 2009 02:37:18 +0200 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: <49DA74B4.5080304@optrak.co.uk> References: <200904062325.23836.alexandre.makarenko@free.fr> <49DA74B4.5080304@optrak.co.uk> Message-ID: <30B1D532-AA2B-4D1E-A8AC-700D54C05CA5@zwitserloot.com> Also, > Map> anagrams(); Actually looks like a method declaration (in fact, it is indistinguishable from it!), so the syntax needs work. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Apr 6, 2009, at 23:31, Mark Thornton wrote: > alex wrote: >> Hi Tim, >> a little bit late comment... >> >> what if >> >> Map> anagrams(); >> >> compiled as >> >> Map> anagrams = new HashMap> List>(); >> >> > Why HashMap and not some other implementation of Map? That approach > only > works if the LHS specifies a concrete type and not an interface or > abstract class. > > Mark Thornton > > From brucechapman at paradise.net.nz Tue Apr 7 01:22:27 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Tue, 07 Apr 2009 20:22:27 +1200 Subject: scripts and results (was Helping to find the usefulness of a proposal) In-Reply-To: <60287e9e1530b3e1ae49976316e8dc57.squirrel@wmail.gradsoft.ua> References: <60287e9e1530b3e1ae49976316e8dc57.squirrel@wmail.gradsoft.ua> Message-ID: <49DB0D43.1050605@paradise.net.nz> Ruslan, Thanks for doing that. Bruce P.S. One answer below Ruslan Shevchenko wrote: > Good day, > > Few days ago Stephan give idea about writing simple script, which > count amount of possible-optimizations of existing code. > > - SNIP - > > Exists one proposal, which I can't find on Joe blog: is change of variable > subtype inside 'if instance' statement > I. e. patterns look: > if (x instanceof something) > { > something sx = (something)x; > } > And proposal tell type 'x' as 'something' inside dominate if block. > Are anybody remember such proposal or it's was my fantasy ? > > > > This is part of the functionality of the switch instanceof proposal, the desugaring probably has something that looks like that in it, and I mentioned it in one of my comments regarding that proposal. Bruce From tim.lebedkov at googlemail.com Tue Apr 7 09:52:29 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Tue, 7 Apr 2009 18:52:29 +0200 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: <200904062325.23836.alexandre.makarenko@free.fr> References: <200904062325.23836.alexandre.makarenko@free.fr> Message-ID: Hello Alex, yes, C++ has a lot of interesting syntax. It is one of Java "parents" and very similar/compatible to Java. IMHO it is always worth a look at how something is implemented there. By the way, C++0x will have both features: "auto" and "definition=initialization". This is probably because you can write something like: auto birthday = user.getBirthday(); // no constructor call and no type name here Regards --Tim On Mon, Apr 6, 2009 at 11:25 PM, alex wrote: > Hi Tim, > a little bit late comment... > > what if > > Map> anagrams(); > > compiled as > > Map> anagrams = new HashMap>(); > > ? > > > > In more general way for a class C > > C c( constructor-args ); > > would be equivalent to > > C c = new C( constructor-args ); > > @lex > > ps: C++ trick ;-) > > > On Saturday 28 March 2009 09:35:46 Tim Lebedkov wrote: >> Type inference for variable definition/initialization using the 'auto' >> keyword. >> >> AUTHOR(S): Tim Lebedkov >> >> OVERVIEW >> >> Provide a two sentence or shorter description of these five aspects of >> the feature: >> >> FEATURE SUMMARY: Should be suitable as a summary in a language tutorial. >> >> This proposal addresses the addition of type inference for >> variable definitions to the Java programming language using the 'auto' >> keyword instead of specific type name. >> >> For example, consider the following assignment statement: >> >> Map> anagrams = new HashMap>(); >> >> This is rather lengthy, so it can be replaced with this: >> >> auto anagrams = new HashMap>(); >> >> and anagrams is automatically typed as HashMap> >> >> MAJOR ADVANTAGE: What makes the proposal a favorable change? >> >> Generics have had a tremendously positive impact on type safety in the >> Java programming language. They ?have made it possible to provide >> static guarantees about the type of instances used by other classes, >> preventing entire classes of runtime errors from occurring. However, >> generics have added complexity to Java, making the code far more >> verbose and occasionally difficult to read. Although solving this >> problem is well outside the scope of this proposal, a limited form of >> type inference would remove unnecessary redundancy from the language. >> Even without generics it seems unnecessary to duplicate type names for >> simple variable definitions/assignments like: >> >> Integer a = new Integer(1023); >> >> MAJOR BENEFIT: Why is the platform better if the proposal is adopted? >> >> Less code and no duplication has a positive impact on many things: >> - faster typing/faster code changes >> - easier code changing without IDE assistance >> - code versioning diffs are more clear >> >> MAJOR DISADVANTAGE: There is always a cost. >> >> - it could be harder to read the code. >> - auto will be a keyword and may break some old code >> >> ALTERNATIVES: Can the benefits and advantages be had some way without >> a language change? >> >> no >> >> EXAMPLES >> >> SIMPLE EXAMPLE: Show the simplest possible program utilizing the new >> feature. >> >> 1. simple assignment >> >> Map> a = new HashMap>(); >> >> becomes >> >> auto a = new HashMap>(); >> >> 2. auto in for >> >> List list = ... >> for (auto s: list) >> ? ? ... >> >> 3. auto for a final variable >> >> final ArrayList list = new ArrayList(); >> >> becomes >> >> final auto list = new ArrayList(); >> >> 4. class field definition >> >> class A { >> ? ? String a = ""; >> } >> >> becomes >> >> class A { >> ? ? auto a = ""; >> } >> >> ADVANCED EXAMPLE: Show advanced usage(s) of the feature. >> >> auto i = 5 + 3; ?// same as "int i = 5 + 3" >> auto i = 5 + 3L; ?// same as "long i = 5 + 3L" >> for (auto entry : (new HashMap>).entrySet()) { } >> >> DETAILS >> >> SPECIFICATION: Describe how the proposal affects the grammar, type >> system, and meaning of expressions and statements in the Java >> Programming Language as well as any other known impacts. >> >> Informally, the specification adds syntax to replace the type definition >> in variable definitions with assignments by 'auto'. The type of the >> variable is automatically determined. >> >> COMPILATION: How would the feature be compiled to class files? Show >> how the simple and advanced examples would be compiled. Compilation >> can be expressed as at least one of a desugaring to existing source >> constructs and a translation down to bytecode. If a new bytecode is >> used or the semantics of an existing bytecode are changed, describe >> those changes, including how they impact verification. Also discuss >> any new class file attributes that are introduced. Note that there are >> many downstream tools that consume class files and that they may to be >> updated to support the proposal! >> >> The resulting bytecode would be identical to bytecode generated by the >> same code with the types inferred. >> >> TESTING: How can the feature be tested? >> >> The proposed construct can be tested by writing a number of statements >> that construct instances using >> inferred types. These instances can then be assigned to variables and >> fields of specific types, and passed to >> methods that expect specific types. These tests should compile and run >> as expected: >> auto set = new SortedSet(); >> set.add("A"); >> set.add("B"); >> set.add("C"); >> // verify that set contains "A", "B", "C". >> >> LIBRARY SUPPORT: Are any supporting libraries needed for the feature? >> >> No library support is required, although libraries can be rewritten to >> take advantage of the new feature. >> >> REFLECTIVE APIS: Do any of the various and sundry reflection APIs need >> to be updated? This list of reflective APIs includes but is not >> limited to core reflection (java.lang.Class and java.lang.reflect.*), >> javax.lang.model.*, the doclet API, and JPDA. >> >> No reflective APIs need to be changed. >> >> OTHER CHANGES: Do any other parts of the platform need be updated too? >> Possibilities include but are not limited to JNI, serialization, and >> output of the javadoc tool. >> >> No other parts of the platform need to be updated. >> >> MIGRATION: Sketch how a code base could be converted, manually or >> automatically, to use the new feature. >> >> Libraries can be rewritten to take advantage of this feature, but it >> is not imperative that they do so. >> >> COMPATIBILITY >> >> This change is backwards incompatible on the source code level. >> >> BREAKING CHANGES: Are any previously valid programs now invalid? If >> so, list one. >> >> All programs that use auto as a name for an identifier would become >> invalid. >> >> EXISTING PROGRAMS: How do source and class files of earlier platform >> versions interact with the feature? Can any new overloadings occur? >> Can any new overriding occur? >> >> The feature is completely transparent to the class files. Class files >> do not contain >> any information about the variables declared using 'auto'. >> >> REFERENCES >> >> [1] Thanks to Jeremy Manson (his proposal served as a template for this >> one) >> http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000009.html >> [2] Jaako Jarvi and Bjarne Stroustrup. Decltype and auto (revision 3). >> Paper N1607, >> JTC1-SC22/WG21, February 17 2004. Online: http://www.open-std.org/jtc1/ >> sc22/wg21/docs/papers/2004/n1607.pdf; same as ANSI NCITS/J16 04-0047. >> [3] James Gosling, Bill Joy, Guy Steele, and Gilad Bracha. The Java >> Language Specification, 3rd Edition. >> Addison Wesley, 2004. >> >> >> EXISTING BUGS: Please include a list of any existing Sun bug ids >> related to this proposal. >> 6242254, 4983159, 6368076 >> >> URL FOR PROTOTYPE (optional): >> none > > From alexandre.makarenko at free.fr Tue Apr 7 11:57:15 2009 From: alexandre.makarenko at free.fr (alexandre.makarenko at free.fr) Date: Tue, 7 Apr 2009 20:57:15 +0200 (CEST) Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: <49DA74B4.5080304@optrak.co.uk> Message-ID: <32658616.5264011239130635849.JavaMail.root@spooler2-g27.priv.proxad.net> exactly ;-) ----- Original Message ----- From: "Mark Thornton" To: "alex" Cc: "Tim Lebedkov" , coin-dev at openjdk.java.net Sent: Monday, April 6, 2009 11:31:32 PM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna Subject: Re: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. alex wrote: > Hi Tim, > a little bit late comment... > > what if > > Map> anagrams(); > > compiled as > > Map> anagrams = new HashMap>(); > > Why HashMap and not some other implementation of Map? That approach only works if the LHS specifies a concrete type and not an interface or abstract class. Mark Thornton From alexandre.makarenko at free.fr Tue Apr 7 12:00:49 2009 From: alexandre.makarenko at free.fr (alexandre.makarenko at free.fr) Date: Tue, 7 Apr 2009 21:00:49 +0200 (CEST) Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: <30B1D532-AA2B-4D1E-A8AC-700D54C05CA5@zwitserloot.com> Message-ID: <20015364.5264851239130849035.JavaMail.root@spooler2-g27.priv.proxad.net> method ? it lacks the method body (or abstract or native modifier) alex ----- Original Message ----- From: "Reinier Zwitserloot" To: coin-dev at openjdk.java.net Sent: Tuesday, April 7, 2009 2:37:18 AM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna Subject: Re: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. Also, > Map> anagrams(); Actually looks like a method declaration (in fact, it is indistinguishable from it!), so the syntax needs work. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Apr 6, 2009, at 23:31, Mark Thornton wrote: > alex wrote: >> Hi Tim, >> a little bit late comment... >> >> what if >> >> Map> anagrams(); >> >> compiled as >> >> Map> anagrams = new HashMap> List>(); >> >> > Why HashMap and not some other implementation of Map? That approach > only > works if the LHS specifies a concrete type and not an interface or > abstract class. > > Mark Thornton > > From alexandre.makarenko at free.fr Tue Apr 7 12:02:36 2009 From: alexandre.makarenko at free.fr (alexandre.makarenko at free.fr) Date: Tue, 7 Apr 2009 21:02:36 +0200 (CEST) Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: Message-ID: <28935064.5265151239130956325.JavaMail.root@spooler2-g27.priv.proxad.net> sounds great ! ----- Original Message ----- From: "Tim Lebedkov" To: "alex" Cc: coin-dev at openjdk.java.net Sent: Tuesday, April 7, 2009 6:52:29 PM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna Subject: Re: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. Hello Alex, yes, C++ has a lot of interesting syntax. It is one of Java "parents" and very similar/compatible to Java. IMHO it is always worth a look at how something is implemented there. By the way, C++0x will have both features: "auto" and "definition=initialization". This is probably because you can write something like: auto birthday = user.getBirthday(); // no constructor call and no type name here Regards --Tim On Mon, Apr 6, 2009 at 11:25 PM, alex wrote: > Hi Tim, > a little bit late comment... > > what if > > Map> anagrams(); > > compiled as > > Map> anagrams = new HashMap>(); > > ? > > > > In more general way for a class C > > C c( constructor-args ); > > would be equivalent to > > C c = new C( constructor-args ); > > @lex > > ps: C++ trick ;-) > > > On Saturday 28 March 2009 09:35:46 Tim Lebedkov wrote: >> Type inference for variable definition/initialization using the 'auto' >> keyword. >> >> AUTHOR(S): Tim Lebedkov >> >> OVERVIEW >> >> Provide a two sentence or shorter description of these five aspects of >> the feature: >> >> FEATURE SUMMARY: Should be suitable as a summary in a language tutorial. >> >> This proposal addresses the addition of type inference for >> variable definitions to the Java programming language using the 'auto' >> keyword instead of specific type name. >> >> For example, consider the following assignment statement: >> >> Map> anagrams = new HashMap>(); >> >> This is rather lengthy, so it can be replaced with this: >> >> auto anagrams = new HashMap>(); >> >> and anagrams is automatically typed as HashMap> >> >> MAJOR ADVANTAGE: What makes the proposal a favorable change? >> >> Generics have had a tremendously positive impact on type safety in the >> Java programming language. They ?have made it possible to provide >> static guarantees about the type of instances used by other classes, >> preventing entire classes of runtime errors from occurring. However, >> generics have added complexity to Java, making the code far more >> verbose and occasionally difficult to read. Although solving this >> problem is well outside the scope of this proposal, a limited form of >> type inference would remove unnecessary redundancy from the language. >> Even without generics it seems unnecessary to duplicate type names for >> simple variable definitions/assignments like: >> >> Integer a = new Integer(1023); >> >> MAJOR BENEFIT: Why is the platform better if the proposal is adopted? >> >> Less code and no duplication has a positive impact on many things: >> - faster typing/faster code changes >> - easier code changing without IDE assistance >> - code versioning diffs are more clear >> >> MAJOR DISADVANTAGE: There is always a cost. >> >> - it could be harder to read the code. >> - auto will be a keyword and may break some old code >> >> ALTERNATIVES: Can the benefits and advantages be had some way without >> a language change? >> >> no >> >> EXAMPLES >> >> SIMPLE EXAMPLE: Show the simplest possible program utilizing the new >> feature. >> >> 1. simple assignment >> >> Map> a = new HashMap>(); >> >> becomes >> >> auto a = new HashMap>(); >> >> 2. auto in for >> >> List list = ... >> for (auto s: list) >> ? ? ... >> >> 3. auto for a final variable >> >> final ArrayList list = new ArrayList(); >> >> becomes >> >> final auto list = new ArrayList(); >> >> 4. class field definition >> >> class A { >> ? ? String a = ""; >> } >> >> becomes >> >> class A { >> ? ? auto a = ""; >> } >> >> ADVANCED EXAMPLE: Show advanced usage(s) of the feature. >> >> auto i = 5 + 3; ?// same as "int i = 5 + 3" >> auto i = 5 + 3L; ?// same as "long i = 5 + 3L" >> for (auto entry : (new HashMap>).entrySet()) { } >> >> DETAILS >> >> SPECIFICATION: Describe how the proposal affects the grammar, type >> system, and meaning of expressions and statements in the Java >> Programming Language as well as any other known impacts. >> >> Informally, the specification adds syntax to replace the type definition >> in variable definitions with assignments by 'auto'. The type of the >> variable is automatically determined. >> >> COMPILATION: How would the feature be compiled to class files? Show >> how the simple and advanced examples would be compiled. Compilation >> can be expressed as at least one of a desugaring to existing source >> constructs and a translation down to bytecode. If a new bytecode is >> used or the semantics of an existing bytecode are changed, describe >> those changes, including how they impact verification. Also discuss >> any new class file attributes that are introduced. Note that there are >> many downstream tools that consume class files and that they may to be >> updated to support the proposal! >> >> The resulting bytecode would be identical to bytecode generated by the >> same code with the types inferred. >> >> TESTING: How can the feature be tested? >> >> The proposed construct can be tested by writing a number of statements >> that construct instances using >> inferred types. These instances can then be assigned to variables and >> fields of specific types, and passed to >> methods that expect specific types. These tests should compile and run >> as expected: >> auto set = new SortedSet(); >> set.add("A"); >> set.add("B"); >> set.add("C"); >> // verify that set contains "A", "B", "C". >> >> LIBRARY SUPPORT: Are any supporting libraries needed for the feature? >> >> No library support is required, although libraries can be rewritten to >> take advantage of the new feature. >> >> REFLECTIVE APIS: Do any of the various and sundry reflection APIs need >> to be updated? This list of reflective APIs includes but is not >> limited to core reflection (java.lang.Class and java.lang.reflect.*), >> javax.lang.model.*, the doclet API, and JPDA. >> >> No reflective APIs need to be changed. >> >> OTHER CHANGES: Do any other parts of the platform need be updated too? >> Possibilities include but are not limited to JNI, serialization, and >> output of the javadoc tool. >> >> No other parts of the platform need to be updated. >> >> MIGRATION: Sketch how a code base could be converted, manually or >> automatically, to use the new feature. >> >> Libraries can be rewritten to take advantage of this feature, but it >> is not imperative that they do so. >> >> COMPATIBILITY >> >> This change is backwards incompatible on the source code level. >> >> BREAKING CHANGES: Are any previously valid programs now invalid? If >> so, list one. >> >> All programs that use auto as a name for an identifier would become >> invalid. >> >> EXISTING PROGRAMS: How do source and class files of earlier platform >> versions interact with the feature? Can any new overloadings occur? >> Can any new overriding occur? >> >> The feature is completely transparent to the class files. Class files >> do not contain >> any information about the variables declared using 'auto'. >> >> REFERENCES >> >> [1] Thanks to Jeremy Manson (his proposal served as a template for this >> one) >> http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000009.html >> [2] Jaako Jarvi and Bjarne Stroustrup. Decltype and auto (revision 3). >> Paper N1607, >> JTC1-SC22/WG21, February 17 2004. Online: http://www.open-std.org/jtc1/ >> sc22/wg21/docs/papers/2004/n1607.pdf; same as ANSI NCITS/J16 04-0047. >> [3] James Gosling, Bill Joy, Guy Steele, and Gilad Bracha. The Java >> Language Specification, 3rd Edition. >> Addison Wesley, 2004. >> >> >> EXISTING BUGS: Please include a list of any existing Sun bug ids >> related to this proposal. >> 6242254, 4983159, 6368076 >> >> URL FOR PROTOTYPE (optional): >> none > > From reinier at zwitserloot.com Tue Apr 7 13:45:26 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 7 Apr 2009 22:45:26 +0200 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: <20015364.5264851239130849035.JavaMail.root@spooler2-g27.priv.proxad.net> References: <20015364.5264851239130849035.JavaMail.root@spooler2-g27.priv.proxad.net> Message-ID: <514D5836-B9FA-438C-AD05-04E9B6C916AF@zwitserloot.com> Yes, so? The parser cannot distinguish between the two, so the only solution would be to amend the semantic translation of parser tokens as such: Any method declaration that is abstract but lacks the abstract or native modifier is actually a field declaration with an auto- initialization scheme. I'm extremely prejudiced against such hackery at the parser level. What if later we want to give the 'abstract' keyword meaning when it is used on fields? All existing tools would also have to do some potentially serious rewriting and refactoring in order to accomodate such a change. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Apr 7, 2009, at 21:00, alexandre.makarenko at free.fr wrote: > method ? > > it lacks the method body (or abstract or native modifier) > > alex > > > ----- Original Message ----- > From: "Reinier Zwitserloot" > To: coin-dev at openjdk.java.net > Sent: Tuesday, April 7, 2009 2:37:18 AM GMT +01:00 Amsterdam / > Berlin / Bern / Rome / Stockholm / Vienna > Subject: Re: Proposal: Type inference for variable definition/ > initialization using the 'auto' keyword. > > Also, > >> Map> anagrams(); > > Actually looks like a method declaration (in fact, it is > indistinguishable from it!), so the syntax needs work. > > --Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On Apr 6, 2009, at 23:31, Mark Thornton wrote: > >> alex wrote: >>> Hi Tim, >>> a little bit late comment... >>> >>> what if >>> >>> Map> anagrams(); >>> >>> compiled as >>> >>> Map> anagrams = new HashMap>> List>(); >>> >>> >> Why HashMap and not some other implementation of Map? That approach >> only >> works if the LHS specifies a concrete type and not an interface or >> abstract class. >> >> Mark Thornton >> >> > > From markmahieu at googlemail.com Thu Apr 9 12:25:47 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 9 Apr 2009 20:25:47 +0100 Subject: Prototype: Elvis and Other Null-Safe Operators Message-ID: <8CD6752E-879D-41BA-BB11-D5AE9F35C3F9@googlemail.com> I've made available a prototype of Stephen Colebourne's Elvis proposal (based on Neal Gafter's spec), if anyone who wants to play around with it: http://slm888.com/javac/elvis.html The usual caveats apply : expect bugs, misinterpretations of the proposal etc. I'll be happy to look into any bug reports, especially if they're accompanied by a simple test case ;) Mark From Joe.Darcy at Sun.COM Thu Apr 9 14:41:12 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Thu, 09 Apr 2009 14:41:12 -0700 Subject: Prototype: Elvis and Other Null-Safe Operators In-Reply-To: <8CD6752E-879D-41BA-BB11-D5AE9F35C3F9@googlemail.com> References: <8CD6752E-879D-41BA-BB11-D5AE9F35C3F9@googlemail.com> Message-ID: <49DE6B78.2040900@sun.com> Thanks for sending in the prototype! Which javac was the starting point? -Joe On 04/09/09 12:25 PM, Mark Mahieu wrote: > I've made available a prototype of Stephen Colebourne's Elvis > proposal (based on Neal Gafter's spec), if anyone who wants to play > around with it: > > http://slm888.com/javac/elvis.html > > The usual caveats apply : expect bugs, misinterpretations of the > proposal etc. I'll be happy to look into any bug reports, especially > if they're accompanied by a simple test case ;) > > Mark > > From markmahieu at googlemail.com Thu Apr 9 14:50:04 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 9 Apr 2009 22:50:04 +0100 Subject: Prototype: Elvis and Other Null-Safe Operators In-Reply-To: <49DE6B78.2040900@sun.com> References: <8CD6752E-879D-41BA-BB11-D5AE9F35C3F9@googlemail.com> <49DE6B78.2040900@sun.com> Message-ID: Hi Joe, The starting point was a clone of the JDK 7 "tl" forest, as of a few days ago. Mark 2009/4/9 Joe Darcy > Thanks for sending in the prototype! > > Which javac was the starting point? > > -Joe > > > On 04/09/09 12:25 PM, Mark Mahieu wrote: > >> I've made available a prototype of Stephen Colebourne's Elvis proposal >> (based on Neal Gafter's spec), if anyone who wants to play around with it: >> >> http://slm888.com/javac/elvis.html >> >> The usual caveats apply : expect bugs, misinterpretations of the proposal >> etc. I'll be happy to look into any bug reports, especially if they're >> accompanied by a simple test case ;) >> >> Mark >> >> >> > > From markmahieu at googlemail.com Mon Apr 13 05:01:53 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 13 Apr 2009 13:01:53 +0100 Subject: Some notes on Elvis and Other Null-Safe Operators Message-ID: <171AADE5-112F-43EB-AEED-4E502EE0914E@googlemail.com> Below are a few observations I compiled while building and testing the prototype for Elvis and friends, in case they're of interest. They are in note form and fairly random order, so please shout if anything isn't clear. Mark -------- Elvis operator can be approximated as a library method: static T elvis(T t1, T t2) { return t1 != null ? t1 : t2; } In a core-libs round table recording (at http://mail.openjdk.java.net/ pipermail/core-libs-dev/2009-April/001406.html) the possibility of adding core library methods for common null-handling tasks is mentioned, such as throwing a standard exception if a supplied argument is null (presumably similar to methods in com.google.common.base.Preconditions). Is it reasonable to implement the Elvis operator as a language change but other null-handling facilities as library changes? Cannot use null-safe method invocation as a statement: stringBuilder?.append(?some text?); // compiler error which is legal in Groovy and Fan, even for methods with void (or Void) result, eg. given: Map map = ... some legal Groovy code: map?.get(someKey)?.run(); and the equivalent with this proposal: Runnable r = map?.get(someKey); if (r != null) r.run(); However, this is accepted: map?.get(someKey).run(); yet is almost certainly an error. Should there at least be a warning in this case? Groovy will also allow the following: someObject?.someField = someValue which does nothing at runtime if someObject is null. Fan and this proposal both reject it. As discussed on coin-dev, this isn't legal as containsKey() returns a primitive type: if (!map?.containsKey(key) ?: false) ... // compiler error Would it be clear to someone reading the code that these two statements are equivalent? if (map?.get(key) == null) ... if (map == null || map.get(key) == null) ... Given: 101: Map map = .. 102: Bar bar = map?.get(someFoo); 103: ... 204: bar.execute(); where the programmer has forgotten to protect the bar.execute() call (or was unaware of the need, perhaps in a different method), the NPE will point at line 204, even if the root cause was 'map' being null. Without use of ?. It would point at line 102 or 204 depending on which variable was null. Groovy has supported Elvis since v1.5 (Dec 2007), other operators for longer. Few Google Code Search results for the former, plenty for the latter (but a large percentage cannot be adapted to use equivalents from this proposal because the method call results in a primitive type, or is used as a statement). Fan has only had Elvis etc since a July 2008 build (1.0.29). C# has had Elvis-equivalent '??' operator since v2.0. From Chris.Allen at nationalcity.com Mon Apr 13 09:26:18 2009 From: Chris.Allen at nationalcity.com (Allen, Chris) Date: Mon, 13 Apr 2009 12:26:18 -0400 Subject: Automatic Resource Management Message-ID: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> I've looked at Automatic Resource Management proposal, and written this email and then sat on it for several days, and it seems that the current proposal, adding a Disposable interface, is arbitrarily restrictive and that by using an attribute combined with a signature matching we could get better bang for our buck. We already use annotations to describe classes such as persistable or deprecated, why not as a resource? I've read the objections on this list to using an annotation, and the interface proposal does list common resources such as Streams and SQL constructs, but while the interface would probably be the preferred way to add this if we were designing the language from scratch, we already have a huge collection of code out there where a typical resource pattern is already used - but where close() is not the disposal method. People have pointed out locks for instance, but were told that locks were beyond the scope of this small change. Why? We're looking to make a small change to Java that will make source code easier to read, write and maintain while making the new constructs easy to recognize. The try() syntax that's been proposed seems to meet that criteria, although I would argue against multiple resources being opened in one try statement (that's not easy to read) and propose this two-step processes to find the method called to dispose the target of the try: 1. If the instance's class or one of it parent classes or interfaces has an attribute of @Disposable the method named in the attributes "value" value is the name of the method to call. The default value for "value" is "close". So: @Disposable("close") public abstract java.io.InputStream { ... or @Disposable public abstract java.io.InputStream { ... Would call close() to dispose of an InputStream. where as @Disposable("unlock") public interface java.util.concurrent.locks.Lock { ... Would call unlock() to dispose of a Lock. 2. If the instance's class and all of it's parent classes and interfaces has no @Disposable attribute, and a instance method matching this signature 'public void close()' exists, regardless of exception thrown, it can also be used as a resource. So: public void MyClass { public void close() throws MyOwnException; } Could still be used even without the @Disposable attribute even if it's compiled in some jar file that I don't have the source for. I understand the parallelism that we'd like to achieve with the interface decisions made with Iterator. There a very small change was introduced in by the addition of an interface, and voila for-each loops. But we're talking a much broader range of classes here, including various 3rd party binaries that have classes that are resources. With Iterator there was a very small set of classes affected - mainly Collection and arrays, but resources could be database connections, text files, locks, threads, servers, memory, scripting engine or any number of other things. Besides, the Disposable interface ends up basically being a marker interface. Since no one is going to go around throwing Exception from the Disposable interface, you're always going to have to narrow the list of thrown exceptions to something like java.sql.ResultSet so that you can deal with SQLException instead. I can't think of a situation where you're going to be using a Disposable objects directly (other than perhaps some resource manager). So Disposable degrades into a marker interface, and when I think marker interface, I squirm a bit. Here's how the annotation might be described. @Documented @Retention(RetentionPolicy.CLASS) @Target({ElementType.TYPE}) public @interface java.lang.Disposable { String value() default "close"; } The compiler simply picks the correct dispose method (or methods if parent classes define additional dispose methods) at compile time so this has no effect on runtime speed. Remember, the whole idea is to change: A a = new A(); try { B b = new B(); try { a.doSomethingTo(b); } finally { b.dispose(); } } finally { a.dispose(); } into an easier to read, easier to understand, easier to write: try (A a = new A()) { try (B b = new B()) { a.doSomethingTo(b); } } Why should it be limited to classes that have a close() method and have to have a Disposable interface, too? As an aside, one of the ideas that needs to be promoted in any of these proposals, is the idea that the exception thrown during the main life of the resource receives priority over any exception thrown by the dispose method(s). This is a fantastic idea, but sounds fishy at first glance. By responsibly closing your resource even during some catastrophic event you can actually erase what the catastrophic event was and waste many hours of debugging. This idea needs to be made clear: the proposal doesn't not hide the dispose exception, just doesn't favor it when competing with the primary exception. We already have a lot of JDK code out there and a good portion of it does not use close() as it's dispose method. Adding the Dispose interface to so many classes seems to break the "small change rule". An annotation combined with a backup method signature match, covers many more resources than the interface proposal and is more compatible with the various types of resources already in use. P.S. Apologies to any people who's toes I've stepped on, some of the ideas I've stated here have been stated by others, too. -Chris Allen ------------------------------------------------------------------------------------------- ***National City made the following annotations ------------------------------------------------------------------------------------------- This communication is a confidential and proprietary business communication. It is intended solely for the use of the designated recipient(s). If this communication is received in error, please contact the sender and delete this communication. =========================================================================================== From jjb at google.com Mon Apr 13 09:38:30 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 13 Apr 2009 09:38:30 -0700 Subject: Automatic Resource Management In-Reply-To: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> References: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> Message-ID: <17b2302a0904130938y76bc6719g25eb5b6aa413a57e@mail.gmail.com> Allen, Hi. Thanks for taking the time to read the proposal. On Mon, Apr 13, 2009 at 9:26 AM, Allen, Chris wrote: > I've looked at Automatic Resource Management proposal, and written this > email and then sat on it for several days, and it seems that the current > proposal, adding a Disposable interface, is arbitrarily restrictive and > that by using an attribute combined with a signature matching we could > get better bang for our buck. We discussed this extensively (you can find it in the archive) and Sun made it clear that this violates the "prime directive" concerning the use of annotations: they are not permitted to change program semantics. I floated a related proposal involving the use of "finally" as a modifier (again, you can find it in the archive), but it necessarily involved changes to the class file format, the tool chain, etc. The consensus was that this was too big a change for Coin, and probably to big a change for the added benefit. Moreover, the added flexibility came with added potential for trouble (how do you ensure that there is a unique disposal method on a given type, or deal with the situation where there's more than one?). > > > As an aside, one of the ideas that needs to be promoted in any of these > proposals, is the idea that the exception thrown during the main life of > the resource receives priority over any exception thrown by the dispose > method(s). This is a fantastic idea, but sounds fishy at first glance. > By responsibly closing your resource even during some catastrophic event > you can actually erase what the catastrophic event was and waste many > hours of debugging. This idea needs to be made clear: the proposal > doesn't not hide the dispose exception, just doesn't favor it when > competing with the primary exception. I'm hard at work on a revision, and hope to have it out later today. I will make sure to make this clear. > > > We already have a lot of JDK code out there and a good portion of it > does not use close() as it's dispose method. That's true, and this facility won't cover everything right away. But it will cover enough types to pay for itself and it will cover more over time. And in the worst case, you can cover arbitrary types by writing adapters. Regards, Josh From angelo.borsotti at gmail.com Mon Apr 13 14:21:10 2009 From: angelo.borsotti at gmail.com (Angelo Borsotti) Date: Mon, 13 Apr 2009 23:21:10 +0200 Subject: Proposal for a small language change Message-ID: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> Author: Angelo Borsotti, former Senior Director Software Technology, Alcatel-Lucent Optics Overview Feature Summary: fast and accurate measurement of execution time Major Advantage: optimization of algorithms by measuring execution times of small snippets of code executed many times Major Benefit: greatly increases observability of programs Major Disadvantage: very little cost Alternatives: there are no alternatives Examples: Simple example: long c0 = System.cycles(); i++; long c = System.cycles() - c0; Advanced example: long cycles = 0; for (int i = 0; i < bound; i++){ ... long c0 = System.cycles(); some statements cycles += System.cycles()- c0; } Details Specification Add a new method System.cycles(). Compilation The method must be compiled inline, translating it into a single instruction, present in most architectures, that reads the cycle counter register (e.g. the TSC in x86 architectures). To measure execution time, System.nanoTime() is currently provided. This, however, is by far too inaccurate to measure the execution time of code which lies inside methods, possibly inside loops. The accuracy that it provides is comparable to the time needed to execute thousands of java statements, which is too low. Moreover, the time spent to execute the nanoTime() method itself makes this tool too much invasive. Execution times become often much higher when nanoTime() is added, to the point to provide useless results. Note that when a piece of code lies inside loops, measuring its execution time means adding many small durations. This means that the invasivity and the accuracy of the tool to measure time is extremely important. Note that also a native method would be too much invasive. The only way to provide a means to measure execution times that introduces an acceptable noise (i.e. an error that is sufficiently lower than the times measured) is to compile the call inline into a machine instruction. Profilers are orders of magnitude coarser than what is needed. Testing A simple test case in which a very simple example (as the one above) is used, that computes the number of cycles needed to perform a simple operation. The result should then be compared agains an estimate. Library suppor None needed Reflective APIs No change Other changes None Migration None Compatibility Completely downward compatible References Bug ID: 6685613 From Joe.Darcy at Sun.COM Mon Apr 13 14:28:49 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 13 Apr 2009 14:28:49 -0700 Subject: Proposal for a small language change In-Reply-To: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> References: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> Message-ID: <49E3AE91.7010303@sun.com> The Project Coin call for proposals phase is over; no new proposals are being accepted. Microbenching is a tricky area, but not one requiring language support! -Joe PS Somewhat related might be JSR 284: Resource Consumption Management API http://www.jcp.org/en/jsr/detail?id=284 Angelo Borsotti wrote: > Author: Angelo Borsotti, former Senior Director Software Technology, > Alcatel-Lucent Optics > > Overview > Feature Summary: fast and accurate measurement of execution time > Major Advantage: optimization of algorithms by measuring execution > times of small snippets of code executed many times > Major Benefit: greatly increases observability of programs > Major Disadvantage: very little cost > Alternatives: there are no alternatives > > Examples: > > Simple example: > long c0 = System.cycles(); > i++; > long c = System.cycles() - c0; > Advanced example: > long cycles = 0; > for (int i = 0; i < bound; i++){ > ... > long c0 = System.cycles(); > some statements > cycles += System.cycles()- c0; > } > > Details > Specification > Add a new method System.cycles(). > Compilation > The method must be compiled inline, translating it into a single > instruction, > present in most architectures, that reads the cycle counter > register (e.g. the > TSC in x86 architectures). > To measure execution time, System.nanoTime() is currently > provided. This, however, > is by far too inaccurate to measure the execution time of code > which lies inside > methods, possibly inside loops. The accuracy that it provides is > comparable to the > time needed to execute thousands of java statements, which is too low. > Moreover, the time spent to execute the nanoTime() method itself > makes this tool > too much invasive. Execution times become often much higher when > nanoTime() is > added, to the point to provide useless results. > Note that when a piece of code lies inside loops, measuring its execution > time means adding many small durations. This means that the invasivity > and the accuracy of the tool to measure time is extremely important. > Note that also a native method would be too much invasive. The > only way to provide > a means to measure execution times that introduces an acceptable > noise (i.e. an > error that is sufficiently lower than the times measured) is to > compile the call > inline into a machine instruction. Profilers are orders of > magnitude coarser than > what is needed. > Testing > A simple test case in which a very simple example (as the one > above) is used, > that computes the number of cycles needed to perform a simple > operation. The > result should then be compared agains an estimate. > Library suppor > None needed > Reflective APIs > No change > Other changes > None > Migration > None > > Compatibility > Completely downward compatible > > References > Bug ID: 6685613 > > From Ulf.Zibis at gmx.de Mon Apr 13 14:43:08 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 13 Apr 2009 23:43:08 +0200 Subject: Proposal for a small language change In-Reply-To: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> References: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> Message-ID: <49E3B1EC.7060309@gmx.de> +1 -Ulf Am 13.04.2009 23:21, Angelo Borsotti schrieb: > Author: Angelo Borsotti, former Senior Director Software Technology, > Alcatel-Lucent Optics > > Overview > Feature Summary: fast and accurate measurement of execution time > Major Advantage: optimization of algorithms by measuring execution > times of small snippets of code executed many times > Major Benefit: greatly increases observability of programs > Major Disadvantage: very little cost > Alternatives: there are no alternatives > > Examples: > > Simple example: > long c0 = System.cycles(); > i++; > long c = System.cycles() - c0; > Advanced example: > long cycles = 0; > for (int i = 0; i < bound; i++){ > ... > long c0 = System.cycles(); > some statements > cycles += System.cycles()- c0; > } > > Details > Specification > Add a new method System.cycles(). > Compilation > The method must be compiled inline, translating it into a single > instruction, > present in most architectures, that reads the cycle counter > register (e.g. the > TSC in x86 architectures). > To measure execution time, System.nanoTime() is currently > provided. This, however, > is by far too inaccurate to measure the execution time of code > which lies inside > methods, possibly inside loops. The accuracy that it provides is > comparable to the > time needed to execute thousands of java statements, which is too low. > Moreover, the time spent to execute the nanoTime() method itself > makes this tool > too much invasive. Execution times become often much higher when > nanoTime() is > added, to the point to provide useless results. > Note that when a piece of code lies inside loops, measuring its execution > time means adding many small durations. This means that the invasivity > and the accuracy of the tool to measure time is extremely important. > Note that also a native method would be too much invasive. The > only way to provide > a means to measure execution times that introduces an acceptable > noise (i.e. an > error that is sufficiently lower than the times measured) is to > compile the call > inline into a machine instruction. Profilers are orders of > magnitude coarser than > what is needed. > Testing > A simple test case in which a very simple example (as the one > above) is used, > that computes the number of cycles needed to perform a simple > operation. The > result should then be compared agains an estimate. > Library suppor > None needed > Reflective APIs > No change > Other changes > None > Migration > None > > Compatibility > Completely downward compatible > > References > Bug ID: 6685613 > > > From mthornton at optrak.co.uk Mon Apr 13 14:44:22 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Mon, 13 Apr 2009 22:44:22 +0100 Subject: Proposal for a small language change In-Reply-To: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> References: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> Message-ID: <49E3B236.2050406@optrak.co.uk> Angelo Borsotti wrote: > Author: Angelo Borsotti, former Senior Director Software Technology, > Alcatel-Lucent Optics > > Overview > Feature Summary: fast and accurate measurement of execution time > Major Advantage: optimization of algorithms by measuring execution > times of small snippets of code executed many times > Major Benefit: greatly increases observability of programs > Major Disadvantage: very little cost > Alternatives: there are no alternatives > > Examples: > > Simple example: > long c0 = System.cycles(); > i++; > long c = System.cycles() - c0; > Advanced example: > long cycles = 0; > for (int i = 0; i < bound; i++){ > ... > long c0 = System.cycles(); > some statements > cycles += System.cycles()- c0; > } > > As Joe has said the proposal period is over and this proposal doesn't need a language change. The existing System.nanoTime() method could be implemented using CPU cycle counters. However there are significant problems on multi-core or multi-processor systems and where power management is in use. Some systems don't keep the cycle counters synchronized across CPUs, so if a thread is migrated from one CPU to another the computed elapsed cycle time is not reliable. Some interesting information on timing can be found here: http://blogs.sun.com/dholmes/entry/inside_the_hotspot_vm_clocks Mark Thornton From reinier at zwitserloot.com Mon Apr 13 14:58:22 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 13 Apr 2009 23:58:22 +0200 Subject: Proposal for a small language change In-Reply-To: <49E3B1EC.7060309@gmx.de> References: <541298b90904131421ocf2aa4buc0bda308f4480367@mail.gmail.com> <49E3B1EC.7060309@gmx.de> Message-ID: Bad Idea: What you're talking about is microbenchmarking. Trying to do it, is almost always a good indicator that you're Doing It Wrong. Java doesn't microbenchmark well for several reasons. If you really must benchmark some code, here's how you MUST do it; the following scheme is a neccessary but not sufficient guarantee that you might just be getting relevant timing numbers: Set up something that can be looped over many times. Then, time the time it takes to run the entire loop. Make sure the data that is calculated is used someplace; for example, if you're calculating lists, add the sizes of the lists to a number, then, at the end, print the number (do the printing after the timing, of course - it takes ages!) - otherwise the hotspot compiler will just excise the entire code! Time it for many different loop invocations, and draw a chart. loop count on the x-axis, time taken (in total, not per iteration) on the y- axis. Keep doing this until you get a graph that looks a little like this: for the first X iterations, the line is roughly linear, with a slope of m. Then, there's a sudden spike, and after the spike, the line becomes linear again, with a different slope of n. n is significantly smaller than m (the line is closer to the horizontal). Once you've reached this chart, you've got your answer: The spike is the hotspot compiler kicking in. The m slope gives you the time for the loop pre-hotspot and is mostly irrelevant. The n slope gives you the post-hotspot and is more relevant. This is better than blind microbenchmarking but I'm leaving out many, many important details about how to do microbenchmarking appropriately in java. A 'cycle' method really isn't going to help much - the timing you need to do is many orders of magnitude larger than what System.nanoTime() can reliably measure, so existing tools are fine. Secondly, and more importantly: That's not where timing is _supposed_ to be done in the first place. That's where JVMTI comes in - that's where you need to be doing this. Download a profiler (netbeans has a nice one!) and work with that. A JVM debug can generate cycle instructions if that really would be helpful, just like debug JVMs can print the assembler code generated when hotspotting for the local architecture. If the profiler team needs something to improve their ability to profile, that should certainly be considered, but I seriously doubt they'll be needing a cycle() JVM bytecode to do their job. --Reinier Zwitserloot On Apr 13, 2009, at 23:43, Ulf Zibis wrote: > +1 > > -Ulf > > > Am 13.04.2009 23:21, Angelo Borsotti schrieb: >> Author: Angelo Borsotti, former Senior Director Software Technology, >> Alcatel-Lucent Optics >> >> Overview >> Feature Summary: fast and accurate measurement of execution time >> Major Advantage: optimization of algorithms by measuring execution >> times of small snippets of code executed many times >> Major Benefit: greatly increases observability of programs >> Major Disadvantage: very little cost >> Alternatives: there are no alternatives >> >> Examples: >> >> Simple example: >> long c0 = System.cycles(); >> i++; >> long c = System.cycles() - c0; >> Advanced example: >> long cycles = 0; >> for (int i = 0; i < bound; i++){ >> ... >> long c0 = System.cycles(); >> some statements >> cycles += System.cycles()- c0; >> } >> >> Details >> Specification >> Add a new method System.cycles(). >> Compilation >> The method must be compiled inline, translating it into a single >> instruction, >> present in most architectures, that reads the cycle counter >> register (e.g. the >> TSC in x86 architectures). >> To measure execution time, System.nanoTime() is currently >> provided. This, however, >> is by far too inaccurate to measure the execution time of code >> which lies inside >> methods, possibly inside loops. The accuracy that it provides is >> comparable to the >> time needed to execute thousands of java statements, which is >> too low. >> Moreover, the time spent to execute the nanoTime() method itself >> makes this tool >> too much invasive. Execution times become often much higher when >> nanoTime() is >> added, to the point to provide useless results. >> Note that when a piece of code lies inside loops, measuring its >> execution >> time means adding many small durations. This means that the >> invasivity >> and the accuracy of the tool to measure time is extremely >> important. >> Note that also a native method would be too much invasive. The >> only way to provide >> a means to measure execution times that introduces an acceptable >> noise (i.e. an >> error that is sufficiently lower than the times measured) is to >> compile the call >> inline into a machine instruction. Profilers are orders of >> magnitude coarser than >> what is needed. >> Testing >> A simple test case in which a very simple example (as the one >> above) is used, >> that computes the number of cycles needed to perform a simple >> operation. The >> result should then be compared agains an estimate. >> Library suppor >> None needed >> Reflective APIs >> No change >> Other changes >> None >> Migration >> None >> >> Compatibility >> Completely downward compatible >> >> References >> Bug ID: 6685613 >> >> >> > > From reinier at zwitserloot.com Mon Apr 13 15:21:44 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 14 Apr 2009 00:21:44 +0200 Subject: Automatic Resource Management In-Reply-To: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> References: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> Message-ID: <1A55DAD4-F03E-4E06-8C52-C9939006A70A@zwitserloot.com> Allen, you haven't answered any of the questions about using an annotation, even if we forget for a moment that annotations aren't supposed to be used for this in the first place: 1. Do @Disposable annotations inherit (if not, the proposal really stinks, so I'll assume it does, which leads to): 2. What if 1 object has multiple @Disposable annotations? Call them all? That's rather a lot of exceptions that could occur - do we stop calling them all once one of them throws an exception, or keep going? 3. What if the close() method doesn't actually exist? Whose job is it to generate a compiler error? 4. Should @Disposable be sorted out at runtime, or at compiletime? In other words, if I have a variable typed 'Foobar', named 'foobar', and I try() on this, should I just call all the close methods that I can find when chasing down the Disposable annotations of Foobar, or should I ask for foobar's actual type (foobar.getClass()) and work with that instead? If we go with the compile-time option, then won't this cause some fairly serious confusion and possible resource leakage? These are all serious issues, and while you could pick a solution for them all, and document this extensively, your average java programming just doesn't read all of the JLS - in other words, language changes should be as self-sensible as possible. Josh's proposal may not work for every existing class, but it has clear and obvious answers for ALL of those issues. In case people are wondering what they are, here they briefly follow: 1. interfaces inherit already (if your superclass implements X, so do you - you can't undo this), so the answer is obvious: Yes. 2. There's only one method, so even if the Disposable interface is implemented many times over, it makes absolutely no difference: close() willbe called, and that's the only method. 3. It's already an error to not implement an abstract method, so that's easy. 4. This situation cannot occur; either the compile-time type is a Disposable, and thus the close() method is called, or it isn't, and the try() form is not even legal. You could cast your object to a Disposable, and this would work, but then the method to call is also obvious (close), as is the error when the object isn't actually disposable at all (ClassCastException). None of these things even need to be specified in Josh's ARM proposal, because these are the rules that already apply to implementing interfaces. I hope this mail summarizes the major issues (aside from the notion that annotations should not affect compilation like this) with using an annotation. Before initiating too much discussion on these problems, please review the (many, many) emails that have already been spent on the topic, lest we just rehash the same arguments over and over. A telling point: NOBODY submitted an official annotation based ARM proposal for coin (at least none that had a snowball's chance of being accepted - i.e. having enough detail to update javac and covering every open issue like the ones stated above). --Reinier Zwitserloot On Apr 13, 2009, at 18:26, Allen, Chris wrote: > I've looked at Automatic Resource Management proposal, and written > this > email and then sat on it for several days, and it seems that the > current > proposal, adding a Disposable interface, is arbitrarily restrictive > and > that by using an attribute combined with a signature matching we could > get better bang for our buck. > > We already use annotations to describe classes such as persistable or > deprecated, why not as a resource? I've read the objections on this > list to using an annotation, and the interface proposal does list > common > resources such as Streams and SQL constructs, but while the interface > would probably be the preferred way to add this if we were designing > the > language from scratch, we already have a huge collection of code out > there where a typical resource pattern is already used - but where > close() is not the disposal method. People have pointed out locks for > instance, but were told that locks were beyond the scope of this small > change. > > Why? > > We're looking to make a small change to Java that will make source > code > easier to read, write and maintain while making the new constructs > easy > to recognize. > > The try() syntax that's been proposed seems to meet that criteria, > although I would argue against multiple resources being opened in one > try statement (that's not easy to read) and propose this two-step > processes to find the method called to dispose the target of the try: > > 1. If the instance's class or one of it parent classes or interfaces > has > an attribute of @Disposable the method named in the attributes "value" > value is the name of the method to call. The default value for > "value" > is "close". > > So: > > @Disposable("close") > public abstract java.io.InputStream { ... > > or > > @Disposable > public abstract java.io.InputStream { ... > > Would call close() to dispose of an InputStream. > > where as > > @Disposable("unlock") > public interface java.util.concurrent.locks.Lock { ... > > Would call unlock() to dispose of a Lock. > > 2. If the instance's class and all of it's parent classes and > interfaces > has no @Disposable attribute, and a instance method matching this > signature 'public void close()' exists, regardless of exception > thrown, > it can also be used as a resource. > > So: > > public void MyClass { > > public void close() throws MyOwnException; > > } > > Could still be used even without the @Disposable attribute even if > it's > compiled in some jar file that I don't have the source for. > > I understand the parallelism that we'd like to achieve with the > interface decisions made with Iterator. There a very small change was > introduced in by the addition of an interface, and voila for-each > loops. > But we're talking a much broader range of classes here, including > various 3rd party binaries that have classes that are resources. With > Iterator there was a very small set of classes affected - mainly > Collection and arrays, but resources could be database connections, > text > files, locks, threads, servers, memory, scripting engine or any number > of other things. > > Besides, the Disposable interface ends up basically being a marker > interface. Since no one is going to go around throwing Exception from > the Disposable interface, you're always going to have to narrow the > list > of thrown exceptions to something like java.sql.ResultSet so that you > can deal with SQLException instead. I can't think of a situation > where > you're going to be using a Disposable objects directly (other than > perhaps some resource manager). So Disposable degrades into a marker > interface, and when I think marker interface, I squirm a bit. > > Here's how the annotation might be described. > > @Documented > @Retention(RetentionPolicy.CLASS) > @Target({ElementType.TYPE}) > public @interface java.lang.Disposable { > String value() default "close"; > } > > The compiler simply picks the correct dispose method (or methods if > parent classes define additional dispose methods) at compile time so > this has no effect on runtime speed. Remember, the whole idea is to > change: > > A a = new A(); > try { > B b = new B(); > try { > a.doSomethingTo(b); > } > finally { > b.dispose(); > } > } > finally { > a.dispose(); > } > > into an easier to read, easier to understand, easier to write: > > try (A a = new A()) { > try (B b = new B()) { > a.doSomethingTo(b); > } > } > > Why should it be limited to classes that have a close() method and > have > to have a Disposable interface, too? > > As an aside, one of the ideas that needs to be promoted in any of > these > proposals, is the idea that the exception thrown during the main > life of > the resource receives priority over any exception thrown by the > dispose > method(s). This is a fantastic idea, but sounds fishy at first > glance. > By responsibly closing your resource even during some catastrophic > event > you can actually erase what the catastrophic event was and waste many > hours of debugging. This idea needs to be made clear: the proposal > doesn't not hide the dispose exception, just doesn't favor it when > competing with the primary exception. > > We already have a lot of JDK code out there and a good portion of it > does not use close() as it's dispose method. Adding the Dispose > interface to so many classes seems to break the "small change > rule". An > annotation combined with a backup method signature match, covers many > more resources than the interface proposal and is more compatible with > the various types of resources already in use. > > P.S. Apologies to any people who's toes I've stepped on, some of the > ideas I've stated here have been stated by others, too. > > -Chris Allen > > ------------------------------------------------------------------------------------------- > ***National City made the following annotations > ------------------------------------------------------------------------------------------- > This communication is a confidential and proprietary business > communication. > It is intended solely for the use of the designated recipient(s). > If this > communication is received in error, please contact the sender and > delete > this communication. > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > = > ====================================================================== > From reinier at zwitserloot.com Mon Apr 13 16:54:54 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 14 Apr 2009 01:54:54 +0200 Subject: Automatic Resource Management In-Reply-To: <200904140134.22467.peter.levart@gmail.com> References: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> <1A55DAD4-F03E-4E06-8C52-C9939006A70A@zwitserloot.com> <200904140134.22467.peter.levart@gmail.com> Message-ID: If the notion that 1 interface, with the associated forced 'close()' method, is considered too great of a problem, then your proposal is certainly the only viable alternative IMO. You can even play with the syntax to open multiple resources (but personally I'm somewhat opposed to letting any kind of ARM block open multiple resources in one statement; what's the problem with nesting a few of them?). The problem I have with your proposal is twofold. One is simple, one is fairly esoteric: 1. Disposable/close() fits almost all use-cases, and the foreach syntax has shown that not covering every single existent base is not going to be a problem; the java world will adapt and come around to it. Especially because the libraries that can't work with this scheme don't seem too important to the java community at this point (more on that later). 2. The esoteric one: For semantics' sake, I would consider the closing statement to be better located at the end of the guarded block - but how do we figure this out, syntax wise? You could use the 'finally' keyword, which makes some sense, but the finally keyword already has meanings which are not quite compatible with the meaning of ARM-style final code: exceptions in the main body have precedence in ARM blocks, but they lose out in the usual try/finally. This makes finally a bad keyword, and in fact gets in the way of the entire concept: It LOOKS like you're just using a slightly different version of try/finally syntax, but that's not really what's going on. That makes your proposal somewhat ambiguous without knowing the JLS specifics. It's not nearly as bad as some of the other proposals, so not a showstopper, but certainly a nit. Having said that, there might be a way out of this, by integrating both proposals. 1. Remove the ability to put multiple resources in one statement; what's the problem with nesting trywith blocks again? 2. Use the ; to switch to the alternate form of resource management: try ( a ; b ) {} no longer requires that is an expression of type 'Disposable' (or a variable declaration of a Disposable), and instead, b is run at the end analogous to your proposal. Then, for all objects that know how to dispose of themselves, you just go try ( object ) { stuff }, but when they don't, you can work around it with try ( object ; closeIt ) { stuff }. NOTE: I'm not actually in favour of this, because, at the risk of taking a contentious position, I don't rate the libraries that can't deal with Disposable very highly. SWT was absolutely excellent when it was released, and the java community owes it a great thank you for lighting the fire of competition under awt/swing's behind, but between new swing versions and javaFX, SWT's time has gone, eclipse needs to migrate over, and SWT needs to slowly but surely go away now. Locks are handled just as well, IMO, with the existing try/finally structure, primarily because lock.unlock() generally doesn't throw exceptions, which is a big reason for using ARM in the first place. --Reinier Zwitserloot On Apr 14, 2009, at 01:34, Peter Levart wrote: > Hello Reinier, > > What do you think of the idea of explicit resource cleanup (as > opposed to > using interface) that I have described a few days ago (in > http://mail.openjdk.java.net/pipermail/coin-dev/2009-April/001383.html) > . > > The way I see it is best described by the following parallelism: > > Cleaning up resources correctly with existing try-catch-finally > construct as > opposed to using Joshua's ARM is like iterating over elements of the > array > using while loop as opposed to using foreach. > > int i = 0; > while (i < array.length) > { > Type a = array[i] ; > ... > i++; > } > > vs. > > foreach (Type a : array) > { > ... > } > > > ... but using existing try-catch-finally vs. Semi-Automatic- > Resource-Cleanup > (described in my previous mail) is like using while vs. for > > int i = 0; > while (i < array.length) > { > Type a = array[i] ; > ... > i++; > } > > vs. > > for (int i = 0; i < array.length; i++) > { > Type a = array[i]; > ... > } > > > ...there's not much less typing, everything is still explicit. But > the idiom > is "captured" in a predefined construct leaving less chance for an > average > programmer to do it wrong. > > Using 'for' instead of 'foreach' leaves you more flexibility if you > need it. > For example: > > for (int i = offset; i < array.length && i < offset + length; i+ > +) ... etc. > > The question is: Do we want to be more flexible (and type a little > more) when > capturing the resource cleanup idiom? > > Regards, Peter > From Joe.Darcy at Sun.COM Mon Apr 13 18:55:08 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 13 Apr 2009 18:55:08 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: References: <4b4f45e00904020439q28caaeacrc6f53fa1cae50187@mail.gmail.com> <28bca0ff0904020528l51d803f2t5a6dc29a8f6a67dc@mail.gmail.com> <31AB3E69-CCE7-4134-95C9-4DB5BF6C9281@zwitserloot.com> <49D516A6.6000404@sun.com> Message-ID: <49E3ECFC.6000002@sun.com> On 04/02/09 04:30 PM, rssh at gradsoft.com.ua wrote: [snip] >>> Note, that I does not propose use polls as one and only one criteria. I >>> just tell that see result of such poll will be interest. >>> >>> // btw - from other side, all this activity is overkill, I can suggest, >>> // that accepted proposals would be exactly same, which was listed in >>> // project-coin description (before coin was started) >>> // http://blogs.sun.com/darcy/entry/project_coin >>> // +ARM +jsr292 and ... it's already 6, which is more than 5 :) >>> >>> >> Your own sentence disproves your point since ARM was not listed among >> the five proposal areas under consideration before Project Coin started. >> >> > > I mean not 'would be exactly same, which was listed in project-coin > description (before coin was started)[url]', but 'would be > exactly same, which was listed in project-coin description (before coin > was started)[url] +ARM +jsr292', > sorry for ambiguity. > > ARM floating around (and widly discussed) from late 2007 or early 2008. > And all we know, that if BGGA will not available, than at least ARM must > be included. I don't know that. > I. e. I can't say that ARM is 'external' and new or not to > be generally known be included in Java 7 before project coin start. > > I have no pretension about judgement process, It's only about information > flow: i. e. Sun have all proposals before and call for new > proposals with process of selecting 5 from set of newly received and 5 > apriory well-known items, for which we know, that they are necessory, it's > near the same, that throw away all non-apriory proposals. > > > I. e. I guess, that when people asked to submit new proposals, they expect > that exists demand for new proposals, not demand for choosing from five > well-known items. When appointment of all new proposals to be thrown away, > with role be backgroung for well-known items, people, which invested some > time in such activity, usually frustrated. It's why I think, that call for > new proposals, whithout real possibility to implement something new (not > well-known before) was an error. If we have slot, for example, in summary > for 10 proposals to implement (5 well know and 5 new) - then all ok, it's > fair game. > Amongst other factors, the maximum number of proposals that can get in is a function of how many people work on implementations. Very few of the proposals had any accompanying prototype. For example, I'm sympathetic to the idea of having literals for bit strings and the like; those are much more likely to end up as part of the platform if people outside of Sun take the lead on the implementation. However, even with help from the broader community, there is still an upper-bound on how many small language changes can get in because of various kinds of coordination activities that do not scale and the non-implementation aspects of the work (specification and testing). Many of the submitted proposals were not really proposals in terms of a thoughtful analysis of what it would take to add a feature to the platform; rather they were "requests for enhancement" in Sun bug database terminology where much of the hard work of thinking through implications and interactions was left undone. Existing discussion of such issues from Sun's bug database were often ignored even though they can be found by a simple web search query. And a specification is much more than the grammatical changes involved! >>> I. e. doing project coin with external auditory was a 'Sun system >>> error', >>> I guess; if they want some feedback from community, correct way was at >>> first implement own stuff, than ask community for something new ;) >>> >>> >> The call of proposal phase of Project Coin is an effort both to solicit >> feedback from the external community and also to invite the external >> community to participate more directly in evolving the language. That >> opportunity to participate also implies participating in the large >> amount of work required to go from "I have this great idea!" to "I have >> this great idea and here is a carefully considered review of all the >> implications of the idea, along with a prototype." The blogs I wrote >> last year and the proposal form itself are part of an effort to explain >> and expose what this language work entails so more people can get >> involved. >> >> > > > It would be great, to participate in language evolution in future. > For now I does not see general aviable process for future participation: > call closed, all new proposal throwed away. > I would counter the list received few serious actual proposals, which is directly tied to why few proposals (so far) have been selected for further consideration. I reviewed all open language specification RFEs last year. A restatement of an existing RFE in Sun's bug database as a Project Coin proposal without any further analysis has approximately zero value. Last year I published a list of five proposal ideas to seed the discussion. Opinions will differ of course (different parts of the elephant), but I think few of the submitted proposals were as compelling as the problems being addressed by those initial five proposals, which again relates to why those proposal areas have not been displaced by subsequent ones. > Finish. Fire bug reports is useless - they will live in bugzilla for years. > > One possible solution: is make 'coin project' regular, for example once a > year. (May be with > entry barrier as 'required implementation in some form') > Another - propose some process (may be long) for author, how to push his > proposal (whith implementation) > into language after JDK7 (or receive official position, that this change > is rejected) > > > >> Unfortunately, many of the submitted proposals did not do a credible job >> of analyzing the true effect the proposal would have, which has a rather >> strong relation to why many were not chosen for further consideration. >> For example, let's take the "'This' type" proposal: >> >> > ... > > > Problem with inaccurate proposals - it's well known problem, the same with > publications, wildly used technique is peer review. (Honesly, overall > quality of proposals was better that I was expected). > Yes, the list is for peer review and many proposals found a vigorous discussion there! In retrospect, I think it would have been helpful to publish, say, the completed strings in switch proposal form sooner after the proposal form was published. That form for a very simple language change indicates the degree of thoroughnesses I would have liked to have seen from all the proposals: http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html > Good entry barrier can be requirement to proposal to be implemented in > some form. > > P.S. Project coin involved me to think about Java more close than before. > So, despite my criticism, you achieve goal to raise interest to > participate in process of Java language evolution ;) > That is something at least ;-) -Joe From peter.levart at gmail.com Tue Apr 14 00:04:23 2009 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 14 Apr 2009 09:04:23 +0200 Subject: Automatic Resource Management In-Reply-To: References: <7108D662C5ED344CBAD8CAFEEC94244115F59488@ohclemsx1023.corp.ntl-city.net> <1A55DAD4-F03E-4E06-8C52-C9939006A70A@zwitserloot.com> <200904140134.22467.peter.levart@gmail.com> Message-ID: On Tue, Apr 14, 2009 at 1:54 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Having said that, there might be a way out of this, by integrating both > proposals. > > 1. Remove the ability to put multiple resources in one statement; what's > the problem with nesting trywith blocks again? > > 2. Use the ; to switch to the alternate form of resource management: try ( > a ; b ) {} no longer requires that is an expression of type 'Disposable' (or > a variable declaration of a Disposable), and instead, b is run at the end > analogous to your proposal. > > Then, for all objects that know how to dispose of themselves, you just go > try ( object ) { stuff }, but when they don't, you can work around it with > try ( object ; closeIt ) { stuff }. That's a great idea. It would encourage people to build APIs around a common interface but still allow using a different style of programming or enable proper resource cleanup even in situations where the shear reference to the resource is not enough to dispose it. What am I talking about? > NOTE: I'm not actually in favour of this, because, at the risk of taking a > contentious position, I don't rate the libraries that can't deal with > Disposable very highly. SWT was absolutely excellent when it was released, > and the java community owes it a great thank you for lighting the fire of > competition under awt/swing's behind, but between new swing versions and > javaFX, SWT's time has gone, eclipse needs to migrate over, and SWT needs to > slowly but surely go away now. Locks are handled just as well, IMO, with the > existing try/finally structure, primarily because lock.unlock() generally > doesn't throw exceptions, which is a big reason for using ARM in the first > place. > > --Reinier Zwitserloot ... I'm thinking of numerous situations where propper clean-up is the responsibility of third party code, not the resource itself. This is usually the case of libraries that are build as a wrapper arround some other lower-level API and expose references to lower-level resources. Take for example Hibernate. There's a snippet of code from an "identity generator" (the resources are not closed optimally here since exceptions thrown in resource cleanup override main exceptions. The reason? Probably laziness): try { PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); try { ResultSet rs = st.executeQuery(); try { rs.next(); return rs.getLong(1); } finally { rs.close(); } } finally { session.getBatcher().closeStatement(st); } } catch (SQLException sqle) { throw JDBCExceptionHelper.convert( session.getFactory().getSQLExceptionConverter(), sqle, "could not execute select statement", sql ); } ... here a special class called Batcher is the manager of the JDBC resource called PreparedStatement. Proper initialization and cleanup is it's responsibillity. You may argue that Hibernate should not "leak" lower-level API through it's own API and should wrap PreparedStatement in it's own class. That is the ideal world. In reality this is often practiced to make code more "economic". Regards, Peter From Ulf.Zibis at gmx.de Wed Apr 15 07:33:04 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Wed, 15 Apr 2009 16:33:04 +0200 Subject: scripts and results (was Helping to find the usefulness of a proposal) In-Reply-To: <60287e9e1530b3e1ae49976316e8dc57.squirrel@wmail.gradsoft.ua> References: <60287e9e1530b3e1ae49976316e8dc57.squirrel@wmail.gradsoft.ua> Message-ID: <49E5F020.7060508@gmx.de> Hi Ruslan, I would like to see the results for "objects and expressions in switch" which includes: - string in switch - instanceof switch I guess a very big chunk of all if-else if-structures would be covered by: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001182.html A n y C A P A C I T Y t o a d d t h i s p a t t e r n t o y o u r s c r i p t ? ? As I argued before, I'm against the current syntax of the "string in switch"-proposal, as it weakens switch..case semantics for identity, and it encumbers later enhancements for the future. See: http://mail.openjdk.java.net/pipermail/coin-dev/2009-April/001328.html. - Ulf Am 07.04.2009 02:33, Ruslan Shevchenko schrieb: > Good day, > > Few days ago Stephan give idea about writing simple script, which > count amount of possible-optimizations of existing code. > > So, I wrote few checks for some of such entries. They count > low bound of number of code patterns, which can be optimized with > some of coin proposal and situated on distinct source lines. > > I'm afraid that information, which come from count of such code patterns > can give incorrect direction: when we have such patterns in code, > it's means that problem is not so big and we can easy live with one. > Big language problems solved (or not) in non-trivial way, when we have no > common (may be ugly) workaround. > For example. in Java we rare will see BigDecimal.add() because it is not > easy to work with BigDecimals, instead people work with double and have > troubles > with floating points rounding issues (see > http://www.ddj.com/java/184405721)). > Yet one example - choosing another language for implementing db-intensive > parts of projects. > > Ok, you warned; data still can be interesting: > > Checked patterns was: > string in switch > instanceof switch > byte literals > multi catch > loop by iterator, with call remove inside loop > > (if you want include other checks, you can add one at > etc/checkers_coin.def or ask me [but without any warranty]) > > > Exists one proposal, which I can't find on Joe blog: is change of variable > subtype inside 'if instance' statement > I. e. patterns look: > if (x instanceof something) > { > something sx = (something)x; > } > And proposal tell type 'x' as 'something' inside dominate if block. > Are anybody remember such proposal or it's was my fantasy ? > > > Some results: > > For jetty6_11: (web server) > byte literal : 52 > elvis : 43 > instanceof switch : 8 > loop with remove : 0 > multi catch : 22 > string in switch : 19 > Files:187 > > For gwt-user (google ajax library) > byte literal : 2 > elvis : 30 > instanceof switch : 6 > loop with remove : 5 > multi catch : 9 > string in switch : 10 > Files:920 > > For openjdk-jdk part: (system library) > byte literal : 1245 > elvis : 725 > instanceof switch : 252 > loop with remove : 61 > multi catch : 349 > string in switch : 380 > Files:7375 > > > > If you want to play with checks - most easy way is get special modified > source > distributive of JavaChecker, which I published as 2.5.0p0 and run it, i.e. > (assuming you on Unix console) > > retrive distributive: > > wget > http://datacenter.gradsoft.ua/public.repository/ua.gradsoft/javachecker/installations/JavaCheckerSourceInstaller-2.5.0p0.jar > > run installer: > java -jar JavaCheckerSourceInstaller-2.5.0p0.jar > (install one from UI) > > cd > > vi build-check-external.xml, look at few last tasks at end > > vi check-external.properties > > add own task and run one, as example: > ant -f build-check-external.xml check-coin-openjdk > > Note, that speed of JavaChecker is far from ideal: openJDK-jdk > processed near 50 minutes, so be patient ;) > > Hope, this information can be useful, as one (and not main) of sources. > > Regards ! > > > > > From paul.martin at gmail.com Wed Apr 15 15:54:04 2009 From: paul.martin at gmail.com (paul.martin at gmail.com) Date: Wed, 15 Apr 2009 22:54:04 +0000 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49E3ECFC.6000002@sun.com> Message-ID: <001485f6307408a1e304679fd349@google.com> (In reply to "On Apr 14, 2009 2:5am, Joe Darcy wrote:") Hi, Some of this discussion is frustrating. I think that to say that "the list received few serious actual proposals" is unfair, at least in terms of the enthusiasm of the discussions, and in terms of the criticism of the proposals themselves. I also don't remember seeing many requests for further detail in discussions about proposals, so it is unfair to criticise their "degree of thoroughness" after the process has closed. Further detail (including prototypes) could always have been provided where necessary, though in most cases I don't think that this was required - the extra detail would be most useful when taking selected proposals further on in the process, but that detail would not necessarily be required when making that selection. Some proposals were effectively repeating RFEs, but without knowing why you didn't include them on your initial candidate list we cannot know whether raising them as proposals is actually justified (maybe you missed an important use case). For example my proposal on named parameters does have a relevant bug: 6444738 (which admittedly I did not mention, though I did reference another), which has an evaluation comment of "We should do this for 7; parameter names are also needed for keyword parameters". Named parameters were even on the slides at a recent (March) Sun Java presentation in London, but they don't now seem to be on the cards for Java 7. My proposal was really to ask why not, but I don't think that question was answered. I am also not suggesting that the selected proposals will not be useful and should not be chosen - they are all good choices (though they mainly ease syntax rather than increasing the capabilities of the language). However, I would like to know why other proposals were not selected, but this only needs to be at a high level. For example, the following categorisation would work for me: 'Good' (the right size, but not as good as the selected proposals), 'out of scope' for Coin (good, but too hard), 'rejected' (we won't ever do this - though a brief reason would help), and 'not understood'. Much of this is probably just miscommunication and misunderstanding: after looking through your posts and presentations in the light of this discussion, I can see that you probably did want fewer and more detailed proposals, but that wasn't clear (to me at least) in your weekly blog posts and comments on the proposals. Hopefully this all makes sense. I really did enjoy the process, and appreciate the effort that you put in to make it happen. But maybe a little 'finessing' of your conclusions would keep me happy! Regards, Paul From reinier at zwitserloot.com Wed Apr 15 17:03:09 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 16 Apr 2009 02:03:09 +0200 Subject: Splitting the meat of a proposal from the trivial details. In-Reply-To: <001485f6307408a1e304679fd349@google.com> References: <001485f6307408a1e304679fd349@google.com> Message-ID: <906692CA-71E0-4869-9591-076C05A15420@zwitserloot.com> Actually, Joe has repeatedly turned down proposals because they were laughably incomplete, and Neal Gafter had gone through the trouble of writing up an example proposal before March 1st that showed most of the concerns that were nonetheless completely skipped in most proposals (such as definitive assignment rules). However - I still mostly agree with your sentiment. The amount of work and detail required before a proposal was considered 'complete' was considerable, and yet the vast majority of proposals (even with the neccessary detail) were clearly going to be rejected (only 4 to 5, tops, that's been said many times). This provides a dilemma: Put in all that effort for not much to show for it? I felt that many (but not all) of the proposals essentially had enough detail in them to allow you to figure out if they were a good idea or not. If there had been another month, such a half-finished proposal could have been pointed out as 'would be on the shortlist, if only someone went through the effort of going through all the details, including writing down something like the definitive assignment rules. I think we'd have seen more useful discussion on proposals, and waste less time on trivialities, if it had been set up like that. For example, I was going to write up my plan to allow named parameters in method signatures, but in the end decided against it, because writing out the full JLS spec including chapter and verse would have been too much effort, compared to the tiny chance it would have been considered worthy for coin. If, however, there was a separate pre- proposal phase, I could have easily written up the gist of the proposal, many examples, and ample support that my proposal would be backwards and migration compatible, would not lead to much confusion, and would not be amiguous. If, then, the proposal would be accepted as 'likely good for java, -if- fully specced and no surprises turn up', I'd gladly have taken the time to write it out in excruciating detail, and cook up a prototype. This Project Coin was pressed for time, so much more than a month just wasn't on the table, but for next time, I suggest smearing out coin across 3 months: Day 1-30: Pre-proposal Month. A Pre-proposal discusses the feature at hand, what it'll solve, ample example code of real-life situations so we can all assess the utility and impact of the change, and much discussion about backwards and migration compatibility, how confusing the feature may be in certain situations (a.k.a. the java puzzler factor), and if the proposal is ambiguous. This is not the time to complain about potential problems and ambiguities for which the complainer-to-be can already think of a fairly simple solution by himself - this is about fundamental issues with a proposal, and the merits of each. Not for sweating the small stuff. The deadline for submitting a pre-proposal is day 20 (to give pre- proposals submitted on the deadline at least 10 days to be discussed). Day 31-37: Rest week. Day 38-45: Pre-proposal sorting. Be it via polling or internal decision by sun or a combination of the two, this is the time to sort pre-proposals into 'no way', and 'on the shortlist'. Day 45-90: Prototype and spec month. This is the time for the shortlisted proposals to be fully specced (with chapter and verse of the JLS as well as rewrites for the JLS), and preferably a working prototype. The deadline for delivering the spec+prototype is day 75, to give the list time to analyse all proposals, even those submitted on the deadline. This IS the time to name rare and easily solved nitpicks, ambiguities, no matter how trivial, and other ommissions. At this point the discussion should turn towards implementation detail, and not so much the merits (all pre-proposals on the shortlist have already been deemed as having the merit to make it, so if you don't like a proposal that's on the shortlist, or you do like one that isn't, tough - the decision has been made, move on). Of course, proposals that end up being more complicated than they appeared to be in the pre-proposal phase can still be discussed on merit (is it STILL worth it, now that we figured out it's going to be this complicated?). I would be tempted to say that ONLY shortlisted pre-proposals should even be considered in this phase, as to keep down unrelated chatter on pet projects. Aftermath: The shortlist is amended: Those on the shortlist that were unsifficiently specced out are tossed, regardless of merit (if it was such a good idea, ostensibly someone would have written it up properly). Those that are fully specced are reconsidered again. Preferably soon after the end of the 3 month period, the semi-official list is released. (semi-official as in: These are the new language features, barring unexpected surprises when we implement these into the JLS and javac). How some of the proposals would have gone, if the above flow had been used for coin: ARM - posted early in the pre-proposal phase, all the discussion we've seen, without the need for Josh to keep updating the proposal in all that detail. Somewhere around today, Josh or someone else coordinating with Josh, starts working on a prototype. 2 months from now, with a complete spec and prototype, ARM is officially accepted into java7 (well, if there hadn't been JSR issues). Neal's expression blocks - little discussion (we haven't seen much in coin either), but nobody can come up with serious issues either, and neal adequatedly shows that the block proposal is unlikely to cause serious issues. For whatever reason (denying pre-proposals should not need a lengthy defense), the pre-proposal is not put on the shortlist, and that's where it ends. --Reinier Zwitserloot On Apr 16, 2009, at 00:54, paul.martin at gmail.com wrote: > (In reply to "On Apr 14, 2009 2:5am, Joe Darcy > wrote:") > > Hi, > > Some of this discussion is frustrating. I think that to say that > "the list > received few serious actual proposals" is unfair, at least in terms > of the > enthusiasm of the discussions, and in terms of the criticism of the > proposals themselves. I also don't remember seeing many requests for > further detail in discussions about proposals, so it is unfair to > criticise > their "degree of thoroughness" after the process has closed. Further > detail > (including prototypes) could always have been provided where > necessary, > though in most cases I don't think that this was required - the extra > detail would be most useful when taking selected proposals further > on in > the process, but that detail would not necessarily be required when > making > that selection. > > Some proposals were effectively repeating RFEs, but without knowing > why you > didn't include them on your initial candidate list we cannot know > whether > raising them as proposals is actually justified (maybe you missed an > important use case). For example my proposal on named parameters > does have > a relevant bug: 6444738 (which admittedly I did not mention, though > I did > reference another), which has an evaluation comment of "We should do > this > for 7; parameter names are also needed for keyword parameters". Named > parameters were even on the slides at a recent (March) Sun Java > presentation in London, but they don't now seem to be on the cards > for Java > 7. My proposal was really to ask why not, but I don't think that > question > was answered. > > I am also not suggesting that the selected proposals will not be > useful and > should not be chosen - they are all good choices (though they mainly > ease > syntax rather than increasing the capabilities of the language). > However, I > would like to know why other proposals were not selected, but this > only > needs to be at a high level. For example, the following categorisation > would work for me: 'Good' (the right size, but not as good as the > selected > proposals), 'out of scope' for Coin (good, but too hard), > 'rejected' (we > won't ever do this - though a brief reason would help), and 'not > understood'. > > Much of this is probably just miscommunication and misunderstanding: > after > looking through your posts and presentations in the light of this > discussion, I can see that you probably did want fewer and more > detailed > proposals, but that wasn't clear (to me at least) in your weekly > blog posts > and comments on the proposals. > > Hopefully this all makes sense. I really did enjoy the process, and > appreciate the effort that you put in to make it happen. But maybe a > little 'finessing' of your conclusions would keep me happy! > > Regards, > > Paul > From neal at gafter.com Wed Apr 15 17:33:55 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 15 Apr 2009 17:33:55 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: <001485f6307408a1e304679fd349@google.com> References: <49E3ECFC.6000002@sun.com> <001485f6307408a1e304679fd349@google.com> Message-ID: <15e8b9d20904151733o32920606ve31c5ade09b6c4fd@mail.gmail.com> On Wed, Apr 15, 2009 at 3:54 PM, wrote: > Some of this discussion is frustrating. I think that to say that "the list > received few serious actual proposals" is unfair, at least in terms of the > enthusiasm of the discussions, and in terms of the criticism of the > proposals themselves. Paul- Specificity is needed to determine if a proposal is simple enough for project Coin. I didn't bother commenting on proposals that had only a hint of a specification. An RFE - requesting that a problem be solved (even if it suggests a direction for the solution) - is far from a proposal for a specific solution. Evaluating an RFE to the needed level of detail would require we not just comment on the problem space, but evaluate the entire solution space and comment on the best of the solutions we can imagine. The proposer was supposed to do that, and describe precisely one selected solution. I know that is a lot of work and may require specialized skills. That is why the readers of a proposal cannot be expected to do it. I didn't bother commenting on some proposals because I just didn't see much benefit compared to the effort. As much fun as it is to discuss language design, this list is not really the best place for that design to take place. If a lot of discussion is needed to move a proposal forward now, that is a sign that the proposal is complex, or imprecise, or immature and likely to require extensive discussion and refinement in the expert group. Any of these suggests that the proposal would probably require more effort than is appropriate for project Coin. Regards, Neal From Joe.Darcy at Sun.COM Wed Apr 15 21:35:24 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 15 Apr 2009 21:35:24 -0700 Subject: Splitting the meat of a proposal from the trivial details. In-Reply-To: <906692CA-71E0-4869-9591-076C05A15420@zwitserloot.com> References: <001485f6307408a1e304679fd349@google.com> <906692CA-71E0-4869-9591-076C05A15420@zwitserloot.com> Message-ID: <49E6B58C.7020107@sun.com> Reinier Zwitserloot wrote: > Actually, Joe has repeatedly turned down proposals because they were > laughably incomplete, Quite so! > and Neal Gafter had gone through the trouble of > writing up an example proposal before March 1st that showed most of > the concerns that were nonetheless completely skipped in most > proposals (such as definitive assignment rules). > Part of my goal of sending in the strings in switch proposal (first post!) was to demonstrate the sort of details that can come up even in the simplest of changes. > However - I still mostly agree with your sentiment. The amount of work > and detail required before a proposal was considered 'complete' was > considerable, and yet the vast majority of proposals (even with the > neccessary detail) were clearly going to be rejected (only 4 to 5, > tops, that's been said many times). > Yes, the limited size of the set of possible proposals was established before the call for proposals started. However, the time required to write up even a fairly detailed proposal, say 8 hours, pales in comparison to the possible effort needed to fully implement a proposal. For example, implementing just the *single method* Class.isEnum probably took around five hours of effort during JDK 5. While this method is only two lines long, three tries were needed before getting the right two lines; more detail on why this happened is described in: http://blogs.sun.com/darcy/entry/so_you_want_to_change > This provides a dilemma: Put in all that effort for not much to show > for it? > As I've stated before, Project Coin is a participatory process, which means people have the opportunity to participate in the work of a proposal too :-) > I felt that many (but not all) of the proposals essentially had enough > detail in them to allow you to figure out if they were a good idea or > not. If there had been another month, such a half-finished proposal > could have been pointed out as 'would be on the shortlist, if only > someone went through the effort of going through all the details, > including writing down something like the definitive assignment rules. > I think we'd have seen more useful discussion on proposals, and waste > less time on trivialities, if it had been set up like that. > While some iteration and refinement of proposals is fine and expected, details are not trivialities. Seemingly small details can make a difference and having some set of details available early allows better decisions to be made. > For example, I was going to write up my plan to allow named parameters > in method signatures, but in the end decided against it, because > writing out the full JLS spec including chapter and verse would have > been too much effort, compared to the tiny chance it would have been > considered worthy for coin. If, however, there was a separate pre- > proposal phase, I could have easily written up the gist of the > proposal, many examples, and ample support that my proposal would be > backwards and migration compatible, would not lead to much confusion, > and would not be amiguous. If, then, the proposal would be accepted as > 'likely good for java, -if- fully specced and no surprises turn up', > I'd gladly have taken the time to write it out in excruciating detail, > and cook up a prototype. > > > This Project Coin was pressed for time, so much more than a month just > wasn't on the table, but for next time, I suggest smearing out coin > across 3 months: > The future existence of what would be known of Project Coin was announced on December 8, 2008 (http://blogs.sun.com/darcy/entry/small_language_changes_jdk_7). This included an overview of the coming call for proposals and a link to "So you want to change the Java Programming Language...", whose content served as the skeleton for the later proposal form. The proposal form was published in January 27, 2009 (http://blogs.sun.com/darcy/entry/project_coin) and the mailing list started a month later, February 27, 2009. So there was a three month period before the call for proposals officially got underway, and a month after the form was published but before a proposal could be submitted, where interested parties could think about proposal ideas and possibly implement them, guided by the published criteria for the effort. There were a few inquiries to the list to ask for help drafting a proposal and some "pre-proposals" sent in to get a reading on whether a proposal topic would be smiled upon, both of which are good, on-topic uses of the list! However, after my unfavorable assessment of the "Source and Encoding keyword" pre-proposal (http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000298.html) was sent to the list, people choose to continue the discussion for a time. Some continued discussion is fine, but people who send in proposals or pre-proposals don't to tend to give up right away ;-) To reiterate terms of roles and responsibilities here, "Especially with the maturity of the Java platform, the onus is on the proposer to convince that a language change should go in; the onus is not to prove the change should stay out." http://blogs.sun.com/darcy/entry/criteria_for_desirable_small_language December 23, 2008 Having thought through the details is one way to be more convincing. -Joe From Joe.Darcy at Sun.COM Wed Apr 15 23:00:23 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 15 Apr 2009 23:00:23 -0700 Subject: Helping to find the usefulness of a proposal In-Reply-To: <15e8b9d20904151733o32920606ve31c5ade09b6c4fd@mail.gmail.com> References: <49E3ECFC.6000002@sun.com> <001485f6307408a1e304679fd349@google.com> <15e8b9d20904151733o32920606ve31c5ade09b6c4fd@mail.gmail.com> Message-ID: <49E6C977.5080702@sun.com> Neal Gafter wrote: > On Wed, Apr 15, 2009 at 3:54 PM, wrote: > >> Some of this discussion is frustrating. I think that to say that "the list >> received few serious actual proposals" is unfair, at least in terms of the >> enthusiasm of the discussions, and in terms of the criticism of the >> proposals themselves. >> > > Paul- > > Specificity is needed to determine if a proposal is simple enough for > project Coin. I didn't bother commenting on proposals that had only a > hint of a specification. An RFE - requesting that a problem be solved > (even if it suggests a direction for the solution) - is far from a > proposal for a specific solution. Evaluating an RFE to the needed > level of detail would require we not just comment on the problem > space, but evaluate the entire solution space and comment on the best > of the solutions we can imagine. The proposer was supposed to do > that, and describe precisely one selected solution. I know that is a > lot of work and may require specialized skills. That is why the > readers of a proposal cannot be expected to do it. > Moreover, the set of people currently with these skills is small and it would be helpful if this set grew in size. The Project Coin proposal form and other material was intended to give guidance on all that can be required as part of the task of growing the Java language so that more people can participate now and going forward. Discussions on the list provide a public, archived record of the proposals, their analysis, and decision making to better inform current and future discussions. Certainly merely sending an incomplete proposal to the list should in no way be expected to oblige others to undertake the hard task of analyzing and completing the work! -Joe From Ruslan at Shevchenko.Kiev.UA Wed Apr 15 23:27:08 2009 From: Ruslan at Shevchenko.Kiev.UA (Ruslan Shevchenko) Date: Thu, 16 Apr 2009 09:27:08 +0300 (EEST) Subject: scripts and results (was Helping to find the usefulness of a proposal) In-Reply-To: <49E5F020.7060508@gmx.de> References: <60287e9e1530b3e1ae49976316e8dc57.squirrel@wmail.gradsoft.ua> <49E5F020.7060508@gmx.de> Message-ID: <114ad93adfd2eb30f7ecd1388b69b1be.squirrel@wmail.gradsoft.ua> > Hi Ruslan, > > I would like to see the results for > > "objects and expressions in switch" > > which includes: > - string in switch > - instanceof switch > > I guess a very big chunk of all if-else if-structures would be covered by: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001182.html > Ok, I will alloc some time during next week-end for more patterns and statistics and will try include this one. This will some 'near' refinemed of proposal, becouse original proposal does not define what is 'leftPart' and 'rightPart' of Java expression in formal way [this is not so trivial, as expected. For example what left part will be in function expressions: 'this' or nothing ?. How we split chained expressions on left and right ?] For this reasons, I guess probability that this proposal will seen seriously is very low. (Second change which I plan: add statistics about relative number of chainged construction/number of all such constructions). > A n y C A P A C I T Y t o a d d t h i s p a t t e r n t o y > o u r s c r i p t ? ? > > As I argued before, I'm against the current syntax of the "string in > switch"-proposal, as it weakens switch..case semantics for identity, and > it encumbers later enhancements for the future. See: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-April/001328.html. > > - Ulf > > > > Am 07.04.2009 02:33, Ruslan Shevchenko schrieb: >> Good day, >> >> Few days ago Stephan give idea about writing simple script, which >> count amount of possible-optimizations of existing code. >> >> So, I wrote few checks for some of such entries. They count >> low bound of number of code patterns, which can be optimized with >> some of coin proposal and situated on distinct source lines. >> >> I'm afraid that information, which come from count of such code patterns >> can give incorrect direction: when we have such patterns in code, >> it's means that problem is not so big and we can easy live with one. >> Big language problems solved (or not) in non-trivial way, when we have >> no >> common (may be ugly) workaround. >> For example. in Java we rare will see BigDecimal.add() because it is >> not >> easy to work with BigDecimals, instead people work with double and have >> troubles >> with floating points rounding issues (see >> http://www.ddj.com/java/184405721)). >> Yet one example - choosing another language for implementing >> db-intensive >> parts of projects. >> >> Ok, you warned; data still can be interesting: >> >> Checked patterns was: >> string in switch >> instanceof switch >> byte literals >> multi catch >> loop by iterator, with call remove inside loop >> >> (if you want include other checks, you can add one at >> etc/checkers_coin.def or ask me [but without any warranty]) >> >> >> Exists one proposal, which I can't find on Joe blog: is change of >> variable >> subtype inside 'if instance' statement >> I. e. patterns look: >> if (x instanceof something) >> { >> something sx = (something)x; >> } >> And proposal tell type 'x' as 'something' inside dominate if block. >> Are anybody remember such proposal or it's was my fantasy ? >> >> >> Some results: >> >> For jetty6_11: (web server) >> byte literal : 52 >> elvis : 43 >> instanceof switch : 8 >> loop with remove : 0 >> multi catch : 22 >> string in switch : 19 >> Files:187 >> >> For gwt-user (google ajax library) >> byte literal : 2 >> elvis : 30 >> instanceof switch : 6 >> loop with remove : 5 >> multi catch : 9 >> string in switch : 10 >> Files:920 >> >> For openjdk-jdk part: (system library) >> byte literal : 1245 >> elvis : 725 >> instanceof switch : 252 >> loop with remove : 61 >> multi catch : 349 >> string in switch : 380 >> Files:7375 >> >> >> >> If you want to play with checks - most easy way is get special modified >> source >> distributive of JavaChecker, which I published as 2.5.0p0 and run it, >> i.e. >> (assuming you on Unix console) >> >> retrive distributive: >> >> wget >> http://datacenter.gradsoft.ua/public.repository/ua.gradsoft/javachecker/installations/JavaCheckerSourceInstaller-2.5.0p0.jar >> >> run installer: >> java -jar JavaCheckerSourceInstaller-2.5.0p0.jar >> (install one from UI) >> >> cd >> >> vi build-check-external.xml, look at few last tasks at end >> >> vi check-external.properties >> >> add own task and run one, as example: >> ant -f build-check-external.xml check-coin-openjdk >> >> Note, that speed of JavaChecker is far from ideal: openJDK-jdk >> processed near 50 minutes, so be patient ;) >> >> Hope, this information can be useful, as one (and not main) of sources. >> >> Regards ! >> >> >> >> >> > > From markmahieu at googlemail.com Wed Apr 15 23:40:43 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 16 Apr 2009 07:40:43 +0100 Subject: Some notes on Elvis and Other Null-Safe Operators In-Reply-To: <171AADE5-112F-43EB-AEED-4E502EE0914E@googlemail.com> References: <171AADE5-112F-43EB-AEED-4E502EE0914E@googlemail.com> Message-ID: <6BDB603A-7DCB-4621-9691-E31566265C32@googlemail.com> One more thought regarding Elvis and friends. In the code-base I'm currently working on, I keep seeing code like the following: Map> map = ... if (map != null) { Set fooSet = map.get(key); if (fooSet != null) { for (Foo foo : fooSet) { ... } } } which can be 'simplified' in a number of ways, for example with the liberal sprinkling of a couple of null-transforming methods: Set fooSet = emptyIfNull(map).get(key); for (Foo foo : emptyIfNull(fooSet)) { ... } Alternatively, with Elvis etc it could be written like this: for (Foo foo : map?.get(key) ?: Collections.emptySet()) { ... } Which doesn't seem like much of an improvement, to me. But I keep thinking that, in the context of this proposal, a null-safe form of the foreach loop might not be so bad: for (Foo foo :? map?.get(key)) { ... } I seem to recall that kind of example being talked about fairly extensively during JSR-201, but I think the discussion then was around whether foreach should be 'null-safe' by default. Perhaps it's an example of trying to fit the proposal to the use-case, though. Mark From paul.martin at gmail.com Thu Apr 16 01:35:20 2009 From: paul.martin at gmail.com (Paul Martin) Date: Thu, 16 Apr 2009 09:35:20 +0100 Subject: Helping to find the usefulness of a proposal In-Reply-To: <49E6C977.5080702@sun.com> References: <49E3ECFC.6000002@sun.com> <001485f6307408a1e304679fd349@google.com> <15e8b9d20904151733o32920606ve31c5ade09b6c4fd@mail.gmail.com> <49E6C977.5080702@sun.com> Message-ID: <4ce75f920904160135m66750f12ja9e85c134082c554@mail.gmail.com> Hi, Joe, Neal, and Reinier - many thanks for your replies. I think that I do understand the process much better now, and appreciate its goals. I had actually considered just asking the question about named parameters and/or just submitting a pre-proposal, which in hindsight would probably have been more useful (maybe I'll update the existing related bugs if necessary). In particular, I hadn't really considered the following idea, but can see that it is a valuable result of the process: > ... Discussions on the list provide a > public, archived record of the proposals, their analysis, and decision > making to better inform current and future discussions. Being able to see why changes were made and what was considered is definitely a good thing. Once again, thanks for your replies. Regards, Paul From brucechapman at paradise.net.nz Thu Apr 16 03:12:21 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Thu, 16 Apr 2009 22:12:21 +1200 Subject: PROPOSAL: Underscores in numbers In-Reply-To: <11482659.1238468832504.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <11482659.1238468832504.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <49E70485.5050100@paradise.net.nz> I am just doing some work (in kijaro) building prototype compiler for my integer literal proposals, and this proposal, and during testing found a wee bug in this spec. > long alsoMaxLong = 9_223_372_036_854_775_808L; that particular literal is only valid as the right hand side of a unary minus. The last digit should be changed to a '7'. Will post a link to the prototype in the next few days now that I have everything working. I still need to create something that is relatively easy to download and deploy. Bruce From reinier at zwitserloot.com Thu Apr 16 03:51:28 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 16 Apr 2009 12:51:28 +0200 Subject: Splitting the meat of a proposal from the trivial details. In-Reply-To: <49E6B58C.7020107@sun.com> References: <001485f6307408a1e304679fd349@google.com> <906692CA-71E0-4869-9591-076C05A15420@zwitserloot.com> <49E6B58C.7020107@sun.com> Message-ID: <059B6404-A031-4340-ADC8-92BDBFDB2719@zwitserloot.com> If Coin did effectively take 3 months, that's all the more reason to open up coin-dev for the complete 3 month timespan! By restricting discussion to the shortlist after a month and a week, a lot of interesting but not relevant chatter about proposals that definitely won't make the grade anyway can be weeded out. At times I felt the coin discussion turned needlessly specific for early stage proposals, and yet for other proposals, the idle banter on vague proposals was distracting from finalizing the details on something like ARM. --Reinier Zwitserloot On Apr 16, 2009, at 06:35, Joseph D. Darcy wrote: > Reinier Zwitserloot wrote: >> Actually, Joe has repeatedly turned down proposals because they >> were laughably incomplete, > > Quite so! > >> and Neal Gafter had gone through the trouble of writing up an >> example proposal before March 1st that showed most of the concerns >> that were nonetheless completely skipped in most proposals (such >> as definitive assignment rules). >> > > Part of my goal of sending in the strings in switch proposal (first > post!) was to demonstrate the sort of details that can come up even > in the simplest of changes. > >> However - I still mostly agree with your sentiment. The amount of >> work and detail required before a proposal was considered >> 'complete' was considerable, and yet the vast majority of >> proposals (even with the neccessary detail) were clearly going to >> be rejected (only 4 to 5, tops, that's been said many times). >> > > Yes, the limited size of the set of possible proposals was > established before the call for proposals started. > > However, the time required to write up even a fairly detailed > proposal, say 8 hours, pales in comparison to the possible effort > needed to fully implement a proposal. > > For example, implementing just the *single method* Class.isEnum > probably took around five hours of effort during JDK 5. While this > method is only two lines long, three tries were needed before > getting the right two lines; more detail on why this happened is > described in: > http://blogs.sun.com/darcy/entry/so_you_want_to_change > >> This provides a dilemma: Put in all that effort for not much to >> show for it? >> > > As I've stated before, Project Coin is a participatory process, > which means people have the opportunity to participate in the work > of a proposal too :-) > >> I felt that many (but not all) of the proposals essentially had >> enough detail in them to allow you to figure out if they were a >> good idea or not. If there had been another month, such a half- >> finished proposal could have been pointed out as 'would be on the >> shortlist, if only someone went through the effort of going >> through all the details, including writing down something like the >> definitive assignment rules. I think we'd have seen more useful >> discussion on proposals, and waste less time on trivialities, if >> it had been set up like that. >> > > While some iteration and refinement of proposals is fine and > expected, details are not trivialities. Seemingly small details can > make a difference and having some set of details available early > allows better decisions to be made. > >> For example, I was going to write up my plan to allow named >> parameters in method signatures, but in the end decided against >> it, because writing out the full JLS spec including chapter and >> verse would have been too much effort, compared to the tiny chance >> it would have been considered worthy for coin. If, however, there >> was a separate pre- proposal phase, I could have easily written up >> the gist of the proposal, many examples, and ample support that my >> proposal would be backwards and migration compatible, would not >> lead to much confusion, and would not be amiguous. If, then, the >> proposal would be accepted as 'likely good for java, -if- fully >> specced and no surprises turn up', I'd gladly have taken the time >> to write it out in excruciating detail, and cook up a prototype. >> >> >> This Project Coin was pressed for time, so much more than a month >> just wasn't on the table, but for next time, I suggest smearing >> out coin across 3 months: >> > > The future existence of what would be known of Project Coin was > announced on December 8, 2008 (http://blogs.sun.com/darcy/entry/small_language_changes_jdk_7 > ). This included an overview of the coming call for proposals and a > link to "So you want to change the Java Programming Language...", > whose content served as the skeleton for the later proposal form. > The proposal form was published in January 27, 2009 (http://blogs.sun.com/darcy/entry/project_coin > ) and the mailing list started a month later, February 27, 2009. > > So there was a three month period before the call for proposals > officially got underway, and a month after the form was published > but before a proposal could be submitted, where interested parties > could think about proposal ideas and possibly implement them, guided > by the published criteria for the effort. > > There were a few inquiries to the list to ask for help drafting a > proposal and some "pre-proposals" sent in to get a reading on > whether a proposal topic would be smiled upon, both of which are > good, on-topic uses of the list! However, after my unfavorable > assessment of the "Source and Encoding keyword" pre-proposal (http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000298.html > ) was sent to the list, people choose to continue the discussion for > a time. Some continued discussion is fine, but people who send in > proposals or pre-proposals don't to tend to give up right away ;-) > To reiterate terms of roles and responsibilities here, > > "Especially with the maturity of the Java platform, the onus is on > the proposer to convince that a language change should go in; the > onus is not to prove the change should stay out." > http://blogs.sun.com/darcy/entry/criteria_for_desirable_small_language > December 23, 2008 > > Having thought through the details is one way to be more convincing. > > -Joe > From scolebourne at joda.org Sat Apr 18 03:33:31 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 18 Apr 2009 11:33:31 +0100 Subject: Some notes on Elvis and Other Null-Safe Operators In-Reply-To: <6BDB603A-7DCB-4621-9691-E31566265C32@googlemail.com> References: <171AADE5-112F-43EB-AEED-4E502EE0914E@googlemail.com> <6BDB603A-7DCB-4621-9691-E31566265C32@googlemail.com> Message-ID: <49E9AC7B.3010509@joda.org> Mark Mahieu wrote: > Which doesn't seem like much of an improvement, to me. But I keep > thinking that, in the context of this proposal, a null-safe form of > the foreach loop might not be so bad: > > for (Foo foo :? map?.get(key)) { > ... > } I certainly think thats an interesting idea. However, having a null list is something that rarely comes up in the code I write. I think thats because I always return an empty list from methods and never null (something that is definitely good practice). Where the null-safe operators come in is in handling object model structure such as a bean holding an optional value (String/Integer/Date etcc), or a bean holding another optional bean (person holding optional spouse). In these cases, holding null to represent the absence of data is a valid design choice. Stephen From markmahieu at googlemail.com Sat Apr 18 12:17:07 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 18 Apr 2009 20:17:07 +0100 Subject: Some notes on Elvis and Other Null-Safe Operators In-Reply-To: <49E9AC7B.3010509@joda.org> References: <171AADE5-112F-43EB-AEED-4E502EE0914E@googlemail.com> <6BDB603A-7DCB-4621-9691-E31566265C32@googlemail.com> <49E9AC7B.3010509@joda.org> Message-ID: <7ED41D61-84A5-4149-82F1-D39333038C21@googlemail.com> On 18 Apr 2009, at 11:33, Stephen Colebourne wrote: > Mark Mahieu wrote: >> Which doesn't seem like much of an improvement, to me. But I keep >> thinking that, in the context of this proposal, a null-safe form of >> the foreach loop might not be so bad: >> >> for (Foo foo :? map?.get(key)) { >> ... >> } > > I certainly think thats an interesting idea. > > However, having a null list is something that rarely comes up in the > code I write. I think thats because I always return an empty list from > methods and never null (something that is definitely good practice). Yes, if I were writing the code I mentioned I would also consider using different data structures entirely, such as: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/ common/collect/Multimap.html That's not always an option though. It would certainly be a fairly substantial change in my example. Mark From bugeaud at gmail.com Sat Apr 18 15:15:42 2009 From: bugeaud at gmail.com (Jean-Baptiste Bugeaud) Date: Sun, 19 Apr 2009 00:15:42 +0200 Subject: SUBMISSION : A second look on "named parameters" Message-ID: <2dc3bd00904181515o2df0a1d3n3cf5ddd75d58d4ff@mail.gmail.com> Hi everybody, Here is an late submission, sorry I missed the initial deadline. If you think (as I do) that this is a key small change for lots of improvement, maybe there is still a very small gap to go for JDK7;-) A proposition including the same goal was introduced in JDK6 JSR but withdawn in final version. So legacy impact, issues ... should be already well known by the JDK core team. This second look has tried to solve all the problems. Let's go .... Author(s): Jean-Baptiste BUGEAUD, Paris, France OVERVIEW : FEATURE SUMMARY : Introduce named parameter on methods into the language MAJOR ADVANTAGE : Integration with the legacy, fully backward compatible. Clear paradigm separation. MAJOR BENEFIT : Consistent way of naming the parameter help to unify existing APIs, remove boiler plate core thus simplify object marshaling and reflection usage (WS, JMX, EJB ...). MAJOR DISADVANTAGE : Semantic of static keyword on parameter might not be clear for beginers ALTERNATIVES : Usage of existing bytecode handling lib can expose the parameter names already, but this leads to dependency [5][6] and potential security issues. Usage of APT[7] to store parameter names constraint to a prequirement : apply it to all the code you target. This is unlikely to happen for JARS you have not created, thus reducing the potential benefits. EXAMPLE SIMPLE EXAMPLE : (1a) : class OrderManager{ public void order(String product, int amount){ // do the login } } (1b) class OrderManager{ public void order(static String product, static int amount){ // do the login } } (2a) void displayOrderCriteria(){ Method[] methods = OrderManager.class.getMedthods(); for (Method m : methods){ System.out.println("To call :"+m); for(String n : m.getParameterNames[]){ System.out.println("\tYou must provide :"+n); } } } (2b) void displayOrderCriteria(){ Method[] methods = OrderManager.class.getMedthods(); for (Method m : methods){ System.out.println("To call :"+m); for(String n : m.getStaticParameterNames[]){ System.out.println("\tYou must provide :"+n); } } } ADVANCED EXAMPLE : (3.1) package java.lang.annotation @Documented @Retention(value = RetentionPolicy.SOURCE) @Target( { ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface StaticParameterNames { }; (3.2) @Retention(value = RetentionPolicy.RUNTIME) @Target( { ElementType.METHOD }) @Inside(WebService.class) @ValidWebOperation @StaticParameterNames public @interface WebMethod { String operationName() default ""; String action() default ""; }; (3.3) @WebService class LoginManager{ @WebMethod public void doLogin(String user, char[] password){ // simply log the user } } DETAILS SPECIFICATION : Historicaly, method's parameter names can be stored in the Java bytecode using appropriate compiler switch [2]. Although, no standard API is available to benefit from them they aready. But when compiler optimisation is set or an obfuscater is enabled, then are no more available. This is not reliable. Such inconsistency, along with some other problems, have prevented the inclusion for JDK6 of previous proposition [3][4]. This proposition of small language change, introduce named parameter on methods into the language thru the add of a new language paradigm : static named parameter. At source level, this new kind of parameter is simply a regular parameter with the modifier static set on it. As a summary, we will get two kind of parameters in the language : - regular named parameter (see method on (1a)) : the legacy, we "keep the good-old way", parameter might be stored in bytecode depending on compiler option, no change on language/semantic/compilation - static named parameter (see method on (1b)) : a regular named parameter with a static modifier added, whatever happens (compiler option, obfuscator, etc) parameter name will always be kept at bytecode level. At Java API level, on java.lang.reflec.Method, two new method will help API implementer to leverage both kind of parameters. - String[] getParameterNames() - String[] getParameterStaticNames() IDE would be most interrested into calling the first one. But API implementer (such as JAXWS for instance) requiring a consistent behavior could rely on the second. But they could downgrade on the first one for legacy JAR if they wish so. Introduction of an annotation StaticParameterNames could also be leverage by API implementer to include automatic parameter name storage. This one alone will ease lots of library code. For instance, in JAXWS (see example 3.3), WebParam are now optional to get a web service working : WebMethod would be enough as long as JAXWS implementer apply StaticParameterNames on the WebMethod annotation (see example 3.2). COMPILATION : Static named parameters are compiled the same way of regular named ones but with addition of the static modifier set on the reference at the bytecode level and the parameter name parameter kept in the table. No compiler/optimizer/obfuscator should remove/change the parameter names at bytecode level on a static named parameter. Thus, at a higher level, although not taking part of the method signature (and call resolution), the static named parameter could now be seen as part of the method contract: changing a static named parameter's name could have the same impact as renaming a method. This is the developper resposability to analyze impact of such a change. If a method is tagged with the annotation (or an inherited annotation) StaticParameterNames, all its method parameter should be compiled as if they were static named parameters. TESTING : Compile test classes (such as examples 1a & 1b) using compiler with the feature enable with and without optimization enable (the one that remove the parameter names on regular named parameters). For each scenario (with & without optimization) : Call the reflection API for listing regular named parameters, and check according to the names that should be returned as per the test class. Call the reflection API for listing static named parameters, and check according to the names that should be returned as per the test class. LIBRARY SUPPORT : Two methods must be added to java.lang.relfect.Method : String[] getParameterNames() List the parameter names as existing in the bytecode. No guaranty of reliability is made : can be renamed, removed, added, ... Array is of the same size of getParameterTypes(), for a given index, if the corresponding name is not found a null value is returned. String[] getParameterStaticNames() List the static parameter names as existing in the bytecode. Those named are reliable. Any change impact the contract. Array is of the same size of getParameterTypes(), for a given index, if the corresponding parameter is not tagged with static modifier, a null value is returned. StaticParameterNames (see example 3.1) annotation must be introduced to indicate to the compiler all parameters of a tagged method are meant to be static nammed parameters although not tagged with the static modifier. This anotation can tag other annotation. OTHER CHANGES: Any existing API willing to benefit from this feature, could inherit from StaticParameterNames but this is out of scope of this proposal. COMPATIBILITY MIGRATION : Manual migration is done adding static modifier on parameters. Automatic migration could be done by APIs leader using the StaticParameterNames annotation, thus all the existing code base would be migrated at the next build automatically. COMPATIBILITY : BREAKING CHANGES: no, this is the reason of using static modifier. EXISTING PROGRAMS: code using legacy class can benefit from the getParameterNames(). But getParameterStaticNames() will always return an array of null values. REFERENCES EXISTING BUGS http://bugs.sun.com/view_bug.do?bug_id=6444738 URL FOR PROTOTYPE None at this time. Early feasibility check in the native VM coden plus pure Java code is feasible [5]. [1] http://paulhammant.com/blog/parameter-names-for-java6-question.html [2] http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javac.html [3] http://weblogs.java.net/blog/mreinhold/archive/2005/12/mustang_release.html [4] http://blogs.sun.com/mr/entry/java_se_6_public_review [5] http://paranamer.codehaus.org/ [6] http://www.jroller.com/eu/entry/using_asm_to_read_mathod [7] http://weblogs.java.net/blog/emcmanus/archive/2006/06/using_annotatio.html From reinier at zwitserloot.com Sat Apr 18 17:14:16 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 19 Apr 2009 02:14:16 +0200 Subject: SUBMISSION : A second look on "named parameters" In-Reply-To: <2dc3bd00904181515o2df0a1d3n3cf5ddd75d58d4ff@mail.gmail.com> References: <2dc3bd00904181515o2df0a1d3n3cf5ddd75d58d4ff@mail.gmail.com> Message-ID: <79191A56-6622-4AFE-A999-02280E1A9CD0@zwitserloot.com> Your proposal is very incomplete. Three major nits: A. Did I miss something, or did you totally forget to include an example of calling a method with named parameters? Something like: doLogin(user: "foobar", password: new char[] { 'a', 'b', 'c' }); B. Why static? You might as well have picked 'strictfp' - it's a total non-sequitur choice. Re-use of existing keywords is not really a panacea; it waters down the anchoring ability of a keyword to virtually nothing. I'm not sure if context-sensitive keywords are any better, but java7 is already going to have at least one ('module'), so don't beat around the bush and just call it 'named'). Could be just me, but introducing a change which is not backwards compatible IF you have a type that's called 'named' (written just like that, all-lower case), is not something I find troublesome in the least. That's very ugly code, and a migration tool can fix this easily. C. You don't mention having default values for parameters, which is sort of the point of this exercise (otherwise you really still need builders ; any method that has so many parameters that they need names probably needs a builder, and without defaults, not providing one and instead relying on named params is just an inferior bandaid to your ugly API; to get it right you STILL need to provide a builder. If, however, parameters can have defaults, then you no longer need to make builders at all). I suggest you look over the coin-dev mailing list; I entered a rough sketch of a named parameters proposal near the end of coin. I never wrote it up because I thought of it far too close to the deadline, and it's still of such high impact that I doubt it would pass muster for coin. --Reinier Zwitserloot On Apr 19, 2009, at 00:15, Jean-Baptiste Bugeaud wrote: > Hi everybody, > > Here is an late submission, sorry I missed the initial deadline. If > you think (as I do) that this is a key small change for lots of > improvement, maybe there is still a very small gap to go for JDK7;-) > > A proposition including the same goal was introduced in JDK6 JSR but > withdawn in final version. So legacy impact, issues ... should be > already well known by the JDK core team. This second look has tried to > solve all the problems. > > Let's go .... > > Author(s): Jean-Baptiste BUGEAUD, Paris, France > > OVERVIEW : > FEATURE SUMMARY : Introduce named parameter on methods into the > language > MAJOR ADVANTAGE : Integration with the legacy, fully backward > compatible. Clear paradigm separation. > MAJOR BENEFIT : Consistent way of naming the parameter help to unify > existing APIs, remove boiler plate core thus simplify object > marshaling and reflection usage (WS, JMX, EJB ...). > MAJOR DISADVANTAGE : Semantic of static keyword on parameter might > not be clear for beginers > ALTERNATIVES : Usage of existing bytecode handling lib can expose > the parameter names already, but this leads to dependency [5][6] and > potential security issues. Usage of APT[7] to store parameter names > constraint to a prequirement : apply it to all the code you target. > This is unlikely to happen for JARS you have not created, thus > reducing the potential benefits. > > EXAMPLE > > SIMPLE EXAMPLE : > > (1a) : > > class OrderManager{ > public void order(String product, int amount){ > // do the login > } > } > > (1b) > > class OrderManager{ > public void order(static String product, static int amount){ > // do the login > } > } > > (2a) > void displayOrderCriteria(){ > Method[] methods = OrderManager.class.getMedthods(); > for (Method m : methods){ > System.out.println("To call :"+m); > for(String n : m.getParameterNames[]){ > System.out.println("\tYou must provide :"+n); > } > } > } > > (2b) > void displayOrderCriteria(){ > Method[] methods = OrderManager.class.getMedthods(); > for (Method m : methods){ > System.out.println("To call :"+m); > for(String n : m.getStaticParameterNames[]){ > System.out.println("\tYou must provide :"+n); > } > } > } > > ADVANCED EXAMPLE : > > (3.1) > package java.lang.annotation > > @Documented > @Retention(value = RetentionPolicy.SOURCE) > @Target( { ElementType.METHOD, ElementType.ANNOTATION_TYPE }) > public @interface StaticParameterNames { > }; > > (3.2) > > @Retention(value = RetentionPolicy.RUNTIME) > @Target( { ElementType.METHOD }) > @Inside(WebService.class) > @ValidWebOperation > @StaticParameterNames > public @interface WebMethod { > String operationName() default ""; > String action() default ""; > }; > > > (3.3) > > @WebService > class LoginManager{ > @WebMethod public void doLogin(String user, char[] password){ > // simply log the user > } > } > > DETAILS > > SPECIFICATION : > > Historicaly, method's parameter names can be stored in the Java > bytecode using appropriate compiler switch [2]. Although, no standard > API is available to benefit from them they aready. But when compiler > optimisation is set or an obfuscater is enabled, then are no more > available. This is not reliable. > > Such inconsistency, along with some other problems, have prevented the > inclusion for JDK6 of previous proposition [3][4]. > > This proposition of small language change, introduce named parameter > on methods into the language thru the add of a new language paradigm : > static named parameter. At source level, this new kind of parameter is > simply a regular parameter with the modifier static set on it. > > As a summary, we will get two kind of parameters in the language : > - regular named parameter (see method on (1a)) : the legacy, we "keep > the good-old way", parameter might be stored in bytecode depending on > compiler option, no change on language/semantic/compilation > - static named parameter (see method on (1b)) : a regular named > parameter with a static modifier added, whatever happens (compiler > option, obfuscator, etc) parameter name will always be kept at > bytecode level. > > At Java API level, on java.lang.reflec.Method, two new method will > help API implementer to leverage both kind of parameters. > - String[] getParameterNames() > - String[] getParameterStaticNames() > > IDE would be most interrested into calling the first one. But API > implementer (such as JAXWS for instance) requiring a consistent > behavior could rely on the second. But they could downgrade on the > first one for legacy JAR if they wish so. > > Introduction of an annotation StaticParameterNames could also be > leverage by API implementer to include automatic parameter name > storage. This one alone will ease lots of library code. For instance, > in JAXWS (see example 3.3), WebParam are now optional to get a web > service working : WebMethod would be enough as long as JAXWS > implementer apply StaticParameterNames on the WebMethod annotation > (see example 3.2). > > COMPILATION : > > Static named parameters are compiled the same way of regular named > ones but with addition of the static modifier set on the reference at > the bytecode level and the parameter name parameter kept in the table. > No compiler/optimizer/obfuscator should remove/change the parameter > names at bytecode level on a static named parameter. > > Thus, at a higher level, although not taking part of the method > signature (and call resolution), the static named parameter could now > be seen as part of the method contract: changing a static named > parameter's name could have the same impact as renaming a method. This > is the developper resposability to analyze impact of such a change. > > If a method is tagged with the annotation (or an inherited annotation) > StaticParameterNames, all its method parameter should be compiled as > if they were static named parameters. > > TESTING : > > Compile test classes (such as examples 1a & 1b) using compiler with > the feature enable with and without optimization enable (the one that > remove the parameter names on regular named parameters). > > For each scenario (with & without optimization) : > Call the reflection API for listing regular named parameters, and > check according to the names that should be returned as per the test > class. > Call the reflection API for listing static named parameters, and check > according to the names that should be returned as per the test class. > > LIBRARY SUPPORT : > > Two methods must be added to java.lang.relfect.Method : > > String[] getParameterNames() > > List the parameter names as existing in the bytecode. No guaranty of > reliability is made : can be renamed, removed, added, ... > Array is of the same size of getParameterTypes(), for a given index, > if the corresponding name is not found a null value is returned. > > String[] getParameterStaticNames() > > List the static parameter names as existing in the bytecode. Those > named are reliable. Any change impact the contract. > Array is of the same size of getParameterTypes(), for a given index, > if the corresponding parameter is not tagged with static modifier, a > null value is returned. > > > StaticParameterNames (see example 3.1) annotation must be introduced > to indicate to the compiler all parameters of a tagged method are > meant to be static nammed parameters although not tagged with the > static modifier. This anotation can tag other annotation. > > > OTHER CHANGES: > > Any existing API willing to benefit from this feature, could inherit > from StaticParameterNames but this is out of scope of this proposal. > > COMPATIBILITY > > MIGRATION : > Manual migration is done adding static modifier on parameters. > Automatic migration could be done by APIs leader using the > StaticParameterNames annotation, thus all the existing code base would > be migrated at the next build automatically. > > > COMPATIBILITY : > > BREAKING CHANGES: no, this is the reason of using static modifier. > EXISTING PROGRAMS: code using legacy class can benefit from the > getParameterNames(). But getParameterStaticNames() will always return > an array of null values. > > > REFERENCES > > EXISTING BUGS > > http://bugs.sun.com/view_bug.do?bug_id=6444738 > > URL FOR PROTOTYPE > > None at this time. Early feasibility check in the native VM coden plus > pure Java code is feasible [5]. > > > [1] http://paulhammant.com/blog/parameter-names-for-java6- > question.html > [2] http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javac.html > [3] http://weblogs.java.net/blog/mreinhold/archive/2005/12/mustang_release.html > [4] http://blogs.sun.com/mr/entry/java_se_6_public_review > [5] http://paranamer.codehaus.org/ > [6] http://www.jroller.com/eu/entry/using_asm_to_read_mathod > [7] http://weblogs.java.net/blog/emcmanus/archive/2006/06/using_annotatio.html > From Joe.Darcy at Sun.COM Sat Apr 18 17:20:41 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 18 Apr 2009 17:20:41 -0700 Subject: SUBMISSION : A second look on "named parameters" In-Reply-To: <2dc3bd00904181515o2df0a1d3n3cf5ddd75d58d4ff@mail.gmail.com> References: <2dc3bd00904181515o2df0a1d3n3cf5ddd75d58d4ff@mail.gmail.com> Message-ID: <49EA6E59.3080700@sun.com> Yes, we are well aware of the desire for named parameters from some quarters and the list received some related proposals. This late submission will not be considered. Regards, -Joe Jean-Baptiste Bugeaud wrote: > Hi everybody, > > Here is an late submission, sorry I missed the initial deadline. If > you think (as I do) that this is a key small change for lots of > improvement, maybe there is still a very small gap to go for JDK7;-) > > A proposition including the same goal was introduced in JDK6 JSR but > withdawn in final version. So legacy impact, issues ... should be > already well known by the JDK core team. This second look has tried to > solve all the problems. > > Let's go .... > > Author(s): Jean-Baptiste BUGEAUD, Paris, France > > OVERVIEW : > FEATURE SUMMARY : Introduce named parameter on methods into the language > MAJOR ADVANTAGE : Integration with the legacy, fully backward > compatible. Clear paradigm separation. > MAJOR BENEFIT : Consistent way of naming the parameter help to unify > existing APIs, remove boiler plate core thus simplify object > marshaling and reflection usage (WS, JMX, EJB ...). > MAJOR DISADVANTAGE : Semantic of static keyword on parameter might > not be clear for beginers > ALTERNATIVES : Usage of existing bytecode handling lib can expose > the parameter names already, but this leads to dependency [5][6] and > potential security issues. Usage of APT[7] to store parameter names > constraint to a prequirement : apply it to all the code you target. > This is unlikely to happen for JARS you have not created, thus > reducing the potential benefits. > > EXAMPLE > > SIMPLE EXAMPLE : > > (1a) : > > class OrderManager{ > public void order(String product, int amount){ > // do the login > } > } > > (1b) > > class OrderManager{ > public void order(static String product, static int amount){ > // do the login > } > } > > (2a) > void displayOrderCriteria(){ > Method[] methods = OrderManager.class.getMedthods(); > for (Method m : methods){ > System.out.println("To call :"+m); > for(String n : m.getParameterNames[]){ > System.out.println("\tYou must provide :"+n); > } > } > } > > (2b) > void displayOrderCriteria(){ > Method[] methods = OrderManager.class.getMedthods(); > for (Method m : methods){ > System.out.println("To call :"+m); > for(String n : m.getStaticParameterNames[]){ > System.out.println("\tYou must provide :"+n); > } > } > } > > ADVANCED EXAMPLE : > > (3.1) > package java.lang.annotation > > @Documented > @Retention(value = RetentionPolicy.SOURCE) > @Target( { ElementType.METHOD, ElementType.ANNOTATION_TYPE }) > public @interface StaticParameterNames { > }; > > (3.2) > > @Retention(value = RetentionPolicy.RUNTIME) > @Target( { ElementType.METHOD }) > @Inside(WebService.class) > @ValidWebOperation > @StaticParameterNames > public @interface WebMethod { > String operationName() default ""; > String action() default ""; > }; > > > (3.3) > > @WebService > class LoginManager{ > @WebMethod public void doLogin(String user, char[] password){ > // simply log the user > } > } > > DETAILS > > SPECIFICATION : > > Historicaly, method's parameter names can be stored in the Java > bytecode using appropriate compiler