From mark at twistedbanana.demon.co.uk Sun Mar 1 00:23:02 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 1 Mar 2009 08:23:02 +0000 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <1FFA42B7-B682-4FD0-A39E-BD9C04207085@zwitserloot.com> References: <1FFA42B7-B682-4FD0-A39E-BD9C04207085@zwitserloot.com> Message-ID: On 1 Mar 2009, at 07:08, Reinier Zwitserloot wrote: > > There's also a typo in 'mneumonic' :) > > NB: For what it's worth, because the need to remember super-produces > extends-consumes does not go away, I don't think this is going to help > much. The PECS mnemonic is the other way around (http://java.sun.com/docs/ books/effective/generics.pdf). I suppose that reinforces the point this proposal is making ;) My current concern with this proposal, is that it appears to suggest migrating any and all code to use 'in/out'; although I can see how that might improve matters when applied to collection-y methods, it's less clear to me that it would be better in some other cases. For example, on the class Class we have: boolean isAnnotationPresent(Class annotationClass) which feels more obvious to me than: boolean isAnnotationPresent(Class annotationClass) To be fair, I haven't given it long to sink in. But perhaps some additional examples that don't involve the Collections API would be a good addition to this proposal? Regards, Mark From jeremy.manson at gmail.com Sun Mar 1 00:58:50 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 00:58:50 -0800 Subject: PROPOSAL: Multiline strings In-Reply-To: References: Message-ID: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> One thought springs to mind: the indentation will be weird in cases where white space matters: { StringBuilder sb = new StringBuilder(); sb.append("""in this case we need multiple lines but we can't start them with lots of whitespace"""); // ... System.err.println(sb); } Alternatively, you could have a special syntax where 4 quotes strips out leading whitespace on each line: { StringBuilder sb = new StringBuilder(); sb.append(""""select a from Area a, CountryCodes cc where cc.isoCode='UA' and a.owner = cc.country """"); } Or you could use the C++ style? { StringBuilder sb = new StringBuilder(); sb.append("select a from Area a, CountryCodes cc" "where" "cc.isoCode='UA'" "and" "a.owner = cc.country"); } Frankly, to me, the big win would actually not be multiline literals, but would be escaped String literals. I'm sick of writing all of my regexps with twice as many \ characters as they need. Jeremy On Sat, Feb 28, 2009 at 7:46 PM, wrote: > AUTHOR(s): Ruslan Shevchenko > > OVERVIEW: > ?FEATURE SUMMARY: > ? add multiline strings to java language. > ?MAJOR ADVANTAGE: > ? Possibility more elegant to write code part of codes in other languages, > ?such as sql constructions or rendering of html components. > ?MAJOR DISADVANTAGE > ? I don't know > ?ALTERNATIVES: > ?use String "+=" operator. > ?using groovy instead java in utility classes. > > EXAMPLES > > SIMPLE EXAMPLE: > > ?StringBuilder sb = new StringBuilder(); > ?sb.append("""select a from Area a, CountryCodes cc > ? ? ? ? ? ? ? ?where > ? ? ? ? ? ? ? ? ? cc.isoCode='UA' > ? ? ? ? ? ? ? ? ?and > ? ? ? ? ? ? ? ? ? a.owner = cc.country > ? ? ? ? ? ? ?"""); > ?if (question.getAreaName()!=null) { > ? ? sb.append("""and > ? ? ? ? ? ? ? ? ?a.name like ? > ? ? ? ? ? ? ? """); > ? ? sqlParams.setString(++i,question.getAreaName()); > ?} > > ?instead: > ?StringBuilder sb = new StringBuilder(); > ?sb.append("select a from Area a, CountryCodes cc\n"); > ?sb.append("where cc.isoCode='UA'\n"); > ?sb.append("and a.owner=cc.country'\n"); > ?if (question.getAreaName()!=null) { > ? ? sb.append("and a.name like ?"); > ? ? sqlParams.setString(++i,question.getAreaName()); > ?} > > > DETAILS: > ?Multiline strings are part of program text, which begin and ends > ?by three double quotes. (as in groovy and scala) Text withing such > ?brackets processed as multiline string with all rulles as normal Java > ?string literals, except it can be multiline. After parsing multiline > ?string is concatenation of lines with inserted value of system property > 'line.separator' between thems. > > > COMPILATION: > ?Multiline strings created and used in .class files exactly as ordinary > strings. > > TESTING: > ?Nothing special. add multiline strings to test-cases. > > LIBRARY SUPPORT: > ?None. > ?(May be exists sence add simple template processing to standard library, but > ?I think this is goal of next janguage iteration. Now exists many good > external > ?frameworks, such as velocity: better wait and standartize support of > winner) > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > ?None > > REFERENCES > > ?http://bugs.sun.com/view_bug.do?bug_id=4165111 > > > > > > > > From akuhn at iam.unibe.ch Sun Mar 1 01:01:44 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Sun, 1 Mar 2009 10:01:44 +0100 Subject: Use "default" keyword for default visibility. Message-ID: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Adrian Kuhn OVERVIEW Allow the "default" keyword to be used as modifier for default visibility. In strict mode, missing use of default is a warning / error, in compatibility mode both the current (ie no default keyword) and the new syntax are accepted. FEATURE SUMMARY: Use "default" keyword for default visibility. MAJOR ADVANTAGE: The missing keyword for default visibility breaks the symmetry of visibility modifiers. Since it is the only implicit modifier, omitting any of the three explicit modifiers by mistake may be the source of unexpected behavior and thus hard to track down bugs. (There was an example on a blog post recently, but I cannot find it know). MAJOR BENEFIT: Symmetry of visibility modifiers is restored. MAJOR DISADVANTAGE: Two ways to express the same thing (in compatibility mode). ALTERNATIVES: Using a comment such as /* default */ is not an alternative since such comments are not processed by the compiler. EXAMPLES public class C { default Field f; } SIMPLE EXAMPLE: See above. ADVANCED EXAMPLE: None. DETAILS SPECIFICATION: "default" is already a keyword and introducing it as a new visibility modifier is save, it does not lead to ambiguous grammar. COMPILATION: Same as now for implicit default visibility. TESTING: Same as now for implicit default visibility. LIBRARY SUPPORT: None. REFLECTIVE APIS: None. OTHER CHANGES: None. MIGRATION: Compatibility mode allows both, implicit and explicit default visibility, to be used at the same time. COMPATIBILITY BREAKING CHANGES: None. EXISTING PROGRAMS: Work fine in compatibility mode. REFERENCES EXISTING BUGS: To my best knowledge, none. URL FOR PROTOTYPE (optional): From mark at twistedbanana.demon.co.uk Sun Mar 1 01:10:18 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 1 Mar 2009 09:10:18 +0000 Subject: PROPOSAL: Multiline strings In-Reply-To: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> Message-ID: <1E34CF6E-6215-439A-B0AF-8EB3A4A43936@twistedbanana.demon.co.uk> On 1 Mar 2009, at 08:58, Jeremy Manson wrote: > > Frankly, to me, the big win would actually not be multiline literals, > but would be escaped String literals. I'm sick of writing all of my > regexps with twice as many \ characters as they need. > > Jeremy > Yeah :( I've seen people convert tried and tested regexes to brute force String searches using indexOf and substring rather than put up with the escaping problem. Mark From jeremy.manson at gmail.com Sun Mar 1 01:15:51 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 01:15:51 -0800 Subject: Use "default" keyword for default visibility. In-Reply-To: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> Message-ID: <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> Could you dig up the example? It is hard to see why this is compelling without it. I think it would have to be a warning instead of an error, because otherwise, it is a change that breaks backwards compatibility (i.e., it makes old stuff not compile). I think there is a reasonable sized danger in introducing so many warnings for a change this small; people are likely to ignore / get upset about the flood of warnings that their compiler is suddenly generating. Did you consider the use of annotations as an alternative? In code that I write, if something has package-private visibility, it is usually for testing; Google has a @VisibleForTesting annotation that we use. Also, why not use the package keyword? Jeremy On Sun, Mar 1, 2009 at 1:01 AM, Adrian Kuhn wrote: > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Adrian Kuhn > > OVERVIEW > > Allow the "default" keyword to be used as modifier for default > visibility. In strict mode, missing use of default is a warning / > error, in compatibility mode both the current (ie no default keyword) > and the new syntax are accepted. > > FEATURE SUMMARY: Use "default" keyword for default visibility. > > MAJOR ADVANTAGE: The missing keyword for default visibility breaks the > symmetry of visibility modifiers. Since it is the only implicit > modifier, omitting any of the three explicit modifiers by mistake may > be the source of unexpected behavior and thus hard to track down bugs. > (There was an example on a blog post recently, but I cannot find it > know). > > MAJOR BENEFIT: Symmetry of visibility modifiers is restored. > > MAJOR DISADVANTAGE: Two ways to express the same thing (in > compatibility mode). > > ALTERNATIVES: Using a comment such as /* default */ is not an > alternative since such comments are not processed by the compiler. > > EXAMPLES > > public class C { > ? ? ? ?default Field f; > } > > SIMPLE EXAMPLE: See above. > > ADVANCED EXAMPLE: None. > > DETAILS > > SPECIFICATION: "default" is already a keyword and introducing it as a > new visibility modifier is save, it does not lead to ambiguous grammar. > > COMPILATION: Same as now for implicit default visibility. > > TESTING: Same as now for implicit default visibility. > > LIBRARY SUPPORT: None. > > REFLECTIVE APIS: None. > > OTHER CHANGES: None. > > MIGRATION: Compatibility mode allows both, implicit and explicit > default visibility, to be used at ?the same time. > > COMPATIBILITY > > BREAKING CHANGES: None. > > EXISTING PROGRAMS: Work fine in compatibility mode. > > REFERENCES > > EXISTING BUGS: To my best knowledge, none. > > URL FOR PROTOTYPE (optional): > > > > From mark at twistedbanana.demon.co.uk Sun Mar 1 01:29:44 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 1 Mar 2009 09:29:44 +0000 Subject: Use "default" keyword for default visibility. In-Reply-To: <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> Message-ID: <50D7A372-4576-4235-B3BB-C25519A85DDD@twistedbanana.demon.co.uk> Regarding use of 'package' as a modifier, Alex Buckley mentioned it as a possibility a while back on his blog, in connection to the modules JSR: http://blogs.sun.com/abuckley/en_US/entry/a_wrinkle_with_module http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4456057 I have no idea whether that's a current consideration, however. Mark On 1 Mar 2009, at 09:15, Jeremy Manson wrote: > Could you dig up the example? It is hard to see why this is > compelling without it. > > I think it would have to be a warning instead of an error, because > otherwise, it is a change that breaks backwards compatibility (i.e., > it makes old stuff not compile). I think there is a reasonable sized > danger in introducing so many warnings for a change this small; people > are likely to ignore / get upset about the flood of warnings that > their compiler is suddenly generating. > > Did you consider the use of annotations as an alternative? In code > that I write, if something has package-private visibility, it is > usually for testing; Google has a @VisibleForTesting annotation that > we use. > > Also, why not use the package keyword? > > Jeremy > > On Sun, Mar 1, 2009 at 1:01 AM, Adrian Kuhn > wrote: >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): Adrian Kuhn >> >> OVERVIEW >> >> Allow the "default" keyword to be used as modifier for default >> visibility. In strict mode, missing use of default is a warning / >> error, in compatibility mode both the current (ie no default keyword) >> and the new syntax are accepted. >> >> FEATURE SUMMARY: Use "default" keyword for default visibility. >> >> MAJOR ADVANTAGE: The missing keyword for default visibility breaks >> the >> symmetry of visibility modifiers. Since it is the only implicit >> modifier, omitting any of the three explicit modifiers by mistake may >> be the source of unexpected behavior and thus hard to track down >> bugs. >> (There was an example on a blog post recently, but I cannot find it >> know). >> >> MAJOR BENEFIT: Symmetry of visibility modifiers is restored. >> >> MAJOR DISADVANTAGE: Two ways to express the same thing (in >> compatibility mode). >> >> ALTERNATIVES: Using a comment such as /* default */ is not an >> alternative since such comments are not processed by the compiler. >> >> EXAMPLES >> >> public class C { >> default Field f; >> } >> >> SIMPLE EXAMPLE: See above. >> >> ADVANCED EXAMPLE: None. >> >> DETAILS >> >> SPECIFICATION: "default" is already a keyword and introducing it as a >> new visibility modifier is save, it does not lead to ambiguous >> grammar. >> >> COMPILATION: Same as now for implicit default visibility. >> >> TESTING: Same as now for implicit default visibility. >> >> LIBRARY SUPPORT: None. >> >> REFLECTIVE APIS: None. >> >> OTHER CHANGES: None. >> >> MIGRATION: Compatibility mode allows both, implicit and explicit >> default visibility, to be used at the same time. >> >> COMPATIBILITY >> >> BREAKING CHANGES: None. >> >> EXISTING PROGRAMS: Work fine in compatibility mode. >> >> REFERENCES >> >> EXISTING BUGS: To my best knowledge, none. >> >> URL FOR PROTOTYPE (optional): >> >> >> >> > From jeremy.manson at gmail.com Sun Mar 1 01:32:49 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 01:32:49 -0800 Subject: Use "default" keyword for default visibility. In-Reply-To: <50D7A372-4576-4235-B3BB-C25519A85DDD@twistedbanana.demon.co.uk> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> <50D7A372-4576-4235-B3BB-C25519A85DDD@twistedbanana.demon.co.uk> Message-ID: <1631da7d0903010132h7ba08a6ep8f344ac4befcd3eb@mail.gmail.com> I can see Alex's argument. I would imagine that that belongs in the modules JSR, though. Jeremy On Sun, Mar 1, 2009 at 1:29 AM, Mark Mahieu wrote: > Regarding use of 'package' as a modifier, Alex Buckley mentioned it as a > possibility a while back on his blog, in connection to the modules JSR: > > http://blogs.sun.com/abuckley/en_US/entry/a_wrinkle_with_module > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4456057 > > I have no idea whether that's a current consideration, however. > > Mark > > > On 1 Mar 2009, at 09:15, Jeremy Manson wrote: > >> Could you dig up the example? ?It is hard to see why this is >> compelling without it. >> >> I think it would have to be a warning instead of an error, because >> otherwise, it is a change that breaks backwards compatibility (i.e., >> it makes old stuff not compile). ?I think there is a reasonable sized >> danger in introducing so many warnings for a change this small; people >> are likely to ignore / get upset about the flood of warnings that >> their compiler is suddenly generating. >> >> Did you consider the use of annotations as an alternative? ?In code >> that I write, if something has package-private visibility, it is >> usually for testing; Google has a @VisibleForTesting annotation that >> we use. >> >> Also, why not use the package keyword? >> >> Jeremy >> >> On Sun, Mar 1, 2009 at 1:01 AM, Adrian Kuhn wrote: >>> >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>> >>> AUTHOR(S): Adrian Kuhn >>> >>> OVERVIEW >>> >>> Allow the "default" keyword to be used as modifier for default >>> visibility. In strict mode, missing use of default is a warning / >>> error, in compatibility mode both the current (ie no default keyword) >>> and the new syntax are accepted. >>> >>> FEATURE SUMMARY: Use "default" keyword for default visibility. >>> >>> MAJOR ADVANTAGE: The missing keyword for default visibility breaks the >>> symmetry of visibility modifiers. Since it is the only implicit >>> modifier, omitting any of the three explicit modifiers by mistake may >>> be the source of unexpected behavior and thus hard to track down bugs. >>> (There was an example on a blog post recently, but I cannot find it >>> know). >>> >>> MAJOR BENEFIT: Symmetry of visibility modifiers is restored. >>> >>> MAJOR DISADVANTAGE: Two ways to express the same thing (in >>> compatibility mode). >>> >>> ALTERNATIVES: Using a comment such as /* default */ is not an >>> alternative since such comments are not processed by the compiler. >>> >>> EXAMPLES >>> >>> public class C { >>> ? ? ? default Field f; >>> } >>> >>> SIMPLE EXAMPLE: See above. >>> >>> ADVANCED EXAMPLE: None. >>> >>> DETAILS >>> >>> SPECIFICATION: "default" is already a keyword and introducing it as a >>> new visibility modifier is save, it does not lead to ambiguous grammar. >>> >>> COMPILATION: Same as now for implicit default visibility. >>> >>> TESTING: Same as now for implicit default visibility. >>> >>> LIBRARY SUPPORT: None. >>> >>> REFLECTIVE APIS: None. >>> >>> OTHER CHANGES: None. >>> >>> MIGRATION: Compatibility mode allows both, implicit and explicit >>> default visibility, to be used at ?the same time. >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: None. >>> >>> EXISTING PROGRAMS: Work fine in compatibility mode. >>> >>> REFERENCES >>> >>> EXISTING BUGS: To my best knowledge, none. >>> >>> URL FOR PROTOTYPE (optional): >>> >>> >>> >>> >> > > From mark at twistedbanana.demon.co.uk Sun Mar 1 01:54:33 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Sun, 1 Mar 2009 09:54:33 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> Message-ID: <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> On 28 Feb 2009, at 19:08, Joshua Bloch wrote: > Neal, > > On Sat, Feb 28, 2009 at 7:41 AM, Neal Gafter wrote: > >> Josh- >> >> The compatibility section must document incompatibilities, whether or >> not you judge them likely to cause problems in practice. > > > Good point. I will add this one. And I am still interested in > whether > anyone can find some code in an existing codebase that tickles this. > Josh, The worst case I've turned up so far is the following, which would not be broken by your proposal, but I think it would be restricted in its ability to take advantage of it without further changes downstream: http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/ javadoc/org/apache/openjpa/datacache/DataCacheManagerImpl.html Here, the class DataCacheManagerImpl implements two interfaces, both of which could logically be retrofitted with Disposable, but doing so would then break DataCacheManagerImpl since different type arguments would be needed (Exception and RuntimeException). (I think the idea is that an alternative implementation of DataCacheManager can be specified by the user of this library; it seems quite likely that these would extend the default DataCacheManagerImpl implementation.) Depends on how ticklish you are I guess. For me it's a hint that an interface may not be the best mechanism. Regards, Mark From akuhn at iam.unibe.ch Sun Mar 1 02:01:15 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Sun, 1 Mar 2009 11:01:15 +0100 Subject: Use "default" keyword for default visibility. In-Reply-To: <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> Message-ID: On 01.03.2009, at 10:15, Jeremy Manson wrote: > Could you dig up the example? It is hard to see why this is > compelling without it. I am working on it ... to many inboxes :) > I think it would have to be a warning instead of an error, because > otherwise, it is a change that breaks backwards compatibility (i.e., > it makes old stuff not compile). I think there is a reasonable sized > danger in introducing so many warnings for a change this small; people > are likely to ignore / get upset about the flood of warnings that > their compiler is suddenly generating. > > Did you consider the use of annotations as an alternative? In code > that I write, if something has package-private visibility, it is > usually for testing; Google has a @VisibleForTesting annotation that > we use. I do, and actually use an annotation processor to reject non-annotated default visibilities. It works but feels ugly, since (at least optically) symmetry of visibility modifiers is still not given. > Also, why not use the package keyword? Wow, that's much better! However because both package and class declaration can start with package now, we might need a lookahead of two tokens in the grammar. --AA > Jeremy > > On Sun, Mar 1, 2009 at 1:01 AM, Adrian Kuhn > wrote: >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): Adrian Kuhn >> >> OVERVIEW >> >> Allow the "default" keyword to be used as modifier for default >> visibility. In strict mode, missing use of default is a warning / >> error, in compatibility mode both the current (ie no default keyword) >> and the new syntax are accepted. >> >> FEATURE SUMMARY: Use "default" keyword for default visibility. >> >> MAJOR ADVANTAGE: The missing keyword for default visibility breaks >> the >> symmetry of visibility modifiers. Since it is the only implicit >> modifier, omitting any of the three explicit modifiers by mistake may >> be the source of unexpected behavior and thus hard to track down >> bugs. >> (There was an example on a blog post recently, but I cannot find it >> know). >> >> MAJOR BENEFIT: Symmetry of visibility modifiers is restored. >> >> MAJOR DISADVANTAGE: Two ways to express the same thing (in >> compatibility mode). >> >> ALTERNATIVES: Using a comment such as /* default */ is not an >> alternative since such comments are not processed by the compiler. >> >> EXAMPLES >> >> public class C { >> default Field f; >> } >> >> SIMPLE EXAMPLE: See above. >> >> ADVANCED EXAMPLE: None. >> >> DETAILS >> >> SPECIFICATION: "default" is already a keyword and introducing it as a >> new visibility modifier is save, it does not lead to ambiguous >> grammar. >> >> COMPILATION: Same as now for implicit default visibility. >> >> TESTING: Same as now for implicit default visibility. >> >> LIBRARY SUPPORT: None. >> >> REFLECTIVE APIS: None. >> >> OTHER CHANGES: None. >> >> MIGRATION: Compatibility mode allows both, implicit and explicit >> default visibility, to be used at the same time. >> >> COMPATIBILITY >> >> BREAKING CHANGES: None. >> >> EXISTING PROGRAMS: Work fine in compatibility mode. >> >> REFERENCES >> >> EXISTING BUGS: To my best knowledge, none. >> >> URL FOR PROTOTYPE (optional): >> >> >> >> From akuhn at iam.unibe.ch Sun Mar 1 02:20:44 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Sun, 1 Mar 2009 11:20:44 +0100 Subject: Use "default" keyword for default visibility. In-Reply-To: <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> Message-ID: <6A1D1254-7506-4410-8DE2-795179B88F60@iam.unibe.ch> On 01.03.2009, at 10:15, Jeremy Manson wrote: > Could you dig up the example? It is hard to see why this is > compelling without it. http://dow.ngra.de/2009/02/16/the-ultimate-java-puzzler --AA From scolebourne at joda.org Sun Mar 1 03:44:56 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sun, 01 Mar 2009 11:44:56 +0000 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <15e8b9d20902280903h32967535l8f6e4f6580fdd93d@mail.gmail.com> References: <15e8b9d20902280903h32967535l8f6e4f6580fdd93d@mail.gmail.com> Message-ID: <49AA7538.5080302@joda.org> After some thought, I've decided I oppose this feature. The basic reasoning is that 'out' and 'in' are sufficiently more meaningful to developers to justify the complexity of a language change and supporting two ways to define the same thing. I disagree with that. (ie. I find nothing wrong with the technical aspects of the proposal/spec, other than a distaste for context sensitive keywords in general) If I see the following: public static createList(Collection coll) then I read it as: "takes a collection of Number or anything extends Number". If I see: public static sort(Comparator coll) then I read it as: "takes a comparator of Number or any superclass of Number" I personally don't find the PECS shorthand that useful. And the 'out' and 'in' keywords don't mean anything to me at all right now. Perhaps the point is whether we want to define the type (Number or anything that extends Number) or the action we can take (get stuff 'out'). I think Java is type-focussed, not action-focussed. Stephen Neal Gafter wrote: > Improved Wildcard Syntax for Java > http://docs.google.com/Doc?id=ddb3zt39_79g2mtpccz > > AUTHOR(S): > > Neal Gafter > > OVERVIEW > > The current syntax for Java's wildcards is confusing enough that > mneumonics are required to read code. We suggest adding an > alternative syntax that is much more readable, and then migrating code > to the more readable syntax over time. > > FEATURE SUMMARY: > > [Note: since this is an additional syntax for a feature already in the > language, most existing tutorial material can be used.] > > A covariant wildcard generic argument can be written either "? extends > Y" or "out Y". > > A contravariant wildcard generic argument can be written either "? > super Y" or "in Y". > > MAJOR ADVANTAGE: > > While the existing syntax is mneumonic from the point of view of > describing its effect on the type system, it is not mneumonic in its > use. The new syntax is self-mneumonic for users. > > MAJOR BENEFIT: > > Jave code that uses wildcards is more readable, as are diagnostics > involving them. > > MAJOR DISADVANTAGE: > > Two ways of doing the same thing, though we hope code will migrate > over time toward the new more readable syntax. > > ALTERNATIVES: > > None. > > EXAMPLES > > SIMPLE EXAMPLE: > > interface Collection { > boolean addAll(Collection c); > ... > } > > ADVANCED EXAMPLE: > > class Collections { > public static > void sort(List list) {...} > public static void sort(List list, Comparator c) {...} > int binarySearch(List> list, T key) {...} > public static void fill(List list, T obj) {...} > public static void copy(List dest, List src) { > ... > } > > DETAILS > > SPECIFICATION: > > "in" and "out" are added as context-sensitive keywords with precisely > the same meaning of "? super" and "? extends". As context-sensitive > keywords, they continue to be usable as identifiers in all contexts. > > COMPILATION: > > As today. > > TESTING: > > As today, though a bit of additional work to ensure that the context > sensitive keyword is handled properly by the compiler. Specifically, > that they continue to be fully usable as identifiers in other > contexts. > > LIBRARY SUPPORT: > > None. > > REFLECTIVE APIS: > > None. > > OTHER CHANGES: > > None. > > MIGRATION: > > A trivial textual substitution can be used to translate old code to > the new syntax. > > COMPATIBILITY > > BREAKING CHANGES: > > None. > > EXISTING PROGRAMS: > > No impact. > > REFERENCES > > EXISTING BUGS: > > None > > URL FOR PROTOTYPE (optional): > > None > > From scolebourne at joda.org Sun Mar 1 08:45:22 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sun, 01 Mar 2009 16:45:22 +0000 Subject: Proposal: Elvis and Other Null-Safe Operators Message-ID: <49AABBA2.3040009@joda.org> Elvis and Other Null-Safe Operators for Java AUTHOR(S): Stephen Colebourne primarily written up by Neal Gafter (Neal Gafter is responsible for the formal write-up[6] of the proposal detailed below. However, in private communication he indicated that he did not intend to submit it to Project Coin, as indicated in his write-up: "[I do] not specifically advocate adding these features to the Java programming language. Rather, this document is offered as an example of a language change proposal in a form suitable for consideration in the JDK7 small language changes JSR. Specifically, it is more like a specification than a tutorial or sales job.". As such, this proposal is submitted by myself, thanks to Neal's willingness to allow me to reuse his write-up. For the submission, I have reworded the advantages/benefits/disadvantages/alternatives sections from Neal's original document and added detail to the examples. Please see the original[6] to compare Neal's version to mine.) *OVERVIEW* FEATURE SUMMARY: The ?: binary "Elvis" operator results in the value of the left-hand-side if it is not null, avoiding evaluation of the right-hand-side. If the left-hand-side is null, the right-hand-side is evaluated and is the result. The ?. null-safe member selection operator provides the same meaning as . (member selection), except when the left-hand-side evaluates to null, in which case any subexpressions on the right-hand-side are not evaluated and the ?. expression yields null. The ?[] indexing operator operates on a left-hand-side that is an array of object type. If the value of the left-hand operand is null, that is the result. If the left-hand-operand is not null, the index subexpression is evaluated and used to index the array, yielding the result. These three operators always result in a value, not a variable. NOTE: The Elvis operator could be added on its own without the other two operators if deemed necessary/desirable (Elvis is generally considered less controversial as far as I can tell). MAJOR ADVANTAGE: It is a common occurance in most large systems to find code that checks for null. Common cases are to provide a default value instead of null, to obtain the result from a nested JavaBean where any of the accessors might be null, or to handle auto-unboxing properly. This proposal captures these common coding patterns, and as a result makes the code clearer and more expresive. Less boilerplate. Clearer business logic. The result of /not/ handling null properly is a NullPointerException. This is such a common mistake amongst developers, that many regular internet users (non-developers) are aware of the term "NullPointerException", because of its prevalence in production systems. MAJOR BENEFIT: Two common coding patterns are simplified - defaulting the value of null, and avoiding a NPE on access. The remaining code is focussed more tightly on the business logic rather than on the details of coding. There are also significant benefits in the handling of auto-unboxing, as well as switching on enums and the for-each loop. In all three cases, the language change added an ability to create a NPE without providing an easy and obvious means to avoid it (you have to add an if statement and another level of block which entirely defeats the purpose of the 'convenience' unboxing). Finally, the proposed code will generally be slightly more performant than the code written by hand. This is because each part of the expression will only be evaluated once with the proposed change, whereas a developer will normally call each part multiple times while checking for null. MAJOR DISADVANTAGE: Associated costs in documentation, tutorials and overall language size. The principle perceived disadvantage, however, is that it encourages, rather than discourages, the use of null values in APIs. No one is disputing that empty arrays or empty collections should be returned from APIs rather than nulls, however that is only a small proportion of the returned types in any large system. Many large systems consist of large numbers of JavaBean type objects which may have null values for many of their fields (representing an absence of information, invalid data, etc.). In these cases, null is a suitable and valuable value to hold in those fields, and is widely used as such. Accessing the resulting data for use often requires defaulting the values or handling nulls, and that is where this proposal comes in. To put that another way, if you write low-level APIs, such as the JDK, Apache Commons or Google Collections, then this proposal is of little value. If your day job involves integrating code from 50 different libraries using hundreds of JavaBean style data structures where fields can all be null, then this proposal will have a huge impact. Its a matter of perspective. ALTERNATIVES: It is possible to solve some of the issues using libraries[1]. These solutions are not terribly appealing however and would be unlikely to make it into the JDK. The other alternative is, as with any proposal, to make no change. This leaves developers to continue to obscure business logic with null-handling clutter despite indicating this as their most-wanted change in Java[5]. *EXAMPLES* SIMPLE EXAMPLE: Standard example: String s = mayBeNull?.toString() ?: "null"; Auto-unboxing example: Integer ival = ...; // may be null int i = ival ?: -1; // no NPE from unboxing ADVANCED EXAMPLE: Given a Java class class Group { Person[] members; // null if no members } class Person { String name; // may be null } Group g = ...; // may be null we can compute the name of a member if the group is non-null and non-empty and the first member has a known (non-null) name, otherwise the string "nobody": final String aMember = g?.members?[0]?.name ?: "nobody"; Without this feature, a developer would currently write: String aMember = null; if (g != null && g.members != null && g.members[0].name != null) { aMember = g.members[0].name; } else { aMember = "nobody"; } The proposed version is a lot shorter, clearer, and can even be assigneed to a final variable. *DETAILS* SPECIFICATION: Lexical: We do not add any tokens to the language. Rather, we introduce new operators that are composed of a sequence of existing tokens. Syntax: The folllowing new grammar rules are added to the syntax PrimaryNoNewArray: NullSafeFieldAccess NullSafeMethodInvocation NullSafeClassInstanceCreationExpression NullSafeArrayAccess NullSafeFieldAccess: PrimaryNoNewArray ? . Identifier NullSafeMethodInvocation: PrimaryNoNewArray ? . NonWildTypeArgumentsopt Identifier ( ArgumentListopt ) NullSafeClassInstanceCreationExpression: PrimaryNoNewArray ? . new TypeArgumentsopt Identifier TypeArgumentsopt ( ArgumentListopt ) ClassBodyopt NullSafeArrayAccess: PrimaryNoNewArray ? [ Expression ] ConditionalExpression: ElvisExpression ElvisExpression: ConditionalOrExpression ? : ConditionalExpression Semantics: A null-safe field access expression e1?.name first evaluates the expression e1. If the result is null, then the null-safe field access expression's result is null. Otherwise, the result is the same as the result of the expression e1.name. In either case, the type of the result is the same as the type of e1.name. It is an error if this is not a reference type. A null-safe method invocation expression e1?.name(args) first evaluates the expression e1. If the result is null, then the null-safe method invocation expression's result is null. Otherwise the arguments are evaluated and the result is the same as the result of the invocation expression e1.name(args). In either case, 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. A null-safe class instance creation expression e1?.new name(args) first evaluates the expression e1. If the result is null, then the null-safe class instance creation expression's result is null. Otherwise, the arguments are evaluated and the result is the same as the result of the class instance creation expression e1.new name(args). In either case, the type of the result is the same as the type of e1.new name(args). A null-safe array access expression e1?[e2] first evaluates the expression e1. If the result is null, then the null-safe array access expression's result is null. Otherwise, e2 is evaluated and the result is the same as the result of e1[e2]. In either case, the type of the result is the same as the type of e1[e2]. It is an error if this is not a reference type. An Elvis expression e1?:e2 first evaluates the expression e1. It is an error if this is not a reference type. If the result is non-null, then that is the Elvis expression's result. Otherwise, e2 is evaluated and is the result of the Elvis expression. In either case, the type of the result is the same as the type of (e1!=null)?e1:e2. [Note: this section must mention bringing the operands to a common type, for example by unboxing when e2 is a primitive, using the same rules as the ternary operator] Exception Analysis: JLS section 12.2.1 (exception analysis of expressions) is modified to read as follows. Additions are shown in bold. A method invocation expression or null-safe method invocation expression can throw an exception type E iff either: * The method to be invoked is of the form Primary.Identifier or Primary?.Identifier and the Primary expression can throw E; or * Some expression of the argument list can throw E; or * E is listed in the throws clause of the type of method that is invoked. A class instance creation expression or null-safe class instance creation expression can throw an exception type E iff either: * The expression is a qualified class instance creation expression or a null-safe class instance creation expression and the qualifying expression can throw E; or * Some expression of the argument list can throw E; or * E is listed in the throws clause of the type of the constructor that is invoked; or * The class instance creation expression or null-safe class instance creation expression includes a ClassBody, and some instnance initializer block or instance variable initializer expression in the ClassBody can throw E. For every other kind of expression, the expression can throw type E iff one of its immediate subexpressions can throw E. Definite Assignment: JLS section 16.1 (definite assignment and expressions) is augmented with the following new subsections 16.1.x Null-safe Method Invocation * v is definitely assigned after e1?.name(args) iff v is definitely assigned after e1. * v is definitely unassigned after e1?.name(args) iff v is definitely unassigned after args. * in an expression of the form e1?.name(args), v is [un]assigned before args iff v is [un]assigned after e1. 16.1.x Null-safe Class Instance Creation Expression * v is definitely assigned after e1?.new name(args) iff v is definitely assigned after e1. * v is definitely unassigned after e1?.new name(args) iff v is definitely unassigned after args. * in an expression of the form e1?.new name(args), v is [un]assigned before args iff v is [un]assigned after e1. 16.1.x Null-safe Array Access * v is definitely assigned after e1?[e2] iff v is definitely assigned after e1. * v is definitely unassigned after e1?[e2] iff v is definitely unassigned after e2. * in an expression of the form e1?[e2], v is [un]assigned before e2 iff v is [un]assigned after e1. 16.1.x Elvis Operator * v is definitely assigned after e1?:e2 iff v is definitely assigned after e1. * v is definitely unassigned after e1?:e2 iff v is definitely unassigned after e2. * in an expression of the form e1?:e2, v is [un]assigned before e2 iff v is [un]assigned after e1. COMPILATION: These new expression forms can be desugared as follows: * e1?.name is rewritten as (t != null ? t.name : null) * e1?.name(args) is rewriten as (t != null ? t.name(args) : null) * e1?.new name(args) is rewritten as (t != null ? t.new name(args) : null) * e1?[e2] is rewritten as (t != null ? t[e2] : null) * e1?:e2 is rewritten as (t != null ? t : e2) where t is a new temporary that holds the computed value of the expression e1. TESTING: This feature can be tested by exercising the various new expression forms, and verifying their correct behavior in erroneous and non-erroneous situations, with or without null as the value of the left-hand operand, and with respect to definite assignment and exception analysis. LIBRARY SUPPORT: No library support is required. REFLECTIVE APIS: No reflective APIs require any changes. However, the not-yet-public javac Tree APIs, which describe the syntactic structure of Java statements and expressions, should be augmented with new tree forms for these new expression types. OTHER CHANGES: No other platform changes are required. MIGRATION: No migration of existing code is recommended. These new language features are mainly to be used in new code. However, IDEs should provide refactoring advice for taking advantage of these new operators when existing code uses the corresponding idiom. *COMPATIBILITY* BREAKING CHANGES: No breaking changes are caused by this proposal. EXISTING PROGRAMS: Because the changes are purely the introduction of new expression forms, there is no impact on the meaning of existing code. *REFERENCES* EXISTING BUGS: 4151957: Proposal: null-safe field access operator URL FOR PROTOTYPE: No Java prototype exists at this time. However, Groovy[2] and Fan[3] (among others) have the Elvis and null-safe member operators. OTHER REFERENCES [1] Stephan Schmidt's discussion of Better Strategies for Null Handling in Java - http://www.slideshare.net/Stephan.Schmidt/better-strategies-for-null-handling-in-java [2] Groovy Operators - http://groovy.codehaus.org/Operators [3] Fan operators - http://fandev.org/doc/docLang/Expressions.html#nullConvenience [4] Stephen Colebourne's brief on null-safe operators - http://docs.google.com/View?docid=dfn5297z_3c73gwb [5] Summary of three recent language change polls showing better null handling as a key developer request - http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_everyone [6] The version of this proposal written by Neal Gafter - http://docs.google.com/Doc?docid=ddb3zt39_78frdf87dc&hl=en From neal at gafter.com Sun Mar 1 09:05:20 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 1 Mar 2009 09:05:20 -0800 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49AABBA2.3040009@joda.org> References: <49AABBA2.3040009@joda.org> Message-ID: <15e8b9d20903010905h79c15eb4vad4cc4ed7af7bc05@mail.gmail.com> Stephen- One small nit: In the aMember example of how things have to be done today, the variable aMember could be declared as a blank final. Regards, Neal On Sun, Mar 1, 2009 at 8:45 AM, Stephen Colebourne wrote: > Elvis and Other Null-Safe Operators for Java > AUTHOR(S): > Stephen Colebourne > primarily written up by Neal Gafter > > (Neal Gafter is responsible for the formal write-up[6] of the proposal > detailed below. However, in private communication he indicated that he > did not intend to submit it to Project Coin, as indicated in his > write-up: "[I do] not specifically advocate adding these features to the > Java programming language. ?Rather, this document is offered as an > example of a language change proposal in a form suitable for > consideration in the JDK7 small language changes JSR. ?Specifically, it > is more like a specification than a tutorial or sales job.". > > As such, this proposal is submitted by myself, thanks to Neal's > willingness to allow me to reuse his write-up. For the submission, I > have reworded the advantages/benefits/disadvantages/alternatives > sections from Neal's original document and added detail to the examples. > Please see the original[6] to compare Neal's version to mine.) > > > *OVERVIEW* > > FEATURE SUMMARY: > The ?: binary "Elvis" operator results in the value of the > left-hand-side if it is not null, avoiding evaluation of the > right-hand-side. ?If the left-hand-side is null, the right-hand-side is > evaluated and is the result. > > The ?. null-safe member selection operator provides the same meaning as > . (member selection), except when the left-hand-side evaluates to null, > in which case any subexpressions on the right-hand-side are not > evaluated and the ?. expression yields null. > > The ?[] indexing operator operates on a left-hand-side that is an array > of object type. ?If the value of the left-hand operand is null, that is > the result. ?If the left-hand-operand is not null, the index > subexpression is evaluated and used to index the array, yielding the result. > These three operators always result in a value, not a variable. > > NOTE: The Elvis operator could be added on its own without the other two > operators if deemed necessary/desirable (Elvis is generally considered > less controversial as far as I can tell). > > MAJOR ADVANTAGE: > It is a common occurance in most large systems to find code that checks > for null. Common cases are to provide a default value instead of null, > to obtain the result from a nested JavaBean where any of the accessors > might be null, or to handle auto-unboxing properly. This proposal > captures these common coding patterns, and as a result makes the code > clearer and more expresive. Less boilerplate. Clearer business logic. > > The result of /not/ handling null properly is a NullPointerException. > This is such a common mistake amongst developers, that many regular > internet users (non-developers) are aware of the term > "NullPointerException", because of its prevalence in production systems. > > MAJOR BENEFIT: > Two common coding patterns are simplified - defaulting the value of > null, and avoiding a NPE on access. The remaining code is focussed more > tightly on the business logic rather than on the details of coding. > > There are also significant benefits in the handling of auto-unboxing, as > well as switching on enums and the for-each loop. In all three cases, > the language change added an ability to create a NPE without providing > an easy and obvious means to avoid it (you have to add an if statement > and another level of block which entirely defeats the purpose of the > 'convenience' unboxing). > > Finally, the proposed code will generally be slightly more performant > than the code written by hand. This is because each part of the > expression will only be evaluated once with the proposed change, whereas > a developer will normally call each part multiple times while checking > for null. > > MAJOR DISADVANTAGE: > Associated costs in documentation, tutorials and overall language size. > > The principle perceived disadvantage, however, is that it encourages, > rather than discourages, the use of null values in APIs. No one is > disputing that empty arrays or empty collections should be returned from > APIs rather than nulls, however that is only a small proportion of the > returned types in any large system. Many large systems consist of large > numbers of JavaBean type objects which may have null values for many of > their fields (representing an absence of information, invalid data, > etc.). In these cases, null is a suitable and valuable value to hold in > those fields, and is widely used as such. Accessing the resulting data > for use often requires defaulting the values or handling nulls, and that > is where this proposal comes in. > > To put that another way, if you write low-level APIs, such as the JDK, > Apache Commons or Google Collections, then this proposal is of little > value. If your day job involves integrating code from 50 different > libraries using hundreds of JavaBean style data structures where fields > can all be null, then this proposal will have a huge impact. Its a > matter of perspective. > > ALTERNATIVES: > It is possible to solve some of the issues using libraries[1]. These > solutions are not terribly appealing however and would be unlikely to > make it into the JDK. > > The other alternative is, as with any proposal, to make no change. This > leaves developers to continue to obscure business logic with > null-handling clutter despite indicating this as their most-wanted > change in Java[5]. > > > *EXAMPLES* > > SIMPLE EXAMPLE: > Standard example: > ?String s = mayBeNull?.toString() ?: "null"; > > Auto-unboxing example: > ?Integer ival = ...; ?// may be null > ?int i = ival ?: -1; ?// no NPE from unboxing > > ADVANCED EXAMPLE: > Given a Java class > > class Group { > ? Person[] members; // null if no members > } > class Person { > ? ?String name; // may be null > } > Group g = ...; // may be null > > we can compute the name of a member if the group is non-null and > non-empty and the first member has a known (non-null) name, otherwise > the string "nobody": > > ?final String aMember = g?.members?[0]?.name ?: "nobody"; > > Without this feature, a developer would currently write: > > ?String aMember = null; > ?if (g != null && g.members != null && g.members[0].name != null) { > ? ?aMember = g.members[0].name; > ?} else { > ? ?aMember = "nobody"; > ?} > > The proposed version is a lot shorter, clearer, and can even be > assigneed to a final variable. > > > *DETAILS* > > SPECIFICATION: > Lexical: > > We do not add any tokens to the language. ?Rather, we introduce new > operators that are composed of a sequence of existing tokens. > > Syntax: > > The folllowing new grammar rules are added to the syntax > > PrimaryNoNewArray: > > NullSafeFieldAccess > NullSafeMethodInvocation > NullSafeClassInstanceCreationExpression > NullSafeArrayAccess > > NullSafeFieldAccess: > > PrimaryNoNewArray ? . Identifier > > NullSafeMethodInvocation: > > PrimaryNoNewArray ? . NonWildTypeArgumentsopt Identifier ( ArgumentListopt ) > > NullSafeClassInstanceCreationExpression: > > PrimaryNoNewArray ? . new TypeArgumentsopt Identifier TypeArgumentsopt ( > ArgumentListopt ) ClassBodyopt > > NullSafeArrayAccess: > > PrimaryNoNewArray ? [ Expression ] > > ConditionalExpression: > > ElvisExpression > > ElvisExpression: > > ConditionalOrExpression ? : ConditionalExpression > > Semantics: > > A null-safe field access expression e1?.name first evaluates the > expression e1. ?If the result is null, then the null-safe field access > expression's result is null. ?Otherwise, the result is the same as the > result of the expression e1.name. ?In either case, the type of the > result is the same as the type of e1.name. ?It is an error if this is > not a reference type. > > A null-safe method invocation expression e1?.name(args) first evaluates > the expression e1. ?If the result is null, then the null-safe method > invocation expression's result is null. ?Otherwise the arguments are > evaluated and the result is the same as the result of the invocation > expression e1.name(args). ?In either case, 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. > > A null-safe class instance creation expression e1?.new name(args) first > evaluates the expression e1. ?If the result is null, then the null-safe > class instance creation expression's result is null. ?Otherwise, the > arguments are evaluated and the result is the same as the result of the > class instance creation expression e1.new name(args). ?In either case, > the type of the result is the same as the type of e1.new name(args). > > A null-safe array access expression e1?[e2] first evaluates the > expression e1. ?If the result is null, then the null-safe array access > expression's result is null. ?Otherwise, e2 is evaluated and the result > is the same as the result of e1[e2]. ?In either case, the type of the > result is the same as the type of e1[e2]. ?It is an error if this is not > a reference type. > > An Elvis expression e1?:e2 first evaluates the expression e1. ?It is an > error if this is not a reference type. ?If the result is non-null, then > that is the Elvis expression's result. ?Otherwise, e2 is evaluated and > is the result of the Elvis expression. ?In either case, the type of the > result is the same as the type of (e1!=null)?e1:e2. ?[Note: this section > must mention bringing the operands to a common type, for example by > unboxing when e2 is a primitive, using the same rules as the ternary > operator] > > Exception Analysis: > > JLS section 12.2.1 (exception analysis of expressions) is modified to > read as follows. ?Additions are shown in bold. > > A method invocation expression or null-safe method invocation expression > can throw an exception type E iff either: > > ? ? * The method to be invoked is of the form Primary.Identifier or > Primary?.Identifier and the Primary expression can throw E; or > ? ? * Some expression of the argument list can throw E; or > ? ? * E is listed in the throws clause of the type of method that is > invoked. > > A class instance creation expression or null-safe class instance > creation expression can throw an exception type E iff either: > > ? ? * The expression is a qualified class instance creation expression > or a null-safe class instance creation expression and the qualifying > expression can throw E; or > ? ? * Some expression of the argument list can throw E; or > ? ? * E is listed in the throws clause of the type of the constructor > that is invoked; or > ? ? * The class instance creation expression or null-safe class > instance creation expression includes a ClassBody, and some instnance > initializer block or instance variable initializer expression in the > ClassBody can throw E. > > For every other kind of expression, the expression can throw type E iff > one of its immediate subexpressions can throw E. > > Definite Assignment: > > JLS section 16.1 (definite assignment and expressions) is augmented with > the following new subsections > > 16.1.x Null-safe Method Invocation > > ? ? * v is definitely assigned after e1?.name(args) iff v is definitely > assigned after e1. > ? ? * v is definitely unassigned after e1?.name(args) iff v is > definitely unassigned after args. > ? ? * in an expression of the form e1?.name(args), v is [un]assigned > before args iff v is [un]assigned after e1. > > > 16.1.x Null-safe Class Instance Creation Expression > > ? ? * v is definitely assigned after e1?.new name(args) iff v is > definitely assigned after e1. > ? ? * v is definitely unassigned after e1?.new name(args) iff v is > definitely unassigned after args. > ? ? * in an expression of the form e1?.new name(args), v is > [un]assigned before args iff v is [un]assigned after e1. > > > 16.1.x Null-safe Array Access > > ? ? * v is definitely assigned after e1?[e2] iff v is definitely > assigned after e1. > ? ? * v is definitely unassigned after e1?[e2] iff v is definitely > unassigned after e2. > ? ? * in an expression of the form e1?[e2], v is [un]assigned before e2 > iff v is [un]assigned after e1. > > > 16.1.x Elvis Operator > > ? ? * v is definitely assigned after e1?:e2 iff v is definitely > assigned after e1. > ? ? * v is definitely unassigned after e1?:e2 iff v is definitely > unassigned after e2. > ? ? * in an expression of the form e1?:e2, v is [un]assigned before e2 > iff v is [un]assigned after e1. > > COMPILATION: > These new expression forms can be desugared as follows: > > ? ? * e1?.name is rewritten as (t != null ? t.name : null) > ? ? * e1?.name(args) is rewriten as (t != null ? t.name(args) : null) > ? ? * e1?.new name(args) is rewritten as (t != null ? t.new name(args) > : null) > ? ? * e1?[e2] is rewritten as (t != null ? t[e2] : null) > ? ? * e1?:e2 is rewritten as (t != null ? t : e2) > > > where t is a new temporary that holds the computed value of the > expression e1. > > TESTING: > This feature can be tested by exercising the various new expression > forms, and verifying their correct behavior in erroneous and > non-erroneous situations, with or without null as the value of the > left-hand operand, and with respect to definite assignment and exception > analysis. > > LIBRARY SUPPORT: > No library support is required. > > REFLECTIVE APIS: > No reflective APIs require any changes. ?However, the not-yet-public > javac Tree APIs, which describe the syntactic structure of Java > statements and expressions, should be augmented with new tree forms for > these new expression types. > > OTHER CHANGES: > No other platform changes are required. > > MIGRATION: > No migration of existing code is recommended. ?These new language > features are mainly to be used in new code. ?However, IDEs should > provide refactoring advice for taking advantage of these new operators > when existing code uses the corresponding idiom. > > > *COMPATIBILITY* > > BREAKING CHANGES: > No breaking changes are caused by this proposal. > > EXISTING PROGRAMS: > Because the changes are purely the introduction of new expression forms, > there is no impact on the meaning of existing code. > > > *REFERENCES* > > EXISTING BUGS: > 4151957: Proposal: null-safe field access operator > > URL FOR PROTOTYPE: > No Java prototype exists at this time. ?However, Groovy[2] and Fan[3] > (among others) have the Elvis and null-safe member operators. > > OTHER REFERENCES > [1] Stephan Schmidt's discussion of Better Strategies for Null Handling > in Java - > http://www.slideshare.net/Stephan.Schmidt/better-strategies-for-null-handling-in-java > [2] Groovy Operators - http://groovy.codehaus.org/Operators > [3] Fan operators - > http://fandev.org/doc/docLang/Expressions.html#nullConvenience > [4] Stephen Colebourne's brief on null-safe operators - > http://docs.google.com/View?docid=dfn5297z_3c73gwb > [5] Summary of three recent language change polls showing better null > handling as a key developer request - > http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_everyone > [6] The version of this proposal written by Neal Gafter - > http://docs.google.com/Doc?docid=ddb3zt39_78frdf87dc&hl=en > > > From jeremy.manson at gmail.com Sun Mar 1 09:07:23 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 09:07:23 -0800 Subject: Use "default" keyword for default visibility. In-Reply-To: <6A1D1254-7506-4410-8DE2-795179B88F60@iam.unibe.ch> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> <6A1D1254-7506-4410-8DE2-795179B88F60@iam.unibe.ch> Message-ID: <1631da7d0903010907p2b3d0fd5nb03dca435608742e@mail.gmail.com> I'm not sure that I understand how using a package qualifier would actually help anyone's intuition in this case. You still get the same behavior. If you are getting the behavior anyway, the only people who would be helped by putting in an explicit package qualifier are those who already understand the existing override semantics. Those are the people who likely wouldn't have this problem in the first place. No? It is also worth pointing out that using the existing @Override annotation does, in fact, cover many of the cases that concern the author of this puzzler. Jeremy On Sun, Mar 1, 2009 at 2:20 AM, Adrian Kuhn wrote: > On 01.03.2009, at 10:15, Jeremy Manson wrote: > >> Could you dig up the example? ?It is hard to see why this is >> compelling without it. > > http://dow.ngra.de/2009/02/16/the-ultimate-java-puzzler > > --AA > From akuhn at gmx.ch Sun Mar 1 01:16:57 2009 From: akuhn at gmx.ch (Adrian Kuhn) Date: Sun, 1 Mar 2009 10:16:57 +0100 Subject: PROPOSAL: Multiline strings In-Reply-To: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> Message-ID: <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> On 01.03.2009, at 09:58, Jeremy Manson wrote: > Frankly, to me, the big win would actually not be multiline literals, > but would be escaped String literals. I'm sick of writing all of my > regexps with twice as many \ characters as they need. In this case, why not allow regexps to be written literally in source code? As is done in many other languages. Although, this change would couple the regexp API with the language. But maybe here, the benefit might be worth the costs. --AA From jeremy.manson at gmail.com Sun Mar 1 09:48:53 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 09:48:53 -0800 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49AABBA2.3040009@joda.org> References: <49AABBA2.3040009@joda.org> Message-ID: <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> > The principle perceived disadvantage, however, is that it encourages, > rather than discourages, the use of null values in APIs. I would think that the principle disadvantage would be not that it encourages use of null values (which, as you point out, is fine in some contexts), but that it encourages programmers not to think about what happens when there is a null value. I can easily imagine programmers using this all of the time without thinking about it, and then being surprised when a null ends up in the wrong place and not knowing how it got there. Even with a simple example: public String someFunction(String a, String b) { String s = a?.concat("foo"); String t = b?.concat(a); return myHashMap?.get(t); } Now, someFunction returns null. Is it because a was null? Or b was null? Or myHashMap was null? Or there was no mapping for t in myHashMap? I then imagine this spread out over 70 methods and 10,000 LOC, and realize that problems will be much harder to track down. In short, the danger is that lazy programmers start using this construct when getting a null value actually matters. I'd much rather stick with fail-fast NPEs for this case. If you want to cut down on extraneous if-testing, I would use JSR-305's Nullity annotations instead. Jeremy From jeremy.manson at gmail.com Sun Mar 1 09:53:35 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 09:53:35 -0800 Subject: PROPOSAL: Multiline strings In-Reply-To: <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> Message-ID: <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> The plus side of the escaped String approach is that you can then use any language, not just regexps. Also, escaped Strings might be a plus for security purposes. Also, I'm not a big fan of the idea of embedding the domain-specific-language-du-jour into my programming language. I see it as a slippery slope. It's regexps today, but it's XML tomorrow (I'm looking at you, Scala). Jeremy On Sun, Mar 1, 2009 at 1:16 AM, Adrian Kuhn wrote: > On 01.03.2009, at 09:58, Jeremy Manson wrote: > >> Frankly, to me, the big win would actually not be multiline literals, >> but would be escaped String literals. ?I'm sick of writing all of my >> regexps with twice as many \ characters as they need. > > In this case, why not allow regexps to be written literally in source > code? As is done in many other languages. Although, this change would > couple the regexp API with the language. But maybe here, the benefit > might be worth the costs. > > --AA > > From develop4lasu at gmail.com Sun Mar 1 10:39:25 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 1 Mar 2009 19:39:25 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49AABBA2.3040009@joda.org> References: <49AABBA2.3040009@joda.org> Message-ID: <28bca0ff0903011039n213e242dh52e2452e44ec856e@mail.gmail.com> Hello! I need add something MAJOR ADVANTAGE: It's multi-thread safe. Same goal for: final String aMember = g?.members?[0]?.name ?: "nobody"; would require for example: static String getBody(G g){ __ Member[] members = g==null ? null : g.members; __ Member member = members==null ? null : members[0]; __ String name = member==null ? "nobody" : member.name; __ return name; } final String aMember = g?.members?[0]?.name ?: "nobody"; >The ?: binary "Elvis" ... avoiding evaluation of the right-hand-side. I would like to see this operator more like: '?()' this would allow right-hand-side int len =g?.members?.[0]?.name ?("nobody") .length; I still wander how this operator should look like to be really easy to read '.?.' or '?.' or '?..'. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Sun Mar 1 10:41:54 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 1 Mar 2009 19:41:54 +0100 Subject: PROPOSAL: Multiline strings In-Reply-To: <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> Message-ID: <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> Embedding regexps has two significant advantages: 1. compile-time checking of your regexps. Sure, most random gibberish just so happens to be a valid regexp, but there are rules - you can have mismatched parentheses, for example. 2. compile-time compilation of regexps. If compiling the regexp is allowed to take rather long, then you can effectively create O(n) matching algorithms, where n is the size of the input string. What better time is there to do the compilation of the regexp than when you're compiling the code? Javac would essentially include the serialized form of a compiled regexp into the class file, instead of the string. As far as the multi-line string proposal: It is very incomplete. I suggest resubmitting it with documentation on handling raw strings (let's leave regexp literals for another proposal; as has been said, even if the language has regexp literals, raw strings are still a useful constrict), and on handling white space. It should also cover handling of newlines (if the file contains \r\n because it was written on windows, should those be kept as is or should they be replaced with \n line-endings, which seems like the right answer to me). My personal favourite way to do whitespace: After the first newline, eliminate all leading whitespace. Then consider that amount of whitespace (no translating of tabs to spaces) to be the indent. Thus, the following: String foo = """ bar baz bla qux"; is equal to: String foo = "bar\n baz\n bla\nqux"; and the following: String foo = """ foo bar"""; is a compile-time error. If you need leading whitespace, you'll need to prefix this in a separate string and concatenate them, or add them on the same line. So, if you need "\t\nfoo\n", and you don't want to use \t, you could write it as: String foo = "" < - You don't see it, but there's a tab here. foo """; or as: String foo = "\t" + """ foo """; --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 1, 2009, at 18:53, Jeremy Manson wrote: > The plus side of the escaped String approach is that you can then use > any language, not just regexps. Also, escaped Strings might be a plus > for security purposes. > > Also, I'm not a big fan of the idea of embedding the > domain-specific-language-du-jour into my programming language. I see > it as a slippery slope. It's regexps today, but it's XML tomorrow > (I'm looking at you, Scala). > > Jeremy > > On Sun, Mar 1, 2009 at 1:16 AM, Adrian Kuhn wrote: >> On 01.03.2009, at 09:58, Jeremy Manson wrote: >> >>> Frankly, to me, the big win would actually not be multiline >>> literals, >>> but would be escaped String literals. I'm sick of writing all of my >>> regexps with twice as many \ characters as they need. >> >> In this case, why not allow regexps to be written literally in source >> code? As is done in many other languages. Although, this change would >> couple the regexp API with the language. But maybe here, the benefit >> might be worth the costs. >> >> --AA >> >> > From reinier at zwitserloot.com Sun Mar 1 10:49:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 1 Mar 2009 19:49:06 +0100 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <15e8b9d20902282328v66a000e4ub1613d9811b86642@mail.gmail.com> References: <1FFA42B7-B682-4FD0-A39E-BD9C04207085@zwitserloot.com> <15e8b9d20902282328v66a000e4ub1613d9811b86642@mail.gmail.com> Message-ID: Neal, what I mean is the following sample cannot be translated to your 'out/in' syntax: public static > void sort(List list); The "T extends Comparable" part cannot be replaced with just 'out Comparable'. My suggestion involves allowing this to be rewritten as: public static > void sort(List list); Though, I share Stephen Colebourne's concern that the out/in syntax can be just as confusing in other situations, again highlighting how out/in and extends/super would co-exist (instead of a slow but steady migration towards out/in syntax), complicating the language. --Reinier Zwitserloot On Mar 1, 2009, at 08:28, Neal Gafter wrote: > On Sat, Feb 28, 2009 at 11:08 PM, Reinier Zwitserloot > wrote: >> This proposal is lacking in the 'disadvantages' section, in two ways. >> >> The listed disadvantage is unfairly sugared over; because the 'out/ >> in' >> terminology does not allow you to bind the generics parameter, the >> 'extends'/'super' syntax will never become outdated and the need to >> remember that 'out' is analogous to 'extends' and 'in' is analogous >> to >> 'super' does not go away. > > I don't understand. out/in bind the generic parameter in precisely > the same way that ?extends and ?super do. What you describe is a > disadvantage of the current syntax, but when using the new syntax you > don't have to remember it, because the new syntax is self-mneumonic. > >> There's another disadvantage that isn't listed at all: Neither 'in' >> nor 'out' are keywords in java currently. Therefore, you introduce >> the >> notion of a context-sensitive keyword, but as far as I understand it, >> java does not currently have context-sensitive keywords. Adding them >> is a big can of worms that should probably warrant some discussion >> (in >> the sense that it may complicate java parsers, and how the idea of >> context-sensitive keywords makes it a lot harder for any parser to >> use >> a keyword as an anchor point); at any rate it is a disadvantage that >> should be listed. > > Any change in syntax has to be considered for its interaction with > other tools, but for this particular case the general concerns you > express don't seem to be an issue. For example, this syntax is very > easy to parse with no more than the usual one-token lookahead. > >> There's also a typo in 'mneumonic' :) >> >> NB: For what it's worth, because the need to remember super-produces >> extends-consumes does not go away, I don't think this is going to >> help >> much. > > You don't have to remember that when reading and writing the new > syntax. > >> Perhaps make 'out' and 'in' valid context-sensitive keywords >> that can be used as a substitution for super and extends > > That's exactly what we've done, but with in/out you don't use the > question mark either. > >> and add that >> a missing generics variable on the LHS implies a wildcard? > > I don't understand what you propose, or see how it relates to this > proposal. From develop4lasu at gmail.com Sun Mar 1 11:10:20 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 1 Mar 2009 20:10:20 +0100 Subject: PROPOSAL: Multiline strings In-Reply-To: References: Message-ID: <28bca0ff0903011110k8bba3f8i4c14fb9de056c020@mail.gmail.com> Hello! MAJOR DISADVANTAGE: Code formatting can be some problem (visual). Now formatting consider code logic, not text logic. . Add to IDE (like eclipse,...) possibility to "paste escaped" "copy escaped" "view escaped" would not solve problem finally? And allow to keep language as it is? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From akuhn at iam.unibe.ch Sun Mar 1 11:58:27 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Sun, 1 Mar 2009 20:58:27 +0100 Subject: Use "default" keyword for default visibility. In-Reply-To: <1631da7d0903010907p2b3d0fd5nb03dca435608742e@mail.gmail.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> <6A1D1254-7506-4410-8DE2-795179B88F60@iam.unibe.ch> <1631da7d0903010907p2b3d0fd5nb03dca435608742e@mail.gmail.com> Message-ID: <99618040-66B2-40C1-BE5A-20006CBA5FBF@iam.unibe.ch> On Mar 1, 2009, at 18:07 , Jeremy Manson wrote: > I'm not sure that I understand how using a package qualifier would > actually help anyone's intuition in this case. It help by making it explicit. --AA From akuhn at iam.unibe.ch Sun Mar 1 12:03:07 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Sun, 1 Mar 2009 21:03:07 +0100 Subject: PROPOSAL: Multiline strings In-Reply-To: <28bca0ff0903011110k8bba3f8i4c14fb9de056c020@mail.gmail.com> References: <28bca0ff0903011110k8bba3f8i4c14fb9de056c020@mail.gmail.com> Message-ID: <4114D9EB-D2F5-442F-AA91-F0BA1806A078@iam.unibe.ch> On Mar 1, 2009, at 20:10 , Marek Kozie? wrote: > Add to IDE (like eclipse,...) possibility to "paste escaped" "copy > escaped" > "view escaped" would not solve problem finally? > And allow to keep language as it is? I would love to have "edit string" which pop-ups a text editor on the string's content. (Alas, I lack the Eclipse-Fu to hack this plugin myself.) --AA NB sorry, for being so offtopic. From jeremy.manson at gmail.com Sun Mar 1 13:17:49 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 1 Mar 2009 13:17:49 -0800 Subject: Use "default" keyword for default visibility. In-Reply-To: <99618040-66B2-40C1-BE5A-20006CBA5FBF@iam.unibe.ch> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <1631da7d0903010115k8e9d868ld823066dc679ad4e@mail.gmail.com> <6A1D1254-7506-4410-8DE2-795179B88F60@iam.unibe.ch> <1631da7d0903010907p2b3d0fd5nb03dca435608742e@mail.gmail.com> <99618040-66B2-40C1-BE5A-20006CBA5FBF@iam.unibe.ch> Message-ID: <1631da7d0903011317r5f07e429ne186e62b44913e49@mail.gmail.com> I think I was perhaps unclear. I'm not sure how making it explicit would make people understand the inheritance properties (as described in your link) any better. If they don't know that package-private methods can't be overridden in those cases, then making it explicit seems unlikely to change that. Jeremy On Sun, Mar 1, 2009 at 11:58 AM, Adrian Kuhn wrote: > On Mar 1, 2009, at 18:07 , Jeremy Manson wrote: > >> I'm not sure that I understand how using a package qualifier would >> actually help anyone's intuition in this case. > > It help by making it explicit. > > --AA > From rssh at gradsoft.com.ua Sun Mar 1 10:15:00 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 1 Mar 2009 20:15:00 +0200 (EET) Subject: PROPOSAL: Multiline strings (EOL handling) In-Reply-To: <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> Message-ID: > Embedding regexps has two significant advantages: > ....... > I think that unescaped strings are useful not only for reqular expressions. Embedding of special syntax for regexprs -- may be this is another issue (and I afraid much less trivial then this) > > As far as the multi-line string proposal: It is very incomplete. I > suggest resubmitting it with documentation on handling raw strings > (let's leave regexp literals for another proposal; as has been said, > even if the language has regexp literals, raw strings are still a > useful constrict), and on handling white space. It should also cover > handling of newlines (if the file contains \r\n because it was written > on windows, should those be kept as is or should they be replaced with > \n line-endings, which seems like the right answer to me). > Sorry, but handling of newlines is described: After parsing multiline string is concatenation of lines with inseted value of system property 'line.separator' between thems. And 'line.separator' is '\n' on unix and '\r\n' on windows. but yes, replacing all end of lines to '\n' (string normalizing) make sence. (I will add issue) Yet on question: it can be optional or by default. I. e. variant OPTIONAL: a) we can add suffix "u" or "w" for unix-like or windows-like EOL handling and leave one as in program text by default. variant DEFAULT: b) always normalize multiline strings, by replacing '\r\n' to '\n' > My personal favourite way to do whitespace: > > After the first newline, eliminate all leading whitespace. Then .... (Ok, will add issue [next letter will be about this to spit different issues to different threads]) From rssh at gradsoft.com.ua Sun Mar 1 10:48:44 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 1 Mar 2009 20:48:44 +0200 (EET) Subject: PROPOSAL: Multiline strings (processing of whitespaces) In-Reply-To: <4114D9EB-D2F5-442F-AA91-F0BA1806A078@iam.unibe.ch> References: <28bca0ff0903011110k8bba3f8i4c14fb9de056c020@mail.gmail.com> <4114D9EB-D2F5-442F-AA91-F0BA1806A078@iam.unibe.ch> Message-ID: <2738e7cc1a4f2e6e46d6ae4fde76279e.squirrel@wmail.gradsoft.ua> About algorith of witespace processing, described by Reinier Zwitserloot: (see comments to http://redmine.gradsoft.ua/issues/show/161). Clearly we have next variants to choose from: A) keep multiline string without any special whitespace proccessing, but add special syntax (with four double quotes or suffixes) for whitespace processing. B) do whitespace processing by default, without any special form C) does not do any whitespace processing. is overkill or not ? look's fine (usially we have logic in identation). But let think twice about potential hidden problems ? Any ideas ? From mark at twistedbanana.demon.co.uk Sun Mar 1 17:57:26 2009 From: mark at twistedbanana.demon.co.uk (Mark Mahieu) Date: Mon, 2 Mar 2009 01:57:26 +0000 Subject: PROPOSAL: Multiline strings In-Reply-To: <9724b4d386667dda06c3586d7ce0748e.squirrel@wmail.gradsoft.ua> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <9724b4d386667dda06c3586d7ce0748e.squirrel@wmail.gradsoft.ua> Message-ID: <1FF9F7A4-C193-44A5-8C59-849922B2B391@twistedbanana.demon.co.uk> On 1 Mar 2009, at 06:50, rssh at gradsoft.com.ua wrote: > > 1. Since we have non-empty discussion, I setup wiki with current > proposal > ('new string literals instead multiline strings (?)') You may want to consider adding a couple of references to your proposal: http://bugs.sun.com/view_bug.do?bug_id=4472509 which has 76 votes, and links to a number of related bug reports http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd by Jacek Furmankiewicz, see the Kijaro mailing list archive for more information (https://kijaro.dev.java.net/) Regards, Mark From rssh at gradsoft.com.ua Sun Mar 1 18:38:11 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 2 Mar 2009 04:38:11 +0200 (EET) Subject: PROPOSAL: Multiline strings In-Reply-To: <1FF9F7A4-C193-44A5-8C59-849922B2B391@twistedbanana.demon.co.uk> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <9724b4d386667dda06c3586d7ce0748e.squirrel@wmail.gradsoft.ua> <1FF9F7A4-C193-44A5-8C59-849922B2B391@twistedbanana.demon.co.uk> Message-ID: > > On 1 Mar 2009, at 06:50, rssh at gradsoft.com.ua wrote: > >> >> 1. Since we have non-empty discussion, I setup wiki with current >> proposal >> ('new string literals instead multiline strings (?)') > > > You may want to consider adding a couple of references to your proposal: > Added (interesting, that 4165111 have 0 votes, when 4472509 - 76) > http://bugs.sun.com/view_bug.do?bug_id=4472509 > which has 76 votes, and links to a number of related bug reports > > http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd > by Jacek Furmankiewicz, see the Kijaro mailing list archive for more > information (https://kijaro.dev.java.net/) > > > Regards, > > Mark > > From brucechapman at paradise.net.nz Mon Mar 2 00:23:57 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Mon, 02 Mar 2009 21:23:57 +1300 Subject: Byte and short Integer Literals - discussion Message-ID: <49AB979D.9040301@paradise.net.nz> I am working on a proposal to add byte and short integer literals in order to ease some of the pain caused by byte being a signed type when most uses are just as a set of bits. Its mostly about byte size hexadecimal literals but other forms should be considered for completeness. One option ( work in progress at http://docs.google.com/Doc?docid=dcvp3mkv_0fvz5gx7b&hl=en ) is to allow integer type suffixes for byte (say y and Y) and short (say s and S) . That fits into the existing spec quite easily but looks a bit odd e.g. byte[] stuff = { 0x00y, 0x7Fy, 0x80y, 0xFFy }; Another approach would be to introduce a completely new syntax for hexadecimal integer literals which are typed according to the number of digits. for example (new syntax uses 0h compared with 0x for current int literals) byte b = 0hFF; short s = 0hFFFF; int i = 0hffffffff; long l = 0hffffffffffffffff; type determination would follow these rough rules. 1 or 2 digits -> byte literal 3 or 4 digits -> short 5 - 8 digits -> int 9 - 16 digits -> long. leading zeros permissible eg short s = 0h0000; So question: Do either of these stand out as superior (from a coin perspective) to the other in any significant way? I'd like to spend the majority effort on the better one if there is a significant preference on the mailing list. I am of two minds which is why I am asking. Bruce From rssh at gradsoft.com.ua Sun Mar 1 20:14:03 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 2 Mar 2009 06:14:03 +0200 (EET) Subject: Byte and short Integer Literals - discussion In-Reply-To: <49AB979D.9040301@paradise.net.nz> References: <49AB979D.9040301@paradise.net.nz> Message-ID: > integer type suffixes for byte (say y and Y) and short (say s and S) . > .... > Another approach would be to introduce a completely new syntax for > hexadecimal integer literals which are typed according to the number of ... I vote for suffixes. From rssh at gradsoft.com.ua Sun Mar 1 20:16:22 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 2 Mar 2009 06:16:22 +0200 (EET) Subject: Byte and short Integer Literals - discussion In-Reply-To: <49AB979D.9040301@paradise.net.nz> References: <49AB979D.9040301@paradise.net.nz> Message-ID: <7c991a71a0a7d27807517feac45aa7f3.squirrel@wmail.gradsoft.ua> > http://docs.google.com/Doc?docid=dcvp3mkv_0fvz5gx7b&hl=en ) is to allow > > byte[] stuff = { 0x00y, 0x7Fy, 0x80y, 0xFFy }; > Why 'y', not 'b' ? From reinier at zwitserloot.com Mon Mar 2 04:19:36 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 2 Mar 2009 13:19:36 +0100 Subject: Byte and short Integer Literals - discussion In-Reply-To: <7c991a71a0a7d27807517feac45aa7f3.squirrel@wmail.gradsoft.ua> References: <49AB979D.9040301@paradise.net.nz> <7c991a71a0a7d27807517feac45aa7f3.squirrel@wmail.gradsoft.ua> Message-ID: rssh: Because 'b' is a legal hexadecimal character. is 0xbb: '11 decimal as a byte literal', or is it '187 decimal as an int literal'? I think 0h as a general unsigned literal prefix that will automatically adjust its type based on length is far superior to introducing a gaggle of more or less random character suffixes - while doing byte hackery in java is painful, it still is a relatively small and niche aspect of java. In theory, every language aspect needs to be known implicitly by all java developers because its not easy to ask your IDE about showing you some javadoc for such a feature. Therefore, it should look obvious and simple, and not like voodoo, which 0x00y smacks of. Also, if you're going to go with suffixes, then for completeness sake, don't you need 6 suffixes total? (Byte Unsigned, Byte Signed, Short Unsigned, Short signed, int unsigned, long unsigned)? Just to highlight the mess that's going to become. Also note that the current suffix-L notation for long is part of a java puzzler (a minor one; l can be lowercase, which looks just like a 1, which is unfortunate). --Reinier Zwitserloot On Mar 2, 2009, at 05:16, rssh at gradsoft.com.ua wrote: >> http://docs.google.com/Doc?docid=dcvp3mkv_0fvz5gx7b&hl=en ) is to >> allow >> >> byte[] stuff = { 0x00y, 0x7Fy, 0x80y, 0xFFy }; >> > > Why 'y', not 'b' ? > > > > > From Joe.Darcy at Sun.COM Mon Mar 2 21:46:50 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 02 Mar 2009 21:46:50 -0800 Subject: Proposal: Block Expressions for Java In-Reply-To: <15e8b9d20902272130i3e52b349ta500f4b98accec01@mail.gmail.com> References: <15e8b9d20902272121q2f625b1cq3230f5260bcddfe4@mail.gmail.com> <15e8b9d20902272130i3e52b349ta500f4b98accec01@mail.gmail.com> Message-ID: <49ACC44A.1040609@sun.com> Hi Neal. While I have some sympathy for expression-oriented rather than statement-oriented languages, my general reaction to this proposal is that it doesn't offer much incremental utility for expressing and simplifying programming idioms commonly used today, which is the main goal for Project Coin. Some more comments in line... Neal Gafter wrote: > [Resending in plain text] > > Block Expressions for Java > > AUTHOR(S): > > Neal Gafter > > OVERVIEW > > FEATURE SUMMARY: > > A parenthesized expression can now contain additional statements, for > example declarations of temporary local variables to avoid recomputing > a value used only within the expression. This feature is especially > useful in machine-generated code. > > MAJOR ADVANTAGE: > > Allows the declaration of local temporary variables closer to the > point of use. Simplifies programs that generate Java code, as > temporary variables that are used in only a single expression can be > declared with the expression. > > MAJOR BENEFIT: > > Simplifies some patterns of code (see above). Makes it easier to > write expression-oriented code even though many APIs are statement- or > side-effect-oriented. Allows temporaries to be declared closer to the > point of use. > > MAJOR DISADVANTAGE: > > Slightly more complex language specification. Like most other > language features, can be overused to the detriment of the readability > of the code. > > ALTERNATIVES: > > In many cases, there are alternate though awkward ways of writing the > code, such as introducing small helper functions that are used only > once or introducing temporary variables. > > EXAMPLES > > SIMPLE EXAMPLE: > > double pi2 = (double pi = Math.PI ; pi*pi); // pi squared > > ADVANCED EXAMPLE: > > public static final Map primes = ( > Map t = new HashMap(); > t.put(1, 2); t.put(2, 3); t.put(3, 5); t.put(4, 7); > Collections.UnmodifiableMap(t)); > > DETAILS > > SPECIFICATION: > > Grammar: the grammar for a parenthesized expression [JLS 15.8.5] is changed to: > > ParExpression: > ( BlockStatementsopt Expression ) > > Note that the existing syntax for a parenthesized expression is a > special case of this. > > Meaning of Expressions: The specification for a parenthesized > expression should be modified to describe its new execution semantics: > The block statements (if any) are executed in sequence, from left to > right, exactly as in a block statement. The result of the > parenthesized expression is the result of evaluating its > subexpression. > So what about return, break, and continue statements inside the BlockStatements? > Definite Assignment: The definite assignment rules for this construct > are almost identical to that for the block statement. The definite > assignment state before the subexpression is the definite assignment > state following the last block statement. > > Exception Checking: A parenthesized expression can throw exception > type E if any statement or expression immediately contained in it can > throw E. > > Scoping: Local variables and classes declared by an immediately > contained statement is in scope until the end of the parenthesized > expression. > > Meaning of Statements: No changes. > > Type System: No changes. > > COMPILATION: > > Compilation is straightforward, with one minor exception (no pun > intended). The compiler must arrange the generated code such that the > stack is empty at the beginning of any try statement that can complete > normally when the try statement is embedded within a parenthesized > expression. That is because the VM empties the stack when exceptions > are handled. This can be accommodated by spilling values from the > stack into VM locals. > That doesn't necessarily sound minor! > TESTING: > > Since the language change is completely local, it can be tested by > exercising each of its interactions described above. > > LIBRARY SUPPORT: > > None required. > > REFLECTIVE APIS: > > No changes required. > > OTHER CHANGES: > > It would be desirable, at the same time that this change is made, to > update the non-public Tree API that can be used with APT to express > the syntax extension. > FYI and to be precise on notation, we will *not* be updating apt to work with JDK 7 language features at all. In contrast, the JSR 269 language model and annotation processing API used by javac will be updated. The tree API will be updated as needed for any new language features, and, as you imply, using javac-specific APIs (i.e. non JCP APIs) it is possible to use the Tree API with JSR 269 annotation processing. Cheers, -Joe > MIGRATION: > > None required. > > COMPATIBILITY > > BREAKING CHANGES: > > No breaking changes. > > EXISTING PROGRAMS: > > No effect on existing programs. This is a pure extension. > > REFERENCES > > EXISTING BUGS: > > None. > > URL FOR PROTOTYPE (optional): > > None. > > From philvarner at gmail.com Mon Mar 2 22:11:50 2009 From: philvarner at gmail.com (Phil Varner) Date: Mon, 2 Mar 2009 22:11:50 -0800 Subject: Proposal: Import Aliases for Classes and Static Methods Message-ID: Import Aliases for Classes and Static Methods http://docs.google.com/Doc?id=dgx74dt7_19dxnspbhj AUTHOR: Phil Varner OVERVIEW FEATURE SUMMARY: The import aliases feature allows a user to provide an alias underwhich an imported class or statically imported method must be referred to in the containing source file. An example of the use of this feature is "import java.sql.Date as SqlDate;" MAJOR ADVANTAGE: This feature would allow easier use of multiple classes which have the same name but different packages to be used in the same source file. MAJOR BENEFIT: This will prevent the necessity of fully-qualifiying all class references when there is a name collision, leading to more readable code. MAJOR DISADVANTAGE: This will introduce an extra level of indirection when determing the source of a given class or method, introduce a new keyword 'as', and will require changes to IDE code completion functionality. ALTERNATIVES: In some cases, a nested class can be created which trivially derives a class involved in the name collision. For a method, a wrapper method can be created in the source file. EXAMPLES SIMPLE EXAMPLE: Example #1, duplicate class name Current code: new java.sql.Date(new java.util.Date()); New code: import java.sql.Date as SqlDate; import java.util.Date as UtilDate; new SqlDate(new UtilDate()); Example #2, statically imported method alias Current code: import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName; public static int mrlacsmn(final int arg1, final String arg2){ return myReallyLongAndComplicatedStaticMethodName(arg1, arg2); } mrlacsmn(1, a); New code: import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName as mrlacsmn; mrlacsmn(1, a); ADVANCED EXAMPLE: Example #3 Translation of persistent formats between similar APIs. In many domains, it is not uncommon to have two different APIs with classes with the same name. For example, in a production rules API, one may have classes "RuleSet" and "Rule". When attempting to use the API to translate between these these APIs, it must be decided that one is fully-qualified and one is not. This can lead to code like: com.example.foo.bar.sdk.RuleSet srcRuleSet = ...; com.example.foo.bar.sdk2.RuleSet dstRuleSet = new com.example.foo.bar.sdk2.RuleSet(); migrate(srcRuleSet, dstRuleSet); ... private static void migrate(com.example.foo.bar.sdk.RuleSet srcRuleSet, com.example.foo.bar.sdk2.RuleSet dstRuleSet){ ... } Note that it is good practice here not to import either class because it is too easy to accidentally misuse constants and static methods. With the 'as' syntax, one could instead write the far less verbose and more readible: import com.example.foo.bar.sdk.RuleSet as SrcRuleSet; import com.example.foo.bar.sdk2.RuleSet as DstRuleSet; ... SrcRuleSet srcRuleSet = ...; DstRuleSet destRuleSet = new DstRuleSet(); migrate(srcRuleSet, dstRuleSet); ... private static void migrate(SrcRuleSet srcRuleSet, DstRuleSet dstRuleSet){ ... } Example #4 Ensuring correct method selection when static importing overloaded methods. Current code: import static org.testng.Assert.assertEquals; public static int aeo(Object arg1, Object arg2){ assertEquals(arg1, arg2); } public static int aec(Collection arg1, Collection arg2){ assertEquals(arg1, arg2); } aeo(obj1, obj2); aec(list1, list2); New code: import static org.testng.Assert.assertEquals(Object, Object) as aeo; import static org.testng.Assert.assertEquals(Collection, Collection) as aec; aeo(obj1, obj2); aec(list1, list2); Note: it is possible that this sort of method selection is beyond the scope of a COIN proposal DETAILS SPECIFICATION: Grammar modification (JLS 3.9): Keyword: as ... modification (JLS 7.5): ImportDeclaration: SingleTypeImportDeclarationWithAlias SingleStaticImportDeclarationWithAlias ... addition: SingleTypeImportDeclarationWithAlias: import TypeName as Identifier; addition: SingleStaticImportDeclarationWithAlias: import static TypeName . Identifier as Identifier; Note that this would explicitly forbid wildcard imports from being aliased. There are no known effects on the type system or meaning of expressions and statements in the Java Programming Language. COMPILATION: This feature would be a compile-time transform. It would only affect the way in which a non-fully qualified class or method name was resolved to a fully-qualified class or method name. TESTING: This change would be tested in a manner similar how how the existing code which resolves the fully-qualified names of classes and methods is tested. LIBRARY SUPPORT: No change REFLECTIVE APIS: No change OTHER CHANGES: No change MIGRATION: This change is backwards-compatible with existing code. COMPATIBILITY BREAKING CHANGES: No change EXISTING PROGRAMS: No change REFERENCES EXISTING BUGS: None at present URL FOR PROTOTYPE (optional): None at present From Joe.Darcy at Sun.COM Mon Mar 2 22:29:29 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 02 Mar 2009 22:29:29 -0800 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> Message-ID: <49ACCE49.8030103@sun.com> Hello. Comments in line... Neal Gafter wrote: > [Resending in plain text] > > Improved Exception Handling for Java > > AUTHOR(S): > > Neal M Gafter > > OVERVIEW > > FEATURE SUMMARY: > > Catching multiple exception types: A single catch clause can now catch > more than one exception types, enabling a series of otherwise > identical catch clauses to be written as a single catch clause. > Improved checking for rethrown exceptions: Previously, rethrowing an > exception was treated as throwing the type of the catch parameter. > Now, when a catch parameter is declared final, rethrowing the > exception is known statically to throw only those checked exception > types that were thrown in the try block, are a subtype of the catch > parameter type, and not caught in preceding catch clauses. > > MAJOR ADVANTAGE: > > Catching multiple exception types: Simplifies a commonly appearing > pattern of redundant code. > Improved checking for rethrown exceptions: This improvement makes it > possible to add a try-catch statement around a block of code to > intercept, process, and rethrow an exception without affecting the > statically determined set of exceptions thrown from the code. > > MAJOR BENEFIT: > > Greatly simplifies writing and maintaining code where intercepting or > processing exceptions is common. > > MAJOR DISADVANTAGE: > > One-time implementation cost for adding the features to the compiler. > Longer language specification in describing the behavior. > What sort of poor programming practices could this feature encourage or enable? > ALTERNATIVES: > > These behaviors are approximated currently by writing a series of > identical catch clauses. During maintenance, the set of catch clauses > must be modified so that it continues to match the set of exceptions > statically thrown in the try block. With the proposed changes, the > catch block can be written to catch a supertype of the set of > exceptions to be intercepted, resulting in fewer catch clauses and > fewer changes required when the try block evolves. > Another poor alternative used too often in practice is to catch a too general type, like Throwable, to avoid repeating more specific catch clauses. > EXAMPLES > > SIMPLE EXAMPLE: > > try { > doWork(file); > } catch (final IOException|SQLException ex) { > logger.log(ex); > throw ex; > } > > ADVANCED EXAMPLE: > > Show advanced usage(s) of the feature. > > DETAILS > > SPECIFICATION: > > The grammar of Java is extended to allow a series of exception types, > separated by the "OR" operator symbol, to be used in a catch clause: > > CatchClause: > catch ( CatchFormalParameter ) Block > CatchFormalParameter: > VariableModifiers CatchType VariableDeclaratorId > CatchType: > DisjunctionType > DisjunctionType: > Type > Type | DisjunctionType > > The type system is affected as follows: For the purpose of type > checking, a catch parameter declared with a disjunction has type > lub(t1, t2, ...) [JLS3 15.12.2.5]. In terms of finding the members of the type, it is good existing concepts in the JLS can be used. What happens if someone writes catch(final IOException | SomeSubclassOfIOException e) {...} In other words, is it legal to have subclasses of a caught exception listed too? > For the purpose of exception > checking [JLS3 11.2], a throw statement [JLS3 11.2.2] that rethrows a > final catch parameter is treated as throwing precisely those exception > types that > > the try block can throw, > no previous catch clause handles, and > is a subtye of one of the types in the declaration of the catch parameter > > To avoid the need to add support for general disjunctive types, but > leaving open the possibility of a future extension along these lines, > a catch parameter whose type has more than one disjunct is required to > be declared final. > I think that is a fine compromise that keep the current feature smaller while allowing room for a broader feature later. Some worked examples of the sets of thrown exceptions types under various tricky code samples would help clarify the data flow algorithm for me. > COMPILATION: > > A catch clause is currently compiled (before this change) to an entry > in an exception table that specifies the type of the exception and the > address of the code for the catch body. To generate code for this new > construct, the compiler would generate an entry in the exception table > for each type in the exception parameter's list of types. > Interesting; so there would be no code duplication even in the class files. > TESTING: > > The feature can be tested by compiling and running programs that > exercise the feature. > > LIBRARY SUPPORT: > > No. > > REFLECTIVE APIS: > > No reflective API changes are required. > > OTHER CHANGES: > > It would be desirable, at the same time that this change is made, to > update the non-public Tree API that can be used with APT to express > the syntax extension. > The Tree API (http://java.sun.com/javase/6/docs/jdk/api/javac/tree/index.html) has a bit different situation than other APIs in the JDK. The tree API is *not* a JCP API, but we at Sun choose to ship it and document it as part of Sun's JDK. So the API is public in that sense, but it has a different support, stability, and compatibility contract than JCP APIs. > MIGRATION: > > None required. However, it would be easy to detect a series of > otherwise identical catch clauses for different types and collapse > them to a single catch clause. > > COMPATIBILITY > > BREAKING CHANGES: > > Joe Darcy observes that the following program compiles before this > change, but not after: > > try { > throw new DaughterOfFoo(); > } catch (final Foo exception) { > try { > throw exception; // used to throw Foo, now throws DaughterOfFoo > } catch (SonOfFoo anotherException) { // Reachable? > } > } > > However > > This breakage is compile-time-only; already-compiled programs continue > to behave as before > This kind of breakage is very unlikely to occur in practice, and > The broken code was likely wrong before, as it attempts to catch > exceptions that simply cannot occur. > I am a bit concerned by the existence of such a program, as uncommon or ill-posed as it might be. It is preferable to have a pure extension that doesn't invalidate any existing programs. The platform promises JLS chapter 13 binary compatibility from release to release; that binary compatibility is defined to be the continued ability to link, nothing more. Source compatibility is *not* promised from release to release, and source compatibility is not defined in the JLS (I take a stab at drawing out source compatibility thread levels in http://blogs.sun.com/darcy/entry/kinds_of_compatibility). However, source compatibility should be maintained if possible. How could the increased exception precision be maintained will still allow programs such as the one above to compile? Thanks for sending this in, -Joe > EXISTING PROGRAMS: > > Except as above, none. > > REFERENCES > > EXISTING BUGS: > > No existing bugs that I am aware of. > > URL FOR PROTOTYPE (optional): > > An implementation of disjunctive catch parameters, but without special > handling for final catch parameters: > > http://www.javac.info/ > > See also > > Catching Multiple Exception Types: http://www.javac.info/Multicatch.html > Improved Checking for Rethrown Exceptions: http://www.javac.info/Rethrown.html > > From rhvarona at gmail.com Mon Mar 2 21:02:08 2009 From: rhvarona at gmail.com (Roger Hernandez) Date: Tue, 3 Mar 2009 00:02:08 -0500 Subject: Simple Resource Clean-up Message-ID: I saw how the previous Automatic Resource Management proposal got torn to pieces but I feel strongly enough about this issue to post a similar proposal. Some points: I am not a programming language designer. I have very little experience with byte code and with design and implementation of compilers. What I do have is many years of experience in writing code for large business applications, both in house-custom programs and shrink-wrapped products sold to customers. About 1/3 of the Java code I write contributes almost nothing to the functionality or flexibility of the program. It is composed of very simple and very repetitive resource clean-up code. JDBC code is an especially bad case. I know we should be using JDO or JPA, but: 1) most of the Java database code in existence is using JDBC to some extent or another, 2) for the kind of processing our software does with large datasets having hundreds of megabytes of row data and millions of rows per account per month, custom JDBC code still beats the other solutions in memory utilization and throughput. In most business code we don't do complex exception processing. If we get a exception we rollback the transaction and unroll the stack until we reach some program level error handler that logs the error for some administrator to review at a later date. So if this proposal is not applicable to complex error handling scenarios, that is fine. Taking care of the simple scenarios will still get rid of most of that 1/3 of the code I write, allowing me to concentrate on the actual program logic, not the resource clean-up noise. I also program quite a bit in C++ and C# and when I work in Java I sorely miss RAII (Resource Acquisition Is Initialization) and the "using" statement respectively. At the end of the day, what I would like is a solution to minimize all the resource clean-up boiler plate. ----------------------------------------------------------------------------------------- PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR: Roger Hernandez, rogerh at velocityconsultinginc.com OVERVIEW FEATURE SUMMARY: Syntactic sugar for simple cases of the common new/try/finally/close language idiom. The object being created must implement the Closeable interface. MAJOR ADVANTAGE: Significantly reduces lines of code when working with objects that encapsulate external resources that should be closed as soon as possible. Examples are Stream, Reader, Writer classes in java.io, and Connection, Statement, PreparedStatement, ResultSet in java.sql.*. MAJOR BENEFIT: It allows writing code that uses these kinds of object to more clearly express the both the lifetime of the utilization of each resource, and allows the logic flow of the code to be more visible. MAJOR DISADVANTAGE: Either a new keyword, or an additional overloaded meaning on an existing keyword. ALTERNATIVES: You can always use the standard idiom: SomeType val = new val(...); try { ... } finally { val.close(); } EXAMPLES SIMPLE EXAMPLE: A simple Java version of the command line utility "tee". //This is the existing way of doing it. //Lines of code: 19 package com.vci.projectcoin.using; import java.io.*; public class SimpleExample { public static void main(String[] args) throws IOException { byte []buffer = new byte[1024]; FileOutputStream out = new FileOutputStream(args[0]); try { for (int count; (count = System.in.read(buffer)) != -1;) { out.write(buffer, 0, count); System.out.write(buffer, 0, count); } } finally { out.close(); } } } //This is the proposed way of doing it, the compiler converts the syntactic sugar into the same byte codes //I am adding a new use to the the "try" keyword to avoid adding more to the language, but it would work //just a well with a "using" keyword. //Lines of code: 16 package com.vci.projectcoin.using; import java.io.*; public class SimpleExample { public static void main(String[] args) throws IOException { byte []buffer = new byte[1024]; try (FileOutputStream out = new FileOutputStream(args[0])) { for (int count; (count = System.in.read(buffer)) != -1;) { out.write(buffer, 0, count); System.out.write(buffer, 0, count); } } } } ADVANCED EXAMPLE: A simple utility to execute a query and write values as a comma delimited file. //This is the existing way of doing it //Lines of code: 55 package com.vci.projectcoin.using; import java.sql.*; import java.io.*; public class AdvancedExample { final static String EOL = System.getProperty("line.separator"); //Command Line: [] static public void main(String []args) throws SQLException, FileNotFoundException { String url = args[0]; String sql = args[1]; PrintWriter out = new PrintWriter(args.length > 2 ? new FileOutputStream(args[2]) : System.out); try { Connection conn = DriverManager.getConnection(url); try { Statement query = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); try { ResultSet results = query.executeQuery(sql); try { ResultSetMetaData meta = results.getMetaData(); int colCount = meta.getColumnCount(); while (results.next()) { for (int index = 1; index <= colCount; index++) { int colType = meta.getColumnType(index); boolean quoted = colType == Types.CHAR || colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; if (quoted) { System.out.append('"'); } System.out.append(results.getString(index)); if (quoted) { System.out.append('"'); } if (index < colCount) { System.out.print(','); } else { System.out.print(EOL); } } } } finally { results.close(); } } finally { query.close(); } } finally { conn.close(); } } finally { out.close(); } } } //This is the proposed way of doing it //This proposal gets rid of the finally clean up per object. It lets one write robust resource clean-up code without a lot of effort. //Lines of code: 43 package com.vci.projectcoin.using; import java.sql.*; import java.io.*; public class AdvancedExample { final static String EOL = System.getProperty("line.separator"); //Command Line: [] static public void main(String []args) throws SQLException, FileNotFoundException { String url = args[0]; String sql = args[1]; try (PrintWriter out = new PrintWriter(args.length > 2 ? new FileOutputStream(args[2]) : System.out)) { try (Connection conn = DriverManager.getConnection(url)) { try (Statement query = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) { try (ResultSet results = query.executeQuery(sql)) { ResultSetMetaData meta = results.getMetaData(); int colCount = meta.getColumnCount(); while (results.next()) { for (int index = 1; index <= colCount; index++) { int colType = meta.getColumnType(index); boolean quoted = colType == Types.CHAR || colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; if (quoted) { System.out.append('"'); } System.out.append(results.getString(index)); if (quoted) { System.out.append('"'); } if (index < colCount) { System.out.print(','); } else { System.out.print(EOL); } } System.out.println(); } } } } } } } //This is an additional syntactic sugar proposal, allowing multiple objects to be allocated inside one try block. The compiler converts all three programs into the same bytecode //This proposal gets rid of the additional indentation level and closing brace per object. It further minimize the clean-up boiler-plate, allowing the point of the program logic to be clearer. //Lines of code: 38 package com.vci.projectcoin.using; import java.sql.*; import java.io.*; public class AdvancedExample { final static String EOL = System.getProperty("line.separator"); //Command Line: [] static public void main(String []args) throws SQLException, FileNotFoundException { String url = args[0]; String sql = args[1]; try (PrintWriter out = new PrintWriter(args.length > 2 ? new FileOutputStream(args[2]) : System.out), Statement query = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY), ResultSet results = query.executeQuery(sql)) { ResultSetMetaData meta = results.getMetaData(); int colCount = meta.getColumnCount(); while (results.next()) { for (int index = 1; index <= colCount; index++) { int colType = meta.getColumnType(index); boolean quoted = colType == Types.CHAR || colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; if (quoted) { System.out.append('"'); } System.out.append(results.getString(index)); if (quoted) { System.out.append('"'); } if (index < colCount) { System.out.print(','); } else { System.out.print(EOL); } } System.out.println(); } } } } DETAILS The specification requires that the object in the try () block have a "close()" method. Wether the method throws any or no exception, or if it returns a value or no value does not matter. The proposal is not trying to introduce any new intelligence into the try finally clause, it is just syntactic sugar to minimize simple resource clean-up code. SPECIFICATION: The "try" keyword will have an overloaded meaning CASE 1 ------ try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { //work gets done here } Will be syntactic sugar for: ClassWithCloseMethod value = new ClassWithCloseMethod(...); try { //work gets done here } finally { value.close(); } CASE 2 ------ try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { //work gets done here } finally { //additional clean-up code } Will be syntactic sugar for: ClassWithCloseMethod value = new ClassWithCloseMethod(...); try { //work gets done here } finally { value.close(); //additional clean-up code } CASE 3 ------ try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { //work gets done here } catch (Exception ex) { //exception handling code } finally { //additional clean-up code } Will be syntactic sugar for: ClassWithCloseMethod value = new ClassWithCloseMethod(...); try { //work gets done here } catch (Exception ex) { //exception handling code } finally { value.close(); //additional clean-up code } CASE 4 ------ try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) { //work gets done here } Will be syntactic sugar for: Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); try { Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); try { Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); try { //work gets done here } finally { value3.close(); } } finally { value2.close(); } } finally { value1.close(); } CASE 5 ------ try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) { //work gets done here } finally { //additional clean-up code } Will be syntactic sugar for: Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); try { Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); try { Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); try { //work gets done here } finally { value3.close(); } } finally { value2.close(); } } finally { value1.close(); //additional clean-up code } CASE 6 ------ try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) { //work gets done here } catch (Exception ex) { //exception handling code } finally { //additional clean-up code } Will be syntactic sugar for: Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); try { Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); try { Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); try { //work gets done here } finally { value3.close(); } } finally { value2.close(); } } catch (Exception ex) { //exception handling code } finally { value1.close(); //additional clean-up code } COMPILATION: The SPECIFICATION section above shows the desugaring for each case. Byte code would be identical to the desugared constructs. TESTING: Byte code comparison of common code constructs. If the byte code is not identical to the desugared version, test fails. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: For each case in the SPECIFICATION section, convert the existing code to the syntactic sugar proposal. COMPATIBILITY BREAKING CHANGES: None. EXISTING PROGRAMS: Compile accepts both existing and new forms of the "try" statement. Byte code does not change. REFERENCES EXISTING BUGS: None -- Roger Hernandez From Joe.Darcy at Sun.COM Mon Mar 2 22:34:24 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 02 Mar 2009 22:34:24 -0800 Subject: PROPOSAL: Multiline strings In-Reply-To: <9724b4d386667dda06c3586d7ce0748e.squirrel@wmail.gradsoft.ua> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <9724b4d386667dda06c3586d7ce0748e.squirrel@wmail.gradsoft.ua> Message-ID: <49ACCF70.20908@sun.com> rssh at gradsoft.com.ua wrote: > 1. Since we have non-empty discussion, I setup wiki with current proposal > ('new string literals instead multiline strings (?)') > > http://redmine.gradsoft.ua/wiki/java7stringliterals > and will try to track all changes as issues. > The Project Coin mailing list is the place for discussion of proposals submitted to Project Coin! -Joe From Joe.Darcy at Sun.COM Mon Mar 2 22:35:41 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 02 Mar 2009 22:35:41 -0800 Subject: PROPOSAL: Multiline strings In-Reply-To: <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> Message-ID: <49ACCFBD.3010509@sun.com> Reinier Zwitserloot wrote: > Embedding regexps has two significant advantages: > > 1. compile-time checking of your regexps. Sure, most random > gibberish just so happens to be a valid regexp, but there are rules - > you can have mismatched parentheses, for example. > At least in principle tools can do this kind of checking without language support. -Joe From Joe.Darcy at Sun.COM Mon Mar 2 22:44:11 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 02 Mar 2009 22:44:11 -0800 Subject: PROPOSAL: Multiline strings In-Reply-To: References: Message-ID: <49ACD1BB.7060505@sun.com> Ruslan, This proposal is missing many important details. rssh at gradsoft.com.ua wrote: > AUTHOR(s): Ruslan Shevchenko > > OVERVIEW: > FEATURE SUMMARY: > add multiline strings to java language. > MAJOR ADVANTAGE: > Possibility more elegant to write code part of codes in other languages, > such as sql constructions or rendering of html components. > MAJOR DISADVANTAGE > I don't know > ALTERNATIVES: > use String "+=" operator. > using groovy instead java in utility classes. > "This is \n" + "an alternative \n" + "too.\n" As is concat("If you save on \"\\n\", "you might still pay ", "with a comma."); public static concat(String... args) { // concat args together separated by newlines } > EXAMPLES > > SIMPLE EXAMPLE: > > StringBuilder sb = new StringBuilder(); > sb.append("""select a from Area a, CountryCodes cc > where > cc.isoCode='UA' > and > a.owner = cc.country > """); > if (question.getAreaName()!=null) { > sb.append("""and > a.name like ? > """); > sqlParams.setString(++i,question.getAreaName()); > } > > instead: > StringBuilder sb = new StringBuilder(); > sb.append("select a from Area a, CountryCodes cc\n"); > sb.append("where cc.isoCode='UA'\n"); > sb.append("and a.owner=cc.country'\n"); > if (question.getAreaName()!=null) { > sb.append("and a.name like ?"); > sqlParams.setString(++i,question.getAreaName()); > } > > > DETAILS: > Multiline strings are part of program text, which begin and ends > by three double quotes. (as in groovy and scala) Text withing such > brackets processed as multiline string with all rulles as normal Java > string literals, except it can be multiline. After parsing multiline > string is concatenation of lines with inserted value of system property > 'line.separator' between thems. > What are the grammar changes? Is are three consecutive quote characters escaped in a multi-line string? As has been mentioned in earlier responses, how is whitespace handed? > COMPILATION: > Multiline strings created and used in .class files exactly as ordinary > strings. > What is the desugaring? Regards, -Joe > TESTING: > Nothing special. add multiline strings to test-cases. > > LIBRARY SUPPORT: > None. > (May be exists sence add simple template processing to standard library, but > I think this is goal of next janguage iteration. Now exists many good > external > frameworks, such as velocity: better wait and standartize support of > winner) > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > None > > REFERENCES > > http://bugs.sun.com/view_bug.do?bug_id=4165111 > > > > > > > > From Joe.Darcy at Sun.COM Mon Mar 2 23:04:44 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 02 Mar 2009 23:04:44 -0800 Subject: Notes on implementing concise calls to constructors with type parameters Message-ID: <49ACD68C.2010405@sun.com> Hello. As implied by previous email on the list, Neal and I met recently and discussed an implementation strategy for supporting concise calls to constructors with type parameters using the diamond "<>" notation. In brief, since the desired behavior to emulate is having the bounds of constructors determined as if a static generic factory method was used instead, the compiler could synthesize artificial static methods for the purposes of method resolution and finding the bounds, but then discard those synthesized methods and map back to the right constructor. There are a few hazards to watch out for: * Generic constructors that declare their own type variables * accessibility modifiers * var-args * boxing/unboxing conversion The running example was something like class C { C(Arg1 arg1) C(Arg 1 arg1, Arg 2 arg2) C(Arg 1 arg1) } Both T and U could appear in the argument list somewhere; they could also have bounds. The translation would be to static /* orig. modifiers */ C staticFactory(/* orig. list of args*/) where S is just an alpha-rename of T and U would be omitted for non-generic constructors. Once the appropriate constructor with its bound is chosen, inference might have to be redone on the constructor to bind any generic type parameters (and account for var-args and boxing and unboxing). Any diagnostic messages should be mapped back to the constructors rather than the synthesized static factories. The resolution process results in Symbols and only the phases through Attr and Resolved should need to be modified. This mapping of static factories to constructors should probably inform the specification of the feature as well as its implementation, but I haven't written any specification along those lines. Regards, -Joe From neal at gafter.com Mon Mar 2 23:23:41 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 2 Mar 2009 23:23:41 -0800 Subject: Simple Resource Clean-up In-Reply-To: References: Message-ID: <15e8b9d20903022323k17c3f1afo9919c311070b17be@mail.gmail.com> You say "The object being created must implement the Closeable interface." But java.sql.Statement, to pick one example, cannot be made to implement that interface because the exception signatures are not compatible. I'll let others comment about issues with exception handling in the translation. -Neal On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez wrote: > I saw how the previous Automatic Resource Management proposal got torn to > pieces but I feel strongly enough about this issue to post a similar > proposal. > > Some points: > > I am not a programming language designer. ?I have very little experience > with byte code and with design and implementation of compilers. ?What I do > have is many years of experience in writing code for large business > applications, both in house-custom programs and shrink-wrapped products sold > to customers. > > About 1/3 of the Java code I write contributes almost nothing to the > functionality or flexibility of the program. ?It is composed of very simple > and very repetitive resource clean-up code. ?JDBC code is an especially bad > case. ?I know we should be using JDO or JPA, but: 1) most of the Java > database code in existence is using JDBC to some extent or another, 2) for > the kind of processing our software does with large datasets having hundreds > of megabytes of row data and millions of rows per account per month, custom > JDBC code still beats the other solutions in memory utilization and > throughput. > > In most business code we don't do complex exception processing. ?If we get a > exception we rollback the transaction and unroll the stack until we reach > some program level error handler that logs the error for some administrator > to review at a later date. ?So if this proposal is not applicable to complex > error handling scenarios, that is fine. ?Taking care of the simple scenarios > will still get rid of most of that 1/3 of the code I write, allowing me to > concentrate on the actual program logic, not the resource clean-up noise. > > I also program quite a bit in C++ and C# and when I work in Java I sorely > miss RAII (Resource Acquisition Is Initialization) and the "using" statement > respectively. > > At the end of the day, what I would like is a solution to minimize all the > resource clean-up boiler plate. > > ----------------------------------------------------------------------------------------- > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > ? AUTHOR: Roger Hernandez, rogerh at velocityconsultinginc.com > > OVERVIEW > > ? FEATURE SUMMARY: Syntactic sugar for simple cases of the common > new/try/finally/close language idiom. ?The object being created must > implement the Closeable interface. > > ? MAJOR ADVANTAGE: Significantly reduces lines of code when working with > objects that encapsulate external resources that should be closed as soon as > possible. ?Examples are Stream, Reader, Writer classes in java.io, and > Connection, Statement, PreparedStatement, ResultSet in java.sql.*. > > ? MAJOR BENEFIT: It allows writing code that uses these kinds of object to > more clearly express the both the lifetime of the utilization of each > resource, and allows the logic flow of the code to be more visible. > > ? MAJOR DISADVANTAGE: Either a new keyword, or an additional overloaded > meaning on an existing keyword. > > ? ALTERNATIVES: You can always use the standard idiom: SomeType val = new > val(...); try { ... } finally { val.close(); } > > EXAMPLES > > ? SIMPLE EXAMPLE: ?A simple Java version of the command line utility "tee". > ? ? ?//This is the existing way of doing it. > ? ? ?//Lines of code: 19 > ? ? ?package com.vci.projectcoin.using; > > ? ? ?import java.io.*; > > ? ? ?public class SimpleExample { > > ? ? ? ? public static void main(String[] args) throws IOException { > ? ? ? ? ? ?byte []buffer = new byte[1024]; > ? ? ? ? ? ?FileOutputStream out = new FileOutputStream(args[0]); > ? ? ? ? ? ?try { > ? ? ? ? ? ? ? for (int count; (count = System.in.read(buffer)) != -1;) { > ? ? ? ? ? ? ? ? ?out.write(buffer, 0, count); > ? ? ? ? ? ? ? ? ?System.out.write(buffer, 0, count); > ? ? ? ? ? ? ? } > ? ? ? ? ? ?} finally { > ? ? ? ? ? ? ? out.close(); > ? ? ? ? ? ?} > ? ? ? ? } > ? ? ?} > > ? ? ?//This is the proposed way of doing it, the compiler converts the > syntactic sugar into the same byte codes > ? ? ?//I am adding a new use to the the "try" keyword to avoid adding more > to the language, but it would work > ? ? ?//just a well with a "using" keyword. > ? ? ?//Lines of code: 16 > ? ? ?package com.vci.projectcoin.using; > > ? ? ?import java.io.*; > > ? ? ?public class SimpleExample { > > ? ? ? ? public static void main(String[] args) throws IOException { > ? ? ? ? ? ?byte []buffer = new byte[1024]; > ? ? ? ? ? ?try (FileOutputStream out = new FileOutputStream(args[0])) { > ? ? ? ? ? ? ? for (int count; (count = System.in.read(buffer)) != -1;) { > ? ? ? ? ? ? ? ? ?out.write(buffer, 0, count); > ? ? ? ? ? ? ? ? ?System.out.write(buffer, 0, count); > ? ? ? ? ? ? ? } > ? ? ? ? ? ?} > ? ? ? ? } > ? ? ?} > > ? ADVANCED EXAMPLE: A simple utility to execute a query and write values as > a comma delimited file. > > ? ? ?//This is the existing way of doing it > ? ? ?//Lines of code: 55 > ? ? ?package com.vci.projectcoin.using; > > ? ? ?import java.sql.*; > ? ? ?import java.io.*; > > ? ? ?public class AdvancedExample { > ? ? ? ? final static String EOL = System.getProperty("line.separator"); > > ? ? ? ? //Command Line: [] > ? ? ? ? static public void main(String []args) throws SQLException, > FileNotFoundException { > ? ? ? ? ? ?String url = args[0]; > ? ? ? ? ? ?String sql = args[1]; > ? ? ? ? ? ?PrintWriter out = new PrintWriter(args.length > 2 ? new > FileOutputStream(args[2]) : System.out); > ? ? ? ? ? ?try { > ? ? ? ? ? ? ? Connection conn = DriverManager.getConnection(url); > ? ? ? ? ? ? ? try { > ? ? ? ? ? ? ? ? ?Statement query = > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > ResultSet.CONCUR_READ_ONLY); > ? ? ? ? ? ? ? ? ?try { > ? ? ? ? ? ? ? ? ? ? ResultSet results = query.executeQuery(sql); > ? ? ? ? ? ? ? ? ? ? try { > ? ? ? ? ? ? ? ? ? ? ? ?ResultSetMetaData meta = results.getMetaData(); > ? ? ? ? ? ? ? ? ? ? ? ?int colCount = meta.getColumnCount(); > ? ? ? ? ? ? ? ? ? ? ? ?while (results.next()) { > ? ? ? ? ? ? ? ? ? ? ? ? ? for (int index = 1; index <= colCount; index++) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int colType = meta.getColumnType(index); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?boolean quoted = colType == Types.CHAR ?|| > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? colType == Types.NCHAR || > colType == Types.NVARCHAR ? ? || colType == Types.VARCHAR; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?System.out.append(results.getString(index)); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (index < colCount) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(','); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(EOL); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? } finally { > ? ? ? ? ? ? ? ? ? ? ? ?results.close(); > ? ? ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? ? ?} finally { > ? ? ? ? ? ? ? ? ? ? query.close(); > ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? } finally { > ? ? ? ? ? ? ? ? ?conn.close(); > ? ? ? ? ? ? ? } > ? ? ? ? ? ?} finally { > ? ? ? ? ? ? ? out.close(); > ? ? ? ? ? ?} > ? ? ? ? } > ? ? ?} > > ? ? ?//This is the proposed way of doing it > ? ? ?//This proposal gets rid of the finally clean up per object. ?It lets > one write robust resource clean-up code without a lot of effort. > ? ? ?//Lines of code: 43 > ? ? ?package com.vci.projectcoin.using; > > ? ? ?import java.sql.*; > ? ? ?import java.io.*; > > ? ? ?public class AdvancedExample { > ? ? ? ? final static String EOL = System.getProperty("line.separator"); > > ? ? ? ? //Command Line: [] > ? ? ? ? static public void main(String []args) throws SQLException, > FileNotFoundException { > ? ? ? ? ? ?String url = args[0]; > ? ? ? ? ? ?String sql = args[1]; > ? ? ? ? ? ?try (PrintWriter out = new PrintWriter(args.length > 2 ? new > FileOutputStream(args[2]) : System.out)) { > ? ? ? ? ? ? ? try (Connection conn = DriverManager.getConnection(url)) { > ? ? ? ? ? ? ? ? ?try (Statement query = > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > ResultSet.CONCUR_READ_ONLY)) { > ? ? ? ? ? ? ? ? ? ? try (ResultSet results = query.executeQuery(sql)) { > ? ? ? ? ? ? ? ? ? ? ? ?ResultSetMetaData meta = results.getMetaData(); > ? ? ? ? ? ? ? ? ? ? ? ?int colCount = meta.getColumnCount(); > ? ? ? ? ? ? ? ? ? ? ? ?while (results.next()) { > ? ? ? ? ? ? ? ? ? ? ? ? ? for (int index = 1; index <= colCount; index++) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int colType = meta.getColumnType(index); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?boolean quoted = colType == Types.CHAR || > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == > Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?System.out.append(results.getString(index)); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (index < colCount) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(','); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(EOL); > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(); > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? } > ? ? ? ? ? ?} > ? ? ? ? } > ? ? ?} > > ? ? ?//This is an additional syntactic sugar proposal, allowing multiple > objects to be allocated inside one try block. ?The compiler converts all > three programs into the same bytecode > ? ? ?//This proposal gets rid of the additional indentation level and > closing brace per object. ?It further minimize the clean-up boiler-plate, > allowing the point of the program logic to be clearer. > ? ? ?//Lines of code: 38 > ? ? ?package com.vci.projectcoin.using; > > ? ? ?import java.sql.*; > ? ? ?import java.io.*; > > ? ? ?public class AdvancedExample { > ? ? ? ? final static String EOL = System.getProperty("line.separator"); > > ? ? ? ? //Command Line: [] > ? ? ? ? static public void main(String []args) throws SQLException, > FileNotFoundException { > ? ? ? ? ? ?String url = args[0]; > ? ? ? ? ? ?String sql = args[1]; > ? ? ? ? ? ?try (PrintWriter out = new PrintWriter(args.length > 2 ? new > FileOutputStream(args[2]) : System.out), > ? ? ? ? ? ? ? ? Statement query = > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > ResultSet.CONCUR_READ_ONLY), > ? ? ? ? ? ? ? ? ResultSet results = query.executeQuery(sql)) { > ? ? ? ? ? ? ? ResultSetMetaData meta = results.getMetaData(); > ? ? ? ? ? ? ? int colCount = meta.getColumnCount(); > ? ? ? ? ? ? ? while (results.next()) { > ? ? ? ? ? ? ? for (int index = 1; index <= colCount; index++) { > ? ? ? ? ? ? ? ? ?int colType = meta.getColumnType(index); > ? ? ? ? ? ? ? ? ?boolean quoted = colType == Types.CHAR ?|| colType == > Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == Types.NCHAR > || colType == Types.NVARCHAR ? ? || colType == Types.VARCHAR; > ? ? ? ? ? ? ? ? ?if (quoted) { > ? ? ? ? ? ? ? ? ? ? System.out.append('"'); > ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ?System.out.append(results.getString(index)); > ? ? ? ? ? ? ? ? ?if (quoted) { > ? ? ? ? ? ? ? ? ? ? System.out.append('"'); > ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ?if (index < colCount) { > ? ? ? ? ? ? ? ? ? ? System.out.print(','); > ? ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? System.out.print(EOL); > ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? System.out.println(); > ? ? ? ? ? ? ? } > ? ? ? ? ? ?} > ? ? ? ? } > ? ? ?} > > DETAILS > ? The specification requires that the object in the try () block have a > "close()" method. ?Wether the method throws any or no exception, or if it > returns a value or no value does not matter. ?The proposal is not trying to > introduce any new intelligence into the try finally clause, it is just > syntactic sugar to minimize simple resource clean-up code. > > ? SPECIFICATION: > ? ? ?The "try" keyword will have an overloaded meaning > > ? ? ?CASE 1 > ? ? ?------ > ? ? ?try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { > ? ? ? ? //work gets done here > ? ? ?} > > ? ? ?Will be syntactic sugar for: > ? ? ?ClassWithCloseMethod value = new ClassWithCloseMethod(...); > ? ? ?try { > ? ? ? ? //work gets done here > ? ? ?} finally { > ? ? ? ? value.close(); > ? ? ?} > > ? ? ?CASE 2 > ? ? ?------ > ? ? ?try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { > ? ? ? ? //work gets done here > ? ? ?} finally { > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?Will be syntactic sugar for: > ? ? ?ClassWithCloseMethod value = new ClassWithCloseMethod(...); > ? ? ?try { > ? ? ? ? //work gets done here > ? ? ?} finally { > ? ? ? ? value.close(); > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?CASE 3 > ? ? ?------ > ? ? ?try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { > ? ? ? ? //work gets done here > ? ? ?} catch (Exception ex) { > ? ? ? ? //exception handling code > ? ? ?} finally { > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?Will be syntactic sugar for: > ? ? ?ClassWithCloseMethod value = new ClassWithCloseMethod(...); > ? ? ?try { > ? ? ? ? //work gets done here > ? ? ?} catch (Exception ex) { > ? ? ? ? //exception handling code > ? ? ?} finally { > ? ? ? ? value.close(); > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?CASE 4 > ? ? ?------ > ? ? ?try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), > ? ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), > ? ? ? ? ? Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) { > ? ? ? ? //work gets done here > ? ? ?} > > ? ? ?Will be syntactic sugar for: > ? ? ?Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > ? ? ?try { > ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > ? ? ? ? try { > ? ? ? ? ? ?Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); > ? ? ? ? ? ?try { > ? ? ? ? ? ? ? //work gets done here > ? ? ? ? ? ?} finally { > ? ? ? ? ? ? ? value3.close(); > ? ? ? ? ? ?} > ? ? ? ? } finally { > ? ? ? ? ? ?value2.close(); > ? ? ? ? } > ? ? ?} finally { > ? ? ? ? value1.close(); > ? ? ?} > > ? ? ?CASE 5 > ? ? ?------ > ? ? ?try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), > ? ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), > ? ? ? ? ? Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) { > ? ? ? ? //work gets done here > ? ? ?} finally { > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?Will be syntactic sugar for: > ? ? ?Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > ? ? ?try { > ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > ? ? ? ? try { > ? ? ? ? ? ?Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); > ? ? ? ? ? ?try { > ? ? ? ? ? ? ? //work gets done here > ? ? ? ? ? ?} finally { > ? ? ? ? ? ? ? value3.close(); > ? ? ? ? ? ?} > ? ? ? ? } finally { > ? ? ? ? ? ?value2.close(); > ? ? ? ? } > ? ? ?} finally { > ? ? ? ? value1.close(); > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?CASE 6 > ? ? ?------ > ? ? ?try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), > ? ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), > ? ? ? ? ? Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) { > ? ? ? ? //work gets done here > ? ? ?} catch (Exception ex) { > ? ? ? ? //exception handling code > ? ? ?} finally { > ? ? ? ? //additional clean-up code > ? ? ?} > > ? ? ?Will be syntactic sugar for: > ? ? ?Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > ? ? ?try { > ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > ? ? ? ? try { > ? ? ? ? ? ?Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); > ? ? ? ? ? ?try { > ? ? ? ? ? ? ? //work gets done here > ? ? ? ? ? ?} finally { > ? ? ? ? ? ? ? value3.close(); > ? ? ? ? ? ?} > ? ? ? ? } finally { > ? ? ? ? ? ?value2.close(); > ? ? ? ? } > ? ? ?} catch (Exception ex) { > ? ? ? ? //exception handling code > ? ? ?} finally { > ? ? ? ? value1.close(); > ? ? ? ? //additional clean-up code > ? ? ?} > > ? COMPILATION: The SPECIFICATION section above shows the desugaring for > each case. ?Byte code would be identical to the desugared constructs. > > ? TESTING: Byte code comparison of common code constructs. ?If the byte > code is not identical to the desugared version, test fails. > > ? LIBRARY SUPPORT: No. > > ? REFLECTIVE APIS: No. > > ? OTHER CHANGES: No. > > ? MIGRATION: For each case in the SPECIFICATION section, convert the > existing code to the syntactic sugar proposal. > > > COMPATIBILITY > > ? BREAKING CHANGES: None. > > ? EXISTING PROGRAMS: Compile accepts both existing and new forms of the > "try" statement. ?Byte code does not change. > > REFERENCES > > ? EXISTING BUGS: None > > > -- > Roger Hernandez > > From neal at gafter.com Mon Mar 2 23:33:17 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 2 Mar 2009 23:33:17 -0800 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <49ACCE49.8030103@sun.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> Message-ID: <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> On Mon, Mar 2, 2009 at 10:29 PM, Joseph D. Darcy wrote: >> MAJOR DISADVANTAGE: >> >> One-time implementation cost for adding the features to the compiler. >> Longer language specification in describing the behavior. >> > > What sort of poor programming practices could this feature encourage or > enable? I don't see any, but perhaps I'm shortsighted. >> The type system is affected as follows: For the purpose of type >> checking, a catch parameter declared with a disjunction has type >> lub(t1, t2, ...) [JLS3 15.12.2.5]. > > In terms of finding the members of the type, it is good existing concepts in > the JLS can be used. > > What happens if someone writes > > ? catch(final IOException | SomeSubclassOfIOException e) {...} > > In other words, is it legal to have subclasses of a caught exception listed > too? I don't really care one way or the other. As written, yes, it is allowed and means the same thing as the supertype alone. >> To avoid the need to add support for general disjunctive types, but >> leaving open the possibility of a future extension along these lines, >> a catch parameter whose type has more than one disjunct is required to >> be declared final. >> > > I think that is a fine compromise that keep the current feature smaller > while allowing room for a broader feature later. > > Some worked examples of the sets of thrown exceptions types under various > tricky code samples would help clarify the data flow algorithm for me. Sure, I can do that. Do you think that should go in the specification? >> A catch clause is currently compiled (before this change) to an entry >> in an exception table that specifies the type of the exception and the >> address of the code for the catch body. To generate code for this new >> construct, the compiler would generate an entry in the exception table >> for each type in the exception parameter's list of types. >> > > Interesting; so there would be no code duplication even in the class files. Correct. That's what the current prototype (in the BGGA compiler) does for this construct. > How could the increased exception precision be maintained will still allow > programs such as the one above to compile? I don't think it can without making rather complex rules, but I'll think about it more. However, one could take only the multicatch part of this proposal and not the final/rethrow part, and then I believe one could specify it without there being a breaking change. From neal at gafter.com Mon Mar 2 23:43:27 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 2 Mar 2009 23:43:27 -0800 Subject: Proposal: Block Expressions for Java In-Reply-To: <49ACC44A.1040609@sun.com> References: <15e8b9d20902272121q2f625b1cq3230f5260bcddfe4@mail.gmail.com> <15e8b9d20902272130i3e52b349ta500f4b98accec01@mail.gmail.com> <49ACC44A.1040609@sun.com> Message-ID: <15e8b9d20903022343k4d9a056el513c4b113e27f318@mail.gmail.com> On Mon, Mar 2, 2009 at 9:46 PM, Joseph D. Darcy wrote: >> Meaning of Expressions: The specification for a parenthesized >> expression should be modified to describe its new execution semantics: >> The block statements (if any) are executed in sequence, from left to >> right, exactly as in a block statement. ?The result of the >> parenthesized expression is the result of evaluating its >> subexpression. >> > > So what about return, break, and continue statements inside the > BlockStatements? They behave as already specified in the JLS. >> Compilation is straightforward, with one minor exception (no pun >> intended). ?The compiler must arrange the generated code such that the >> stack is empty at the beginning of any try statement that can complete >> normally when the try statement is embedded within a parenthesized >> expression. ?That is because the VM empties the stack when exceptions >> are handled. ?This can be accommodated by spilling values from the >> stack into VM locals. >> > > That doesn't necessarily sound minor! It is because (1) it will be extremely rare in practice, and (2) even when it happens, the number of additional bytecodes to spill and unspill the registers is small. I prototyped something close to this spilling strategy when I implemented stackmaps: I added an option that causes the stack to be empty at every basic block boundary (which in expressions occurs because of ?:). It caused an additional fraction of a percent in code size. This would have an even smaller impact. From neal at gafter.com Mon Mar 2 23:54:14 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 2 Mar 2009 23:54:14 -0800 Subject: Simple Resource Clean-up In-Reply-To: References: <15e8b9d20903022323k17c3f1afo9919c311070b17be@mail.gmail.com> Message-ID: <15e8b9d20903022354y62f10866t8f403767d22a874f@mail.gmail.com> Just to make sure I understand, in your specification, if an exception is thrown from the try block, and then another exception is thrown from the close() method, the one from the close() is the one that propogates out? On Mon, Mar 2, 2009 at 11:43 PM, Roger Hernandez wrote: > Sorry I meant to take that part out, since I saw the comments from the > previous proposal.? The way I envision it working is in a way how C++ > template instantiation works.? The compiler just requires that a class have > an accessible "close()" function, it should not care what interface or class > it comes from.? That way it can throw any exception type. > - Show quoted text - > > On Tue, Mar 3, 2009 at 2:23 AM, Neal Gafter wrote: >> >> You say "The object being created must implement the Closeable >> interface." ?But java.sql.Statement, to pick one example, cannot be >> made to implement that interface because the exception signatures are >> not compatible. >> >> I'll let others comment about issues with exception handling in the >> translation. >> >> -Neal >> >> On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez >> wrote: >> > I saw how the previous Automatic Resource Management proposal got torn >> > to >> > pieces but I feel strongly enough about this issue to post a similar >> > proposal. >> > >> > Some points: >> > >> > I am not a programming language designer. ?I have very little experience >> > with byte code and with design and implementation of compilers. ?What I >> > do >> > have is many years of experience in writing code for large business >> > applications, both in house-custom programs and shrink-wrapped products >> > sold >> > to customers. >> > >> > About 1/3 of the Java code I write contributes almost nothing to the >> > functionality or flexibility of the program. ?It is composed of very >> > simple >> > and very repetitive resource clean-up code. ?JDBC code is an especially >> > bad >> > case. ?I know we should be using JDO or JPA, but: 1) most of the Java >> > database code in existence is using JDBC to some extent or another, 2) >> > for >> > the kind of processing our software does with large datasets having >> > hundreds >> > of megabytes of row data and millions of rows per account per month, >> > custom >> > JDBC code still beats the other solutions in memory utilization and >> > throughput. >> > >> > In most business code we don't do complex exception processing. ?If we >> > get a >> > exception we rollback the transaction and unroll the stack until we >> > reach >> > some program level error handler that logs the error for some >> > administrator >> > to review at a later date. ?So if this proposal is not applicable to >> > complex >> > error handling scenarios, that is fine. ?Taking care of the simple >> > scenarios >> > will still get rid of most of that 1/3 of the code I write, allowing me >> > to >> > concentrate on the actual program logic, not the resource clean-up >> > noise. >> > >> > I also program quite a bit in C++ and C# and when I work in Java I >> > sorely >> > miss RAII (Resource Acquisition Is Initialization) and the "using" >> > statement >> > respectively. >> > >> > At the end of the day, what I would like is a solution to minimize all >> > the >> > resource clean-up boiler plate. >> > >> > >> > ----------------------------------------------------------------------------------------- >> > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> > >> > ? AUTHOR: Roger Hernandez, rogerh at velocityconsultinginc.com >> > >> > OVERVIEW >> > >> > ? FEATURE SUMMARY: Syntactic sugar for simple cases of the common >> > new/try/finally/close language idiom. ?The object being created must >> > implement the Closeable interface. >> > >> > ? MAJOR ADVANTAGE: Significantly reduces lines of code when working with >> > objects that encapsulate external resources that should be closed as >> > soon as >> > possible. ?Examples are Stream, Reader, Writer classes in java.io, and >> > Connection, Statement, PreparedStatement, ResultSet in java.sql.*. >> > >> > ? MAJOR BENEFIT: It allows writing code that uses these kinds of object >> > to >> > more clearly express the both the lifetime of the utilization of each >> > resource, and allows the logic flow of the code to be more visible. >> > >> > ? MAJOR DISADVANTAGE: Either a new keyword, or an additional overloaded >> > meaning on an existing keyword. >> > >> > ? ALTERNATIVES: You can always use the standard idiom: SomeType val = >> > new >> > val(...); try { ... } finally { val.close(); } >> > >> > EXAMPLES >> > >> > ? SIMPLE EXAMPLE: ?A simple Java version of the command line utility >> > "tee". >> > ? ? ?//This is the existing way of doing it. >> > ? ? ?//Lines of code: 19 >> > ? ? ?package com.vci.projectcoin.using; >> > >> > ? ? ?import java.io.*; >> > >> > ? ? ?public class SimpleExample { >> > >> > ? ? ? ? public static void main(String[] args) throws IOException { >> > ? ? ? ? ? ?byte []buffer = new byte[1024]; >> > ? ? ? ? ? ?FileOutputStream out = new FileOutputStream(args[0]); >> > ? ? ? ? ? ?try { >> > ? ? ? ? ? ? ? for (int count; (count = System.in.read(buffer)) != -1;) { >> > ? ? ? ? ? ? ? ? ?out.write(buffer, 0, count); >> > ? ? ? ? ? ? ? ? ?System.out.write(buffer, 0, count); >> > ? ? ? ? ? ? ? } >> > ? ? ? ? ? ?} finally { >> > ? ? ? ? ? ? ? out.close(); >> > ? ? ? ? ? ?} >> > ? ? ? ? } >> > ? ? ?} >> > >> > ? ? ?//This is the proposed way of doing it, the compiler converts the >> > syntactic sugar into the same byte codes >> > ? ? ?//I am adding a new use to the the "try" keyword to avoid adding >> > more >> > to the language, but it would work >> > ? ? ?//just a well with a "using" keyword. >> > ? ? ?//Lines of code: 16 >> > ? ? ?package com.vci.projectcoin.using; >> > >> > ? ? ?import java.io.*; >> > >> > ? ? ?public class SimpleExample { >> > >> > ? ? ? ? public static void main(String[] args) throws IOException { >> > ? ? ? ? ? ?byte []buffer = new byte[1024]; >> > ? ? ? ? ? ?try (FileOutputStream out = new FileOutputStream(args[0])) { >> > ? ? ? ? ? ? ? for (int count; (count = System.in.read(buffer)) != -1;) { >> > ? ? ? ? ? ? ? ? ?out.write(buffer, 0, count); >> > ? ? ? ? ? ? ? ? ?System.out.write(buffer, 0, count); >> > ? ? ? ? ? ? ? } >> > ? ? ? ? ? ?} >> > ? ? ? ? } >> > ? ? ?} >> > >> > ? ADVANCED EXAMPLE: A simple utility to execute a query and write values >> > as >> > a comma delimited file. >> > >> > ? ? ?//This is the existing way of doing it >> > ? ? ?//Lines of code: 55 >> > ? ? ?package com.vci.projectcoin.using; >> > >> > ? ? ?import java.sql.*; >> > ? ? ?import java.io.*; >> > >> > ? ? ?public class AdvancedExample { >> > ? ? ? ? final static String EOL = System.getProperty("line.separator"); >> > >> > ? ? ? ? //Command Line: [] >> > ? ? ? ? static public void main(String []args) throws SQLException, >> > FileNotFoundException { >> > ? ? ? ? ? ?String url = args[0]; >> > ? ? ? ? ? ?String sql = args[1]; >> > ? ? ? ? ? ?PrintWriter out = new PrintWriter(args.length > 2 ? new >> > FileOutputStream(args[2]) : System.out); >> > ? ? ? ? ? ?try { >> > ? ? ? ? ? ? ? Connection conn = DriverManager.getConnection(url); >> > ? ? ? ? ? ? ? try { >> > ? ? ? ? ? ? ? ? ?Statement query = >> > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, >> > ResultSet.CONCUR_READ_ONLY); >> > ? ? ? ? ? ? ? ? ?try { >> > ? ? ? ? ? ? ? ? ? ? ResultSet results = query.executeQuery(sql); >> > ? ? ? ? ? ? ? ? ? ? try { >> > ? ? ? ? ? ? ? ? ? ? ? ?ResultSetMetaData meta = results.getMetaData(); >> > ? ? ? ? ? ? ? ? ? ? ? ?int colCount = meta.getColumnCount(); >> > ? ? ? ? ? ? ? ? ? ? ? ?while (results.next()) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? for (int index = 1; index <= colCount; >> > index++) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int colType = meta.getColumnType(index); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?boolean quoted = colType == Types.CHAR ?|| >> > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? colType == Types.NCHAR || >> > colType == Types.NVARCHAR ? ? || colType == Types.VARCHAR; >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> > >> > ?System.out.append(results.getString(index)); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (index < colCount) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(','); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(EOL); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ? ? ? ? ? } >> > ? ? ? ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ? ? } finally { >> > ? ? ? ? ? ? ? ? ? ? ? ?results.close(); >> > ? ? ? ? ? ? ? ? ? ? } >> > ? ? ? ? ? ? ? ? ?} finally { >> > ? ? ? ? ? ? ? ? ? ? query.close(); >> > ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? } finally { >> > ? ? ? ? ? ? ? ? ?conn.close(); >> > ? ? ? ? ? ? ? } >> > ? ? ? ? ? ?} finally { >> > ? ? ? ? ? ? ? out.close(); >> > ? ? ? ? ? ?} >> > ? ? ? ? } >> > ? ? ?} >> > >> > ? ? ?//This is the proposed way of doing it >> > ? ? ?//This proposal gets rid of the finally clean up per object. ?It >> > lets >> > one write robust resource clean-up code without a lot of effort. >> > ? ? ?//Lines of code: 43 >> > ? ? ?package com.vci.projectcoin.using; >> > >> > ? ? ?import java.sql.*; >> > ? ? ?import java.io.*; >> > >> > ? ? ?public class AdvancedExample { >> > ? ? ? ? final static String EOL = System.getProperty("line.separator"); >> > >> > ? ? ? ? //Command Line: [] >> > ? ? ? ? static public void main(String []args) throws SQLException, >> > FileNotFoundException { >> > ? ? ? ? ? ?String url = args[0]; >> > ? ? ? ? ? ?String sql = args[1]; >> > ? ? ? ? ? ?try (PrintWriter out = new PrintWriter(args.length > 2 ? new >> > FileOutputStream(args[2]) : System.out)) { >> > ? ? ? ? ? ? ? try (Connection conn = DriverManager.getConnection(url)) { >> > ? ? ? ? ? ? ? ? ?try (Statement query = >> > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, >> > ResultSet.CONCUR_READ_ONLY)) { >> > ? ? ? ? ? ? ? ? ? ? try (ResultSet results = query.executeQuery(sql)) { >> > ? ? ? ? ? ? ? ? ? ? ? ?ResultSetMetaData meta = results.getMetaData(); >> > ? ? ? ? ? ? ? ? ? ? ? ?int colCount = meta.getColumnCount(); >> > ? ? ? ? ? ? ? ? ? ? ? ?while (results.next()) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? for (int index = 1; index <= colCount; >> > index++) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int colType = meta.getColumnType(index); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?boolean quoted = colType == Types.CHAR || >> > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType >> > == >> > Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> > >> > ?System.out.append(results.getString(index)); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (quoted) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.append('"'); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (index < colCount) { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(','); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.print(EOL); >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ? ? ? ? ? } >> > ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(); >> > ? ? ? ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ? ? } >> > ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? } >> > ? ? ? ? ? ?} >> > ? ? ? ? } >> > ? ? ?} >> > >> > ? ? ?//This is an additional syntactic sugar proposal, allowing multiple >> > objects to be allocated inside one try block. ?The compiler converts all >> > three programs into the same bytecode >> > ? ? ?//This proposal gets rid of the additional indentation level and >> > closing brace per object. ?It further minimize the clean-up >> > boiler-plate, >> > allowing the point of the program logic to be clearer. >> > ? ? ?//Lines of code: 38 >> > ? ? ?package com.vci.projectcoin.using; >> > >> > ? ? ?import java.sql.*; >> > ? ? ?import java.io.*; >> > >> > ? ? ?public class AdvancedExample { >> > ? ? ? ? final static String EOL = System.getProperty("line.separator"); >> > >> > ? ? ? ? //Command Line: [] >> > ? ? ? ? static public void main(String []args) throws SQLException, >> > FileNotFoundException { >> > ? ? ? ? ? ?String url = args[0]; >> > ? ? ? ? ? ?String sql = args[1]; >> > ? ? ? ? ? ?try (PrintWriter out = new PrintWriter(args.length > 2 ? new >> > FileOutputStream(args[2]) : System.out), >> > ? ? ? ? ? ? ? ? Statement query = >> > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, >> > ResultSet.CONCUR_READ_ONLY), >> > ? ? ? ? ? ? ? ? ResultSet results = query.executeQuery(sql)) { >> > ? ? ? ? ? ? ? ResultSetMetaData meta = results.getMetaData(); >> > ? ? ? ? ? ? ? int colCount = meta.getColumnCount(); >> > ? ? ? ? ? ? ? while (results.next()) { >> > ? ? ? ? ? ? ? for (int index = 1; index <= colCount; index++) { >> > ? ? ? ? ? ? ? ? ?int colType = meta.getColumnType(index); >> > ? ? ? ? ? ? ? ? ?boolean quoted = colType == Types.CHAR ?|| colType == >> > Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == >> > Types.NCHAR >> > || colType == Types.NVARCHAR ? ? || colType == Types.VARCHAR; >> > ? ? ? ? ? ? ? ? ?if (quoted) { >> > ? ? ? ? ? ? ? ? ? ? System.out.append('"'); >> > ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ?System.out.append(results.getString(index)); >> > ? ? ? ? ? ? ? ? ?if (quoted) { >> > ? ? ? ? ? ? ? ? ? ? System.out.append('"'); >> > ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? ? ?if (index < colCount) { >> > ? ? ? ? ? ? ? ? ? ? System.out.print(','); >> > ? ? ? ? ? ? ? ? ?} else { >> > ? ? ? ? ? ? ? ? ? ? System.out.print(EOL); >> > ? ? ? ? ? ? ? ? ?} >> > ? ? ? ? ? ? ? } >> > ? ? ? ? ? ? ? System.out.println(); >> > ? ? ? ? ? ? ? } >> > ? ? ? ? ? ?} >> > ? ? ? ? } >> > ? ? ?} >> > >> > DETAILS >> > ? The specification requires that the object in the try () block have a >> > "close()" method. ?Wether the method throws any or no exception, or if >> > it >> > returns a value or no value does not matter. ?The proposal is not trying >> > to >> > introduce any new intelligence into the try finally clause, it is just >> > syntactic sugar to minimize simple resource clean-up code. >> > >> > ? SPECIFICATION: >> > ? ? ?The "try" keyword will have an overloaded meaning >> > >> > ? ? ?CASE 1 >> > ? ? ?------ >> > ? ? ?try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { >> > ? ? ? ? //work gets done here >> > ? ? ?} >> > >> > ? ? ?Will be syntactic sugar for: >> > ? ? ?ClassWithCloseMethod value = new ClassWithCloseMethod(...); >> > ? ? ?try { >> > ? ? ? ? //work gets done here >> > ? ? ?} finally { >> > ? ? ? ? value.close(); >> > ? ? ?} >> > >> > ? ? ?CASE 2 >> > ? ? ?------ >> > ? ? ?try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { >> > ? ? ? ? //work gets done here >> > ? ? ?} finally { >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?Will be syntactic sugar for: >> > ? ? ?ClassWithCloseMethod value = new ClassWithCloseMethod(...); >> > ? ? ?try { >> > ? ? ? ? //work gets done here >> > ? ? ?} finally { >> > ? ? ? ? value.close(); >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?CASE 3 >> > ? ? ?------ >> > ? ? ?try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { >> > ? ? ? ? //work gets done here >> > ? ? ?} catch (Exception ex) { >> > ? ? ? ? //exception handling code >> > ? ? ?} finally { >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?Will be syntactic sugar for: >> > ? ? ?ClassWithCloseMethod value = new ClassWithCloseMethod(...); >> > ? ? ?try { >> > ? ? ? ? //work gets done here >> > ? ? ?} catch (Exception ex) { >> > ? ? ? ? //exception handling code >> > ? ? ?} finally { >> > ? ? ? ? value.close(); >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?CASE 4 >> > ? ? ?------ >> > ? ? ?try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), >> > ? ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), >> > ? ? ? ? ? Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) >> > { >> > ? ? ? ? //work gets done here >> > ? ? ?} >> > >> > ? ? ?Will be syntactic sugar for: >> > ? ? ?Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); >> > ? ? ?try { >> > ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); >> > ? ? ? ? try { >> > ? ? ? ? ? ?Class3WithCloseMethod value3 = new >> > Class3WithCloseMethod(...); >> > ? ? ? ? ? ?try { >> > ? ? ? ? ? ? ? //work gets done here >> > ? ? ? ? ? ?} finally { >> > ? ? ? ? ? ? ? value3.close(); >> > ? ? ? ? ? ?} >> > ? ? ? ? } finally { >> > ? ? ? ? ? ?value2.close(); >> > ? ? ? ? } >> > ? ? ?} finally { >> > ? ? ? ? value1.close(); >> > ? ? ?} >> > >> > ? ? ?CASE 5 >> > ? ? ?------ >> > ? ? ?try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), >> > ? ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), >> > ? ? ? ? ? Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) >> > { >> > ? ? ? ? //work gets done here >> > ? ? ?} finally { >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?Will be syntactic sugar for: >> > ? ? ?Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); >> > ? ? ?try { >> > ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); >> > ? ? ? ? try { >> > ? ? ? ? ? ?Class3WithCloseMethod value3 = new >> > Class3WithCloseMethod(...); >> > ? ? ? ? ? ?try { >> > ? ? ? ? ? ? ? //work gets done here >> > ? ? ? ? ? ?} finally { >> > ? ? ? ? ? ? ? value3.close(); >> > ? ? ? ? ? ?} >> > ? ? ? ? } finally { >> > ? ? ? ? ? ?value2.close(); >> > ? ? ? ? } >> > ? ? ?} finally { >> > ? ? ? ? value1.close(); >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?CASE 6 >> > ? ? ?------ >> > ? ? ?try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), >> > ? ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), >> > ? ? ? ? ? Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) >> > { >> > ? ? ? ? //work gets done here >> > ? ? ?} catch (Exception ex) { >> > ? ? ? ? //exception handling code >> > ? ? ?} finally { >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? ? ?Will be syntactic sugar for: >> > ? ? ?Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); >> > ? ? ?try { >> > ? ? ? ? Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); >> > ? ? ? ? try { >> > ? ? ? ? ? ?Class3WithCloseMethod value3 = new >> > Class3WithCloseMethod(...); >> > ? ? ? ? ? ?try { >> > ? ? ? ? ? ? ? //work gets done here >> > ? ? ? ? ? ?} finally { >> > ? ? ? ? ? ? ? value3.close(); >> > ? ? ? ? ? ?} >> > ? ? ? ? } finally { >> > ? ? ? ? ? ?value2.close(); >> > ? ? ? ? } >> > ? ? ?} catch (Exception ex) { >> > ? ? ? ? //exception handling code >> > ? ? ?} finally { >> > ? ? ? ? value1.close(); >> > ? ? ? ? //additional clean-up code >> > ? ? ?} >> > >> > ? COMPILATION: The SPECIFICATION section above shows the desugaring for >> > each case. ?Byte code would be identical to the desugared constructs. >> > >> > ? TESTING: Byte code comparison of common code constructs. ?If the byte >> > code is not identical to the desugared version, test fails. >> > >> > ? LIBRARY SUPPORT: No. >> > >> > ? REFLECTIVE APIS: No. >> > >> > ? OTHER CHANGES: No. >> > >> > ? MIGRATION: For each case in the SPECIFICATION section, convert the >> > existing code to the syntactic sugar proposal. >> > >> > >> > COMPATIBILITY >> > >> > ? BREAKING CHANGES: None. >> > >> > ? EXISTING PROGRAMS: Compile accepts both existing and new forms of the >> > "try" statement. ?Byte code does not change. >> > >> > REFERENCES >> > >> > ? EXISTING BUGS: None >> > >> > >> > -- >> > Roger Hernandez >> > >> > > > > > -- > Roger Hernandez > From jjb at google.com Tue Mar 3 00:18:03 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 00:18:03 -0800 Subject: Simple Resource Clean-up In-Reply-To: References: Message-ID: <17b2302a0903030018p3736108eq9e3baf3ce5ab4b5b@mail.gmail.com> Roger, On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez wrote: > I saw how the previous Automatic Resource Management proposal got torn to > pieces That's not quite fair. Only one person objected, and I had good responses to all of his objections. So I believe the proposal is alive and well. Others have informed me (off list) that they see Automatic Resource Management as perhaps the most valuable language change that we could introduce for Java 7. Regards, Josh From rssh at gradsoft.com.ua Tue Mar 3 00:19:33 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 3 Mar 2009 10:19:33 +0200 (EET) Subject: PROPOSAL: Multiline strings In-Reply-To: <49ACCF70.20908@sun.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <9724b4d386667dda06c3586d7ce0748e.squirrel@wmail.gradsoft.ua> <49ACCF70.20908@sun.com> Message-ID: <32752b516ddfea7aedb868343fce211c.squirrel@wmail.gradsoft.ua> > rssh at gradsoft.com.ua wrote: >> 1. Since we have non-empty discussion, I setup wiki with current >> proposal >> ('new string literals instead multiline strings (?)') >> >> http://redmine.gradsoft.ua/wiki/java7stringliterals >> and will try to track all changes as issues. >> > > The Project Coin mailing list is the place for discussion of proposals > submitted to Project Coin! > Yes, of course. Enumerated list of issues just help me to organize materials for discussions here ;) > -Joe > > From scolebourne at joda.org Tue Mar 3 00:54:39 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 03 Mar 2009 08:54:39 +0000 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> Message-ID: <49ACF04F.60101@joda.org> Neal Gafter wrote: >> What happens if someone writes >> >> catch(final IOException | SomeSubclassOfIOException e) {...} >> >> In other words, is it legal to have subclasses of a caught exception listed >> too? > > I don't really care one way or the other. As written, yes, it is > allowed and means the same thing as the supertype alone. I would continue to allow this in the spec. It means that if someone refactors exceptions changing the hierarchy, then another part of the code with a multi-catch will continue to compile and have the same meaning. >> How could the increased exception precision be maintained will still allow >> programs such as the one above to compile? > > I don't think it can without making rather complex rules, but I'll > think about it more. > > However, one could take only the multicatch part of this proposal and > not the final/rethrow part, and then I believe one could specify it > without there being a breaking change. I would prefer to see them added to Project Coin as two separate proposals. (I have some usability concerns with rethrow, but am OK with multi-catch) Stephen From brucechapman at paradise.net.nz Tue Mar 3 01:21:21 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Tue, 03 Mar 2009 22:21:21 +1300 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: References: Message-ID: <49ACF691.5090104@paradise.net.nz> My 2 cents: This partially covers the need for type aliases, but not for generic types (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4983159), if we are going to introduce aliases it should cover the generic case as well. An alternative syntax to avoid the 'as' keyword could be "import Sqldate = java.sql.Date;" Either syntax could probably cover the generic type alias case as well, however I am not sure if an "import" statement is the right way to do that. I liked your examples, some are very compelling. An alternative mechanism that preserves the simple names might be to alias the package rather than aliasing the type. eg import ju=java.util; // or import package ju=java.util; import js=java.sql; js.Date date = new js.Date(new ju.Date); That gets further away from solving the generics alias issue, which might be a good thing : it leaves it easier to do a complete type aliases solution as a separate issue. (IS anyone working on a type aliases proposal for coin?) Bruce Phil Varner wrote: > Import Aliases for Classes and Static Methods > > http://docs.google.com/Doc?id=dgx74dt7_19dxnspbhj > > AUTHOR: Phil Varner > > OVERVIEW > > FEATURE SUMMARY: The import aliases feature allows a user to provide > an alias underwhich an imported class or statically imported method > must be referred to in the containing source file. An example of the > use of this feature is "import java.sql.Date as SqlDate;" > > MAJOR ADVANTAGE: This feature would allow easier use of multiple > classes which have the same name but different packages to be used in > the same source file. > > MAJOR BENEFIT: This will prevent the necessity of fully-qualifiying > all class references when there is a name collision, leading to more > readable code. > > MAJOR DISADVANTAGE: This will introduce an extra level of indirection > when determing the source of a given class or method, introduce a new > keyword 'as', and will require changes to IDE code completion > functionality. > > ALTERNATIVES: In some cases, a nested class can be created which > trivially derives a class involved in the name collision. For a > method, a wrapper method can be created in the source file. > > EXAMPLES > > SIMPLE EXAMPLE: > > Example #1, duplicate class name > > Current code: > > new java.sql.Date(new java.util.Date()); > > New code: > > import java.sql.Date as SqlDate; > import java.util.Date as UtilDate; > > new SqlDate(new UtilDate()); > > Example #2, statically imported method alias > > Current code: > > import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName; > > public static int mrlacsmn(final int arg1, final String arg2){ > return myReallyLongAndComplicatedStaticMethodName(arg1, arg2); > } > > mrlacsmn(1, a); > > New code: > > import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName > as mrlacsmn; > > mrlacsmn(1, a); > > ADVANCED EXAMPLE: > > Example #3 > > Translation of persistent formats between similar APIs. > > In many domains, it is not uncommon to have two different APIs with > classes with the same name. For example, in a production rules API, > one may have classes "RuleSet" and "Rule". When attempting to use the > API to translate between these these APIs, it must be decided that one > is fully-qualified and one is not. This can lead to code like: > > com.example.foo.bar.sdk.RuleSet srcRuleSet = ...; > com.example.foo.bar.sdk2.RuleSet dstRuleSet = new > com.example.foo.bar.sdk2.RuleSet(); > migrate(srcRuleSet, dstRuleSet); > ... > > private static void migrate(com.example.foo.bar.sdk.RuleSet srcRuleSet, > com.example.foo.bar.sdk2.RuleSet dstRuleSet){ > ... > } > > Note that it is good practice here not to import either class because > it is too easy to accidentally misuse constants and static methods. > > With the 'as' syntax, one could instead write the far less verbose and > more readible: > > import com.example.foo.bar.sdk.RuleSet as SrcRuleSet; > import com.example.foo.bar.sdk2.RuleSet as DstRuleSet; > > ... > > SrcRuleSet srcRuleSet = ...; > DstRuleSet destRuleSet = new DstRuleSet(); > migrate(srcRuleSet, dstRuleSet); > > ... > > private static void migrate(SrcRuleSet srcRuleSet, > DstRuleSet dstRuleSet){ > ... > } > > Example #4 > > Ensuring correct method selection when static importing overloaded methods. > > Current code: > import static org.testng.Assert.assertEquals; > > public static int aeo(Object arg1, Object arg2){ > assertEquals(arg1, arg2); > } > > public static int aec(Collection arg1, Collection arg2){ > assertEquals(arg1, arg2); > } > > aeo(obj1, obj2); > aec(list1, list2); > > New code: > > import static org.testng.Assert.assertEquals(Object, Object) as aeo; > import static org.testng.Assert.assertEquals(Collection, Collection) as aec; > > aeo(obj1, obj2); > aec(list1, list2); > > Note: it is possible that this sort of method selection is beyond the > scope of a COIN proposal > > DETAILS > > SPECIFICATION: > > Grammar > > modification (JLS 3.9): > Keyword: > as > ... > > modification (JLS 7.5): > ImportDeclaration: > SingleTypeImportDeclarationWithAlias > SingleStaticImportDeclarationWithAlias > ... > > addition: > SingleTypeImportDeclarationWithAlias: > import TypeName as Identifier; > > addition: > SingleStaticImportDeclarationWithAlias: > import static TypeName . Identifier as Identifier; > > > Note that this would explicitly forbid wildcard imports from being aliased. > > There are no known effects on the type system or meaning of > expressions and statements in the Java Programming Language. > > COMPILATION: This feature would be a compile-time transform. It would > only affect the way in which a non-fully qualified class or method > name was resolved to a fully-qualified class or method name. > > TESTING: This change would be tested in a manner similar how how the > existing code which resolves the fully-qualified names of classes and > methods is tested. > > LIBRARY SUPPORT: No change > > REFLECTIVE APIS: No change > > OTHER CHANGES: No change > > MIGRATION: This change is backwards-compatible with existing code. > > COMPATIBILITY > > BREAKING CHANGES: No change > > EXISTING PROGRAMS: No change > > REFERENCES > > EXISTING BUGS: None at present > > URL FOR PROTOTYPE (optional): None at present > > From reinier at zwitserloot.com Tue Mar 3 02:06:34 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 3 Mar 2009 11:06:34 +0100 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> Message-ID: <08E77F6F-6D7F-4A0F-B389-4851039220F0@zwitserloot.com> Maybe I'm making this too simple, but what if javac will treat all catch blocks of a type that isn't thrown by the try block as warnings instead of errors? That fixes Neal's Improved Exception Handling issue of not being 100% source compatible with java 6, no? I assume source compatibility where code that is clearly broken results in a warning in java 7 (but is still compiled with exactly the same semantics) whereas it was silently compiled by java 6 is only good news. Also, because in just about every other language on the JVM, checked exceptions can be thrown without being declared, I think this is a good idea in general, considering that java wants to be more interoperable with non-java JVM languages. To work around this issue now, you have to either wrap the call in a wrapper method that adds the exception to the throws list, or you have to create a dummy method that declares the throwable in the throws list but doesn't throw it, just so javac will stop refusing to compile your code. That's clearly a hack solution, and the elimination of it should be a good thing, even if you need to use a @SuppressWarnings instead, no? Should I write up a proposal for this? Should Neal add it to his proposal? Or is it just a horribly stupid idea? :) --Reinier Zwitserloot On Mar 3, 2009, at 08:33, Neal Gafter wrote: > On Mon, Mar 2, 2009 at 10:29 PM, Joseph D. Darcy > wrote: >>> MAJOR DISADVANTAGE: >>> >>> One-time implementation cost for adding the features to the >>> compiler. >>> Longer language specification in describing the behavior. >>> >> >> What sort of poor programming practices could this feature >> encourage or >> enable? > > I don't see any, but perhaps I'm shortsighted. > >>> The type system is affected as follows: For the purpose of type >>> checking, a catch parameter declared with a disjunction has type >>> lub(t1, t2, ...) [JLS3 15.12.2.5]. >> >> In terms of finding the members of the type, it is good existing >> concepts in >> the JLS can be used. >> >> What happens if someone writes >> >> catch(final IOException | SomeSubclassOfIOException e) {...} >> >> In other words, is it legal to have subclasses of a caught >> exception listed >> too? > > I don't really care one way or the other. As written, yes, it is > allowed and means the same thing as the supertype alone. > >>> To avoid the need to add support for general disjunctive types, but >>> leaving open the possibility of a future extension along these >>> lines, >>> a catch parameter whose type has more than one disjunct is >>> required to >>> be declared final. >>> >> >> I think that is a fine compromise that keep the current feature >> smaller >> while allowing room for a broader feature later. >> >> Some worked examples of the sets of thrown exceptions types under >> various >> tricky code samples would help clarify the data flow algorithm for >> me. > > Sure, I can do that. Do you think that should go in the > specification? > >>> A catch clause is currently compiled (before this change) to an >>> entry >>> in an exception table that specifies the type of the exception and >>> the >>> address of the code for the catch body. To generate code for this >>> new >>> construct, the compiler would generate an entry in the exception >>> table >>> for each type in the exception parameter's list of types. >>> >> >> Interesting; so there would be no code duplication even in the >> class files. > > Correct. That's what the current prototype (in the BGGA compiler) > does for this construct. > >> How could the increased exception precision be maintained will >> still allow >> programs such as the one above to compile? > > I don't think it can without making rather complex rules, but I'll > think about it more. > > However, one could take only the multicatch part of this proposal and > not the final/rethrow part, and then I believe one could specify it > without there being a breaking change. > From reinier at zwitserloot.com Tue Mar 3 02:09:11 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 3 Mar 2009 11:09:11 +0100 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: <49ACF691.5090104@paradise.net.nz> References: <49ACF691.5090104@paradise.net.nz> Message-ID: <081BECAE-EF46-408D-AF76-7CA72CC62EE2@zwitserloot.com> An alternative that this proposal doesn't list is package imports. Something like: import java.util; import java.sql; new sql.Date(new util.Date()); --Reinier Zwitserloot On Mar 3, 2009, at 10:21, Bruce Chapman wrote: > My 2 cents: > > This partially covers the need for type aliases, but not for generic > types (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4983159), if > we are going to introduce aliases it should cover the generic case > as well. > > An alternative syntax to avoid the 'as' keyword could be > > "import Sqldate = java.sql.Date;" > > Either syntax could probably cover the generic type alias case as > well, > however I am not sure if an "import" statement is the right way to > do that. > > I liked your examples, some are very compelling. > > An alternative mechanism that preserves the simple names might be to > alias the package rather than aliasing the type. > eg > import ju=java.util; // or import package ju=java.util; > import js=java.sql; > > js.Date date = new js.Date(new ju.Date); > > > That gets further away from solving the generics alias issue, which > might be a good thing : it leaves it easier to do a complete type > aliases solution as a separate issue. (IS anyone working on a type > aliases proposal for coin?) > > Bruce > > > Phil Varner wrote: >> Import Aliases for Classes and Static Methods >> >> http://docs.google.com/Doc?id=dgx74dt7_19dxnspbhj >> >> AUTHOR: Phil Varner >> >> OVERVIEW >> >> FEATURE SUMMARY: The import aliases feature allows a user to provide >> an alias underwhich an imported class or statically imported method >> must be referred to in the containing source file. An example of >> the >> use of this feature is "import java.sql.Date as SqlDate;" >> >> MAJOR ADVANTAGE: This feature would allow easier use of multiple >> classes which have the same name but different packages to be used in >> the same source file. >> >> MAJOR BENEFIT: This will prevent the necessity of fully-qualifiying >> all class references when there is a name collision, leading to more >> readable code. >> >> MAJOR DISADVANTAGE: This will introduce an extra level of >> indirection >> when determing the source of a given class or method, introduce a new >> keyword 'as', and will require changes to IDE code completion >> functionality. >> >> ALTERNATIVES: In some cases, a nested class can be created which >> trivially derives a class involved in the name collision. For a >> method, a wrapper method can be created in the source file. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> >> Example #1, duplicate class name >> >> Current code: >> >> new java.sql.Date(new java.util.Date()); >> >> New code: >> >> import java.sql.Date as SqlDate; >> import java.util.Date as UtilDate; >> >> new SqlDate(new UtilDate()); >> >> Example #2, statically imported method alias >> >> Current code: >> >> import static >> com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName; >> >> public static int mrlacsmn(final int arg1, final String arg2){ >> return myReallyLongAndComplicatedStaticMethodName(arg1, arg2); >> } >> >> mrlacsmn(1, a); >> >> New code: >> >> import static >> com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName >> as mrlacsmn; >> >> mrlacsmn(1, a); >> >> ADVANCED EXAMPLE: >> >> Example #3 >> >> Translation of persistent formats between similar APIs. >> >> In many domains, it is not uncommon to have two different APIs with >> classes with the same name. For example, in a production rules API, >> one may have classes "RuleSet" and "Rule". When attempting to use >> the >> API to translate between these these APIs, it must be decided that >> one >> is fully-qualified and one is not. This can lead to code like: >> >> com.example.foo.bar.sdk.RuleSet srcRuleSet = ...; >> com.example.foo.bar.sdk2.RuleSet dstRuleSet = new >> com.example.foo.bar.sdk2.RuleSet(); >> migrate(srcRuleSet, dstRuleSet); >> ... >> >> private static void migrate(com.example.foo.bar.sdk.RuleSet >> srcRuleSet, >> com.example.foo.bar.sdk2.RuleSet dstRuleSet){ >> ... >> } >> >> Note that it is good practice here not to import either class because >> it is too easy to accidentally misuse constants and static methods. >> >> With the 'as' syntax, one could instead write the far less verbose >> and >> more readible: >> >> import com.example.foo.bar.sdk.RuleSet as SrcRuleSet; >> import com.example.foo.bar.sdk2.RuleSet as DstRuleSet; >> >> ... >> >> SrcRuleSet srcRuleSet = ...; >> DstRuleSet destRuleSet = new DstRuleSet(); >> migrate(srcRuleSet, dstRuleSet); >> >> ... >> >> private static void migrate(SrcRuleSet srcRuleSet, >> DstRuleSet dstRuleSet){ >> ... >> } >> >> Example #4 >> >> Ensuring correct method selection when static importing overloaded >> methods. >> >> Current code: >> import static org.testng.Assert.assertEquals; >> >> public static int aeo(Object arg1, Object arg2){ >> assertEquals(arg1, arg2); >> } >> >> public static int aec(Collection arg1, Collection arg2){ >> assertEquals(arg1, arg2); >> } >> >> aeo(obj1, obj2); >> aec(list1, list2); >> >> New code: >> >> import static org.testng.Assert.assertEquals(Object, Object) as aeo; >> import static org.testng.Assert.assertEquals(Collection, >> Collection) as aec; >> >> aeo(obj1, obj2); >> aec(list1, list2); >> >> Note: it is possible that this sort of method selection is beyond the >> scope of a COIN proposal >> >> DETAILS >> >> SPECIFICATION: >> >> Grammar >> >> modification (JLS 3.9): >> Keyword: >> as >> ... >> >> modification (JLS 7.5): >> ImportDeclaration: >> SingleTypeImportDeclarationWithAlias >> SingleStaticImportDeclarationWithAlias >> ... >> >> addition: >> SingleTypeImportDeclarationWithAlias: >> import TypeName as Identifier; >> >> addition: >> SingleStaticImportDeclarationWithAlias: >> import static TypeName . Identifier as Identifier; >> >> >> Note that this would explicitly forbid wildcard imports from being >> aliased. >> >> There are no known effects on the type system or meaning of >> expressions and statements in the Java Programming Language. >> >> COMPILATION: This feature would be a compile-time transform. It >> would >> only affect the way in which a non-fully qualified class or method >> name was resolved to a fully-qualified class or method name. >> >> TESTING: This change would be tested in a manner similar how how the >> existing code which resolves the fully-qualified names of classes and >> methods is tested. >> >> LIBRARY SUPPORT: No change >> >> REFLECTIVE APIS: No change >> >> OTHER CHANGES: No change >> >> MIGRATION: This change is backwards-compatible with existing code. >> >> COMPATIBILITY >> >> BREAKING CHANGES: No change >> >> EXISTING PROGRAMS: No change >> >> REFERENCES >> >> EXISTING BUGS: None at present >> >> URL FOR PROTOTYPE (optional): None at present >> >> > > > From rssh at gradsoft.com.ua Tue Mar 3 02:11:01 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 3 Mar 2009 12:11:01 +0200 (EET) Subject: PROPOSAL: Multiline strings In-Reply-To: <49ACD1BB.7060505@sun.com> References: <49ACD1BB.7060505@sun.com> Message-ID: > Ruslan, > > This proposal is missing many important details. > .... Thanks, I prepared reviewed proposal >> ALTERNATIVES: understand, thanks for clafifying. > > What are the grammar changes? > Originally idea was: MultilineStringLiteral: """ MultilineStringCharacters/opt """ MultilineStringCharacters: MultilineStringCharacter MultilineStringCharacters MultilineStringCharacter but not " (MultilineStringCharacters but not "") "" MultilineStringCharacter: InputCharacter but not \ EscapeSequence LineTermination But now if we want keep type of LineTermination and unescaped sequence, this will be .. as in next version which I will send by next letter. > Is are three consecutive quote characters escaped in a multi-line string? > \""" will be as (\")""", where \" is EscapeSequence, therefore be escaped. > As has been mentioned in earlier responses, how is whitespace handed? > First idea was does not handle ones at all, now I think that best is adopt proposition by Reinier Zwitserloot (which is the same as in proposal in project koin [http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd] by Jacek Furmankiewicz >> COMPILATION: >> Multiline strings created and used in .class files exactly as ordinary >> strings. >> > > What is the desugaring? > Ok, detailed description is added. Text withing """ brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. escape sequences in each line are processed exactly as in ordinary Java strings. 3. elimination of leading whitespaces are processed in next way: - at first determinated sequence of whitespace symbols (exclude LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. let's call it 'leading whitespace sequence' - all next lines must start with same leading whitespace sequence, otherwise compile-time error is thrown. - whitespace processing erase such leading sequence from resulting lines 4. set of lines after erasing of leading whitespace sequence is concatenated, with line-termination sequences between two neighbour lines. Inserted linetermination sequence is depend from LineTerminationSuffix, and is - value of systen property 'line.separator' is LineTerminationSuffix is empty - LF (i. e. '\n') when LineTerminationSuffix is 'U' or 'u' - CR LF (i. e. '\r''\n') when LineTerminationSuffix is 'W' or 'w' > Regards, > > -Joe > >> TESTING: >> Nothing special. add multiline strings to test-cases. >> >> LIBRARY SUPPORT: >> None. >> (May be exists sence add simple template processing to standard >> library, but >> I think this is goal of next janguage iteration. Now exists many good >> external >> frameworks, such as velocity: better wait and standartize support of >> winner) >> >> REFLECTIVE APIS: None >> >> OTHER CHANGES: None >> >> MIGRATION: None >> >> COMPABILITY >> None >> >> REFERENCES >> >> http://bugs.sun.com/view_bug.do?bug_id=4165111 >> >> >> >> >> >> >> >> > > From rssh at gradsoft.com.ua Tue Mar 3 02:15:32 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 3 Mar 2009 12:15:32 +0200 (EET) Subject: PROPOSAL: String literals: version 1.1 In-Reply-To: <49ACCFBD.3010509@sun.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> <49ACCFBD.3010509@sun.com> Message-ID: AUTHOR(s): Ruslan Shevchenko, Jeremy Manson (if agree), Reinier Zwitserloot (if agree) OVERVIEW: FEATURE SUMMARY: new string literals in java language: * multiline string literals. * string literals without escape processing. MAJOR ADVANTAGE: Possibility more elegant to code strings from other languages, such as sql constructions or inline xml (for multiline strings) or regular expressions (for string literals without escape processing). MAJOR DISADVANTAGE I don't know ALTERNATIVES: For multiline strings use operations and concatenation methods, such as: String,contact("Multiline \n", "string "); or String bigString="First line\n"+ "second line" For unescaped ('row') strings - use escaping of ordinary java string. EXAMPLES SIMPLE EXAMPLE: Multiline string:
  StringBuilder sb = new StringBuilder();
  sb.append("""select a from Area a, CountryCodes cc
                where
                   cc.isoCode='UA'
                  and
                   a.owner = cc.country
              """);
  if (question.getAreaName()!=null) {
     sb.append("""and
                  a.name like ?
               """);
     sqlParams.setString(++i,question.getAreaName());
  }
 
instead:
  StringBuilder sb = new StringBuilder();
  sb.append("select a from Area a, CountryCodes cc\n");
  sb.append("where cc.isoCode='UA'\n");
  sb.append("and a.owner=cc.country'\n");
  if (question.getAreaName()!=null) {
     sb.append("and a.name like ?");
     sqlParams.setString(++i,question.getAreaName());
  }
 
Unescaped String:
 String myParrern=''..*\.*'';
 
instead
 String myParrern="\..*\\.*";
 
ADVANCED EXAMPLE: String platformDepended="""q """; is 'q\n' if compiled on Unix and 'q\n\r' if compiled on Windows. String platformIndepended=""" """U; is always '\n'. String platformIndepended=""" """W; is always '\n\r'. String empty=""" """; is empty String foo = """ bar baz bla qux"; is equal to: String foo = "bar\n baz\n bla\nqux"; and the following: String foo = """ foo bar"""; is a compile-time error. String foo= """\"""" is " String foo= """\""" """ is """ DETAILS: Multiline strings are part of program text, which begin and ends by three double quotes. I. e. grammar in 3.10.5 of JLS can be extented as:
MultilineStringLiteral:
        """ MultilineStringCharacters/opt """  LineTerminationSuffix/opt

MultilineStringCharacters:
        MultilineStringCharacter
        MultilineStringCharacters  (MultilineStringCharacter but not ")
        (MultilineStringCharacters but not "") "

MultilineStringCharacter:
        InputCharacter but not \
        EscapeSequence
        LineTermination

LineTerminationSuffix:
                      U | u | W | w

Unescaped strings are part of program text, which begin and ends by two single quotes.
 RowStringLiteral:
                   '' RowInputCharacters/opt '' LineTerminationSuffix/opt

 RowInputCharacters:
                      ' (InputCharacter but not ')
                     |
                      (InputCharacter but not ') '
                     |
                      LineTermination
COMPILATION: Handling of multiline strings: Text withing """ brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. escape sequences in each line are processed exactly as in ordinary Java strings. 3. elimination of leading whitespaces are processed in next way: - at first determinated sequence of whitespace symbols (exclude LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. let's call it 'leading whitespace sequence' - all next lines must start with same leading whitespace sequence, otherwise compile-time error is thrown. - whitespace processing erase such leading sequence from resulting lines 4. set of lines after erasing of leading whitespace sequence is concatenated, with line-termination sequences between two neighbour lines. Inserted linetermination sequence is depend from LineTerminationSuffix, and is - value of systen property 'line.separator' is LineTerminationSuffix is empty - LF (i. e. '\n') when LineTerminationSuffix is 'U' or 'u' - CR LF (i. e. '\r''\n') when LineTerminationSuffix is 'W' or 'w' Handling of row strings: Text withing '' brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. set of lines after erasing of leading whitespace sequence is concatenated, with line-termination sequences between two neighbour lines, exactly as in case of multiline strings. No escape processing, no leading whitespace elimination are performed for receiving of resulting string value. new strings literals created and used in .class files exactly as ordinary strings. TESTING: Nothing special. add new strings literals to test-cases. LIBRARY SUPPORT: None. (May be exists sense add simple template processing to standard library, but I think this is goal of next language iteration. Now exists many good external frameworks, such as velocity: better wait and standardize support of winner) REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/view_bug.do?bug_id=4165111 http://bugs.sun.com/view_bug.do?bug_id=4472509 http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd by by Jacek Furmankiewicz From reinier at zwitserloot.com Tue Mar 3 02:33:26 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 3 Mar 2009 11:33:26 +0100 Subject: PROPOSAL: String literals: version 1.1 In-Reply-To: References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> <49ACCFBD.3010509@sun.com> Message-ID: <0929E79C-1147-444B-9741-E0833C216D30@zwitserloot.com> I don't think you need the U/W suffix; make all newlines \n regardless of what they are in the source file. If this annoys anybody, they can either manually add the \r in the string, or run a simple .replace("\n", "\r\n") at the end. I find collapsing whitespace far more interesting, but there too a simple method solution works just fine: .replaceAll("\\s+", " ") The problem with the suffixes are the rarity: I doubt anybody would know its even legal in the first place, so anybody that does use it effectively makes his code unreadable until the reader looks up the exotic syntax. Then again, there is precedence; the case of the hexadecimal floating point literal is almost point-for-point the same as this situation: Exotic syntax almost no java programmer even knows is legal ( double foo = 0x1P0D is legal java code!) but exists anyway because literals have a special meaning in java (they get inlined), which stops happening if you use an API utility to do the same thing: Double.longBitsToDouble. Still, in the 0x1P0D case there really is no alternative, whereas here you can always manually add \r to the string. --Reinier Zwitserloot On Mar 3, 2009, at 11:15, rssh at gradsoft.com.ua wrote: > AUTHOR(s): Ruslan Shevchenko, Jeremy Manson (if agree), Reinier > Zwitserloot (if agree) > > OVERVIEW: > > FEATURE SUMMARY: > new string literals in java language: > * multiline string literals. > * string literals without escape processing. > > MAJOR ADVANTAGE: > Possibility more elegant to code strings from other languages, such > as > sql constructions or inline xml (for multiline strings) or regular > expressions > (for string literals without escape processing). > > MAJOR DISADVANTAGE > I don't know > > ALTERNATIVES: > > For multiline strings use operations and concatenation methods, such > as: > > String,contact("Multiline \n", > "string "); > > or > > String bigString="First line\n"+ > "second line" > > For unescaped ('row') strings - use escaping of ordinary java string. > > > EXAMPLES > > SIMPLE EXAMPLE: > > Multiline string: > >
>  StringBuilder sb = new StringBuilder();
>  sb.append("""select a from Area a, CountryCodes cc
>                where
>                   cc.isoCode='UA'
>                  and
>                   a.owner = cc.country
>              """);
>  if (question.getAreaName()!=null) {
>     sb.append("""and
>                  a.name like ?
>               """);
>     sqlParams.setString(++i,question.getAreaName());
>  }
> 
> > instead: >
>  StringBuilder sb = new StringBuilder();
>  sb.append("select a from Area a, CountryCodes cc\n");
>  sb.append("where cc.isoCode='UA'\n");
>  sb.append("and a.owner=cc.country'\n");
>  if (question.getAreaName()!=null) {
>     sb.append("and a.name like ?");
>     sqlParams.setString(++i,question.getAreaName());
>  }
> 
> > Unescaped String: >
> String myParrern=''..*\.*'';
> 
> instead >
> String myParrern="\..*\\.*";
> 
> > ADVANCED EXAMPLE: > > String platformDepended="""q > """; > is 'q\n' if compiled on Unix and 'q\n\r' if compiled on Windows. > > String platformIndepended=""" > """U; > is always '\n'. > > String platformIndepended=""" > """W; > is always '\n\r'. > > String empty=""" > """; > is empty > > String foo = """ > bar > baz > bla > qux"; > > is equal to: String foo = "bar\n baz\n bla\nqux"; > > and the following: > > String foo = """ > foo > bar"""; > > is a compile-time error. > > String foo= """\"""" is " > String foo= """\""" """ is """ > > DETAILS: > > Multiline strings are part of program text, which begin and ends by > three > double quotes. > > I. e. grammar in 3.10.5 of JLS can be extented as: > >
> MultilineStringLiteral:
>        """ MultilineStringCharacters/opt """  LineTerminationSuffix/ 
> opt
>
> MultilineStringCharacters:
>        MultilineStringCharacter
>        MultilineStringCharacters  (MultilineStringCharacter but not ")
>        (MultilineStringCharacters but not "") "
>
> MultilineStringCharacter:
>        InputCharacter but not \
>        EscapeSequence
>        LineTermination
>
> LineTerminationSuffix:
>                      U | u | W | w
>
> 
> > > Unescaped strings are part of program text, which begin and ends by > two > single quotes. > > >
> RowStringLiteral:
>                   '' RowInputCharacters/opt '' LineTerminationSuffix/ 
> opt
>
> RowInputCharacters:
>                      ' (InputCharacter but not ')
>                     |
>                      (InputCharacter but not ') '
>                     |
>                      LineTermination
> 
> > > > COMPILATION: > > Handling of multiline strings: > > Text withing """ brackets processed in next way: > > 1. splitted to sequence of lines by line termination symbols. > 2. escape sequences in each line are processed exactly as in > ordinary Java > strings. > 3. elimination of leading whitespaces are processed in next way: > - at first determinated sequence of whitespace symbols (exclude > LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. > let's call it 'leading whitespace sequence' > - all next lines must start with same leading whitespace sequence, > otherwise compile-time error is thrown. > - whitespace processing erase such leading sequence from resulting > lines > 4. set of lines after erasing of leading whitespace sequence is > concatenated, with line-termination sequences between two neighbour > lines. > Inserted linetermination sequence is depend from > LineTerminationSuffix, > and is > - value of systen property 'line.separator' is > LineTerminationSuffix > is empty > - LF (i. e. '\n') when LineTerminationSuffix is 'U' or 'u' > - CR LF (i. e. '\r''\n') when LineTerminationSuffix is 'W' or 'w' > > > > Handling of row strings: > Text withing '' brackets processed in next way: > 1. splitted to sequence of lines by line termination symbols. > 2. set of lines after erasing of leading whitespace sequence is > concatenated, with line-termination sequences between two neighbour > lines, > exactly as in case of multiline strings. > > No escape processing, no leading whitespace elimination are > performed for > receiving of resulting string value. > > new strings literals created and used in .class files exactly as > ordinary > strings. > > TESTING: > Nothing special. add new strings literals to test-cases. > > LIBRARY SUPPORT: > None. > > (May be exists sense add simple template processing to standard > library, but > I think this is goal of next language iteration. Now exists many good > external > frameworks, such as velocity: better wait and standardize support of > winner) > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > None > > REFERENCES > > http://bugs.sun.com/view_bug.do?bug_id=4165111 > http://bugs.sun.com/view_bug.do?bug_id=4472509 > http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd by by Jacek > Furmankiewicz > > > > > > > > From rssh at gradsoft.com.ua Tue Mar 3 03:24:57 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 3 Mar 2009 13:24:57 +0200 (EET) Subject: PROPOSAL: String literals: version 1.1 In-Reply-To: <0929E79C-1147-444B-9741-E0833C216D30@zwitserloot.com> References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> <49ACCFBD.3010509@sun.com> <0929E79C-1147-444B-9741-E0833C216D30@zwitserloot.com> Message-ID: > I don't think you need the U/W suffix; make all newlines \n regardless > of what they are in the source file. If this annoys anybody, they can > either manually add the \r in the string, or run a > simple .replace("\n", "\r\n") at the end. I find collapsing whitespace 1. We must be able easy receive string in 'platform native' encoding. (If i wrote application, which generate part of text file, which I later will open in text editor: this is matter) 2. Hmm, in principle for me difference between suffix and method of string is not big (and smart compiler will be call this methods on constants during compilation) So, in principle suffixes can be changed to 3 methods nativeLf() - replace '\r\n'|'\n' to line terminaton sequence, native for this platform. unixLf() - replace '\r\n' to '\n' windowsLf() - replace '\n' to '\r\n' 3. I does not like names like unixLf() or windowsLf() Are you have any ideas about better names ? From scolebourne at joda.org Tue Mar 3 03:58:16 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 03 Mar 2009 11:58:16 +0000 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> References: <49AABBA2.3040009@joda.org> <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> Message-ID: <49AD1B58.5060305@joda.org> Jeremy Manson wrote: >> The principle perceived disadvantage, however, is that it encourages, >> rather than discourages, the use of null values in APIs. > > I would think that the principle disadvantage would be not that it > encourages use of null values (which, as you point out, is fine in > some contexts), but that it encourages programmers not to think about > what happens when there is a null value. But that is exactly what already happens today. Most developers are very poor at thinking through the null consequences of a method - the happy day scenario is the one focussed on. > I can easily imagine > programmers using this all of the time without thinking about it, and > then being surprised when a null ends up in the wrong place and not > knowing how it got there. Even with a simple example: > > public String someFunction(String a, String b) { > String s = a?.concat("foo"); > String t = b?.concat(a); > return myHashMap?.get(t); > } > > Now, someFunction returns null. Is it because a was null? Or b was > null? Or myHashMap was null? Or there was no mapping for t in > myHashMap? Or perhaps it doesn't matter, and thats why the code was written that way. Null as 'don't know' or 'don't care' is incredibly common. > If you want to cut down on > extraneous if-testing, I would use JSR-305's Nullity annotations > instead. What does this code do when passed null? Foo f = new Foo(null); int v = f.value; public class Foo { public final Integer value; public Foo(@Nonnull Integer value) { this.value = value; } } There is a NPE at f.value, not at new Foo(null). You would think that you could never construct an instance of Foo with a val of null, but you can. The @Nonnull annotation doesn't have any real meaning unless it is checked using a tool, and javac isn't such a tool. This will be very confusing when you use Foo from another part of your application and expect the value to be non-null and get a NPE. In fact the @Nonnull is positvely misleading. Basically, you can't rely on JSR-305. The information needs to be rechecked. Thus, whats the point in using it at all?!! Documentation perhaps? Annotations are not suitable for handling language level issues like nulls. Stephen From scolebourne at joda.org Tue Mar 3 04:08:36 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 03 Mar 2009 12:08:36 +0000 Subject: PROPOSAL: String literals: version 1.1 In-Reply-To: References: <1631da7d0903010058s20803984lcc37a9eb07f9bb7f@mail.gmail.com> <57840985-0B00-417A-ADDD-3B350D674D32@gmx.ch> <1631da7d0903010953s4c35c49akee6177535e13585f@mail.gmail.com> <1051A8B5-30F0-46B7-A23D-D99F6AE3D32D@zwitserloot.com> <49ACCFBD.3010509@sun.com> <0929E79C-1147-444B-9741-E0833C216D30@zwitserloot.com> Message-ID: <49AD1DC4.8040903@joda.org> rssh at gradsoft.com.ua wrote: >> I don't think you need the U/W suffix; make all newlines \n regardless >> of what they are in the source file. If this annoys anybody, they can >> either manually add the \r in the string, or run a >> simple .replace("\n", "\r\n") at the end. I find collapsing whitespace > > > 1. We must be able easy receive string in 'platform native' encoding. > (If i wrote application, which generate part of text file, which I later > will open in text editor: this is matter) > > 2. Hmm, in principle for me difference between suffix and method of string > is not big (and smart compiler will be call this methods on constants > during compilation) > > So, in principle suffixes can be changed to 3 methods > > nativeLf() - replace '\r\n'|'\n' to line terminaton sequence, native > for this platform. > unixLf() - replace '\r\n' to '\n' > windowsLf() - replace '\n' to '\r\n' > > 3. I does not like names like unixLf() or windowsLf() > Are you have any ideas about better names ? I would recommend doing a thorough survey of what other languages do for multi-line strings, including Groovy, Scala, Fan, Python, C# and any others you can think of. Try to find the common design. Stephen From rhvarona at gmail.com Mon Mar 2 23:43:59 2009 From: rhvarona at gmail.com (Roger Hernandez) Date: Tue, 3 Mar 2009 02:43:59 -0500 Subject: Simple Resource Clean-up In-Reply-To: <15e8b9d20903022323k17c3f1afo9919c311070b17be@mail.gmail.com> References: <15e8b9d20903022323k17c3f1afo9919c311070b17be@mail.gmail.com> Message-ID: Sorry I meant to take that part out, since I saw the comments from the previous proposal. The way I envision it working is in a way how C++ template instantiation works. The compiler just requires that a class have an accessible "close()" function, it should not care what interface or class it comes from. That way it can throw any exception type. On Tue, Mar 3, 2009 at 2:23 AM, Neal Gafter wrote: > You say "The object being created must implement the Closeable > interface." But java.sql.Statement, to pick one example, cannot be > made to implement that interface because the exception signatures are > not compatible. > > I'll let others comment about issues with exception handling in the > translation. > > -Neal > > On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez > wrote: > > I saw how the previous Automatic Resource Management proposal got torn to > > pieces but I feel strongly enough about this issue to post a similar > > proposal. > > > > Some points: > > > > I am not a programming language designer. I have very little experience > > with byte code and with design and implementation of compilers. What I > do > > have is many years of experience in writing code for large business > > applications, both in house-custom programs and shrink-wrapped products > sold > > to customers. > > > > About 1/3 of the Java code I write contributes almost nothing to the > > functionality or flexibility of the program. It is composed of very > simple > > and very repetitive resource clean-up code. JDBC code is an especially > bad > > case. I know we should be using JDO or JPA, but: 1) most of the Java > > database code in existence is using JDBC to some extent or another, 2) > for > > the kind of processing our software does with large datasets having > hundreds > > of megabytes of row data and millions of rows per account per month, > custom > > JDBC code still beats the other solutions in memory utilization and > > throughput. > > > > In most business code we don't do complex exception processing. If we > get a > > exception we rollback the transaction and unroll the stack until we reach > > some program level error handler that logs the error for some > administrator > > to review at a later date. So if this proposal is not applicable to > complex > > error handling scenarios, that is fine. Taking care of the simple > scenarios > > will still get rid of most of that 1/3 of the code I write, allowing me > to > > concentrate on the actual program logic, not the resource clean-up noise. > > > > I also program quite a bit in C++ and C# and when I work in Java I sorely > > miss RAII (Resource Acquisition Is Initialization) and the "using" > statement > > respectively. > > > > At the end of the day, what I would like is a solution to minimize all > the > > resource clean-up boiler plate. > > > > > ----------------------------------------------------------------------------------------- > > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > > > AUTHOR: Roger Hernandez, rogerh at velocityconsultinginc.com > > > > OVERVIEW > > > > FEATURE SUMMARY: Syntactic sugar for simple cases of the common > > new/try/finally/close language idiom. The object being created must > > implement the Closeable interface. > > > > MAJOR ADVANTAGE: Significantly reduces lines of code when working with > > objects that encapsulate external resources that should be closed as soon > as > > possible. Examples are Stream, Reader, Writer classes in java.io, and > > Connection, Statement, PreparedStatement, ResultSet in java.sql.*. > > > > MAJOR BENEFIT: It allows writing code that uses these kinds of object > to > > more clearly express the both the lifetime of the utilization of each > > resource, and allows the logic flow of the code to be more visible. > > > > MAJOR DISADVANTAGE: Either a new keyword, or an additional overloaded > > meaning on an existing keyword. > > > > ALTERNATIVES: You can always use the standard idiom: SomeType val = new > > val(...); try { ... } finally { val.close(); } > > > > EXAMPLES > > > > SIMPLE EXAMPLE: A simple Java version of the command line utility > "tee". > > //This is the existing way of doing it. > > //Lines of code: 19 > > package com.vci.projectcoin.using; > > > > import java.io.*; > > > > public class SimpleExample { > > > > public static void main(String[] args) throws IOException { > > byte []buffer = new byte[1024]; > > FileOutputStream out = new FileOutputStream(args[0]); > > try { > > for (int count; (count = System.in.read(buffer)) != -1;) { > > out.write(buffer, 0, count); > > System.out.write(buffer, 0, count); > > } > > } finally { > > out.close(); > > } > > } > > } > > > > //This is the proposed way of doing it, the compiler converts the > > syntactic sugar into the same byte codes > > //I am adding a new use to the the "try" keyword to avoid adding > more > > to the language, but it would work > > //just a well with a "using" keyword. > > //Lines of code: 16 > > package com.vci.projectcoin.using; > > > > import java.io.*; > > > > public class SimpleExample { > > > > public static void main(String[] args) throws IOException { > > byte []buffer = new byte[1024]; > > try (FileOutputStream out = new FileOutputStream(args[0])) { > > for (int count; (count = System.in.read(buffer)) != -1;) { > > out.write(buffer, 0, count); > > System.out.write(buffer, 0, count); > > } > > } > > } > > } > > > > ADVANCED EXAMPLE: A simple utility to execute a query and write values > as > > a comma delimited file. > > > > //This is the existing way of doing it > > //Lines of code: 55 > > package com.vci.projectcoin.using; > > > > import java.sql.*; > > import java.io.*; > > > > public class AdvancedExample { > > final static String EOL = System.getProperty("line.separator"); > > > > //Command Line: [] > > static public void main(String []args) throws SQLException, > > FileNotFoundException { > > String url = args[0]; > > String sql = args[1]; > > PrintWriter out = new PrintWriter(args.length > 2 ? new > > FileOutputStream(args[2]) : System.out); > > try { > > Connection conn = DriverManager.getConnection(url); > > try { > > Statement query = > > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > > ResultSet.CONCUR_READ_ONLY); > > try { > > ResultSet results = query.executeQuery(sql); > > try { > > ResultSetMetaData meta = results.getMetaData(); > > int colCount = meta.getColumnCount(); > > while (results.next()) { > > for (int index = 1; index <= colCount; index++) > { > > int colType = meta.getColumnType(index); > > boolean quoted = colType == Types.CHAR || > > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || > > colType == Types.NCHAR || > > colType == Types.NVARCHAR || colType == Types.VARCHAR; > > if (quoted) { > > System.out.append('"'); > > } > > System.out.append(results.getString(index)); > > if (quoted) { > > System.out.append('"'); > > } > > if (index < colCount) { > > System.out.print(','); > > } else { > > System.out.print(EOL); > > } > > } > > } > > } finally { > > results.close(); > > } > > } finally { > > query.close(); > > } > > } finally { > > conn.close(); > > } > > } finally { > > out.close(); > > } > > } > > } > > > > //This is the proposed way of doing it > > //This proposal gets rid of the finally clean up per object. It > lets > > one write robust resource clean-up code without a lot of effort. > > //Lines of code: 43 > > package com.vci.projectcoin.using; > > > > import java.sql.*; > > import java.io.*; > > > > public class AdvancedExample { > > final static String EOL = System.getProperty("line.separator"); > > > > //Command Line: [] > > static public void main(String []args) throws SQLException, > > FileNotFoundException { > > String url = args[0]; > > String sql = args[1]; > > try (PrintWriter out = new PrintWriter(args.length > 2 ? new > > FileOutputStream(args[2]) : System.out)) { > > try (Connection conn = DriverManager.getConnection(url)) { > > try (Statement query = > > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > > ResultSet.CONCUR_READ_ONLY)) { > > try (ResultSet results = query.executeQuery(sql)) { > > ResultSetMetaData meta = results.getMetaData(); > > int colCount = meta.getColumnCount(); > > while (results.next()) { > > for (int index = 1; index <= colCount; index++) > { > > int colType = meta.getColumnType(index); > > boolean quoted = colType == Types.CHAR || > > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType > == > > Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; > > if (quoted) { > > System.out.append('"'); > > } > > System.out.append(results.getString(index)); > > if (quoted) { > > System.out.append('"'); > > } > > if (index < colCount) { > > System.out.print(','); > > } else { > > System.out.print(EOL); > > } > > } > > System.out.println(); > > } > > } > > } > > } > > } > > } > > } > > > > //This is an additional syntactic sugar proposal, allowing multiple > > objects to be allocated inside one try block. The compiler converts all > > three programs into the same bytecode > > //This proposal gets rid of the additional indentation level and > > closing brace per object. It further minimize the clean-up boiler-plate, > > allowing the point of the program logic to be clearer. > > //Lines of code: 38 > > package com.vci.projectcoin.using; > > > > import java.sql.*; > > import java.io.*; > > > > public class AdvancedExample { > > final static String EOL = System.getProperty("line.separator"); > > > > //Command Line: [] > > static public void main(String []args) throws SQLException, > > FileNotFoundException { > > String url = args[0]; > > String sql = args[1]; > > try (PrintWriter out = new PrintWriter(args.length > 2 ? new > > FileOutputStream(args[2]) : System.out), > > Statement query = > > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > > ResultSet.CONCUR_READ_ONLY), > > ResultSet results = query.executeQuery(sql)) { > > ResultSetMetaData meta = results.getMetaData(); > > int colCount = meta.getColumnCount(); > > while (results.next()) { > > for (int index = 1; index <= colCount; index++) { > > int colType = meta.getColumnType(index); > > boolean quoted = colType == Types.CHAR || colType == > > Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == > Types.NCHAR > > || colType == Types.NVARCHAR || colType == Types.VARCHAR; > > if (quoted) { > > System.out.append('"'); > > } > > System.out.append(results.getString(index)); > > if (quoted) { > > System.out.append('"'); > > } > > if (index < colCount) { > > System.out.print(','); > > } else { > > System.out.print(EOL); > > } > > } > > System.out.println(); > > } > > } > > } > > } > > > > DETAILS > > The specification requires that the object in the try () block have a > > "close()" method. Wether the method throws any or no exception, or if it > > returns a value or no value does not matter. The proposal is not trying > to > > introduce any new intelligence into the try finally clause, it is just > > syntactic sugar to minimize simple resource clean-up code. > > > > SPECIFICATION: > > The "try" keyword will have an overloaded meaning > > > > CASE 1 > > ------ > > try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { > > //work gets done here > > } > > > > Will be syntactic sugar for: > > ClassWithCloseMethod value = new ClassWithCloseMethod(...); > > try { > > //work gets done here > > } finally { > > value.close(); > > } > > > > CASE 2 > > ------ > > try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { > > //work gets done here > > } finally { > > //additional clean-up code > > } > > > > Will be syntactic sugar for: > > ClassWithCloseMethod value = new ClassWithCloseMethod(...); > > try { > > //work gets done here > > } finally { > > value.close(); > > //additional clean-up code > > } > > > > CASE 3 > > ------ > > try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) { > > //work gets done here > > } catch (Exception ex) { > > //exception handling code > > } finally { > > //additional clean-up code > > } > > > > Will be syntactic sugar for: > > ClassWithCloseMethod value = new ClassWithCloseMethod(...); > > try { > > //work gets done here > > } catch (Exception ex) { > > //exception handling code > > } finally { > > value.close(); > > //additional clean-up code > > } > > > > CASE 4 > > ------ > > try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), > > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), > > Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) > { > > //work gets done here > > } > > > > Will be syntactic sugar for: > > Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > > try { > > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > > try { > > Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); > > try { > > //work gets done here > > } finally { > > value3.close(); > > } > > } finally { > > value2.close(); > > } > > } finally { > > value1.close(); > > } > > > > CASE 5 > > ------ > > try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), > > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), > > Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) > { > > //work gets done here > > } finally { > > //additional clean-up code > > } > > > > Will be syntactic sugar for: > > Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > > try { > > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > > try { > > Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); > > try { > > //work gets done here > > } finally { > > value3.close(); > > } > > } finally { > > value2.close(); > > } > > } finally { > > value1.close(); > > //additional clean-up code > > } > > > > CASE 6 > > ------ > > try (Class1WithCloseMethod value1 = new Class1WithCloseMethod(...), > > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...), > > Class3WithCloseMethod value3 = new Class3WithCloseMethod(...)) > { > > //work gets done here > > } catch (Exception ex) { > > //exception handling code > > } finally { > > //additional clean-up code > > } > > > > Will be syntactic sugar for: > > Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > > try { > > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > > try { > > Class3WithCloseMethod value3 = new Class3WithCloseMethod(...); > > try { > > //work gets done here > > } finally { > > value3.close(); > > } > > } finally { > > value2.close(); > > } > > } catch (Exception ex) { > > //exception handling code > > } finally { > > value1.close(); > > //additional clean-up code > > } > > > > COMPILATION: The SPECIFICATION section above shows the desugaring for > > each case. Byte code would be identical to the desugared constructs. > > > > TESTING: Byte code comparison of common code constructs. If the byte > > code is not identical to the desugared version, test fails. > > > > LIBRARY SUPPORT: No. > > > > REFLECTIVE APIS: No. > > > > OTHER CHANGES: No. > > > > MIGRATION: For each case in the SPECIFICATION section, convert the > > existing code to the syntactic sugar proposal. > > > > > > COMPATIBILITY > > > > BREAKING CHANGES: None. > > > > EXISTING PROGRAMS: Compile accepts both existing and new forms of the > > "try" statement. Byte code does not change. > > > > REFERENCES > > > > EXISTING BUGS: None > > > > > > -- > > Roger Hernandez > > > > > -- Roger Hernandez From rhvarona at gmail.com Tue Mar 3 00:21:19 2009 From: rhvarona at gmail.com (Roger Hernandez) Date: Tue, 3 Mar 2009 03:21:19 -0500 Subject: Simple Resource Clean-up In-Reply-To: <15e8b9d20903022354y62f10866t8f403767d22a874f@mail.gmail.com> References: <15e8b9d20903022323k17c3f1afo9919c311070b17be@mail.gmail.com> <15e8b9d20903022354y62f10866t8f403767d22a874f@mail.gmail.com> Message-ID: The code fragment: class ClassWithClose { public ClassWithClose () { .... } public void close () throws SQLException { if (cond) { throw SQLException("message"); } } } try (ClassWithClose val = new ClassWithClose()) { funcThatThrowsIOException(); } behaves exactly like: ClassWithClose val = new ClassWithClose(); try { funcThatThrowsIOException(); } finally { val.close(); } I am going to see the SQLException being thrown out. On Tue, Mar 3, 2009 at 2:54 AM, Neal Gafter wrote: > Just to make sure I understand, in your specification, if an exception > is thrown from the try block, and then another exception is thrown > from the close() method, the one from the close() is the one that > propogates out? > > On Mon, Mar 2, 2009 at 11:43 PM, Roger Hernandez > wrote: > > Sorry I meant to take that part out, since I saw the comments from the > > previous proposal. The way I envision it working is in a way how C++ > > template instantiation works. The compiler just requires that a class > have > > an accessible "close()" function, it should not care what interface or > class > > it comes from. That way it can throw any exception type. > > - Show quoted text - > > > > On Tue, Mar 3, 2009 at 2:23 AM, Neal Gafter wrote: > >> > >> You say "The object being created must implement the Closeable > >> interface." But java.sql.Statement, to pick one example, cannot be > >> made to implement that interface because the exception signatures are > >> not compatible. > >> > >> I'll let others comment about issues with exception handling in the > >> translation. > >> > >> -Neal > >> > >> On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez > >> wrote: > >> > I saw how the previous Automatic Resource Management proposal got torn > >> > to > >> > pieces but I feel strongly enough about this issue to post a similar > >> > proposal. > >> > > >> > Some points: > >> > > >> > I am not a programming language designer. I have very little > experience > >> > with byte code and with design and implementation of compilers. What > I > >> > do > >> > have is many years of experience in writing code for large business > >> > applications, both in house-custom programs and shrink-wrapped > products > >> > sold > >> > to customers. > >> > > >> > About 1/3 of the Java code I write contributes almost nothing to the > >> > functionality or flexibility of the program. It is composed of very > >> > simple > >> > and very repetitive resource clean-up code. JDBC code is an > especially > >> > bad > >> > case. I know we should be using JDO or JPA, but: 1) most of the Java > >> > database code in existence is using JDBC to some extent or another, 2) > >> > for > >> > the kind of processing our software does with large datasets having > >> > hundreds > >> > of megabytes of row data and millions of rows per account per month, > >> > custom > >> > JDBC code still beats the other solutions in memory utilization and > >> > throughput. > >> > > >> > In most business code we don't do complex exception processing. If we > >> > get a > >> > exception we rollback the transaction and unroll the stack until we > >> > reach > >> > some program level error handler that logs the error for some > >> > administrator > >> > to review at a later date. So if this proposal is not applicable to > >> > complex > >> > error handling scenarios, that is fine. Taking care of the simple > >> > scenarios > >> > will still get rid of most of that 1/3 of the code I write, allowing > me > >> > to > >> > concentrate on the actual program logic, not the resource clean-up > >> > noise. > >> > > >> > I also program quite a bit in C++ and C# and when I work in Java I > >> > sorely > >> > miss RAII (Resource Acquisition Is Initialization) and the "using" > >> > statement > >> > respectively. > >> > > >> > At the end of the day, what I would like is a solution to minimize all > >> > the > >> > resource clean-up boiler plate. > >> > > >> > > >> > > ----------------------------------------------------------------------------------------- > >> > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >> > > >> > AUTHOR: Roger Hernandez, rogerh at velocityconsultinginc.com > >> > > >> > OVERVIEW > >> > > >> > FEATURE SUMMARY: Syntactic sugar for simple cases of the common > >> > new/try/finally/close language idiom. The object being created must > >> > implement the Closeable interface. > >> > > >> > MAJOR ADVANTAGE: Significantly reduces lines of code when working > with > >> > objects that encapsulate external resources that should be closed as > >> > soon as > >> > possible. Examples are Stream, Reader, Writer classes in java.io, > and > >> > Connection, Statement, PreparedStatement, ResultSet in java.sql.*. > >> > > >> > MAJOR BENEFIT: It allows writing code that uses these kinds of > object > >> > to > >> > more clearly express the both the lifetime of the utilization of each > >> > resource, and allows the logic flow of the code to be more visible. > >> > > >> > MAJOR DISADVANTAGE: Either a new keyword, or an additional > overloaded > >> > meaning on an existing keyword. > >> > > >> > ALTERNATIVES: You can always use the standard idiom: SomeType val = > >> > new > >> > val(...); try { ... } finally { val.close(); } > >> > > >> > EXAMPLES > >> > > >> > SIMPLE EXAMPLE: A simple Java version of the command line utility > >> > "tee". > >> > //This is the existing way of doing it. > >> > //Lines of code: 19 > >> > package com.vci.projectcoin.using; > >> > > >> > import java.io.*; > >> > > >> > public class SimpleExample { > >> > > >> > public static void main(String[] args) throws IOException { > >> > byte []buffer = new byte[1024]; > >> > FileOutputStream out = new FileOutputStream(args[0]); > >> > try { > >> > for (int count; (count = System.in.read(buffer)) != -1;) > { > >> > out.write(buffer, 0, count); > >> > System.out.write(buffer, 0, count); > >> > } > >> > } finally { > >> > out.close(); > >> > } > >> > } > >> > } > >> > > >> > //This is the proposed way of doing it, the compiler converts the > >> > syntactic sugar into the same byte codes > >> > //I am adding a new use to the the "try" keyword to avoid adding > >> > more > >> > to the language, but it would work > >> > //just a well with a "using" keyword. > >> > //Lines of code: 16 > >> > package com.vci.projectcoin.using; > >> > > >> > import java.io.*; > >> > > >> > public class SimpleExample { > >> > > >> > public static void main(String[] args) throws IOException { > >> > byte []buffer = new byte[1024]; > >> > try (FileOutputStream out = new FileOutputStream(args[0])) > { > >> > for (int count; (count = System.in.read(buffer)) != -1;) > { > >> > out.write(buffer, 0, count); > >> > System.out.write(buffer, 0, count); > >> > } > >> > } > >> > } > >> > } > >> > > >> > ADVANCED EXAMPLE: A simple utility to execute a query and write > values > >> > as > >> > a comma delimited file. > >> > > >> > //This is the existing way of doing it > >> > //Lines of code: 55 > >> > package com.vci.projectcoin.using; > >> > > >> > import java.sql.*; > >> > import java.io.*; > >> > > >> > public class AdvancedExample { > >> > final static String EOL = > System.getProperty("line.separator"); > >> > > >> > //Command Line: [] > >> > static public void main(String []args) throws SQLException, > >> > FileNotFoundException { > >> > String url = args[0]; > >> > String sql = args[1]; > >> > PrintWriter out = new PrintWriter(args.length > 2 ? new > >> > FileOutputStream(args[2]) : System.out); > >> > try { > >> > Connection conn = DriverManager.getConnection(url); > >> > try { > >> > Statement query = > >> > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > >> > ResultSet.CONCUR_READ_ONLY); > >> > try { > >> > ResultSet results = query.executeQuery(sql); > >> > try { > >> > ResultSetMetaData meta = results.getMetaData(); > >> > int colCount = meta.getColumnCount(); > >> > while (results.next()) { > >> > for (int index = 1; index <= colCount; > >> > index++) { > >> > int colType = meta.getColumnType(index); > >> > boolean quoted = colType == Types.CHAR > || > >> > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || > >> > colType == Types.NCHAR > || > >> > colType == Types.NVARCHAR || colType == Types.VARCHAR; > >> > if (quoted) { > >> > System.out.append('"'); > >> > } > >> > > >> > System.out.append(results.getString(index)); > >> > if (quoted) { > >> > System.out.append('"'); > >> > } > >> > if (index < colCount) { > >> > System.out.print(','); > >> > } else { > >> > System.out.print(EOL); > >> > } > >> > } > >> > } > >> > } finally { > >> > results.close(); > >> > } > >> > } finally { > >> > query.close(); > >> > } > >> > } finally { > >> > conn.close(); > >> > } > >> > } finally { > >> > out.close(); > >> > } > >> > } > >> > } > >> > > >> > //This is the proposed way of doing it > >> > //This proposal gets rid of the finally clean up per object. It > >> > lets > >> > one write robust resource clean-up code without a lot of effort. > >> > //Lines of code: 43 > >> > package com.vci.projectcoin.using; > >> > > >> > import java.sql.*; > >> > import java.io.*; > >> > > >> > public class AdvancedExample { > >> > final static String EOL = > System.getProperty("line.separator"); > >> > > >> > //Command Line: [] > >> > static public void main(String []args) throws SQLException, > >> > FileNotFoundException { > >> > String url = args[0]; > >> > String sql = args[1]; > >> > try (PrintWriter out = new PrintWriter(args.length > 2 ? > new > >> > FileOutputStream(args[2]) : System.out)) { > >> > try (Connection conn = DriverManager.getConnection(url)) > { > >> > try (Statement query = > >> > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > >> > ResultSet.CONCUR_READ_ONLY)) { > >> > try (ResultSet results = query.executeQuery(sql)) > { > >> > ResultSetMetaData meta = results.getMetaData(); > >> > int colCount = meta.getColumnCount(); > >> > while (results.next()) { > >> > for (int index = 1; index <= colCount; > >> > index++) { > >> > int colType = meta.getColumnType(index); > >> > boolean quoted = colType == Types.CHAR || > >> > colType == Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || > colType > >> > == > >> > Types.NCHAR || colType == Types.NVARCHAR || colType == Types.VARCHAR; > >> > if (quoted) { > >> > System.out.append('"'); > >> > } > >> > > >> > System.out.append(results.getString(index)); > >> > if (quoted) { > >> > System.out.append('"'); > >> > } > >> > if (index < colCount) { > >> > System.out.print(','); > >> > } else { > >> > System.out.print(EOL); > >> > } > >> > } > >> > System.out.println(); > >> > } > >> > } > >> > } > >> > } > >> > } > >> > } > >> > } > >> > > >> > //This is an additional syntactic sugar proposal, allowing > multiple > >> > objects to be allocated inside one try block. The compiler converts > all > >> > three programs into the same bytecode > >> > //This proposal gets rid of the additional indentation level and > >> > closing brace per object. It further minimize the clean-up > >> > boiler-plate, > >> > allowing the point of the program logic to be clearer. > >> > //Lines of code: 38 > >> > package com.vci.projectcoin.using; > >> > > >> > import java.sql.*; > >> > import java.io.*; > >> > > >> > public class AdvancedExample { > >> > final static String EOL = > System.getProperty("line.separator"); > >> > > >> > //Command Line: [] > >> > static public void main(String []args) throws SQLException, > >> > FileNotFoundException { > >> > String url = args[0]; > >> > String sql = args[1]; > >> > try (PrintWriter out = new PrintWriter(args.length > 2 ? > new > >> > FileOutputStream(args[2]) : System.out), > >> > Statement query = > >> > conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, > >> > ResultSet.CONCUR_READ_ONLY), > >> > ResultSet results = query.executeQuery(sql)) { > >> > ResultSetMetaData meta = results.getMetaData(); > >> > int colCount = meta.getColumnCount(); > >> > while (results.next()) { > >> > for (int index = 1; index <= colCount; index++) { > >> > int colType = meta.getColumnType(index); > >> > boolean quoted = colType == Types.CHAR || colType == > >> > Types.LONGNVARCHAR || colType == Types.LONGVARCHAR || colType == > >> > Types.NCHAR > >> > || colType == Types.NVARCHAR || colType == Types.VARCHAR; > >> > if (quoted) { > >> > System.out.append('"'); > >> > } > >> > System.out.append(results.getString(index)); > >> > if (quoted) { > >> > System.out.append('"'); > >> > } > >> > if (index < colCount) { > >> > System.out.print(','); > >> > } else { > >> > System.out.print(EOL); > >> > } > >> > } > >> > System.out.println(); > >> > } > >> > } > >> > } > >> > } > >> > > >> > DETAILS > >> > The specification requires that the object in the try () block have > a > >> > "close()" method. Wether the method throws any or no exception, or if > >> > it > >> > returns a value or no value does not matter. The proposal is not > trying > >> > to > >> > introduce any new intelligence into the try finally clause, it is just > >> > syntactic sugar to minimize simple resource clean-up code. > >> > > >> > SPECIFICATION: > >> > The "try" keyword will have an overloaded meaning > >> > > >> > CASE 1 > >> > ------ > >> > try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) > { > >> > //work gets done here > >> > } > >> > > >> > Will be syntactic sugar for: > >> > ClassWithCloseMethod value = new ClassWithCloseMethod(...); > >> > try { > >> > //work gets done here > >> > } finally { > >> > value.close(); > >> > } > >> > > >> > CASE 2 > >> > ------ > >> > try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) > { > >> > //work gets done here > >> > } finally { > >> > //additional clean-up code > >> > } > >> > > >> > Will be syntactic sugar for: > >> > ClassWithCloseMethod value = new ClassWithCloseMethod(...); > >> > try { > >> > //work gets done here > >> > } finally { > >> > value.close(); > >> > //additional clean-up code > >> > } > >> > > >> > CASE 3 > >> > ------ > >> > try (ClassWithCloseMethod value = new ClassWithCloseMethod(...)) > { > >> > //work gets done here > >> > } catch (Exception ex) { > >> > //exception handling code > >> > } finally { > >> > //additional clean-up code > >> > } > >> > > >> > Will be syntactic sugar for: > >> > ClassWithCloseMethod value = new ClassWithCloseMethod(...); > >> > try { > >> > //work gets done here > >> > } catch (Exception ex) { > >> > //exception handling code > >> > } finally { > >> > value.close(); > >> > //additional clean-up code > >> > } > >> > > >> > CASE 4 > >> > ------ > >> > try (Class1WithCloseMethod value1 = new > Class1WithCloseMethod(...), > >> > Class2WithCloseMethod value2 = new > Class2WithCloseMethod(...), > >> > Class3WithCloseMethod value3 = new > Class3WithCloseMethod(...)) > >> > { > >> > //work gets done here > >> > } > >> > > >> > Will be syntactic sugar for: > >> > Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > >> > try { > >> > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > >> > try { > >> > Class3WithCloseMethod value3 = new > >> > Class3WithCloseMethod(...); > >> > try { > >> > //work gets done here > >> > } finally { > >> > value3.close(); > >> > } > >> > } finally { > >> > value2.close(); > >> > } > >> > } finally { > >> > value1.close(); > >> > } > >> > > >> > CASE 5 > >> > ------ > >> > try (Class1WithCloseMethod value1 = new > Class1WithCloseMethod(...), > >> > Class2WithCloseMethod value2 = new > Class2WithCloseMethod(...), > >> > Class3WithCloseMethod value3 = new > Class3WithCloseMethod(...)) > >> > { > >> > //work gets done here > >> > } finally { > >> > //additional clean-up code > >> > } > >> > > >> > Will be syntactic sugar for: > >> > Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > >> > try { > >> > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > >> > try { > >> > Class3WithCloseMethod value3 = new > >> > Class3WithCloseMethod(...); > >> > try { > >> > //work gets done here > >> > } finally { > >> > value3.close(); > >> > } > >> > } finally { > >> > value2.close(); > >> > } > >> > } finally { > >> > value1.close(); > >> > //additional clean-up code > >> > } > >> > > >> > CASE 6 > >> > ------ > >> > try (Class1WithCloseMethod value1 = new > Class1WithCloseMethod(...), > >> > Class2WithCloseMethod value2 = new > Class2WithCloseMethod(...), > >> > Class3WithCloseMethod value3 = new > Class3WithCloseMethod(...)) > >> > { > >> > //work gets done here > >> > } catch (Exception ex) { > >> > //exception handling code > >> > } finally { > >> > //additional clean-up code > >> > } > >> > > >> > Will be syntactic sugar for: > >> > Class1WithCloseMethod value1 = new Class1WithCloseMethod(...); > >> > try { > >> > Class2WithCloseMethod value2 = new Class2WithCloseMethod(...); > >> > try { > >> > Class3WithCloseMethod value3 = new > >> > Class3WithCloseMethod(...); > >> > try { > >> > //work gets done here > >> > } finally { > >> > value3.close(); > >> > } > >> > } finally { > >> > value2.close(); > >> > } > >> > } catch (Exception ex) { > >> > //exception handling code > >> > } finally { > >> > value1.close(); > >> > //additional clean-up code > >> > } > >> > > >> > COMPILATION: The SPECIFICATION section above shows the desugaring > for > >> > each case. Byte code would be identical to the desugared constructs. > >> > > >> > TESTING: Byte code comparison of common code constructs. If the > byte > >> > code is not identical to the desugared version, test fails. > >> > > >> > LIBRARY SUPPORT: No. > >> > > >> > REFLECTIVE APIS: No. > >> > > >> > OTHER CHANGES: No. > >> > > >> > MIGRATION: For each case in the SPECIFICATION section, convert the > >> > existing code to the syntactic sugar proposal. > >> > > >> > > >> > COMPATIBILITY > >> > > >> > BREAKING CHANGES: None. > >> > > >> > EXISTING PROGRAMS: Compile accepts both existing and new forms of > the > >> > "try" statement. Byte code does not change. > >> > > >> > REFERENCES > >> > > >> > EXISTING BUGS: None > >> > > >> > > >> > -- > >> > Roger Hernandez > >> > > >> > > > > > > > > > -- > > Roger Hernandez > > > -- Roger Hernandez From rhvarona at gmail.com Tue Mar 3 00:34:11 2009 From: rhvarona at gmail.com (Roger Hernandez) Date: Tue, 3 Mar 2009 03:34:11 -0500 Subject: Simple Resource Clean-up In-Reply-To: <17b2302a0903030018p3736108eq9e3baf3ce5ab4b5b@mail.gmail.com> References: <17b2302a0903030018p3736108eq9e3baf3ce5ab4b5b@mail.gmail.com> Message-ID: On Tue, Mar 3, 2009 at 3:18 AM, Joshua Bloch wrote: > Roger, > > On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez wrote: > >> I saw how the previous Automatic Resource Management proposal got torn to >> pieces > > > That's not quite fair. Only one person objected, and I had good responses > to all of his objections. So I believe the proposal is alive and well. > Others have informed me (off list) that they see Automatic Resource > Management as perhaps the most valuable language change that we could > introduce for Java 7. > > Regards, > > Josh > > You are right, I used strong wording but my concern was that the proposal would not be followed up on, and we would have to live with another 4 years of this before JDK 1.8 came out. I think that your proposal, Automatic Resource Management is definitely more thought out and more complete than what I proposed, and handles more complex scenarios and corner cases. It would be a very valuable feature if it gets into JDK 1.7. However, I am worried that the extra complexity will cause it to be dropped altogether, so if something gets implemented that takes care of the simpler scenarios that make up 80% of the cases, that would be good enough from my point of view. Thanks, -- Roger Hernandez From R.Spilker at topdesk.com Tue Mar 3 05:01:10 2009 From: R.Spilker at topdesk.com (=?us-ascii?Q?Roel_Spilker?=) Date: Tue, 3 Mar 2009 14:01:10 +0100 Subject: PROPOSAL: String literals: version 1.1 In-Reply-To: <0929E79C-1147-444B-9741-E0833C216D30@zwitserloot.com> References: Message-ID: > String foo= """\""" """ is """ Is there really a need for escaping? If users want to escape, they can still use the regular "" string literals. I'd rather have no escaping at all. Otherwise, you probably also need to escape the \ if you want the string to contain \" at the end. """An example:\\"""". The rule 'The new string literals don't support any escape sequences' if much better than 'The new string literals only support the escape sequences \""", which means """ and \\, which means \\'. Mind though, that \Uxxxx will always an escape sequence, since it is processed while before the source is sent to the tokenizer. What about supporting " or "" at the beginning or end of the new string literals? That would result in """" or """"". Or even """""""" if you push it to the limits. Wouldn't that be hard on the compiler? Roel -----Oorspronkelijk bericht----- Van: reinier at zwitserloot.com [mailto:coin-dev-bounces at openjdk.java.net] Namens Reinier Zwitserloot Verzonden: dinsdag 3 maart 2009 11:33 Aan: coin-dev at openjdk.java.net Onderwerp: Re: PROPOSAL: String literals: version 1.1 I don't think you need the U/W suffix; make all newlines \n regardless of what they are in the source file. If this annoys anybody, they can either manually add the \r in the string, or run a simple .replace("\n", "\r\n") at the end. I find collapsing whitespace far more interesting, but there too a simple method solution works just fine: .replaceAll("\\s+", " ") The problem with the suffixes are the rarity: I doubt anybody would know its even legal in the first place, so anybody that does use it effectively makes his code unreadable until the reader looks up the exotic syntax. Then again, there is precedence; the case of the hexadecimal floating point literal is almost point-for-point the same as this situation: Exotic syntax almost no java programmer even knows is legal ( double foo = 0x1P0D is legal java code!) but exists anyway because literals have a special meaning in java (they get inlined), which stops happening if you use an API utility to do the same thing: Double.longBitsToDouble. Still, in the 0x1P0D case there really is no alternative, whereas here you can always manually add \r to the string. --Reinier Zwitserloot On Mar 3, 2009, at 11:15, rssh at gradsoft.com.ua wrote: > AUTHOR(s): Ruslan Shevchenko, Jeremy Manson (if agree), Reinier > Zwitserloot (if agree) > > OVERVIEW: > > FEATURE SUMMARY: > new string literals in java language: > * multiline string literals. > * string literals without escape processing. > > MAJOR ADVANTAGE: > Possibility more elegant to code strings from other languages, such > as sql constructions or inline xml (for multiline strings) or regular > expressions (for string literals without escape processing). > > MAJOR DISADVANTAGE > I don't know > > ALTERNATIVES: > > For multiline strings use operations and concatenation methods, such > as: > > String,contact("Multiline \n", > "string "); > > or > > String bigString="First line\n"+ > "second line" > > For unescaped ('row') strings - use escaping of ordinary java string. > > > EXAMPLES > > SIMPLE EXAMPLE: > > Multiline string: > >
>  StringBuilder sb = new StringBuilder();  sb.append("""select a from 
> Area a, CountryCodes cc
>                where
>                   cc.isoCode='UA'
>                  and
>                   a.owner = cc.country
>              """);
>  if (question.getAreaName()!=null) {
>     sb.append("""and
>                  a.name like ?
>               """);
>     sqlParams.setString(++i,question.getAreaName());
>  }
> 
> > instead: >
>  StringBuilder sb = new StringBuilder();  sb.append("select a from 
> Area a, CountryCodes cc\n");  sb.append("where cc.isoCode='UA'\n");  
> sb.append("and a.owner=cc.country'\n");  if 
> (question.getAreaName()!=null) {
>     sb.append("and a.name like ?");
>     sqlParams.setString(++i,question.getAreaName());
>  }
> 
> > Unescaped String: >
> String myParrern=''..*\.*'';
> 
> instead >
> String myParrern="\..*\\.*";
> 
> > ADVANCED EXAMPLE: > > String platformDepended="""q > """; > is 'q\n' if compiled on Unix and 'q\n\r' if compiled on Windows. > > String platformIndepended=""" > """U; > is always '\n'. > > String platformIndepended=""" > """W; > is always '\n\r'. > > String empty=""" > """; > is empty > > String foo = """ > bar > baz > bla > qux"; > > is equal to: String foo = "bar\n baz\n bla\nqux"; > > and the following: > > String foo = """ > foo > bar"""; > > is a compile-time error. > > String foo= """\"""" is " > String foo= """\""" """ is """ > > DETAILS: > > Multiline strings are part of program text, which begin and ends by > three double quotes. > > I. e. grammar in 3.10.5 of JLS can be extented as: > >
> MultilineStringLiteral:
>        """ MultilineStringCharacters/opt """  LineTerminationSuffix/ 
> opt
>
> MultilineStringCharacters:
>        MultilineStringCharacter
>        MultilineStringCharacters  (MultilineStringCharacter but not ")
>        (MultilineStringCharacters but not "") "
>
> MultilineStringCharacter:
>        InputCharacter but not \
>        EscapeSequence
>        LineTermination
>
> LineTerminationSuffix:
>                      U | u | W | w
>
> 
> > > Unescaped strings are part of program text, which begin and ends by > two single quotes. > > >
> RowStringLiteral:
>                   '' RowInputCharacters/opt '' LineTerminationSuffix/ 
> opt
>
> RowInputCharacters:
>                      ' (InputCharacter but not ')
>                     |
>                      (InputCharacter but not ') '
>                     |
>                      LineTermination
> 
> > > > COMPILATION: > > Handling of multiline strings: > > Text withing """ brackets processed in next way: > > 1. splitted to sequence of lines by line termination symbols. > 2. escape sequences in each line are processed exactly as in ordinary > Java strings. > 3. elimination of leading whitespaces are processed in next way: > - at first determinated sequence of whitespace symbols (exclude > LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. > let's call it 'leading whitespace sequence' > - all next lines must start with same leading whitespace sequence, > otherwise compile-time error is thrown. > - whitespace processing erase such leading sequence from resulting > lines 4. set of lines after erasing of leading whitespace sequence is > concatenated, with line-termination sequences between two neighbour > lines. > Inserted linetermination sequence is depend from > LineTerminationSuffix, and is > - value of systen property 'line.separator' is > LineTerminationSuffix is empty > - LF (i. e. '\n') when LineTerminationSuffix is 'U' or 'u' > - CR LF (i. e. '\r''\n') when LineTerminationSuffix is 'W' or 'w' > > > > Handling of row strings: > Text withing '' brackets processed in next way: > 1. splitted to sequence of lines by line termination symbols. > 2. set of lines after erasing of leading whitespace sequence is > concatenated, with line-termination sequences between two neighbour > lines, exactly as in case of multiline strings. > > No escape processing, no leading whitespace elimination are performed > for receiving of resulting string value. > > new strings literals created and used in .class files exactly as > ordinary strings. > > TESTING: > Nothing special. add new strings literals to test-cases. > > LIBRARY SUPPORT: > None. > > (May be exists sense add simple template processing to standard > library, but I think this is goal of next language iteration. Now > exists many good external frameworks, such as velocity: better wait > and standardize support of > winner) > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > None > > REFERENCES > > http://bugs.sun.com/view_bug.do?bug_id=4165111 > http://bugs.sun.com/view_bug.do?bug_id=4472509 > http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd by by Jacek > Furmankiewicz > > > > > > > > From neal at gafter.com Tue Mar 3 06:58:36 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 06:58:36 -0800 Subject: Simple Resource Clean-up In-Reply-To: References: <17b2302a0903030018p3736108eq9e3baf3ce5ab4b5b@mail.gmail.com> Message-ID: <15e8b9d20903030658s427e7f7ge52e6f0503ed196b@mail.gmail.com> The problem with addressing this sort of problem as a language change rather than an API is that the solution has to attempt to be a one-size-fits-all: you have to decide which 80% to aim for. An API - or a set of APIs - can instead be tuned to the use cases. On Tue, Mar 3, 2009 at 12:34 AM, Roger Hernandez wrote: > On Tue, Mar 3, 2009 at 3:18 AM, Joshua Bloch wrote: > >> Roger, >> >> On Mon, Mar 2, 2009 at 9:02 PM, Roger Hernandez wrote: >> >>> I saw how the previous Automatic Resource Management proposal got torn to >>> pieces >> >> >> That's not quite fair. ?Only one person objected, and I had good responses >> to all of his objections. ?So I believe the proposal is alive and well. >> ?Others have informed me (off list) that they see Automatic Resource >> Management as perhaps the most valuable language change that we could >> introduce for Java 7. >> >> ? ? ? Regards, >> >> ? ? ? Josh >> >> > > > You are right, I used strong wording but my concern was that the proposal > would not be followed up on, and we would have to live with another 4 years > of this before JDK 1.8 came out. > > I think that your proposal, Automatic Resource Management is definitely more > thought out and more complete than what I proposed, and handles more complex > scenarios and corner cases. ? It would be a very valuable feature if it gets > into JDK 1.7. ?However, I am worried that the extra complexity will cause it > to be dropped altogether, so if something gets implemented that takes care > of the simpler scenarios that make up 80% of the cases, that would be good > enough from my point of view. > > Thanks, > > -- > Roger Hernandez > > From david.goodenough at linkchoose.co.uk Tue Mar 3 06:59:02 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 3 Mar 2009 14:59:02 +0000 Subject: PROPOSAL: Lightweight Properties Message-ID: <200903031459.03331.david.goodenough@linkchoose.co.uk> Below is my proposal for Lightweight Properties. I know that the syntax change is an abbomination to some people, but I have tried to reduce this to its absolute minimum, while still getting a significant benefit. PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): David Goodenough, long time Java user. I can be reached at david.goodenough at linkchoose.co.uk. OVERVIEW FEATURE SUMMARY: Lightweight Property support MAJOR ADVANTAGE: Both BeansBinding (whether JSR-295 or others such an JFace or the JGoodies binding) and the JPA Criteria API currently require field names (as Strings) as arguments, which an IDE/compiler can not check. With this proposal the strings would be abandoned, and the IDE/compiler will be able to check the correctness of the code. MAJOR BENEFIT: Manual checking no longer required. This proposal introduces a simple well defined IDE/compiler checkable solution. MAJOR DISADVANTAGE: It is a language change, and this seems to upset some people. ALTERNATIVES: None really, apart from using another language or continuing to use String names. The existing solutions all require String names which are uncheckable. EXAMPLES Lets assume we have a POJO called foo, of type Foo with a field bar of type Bar, which itself has a field of type Jim called jim. There are two forms of lightweight properties:- 1) foo#bar would be translated by the compiler into:- new Property(foo,"bar"); while foo#bar#jim would be translated into:- new Property(foo,"bar","jim"); 2) Foo#bar would be translated into:- new Property(Foo.class,"bar"); while Foo#bar#jim would be translated into:- new Property(Foo.class,"bar","jim"); These two forms create (1) a bound Property, or (2) an unbound one. Bound Properties are explicitly bound to a particular instance of a class (in this case foo), while unbound Properties are templates which can be applied to any instance of class Foo. Actually bound properties can also be used as unbound properties, but that is a harmless and useful side effect not a primary intent. The Property class would need to be added (it is appended below), and should be added either to the java.beans package or to the java.lang.reflect package (with which is probably has more in common). Syntactically a "#" can be placed wherever a "." can be placed (except inside a number), and the same checks need to be made (that each field to the right of a # is a field in the left hand side) as would be made for a ".". The only difference is in field visibility - For the "#" any field is visible, which follows the model currently available in the Field class with getDeclaredFields(). It also follows the model that while a field might be private and therefore not directly accessible from outside, getters and setters can provide access. The Property object provides type safe access to the field in the form of getters and setters. These come in pairs, one for bound and the other for unbound access. So for bound access no object is required to fetch the value, for an unbound object the parent object needs to be specified. So if we have:- Propertyprop = foo#bar; we can later say:- Bar b = prop.get(); or for an unbound one from a second Foo object foo2:- Bar b = prop.get(foo2); The getters and setters in the Property object will defer to explicitly coded getters and setters if present, otherwise they will use the Field getter and setter. If a setter is not explicitly coded, the implicit setter will look for a PropertyChangeSupport object in the parent object of the rightmost field and fire a PropertyChangeEvent to that object. There are also two Annotations provided by the Property class, ReadOnly and WriteOnly. These stop implicit getters and setters from trying to read/write the property. Talking of Annotations, this notation can also be used to get at the Annotations for a field. So to test for the presence of an Annotation Ann on Foo.bar we would use:- if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... SIMPLE EXAMPLE: To take an example from BeansBinding (taken from Shannon Hickey's blog):- // create a BeanProperty representing a bean's firstName Property firstP = BeanProperty.create("firstName"); // Bind Duke's first name to the text property of a Swing JTextField BeanProperty textP = BeanProperty.create("text"); Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, firstP, textfield, textP); binding.bind(); would instead be written:- Binding binding = Bindings.createAutoBinding(READ_WRITE, duke#firstName, textfield#text); binding.bind(); which of course can be checked by the IDE/compiler, and will not wait until run time (not even instantiation time) to show up the error. ADVANCED EXAMPLE: For a JComboBox (or JList or JTable or JTree) there is a need to map a list of objects to the value strings (or column contents). For this we need to have an unbound Property which can be applied to each element of the list. Duke duke; Listdukes; BoundComboBox combo = new BoundComboBox(dukes,Duke#fullname,this#duke); and now the combo box will be populated from the list dukes, and the display values in the list will be taken from the fullname field of each Duke element, and the initial value will be set from the local class field duke and any changes to the combo box selected element will be reflected back to the duke field. DETAILS SPECIFICATION: This proposal adds a new syntactic element, "#", which can be used in the same way that "." can be used to qualify fields within a Java object. COMPILATION: This proposal requires no change to the class files, and is implemented by a simple generation of the required instance using the relevant Property constructor. Obviously the compiler would have to make sure that the use that the property object was being put to (in the examples above the left hand side of the assignment) had the correct Generic attributes. TESTING: How can the feature be tested? LIBRARY SUPPORT: The new Property class is required (see below). REFLECTIVE APIS: No changes are required to the reflective APIs although it makes extensive use of those APIs. OTHER CHANGES: No other changes are requires. MIGRATION: Fortunately there is no code that is formally part of J2SE 6 which uses such Properties. There are however two proposals which will need it (BeansBinding and JPA Criteria API), but neither of these seem to be destined to be part of J2SE 7 (BeansBinding seems to have died the death and the Criteria API would be part of the next J2EE which will follow J2SE 7), so this will provide a base for them to use and no existing code need to be updated. There are other extant Beans-Binding libraries, which could be modified to use this proposal, but as none of the existing features have been changed there is no need to change them (other than for type safety and compiler/IDE checkability). COMPATIBILITY BREAKING CHANGES: None. This change should not make any existing correct code fail to compile or run or change the way in which it compiles/runs. EXISTING PROGRAMS: No change required to any existing programs REFERENCES EXISTING BUGS: None URL FOR PROTOTYPE (optional): I do not have the knowledge to make changes to the compiler, and the only documentation making such changes concentrated on adding operators not changes at this level. So there is no prototype of the compiler part, but the Property class follows:- package java.lang.reflect; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyChangeSupport; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Property class * This is the support class for use with the # notation to provide lightweight * Property support for Java. * * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd * @licence LPGL V2 : details of which can be found at http://fsf.org. * @author david.goodenough at linkchoose.co.uk * * @param The Parent class for this field * @param The Type of this field */ public class Property { ????private C parent; ???private Class parentClass; private Field[] fields; private PropertyDescriptor[] pd = null; /** * Constructor used to create Property objects. The Parent object may be * null, but should normally be specified as it can be overridden anyway. * @param parent C object that contains the field * @param field Field describing this field */ public Property(C parent, String ... fieldNames) { ???????this.parent = parent; ????????this(parent.getClass(), fieldNames); ????????} ????/** ?????* Constructor for unbound Properties, but also used internally after setting ?????* the parent object by the bound Property objects. ?????* @param parentClass Class of the parent object ?????* @param fieldNames String[] of field names ?????*/ ????public Property(ClassparentClass, String .. fieldNames) { ????????this.parentClass = parentClass; fields = new Field[fieldNames.length]; pd = new PropertyDescriptor[fieldNames.length]; outer: for(int index = 0; index < fields.length; index++) { Field[]dclFields = parentClass.getDeclaredFields(); ????for(Field field:dclFields) { if(field.getName().equals(fieldNames[index])) { fields[index] = field; field.setAccessible(true); try { BeanInfo beanInfo = Introspector.getBeanInfo(parent.getClass()); PropertyDescriptor[]props = beanInfo.getPropertyDescriptors(); for(PropertyDescriptor prop : props) { if(prop.getName().equals(field.getName())) { pd[index] = prop; break; } } } catch(Exception e) { /* assume can not find getter/setter */ } parentClass = field.getType(); continue outer; } } throw new IllegalArgumentException("Field " + fieldNames[index] + " not found in class " + parentClass.getCanonicalName()); } } /** * Getter from the field in the parent specified when this Property was created. * @see Property.get(C otherParent) * @return F the value of this field */ public F get() { return get(parent); } /** * Getter with explicit parent. * This code will check see if this field is WriteOnly, and complain if it is. * It will then see if the use has provided am explicit getter, and call that * if present, otherwise it will just fetch the value through the Field provided * method. * @param otherParent C parent object * @return F value of the field */ @SuppressWarnings("unchecked") // This should actually not be needed, // but the Field.get method is not typed public F get(C otherParent) { Object result = otherParent; try { for(int index = 0; index < fields.length; index++) { if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) throw new IllegalAccessException( "Can not get from a WriteOnly field - " + fields[index].getName()); Method getter = pd[index] == null ? null : pd[index].getReadMethod(); if(getter == null) result = fields[index].get(result); else result = getter.invoke(result); } } catch(Exception e) { throw new RuntimeException("Should not occur exception", e); } return (F)result; } /** * Setter to set the value of the field in the parent object declared with the * Property object * @param newValue F new value of this field */ public void set(F newValue) { set(parent,newValue); } /** * Setter to set the value of the field to an explicit parent object. * If there is a ReadOnly annotation, then we object. If there is an explicit * setter then we use that, otherwise we set the field using the Field provided * set method and if there is a PropertyChangeSupport field, fire a property * change event to it. * We walk our way down the field chain, until we have the last object and its * field, and then we do the set. * @param parent C explicit parent object * @param newValue F new value for field in parent */ public void set(C parent,F newValue) { try { Object last = parent; int index; for(index = 0; index < fields.length - 1; index++) { if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) throw new IllegalAccessException( "Can not get from a WriteOnly field - " + fields[index].getName()); Method getter = pd[index] == null ? null : pd[index].getReadMethod(); if(getter == null) last = fields[index].get(last); else last = getter.invoke(last); } if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) throw new IllegalAccessException( "Can not get from a WriteOnly field - " + fields[index].getName()); Method setter = pd[index] == null ? null : pd[index].getWriteMethod(); if(setter == null) { PropertyChangeSupport pcs = findPcs(last.getClass()); fields[index].set(last,newValue); if(pcs != null) pcs.firePropertyChange(fields[index].getName(), newValue, fields[index].get(last)); } else setter.invoke(last,newValue); } catch(Exception e) { throw new RuntimeException("Should not occur exception", e); } } /** * This is used so that the caller can view the Field name * @return String field name */ public String[] getFieldName() { String[]names = new String[fields.length]; for(int index = 0; index < fields.length; index++) { names[index] = fields[index].getName(); } return names; } ????/** ?????* This method is used to fetch the Field array, which is useful if you need to ?????* access the Annotations of a field. ?????* @return Field[] the array of Fields describing this Property. ?????*/ ????public Field[] getFields() { ????????return fields; ????????} /** * This private method looks for a PropertyChangeSupport object in the class and * if one is found it will return it. It looks right the way up the class tree * by recurring up the superClasses. * @param parent Class to check for PropertyChangeSupport fields * @return PropertyChangeSupport first found object, or null if not found */ private PropertyChangeSupport findPcs(Class parent) { Field fields[] = parent.getDeclaredFields(); for(Field field:fields) { field.setAccessible(true); try { if(field.getType() == PropertyChangeSupport.class) return (PropertyChangeSupport)field.get(parent); } catch(Exception e) { } } // If we did not find it then try the superclass ClasssuperClass = parent.getSuperclass(); if(superClass == null) return null; return findPcs(parent.getClass().getSuperclass()); } /** * This annotation is used to mark a field as WriteOnly, i.e. it can not be read. * This stops the automatic getter operation. */ public @interface WriteOnly { } /** * This annotation is used to mark a field as ReadOnly, i.e. it can not be written. * This stops the automatic setter operation. */ public @interface ReadOnly { } } From neal at gafter.com Tue Mar 3 07:04:04 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 07:04:04 -0800 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <08E77F6F-6D7F-4A0F-B389-4851039220F0@zwitserloot.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> <08E77F6F-6D7F-4A0F-B389-4851039220F0@zwitserloot.com> Message-ID: <15e8b9d20903030704j4fbf2f31if64f59b381c8864f@mail.gmail.com> I think relaxing the rules for interoperability is a great idea. I know a few places where Java's language rules interfere with interoperability, but I wasn't aware of this one before. I suggest you write it as a separate proposal, please. On Tue, Mar 3, 2009 at 2:06 AM, Reinier Zwitserloot wrote: > Maybe I'm making this too simple, but what if javac will treat all > catch blocks of a type that isn't thrown by the try block as warnings > instead of errors? That fixes Neal's Improved Exception Handling issue > of not being 100% source compatible with java 6, no? > > I assume source compatibility where code that is clearly broken > results in a warning in java 7 (but is still compiled with exactly the > same semantics) whereas it was silently compiled by java 6 is only > good news. > > Also, because in just about every other language on the JVM, checked > exceptions can be thrown without being declared, I think this is a > good idea in general, considering that java wants to be more > interoperable with non-java JVM languages. To work around this issue > now, you have to either wrap the call in a wrapper method that adds > the exception to the throws list, or you have to create a dummy method > that declares the throwable in the throws list but doesn't throw it, > just so javac will stop refusing to compile your code. That's clearly > a hack solution, and the elimination of it should be a good thing, > even if you need to use a @SuppressWarnings instead, no? > > Should I write up a proposal for this? Should Neal add it to his > proposal? Or is it just a horribly stupid idea? :) > > ?--Reinier Zwitserloot > > > > On Mar 3, 2009, at 08:33, Neal Gafter wrote: > >> On Mon, Mar 2, 2009 at 10:29 PM, Joseph D. Darcy >> wrote: >>>> MAJOR DISADVANTAGE: >>>> >>>> One-time implementation cost for adding the features to the >>>> compiler. >>>> Longer language specification in describing the behavior. >>>> >>> >>> What sort of poor programming practices could this feature >>> encourage or >>> enable? >> >> I don't see any, but perhaps I'm shortsighted. >> >>>> The type system is affected as follows: For the purpose of type >>>> checking, a catch parameter declared with a disjunction has type >>>> lub(t1, t2, ...) [JLS3 15.12.2.5]. >>> >>> In terms of finding the members of the type, it is good existing >>> concepts in >>> the JLS can be used. >>> >>> What happens if someone writes >>> >>> ? catch(final IOException | SomeSubclassOfIOException e) {...} >>> >>> In other words, is it legal to have subclasses of a caught >>> exception listed >>> too? >> >> I don't really care one way or the other. ?As written, yes, it is >> allowed and means the same thing as the supertype alone. >> >>>> To avoid the need to add support for general disjunctive types, but >>>> leaving open the possibility of a future extension along these >>>> lines, >>>> a catch parameter whose type has more than one disjunct is >>>> required to >>>> be declared final. >>>> >>> >>> I think that is a fine compromise that keep the current feature >>> smaller >>> while allowing room for a broader feature later. >>> >>> Some worked examples of the sets of thrown exceptions types under >>> various >>> tricky code samples would help clarify the data flow algorithm for >>> me. >> >> Sure, I can do that. ?Do you think that should go in the >> specification? >> >>>> A catch clause is currently compiled (before this change) to an >>>> entry >>>> in an exception table that specifies the type of the exception and >>>> the >>>> address of the code for the catch body. To generate code for this >>>> new >>>> construct, the compiler would generate an entry in the exception >>>> table >>>> for each type in the exception parameter's list of types. >>>> >>> >>> Interesting; so there would be no code duplication even in the >>> class files. >> >> Correct. ?That's what the current prototype (in the BGGA compiler) >> does for this construct. >> >>> How could the increased exception precision be maintained will >>> still allow >>> programs such as the one above to compile? >> >> I don't think it can without making rather complex rules, but I'll >> think about it more. >> >> However, one could take only the multicatch part of this proposal and >> not the final/rethrow part, and then I believe one could specify it >> without there being a breaking change. >> > > > From rssh at gradsoft.com.ua Tue Mar 3 07:23:56 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 3 Mar 2009 17:23:56 +0200 (EET) Subject: PROPOSAL: String literals: version 1.1 In-Reply-To: References: Message-ID: <9fc1ca7a774a8fb8cad30901eac67bd4.squirrel@wmail.gradsoft.ua> >> String foo= """\""" """ is """ > > Is there really a need for escaping? If users want to escape, they can > still use the regular "" string literals. I'd rather have no escaping at > all. Otherwise, you probably also need to escape the \ if you want the We have row unescaped strings with '' brackets already in this proposal. > string to contain \" at the end. """An example:\\"""". The rule 'The new > string literals don't support any escape sequences' if much better than > 'The new string literals only support the escape sequences \""", which > means """ and \\, which means \\'. > Rule can be formed as: we have two new types of literals: with or without escape sequences. First supports all traditional escape sequences, second have no escape sequences at all. > What about supporting " or "" at the beginning or end of the new string > literals? That would result in """" or """"". Or even """""""" if you push > it to the limits. Wouldn't that be hard on the compiler? > Will try ;) From akuhn at iam.unibe.ch Tue Mar 3 09:03:42 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Tue, 3 Mar 2009 18:03:42 +0100 Subject: (update) Use "default" keyword for default visibility In-Reply-To: <49AD1C0B.3070907@joda.org> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <49AD1C0B.3070907@joda.org> Message-ID: <43577BD5-8BD8-45F0-B190-EB04FBB283C3@iam.unibe.ch> Updated the default visibility proposal PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Adrian Kuhn OVERVIEW: Allow the "package" keyword to be used as modifier for default visibility. FEATURE SUMMARY: Use "package" keyword for default visibility. MAJOR ADVANTAGE: This change is a "5 cent coin" at best, there are not many advantages beyond improved readability and a more beautiful language definition. However, the benefit of improved readability is not to be underestimated. The missing keyword for default visibility breaks the symmetry of visibility modifiers. The use of package visibility is less obvious than other visibility since an explicit modifier is missing. This decreases readability of source code. For example, omitting any of the three explicit modifiers by mistake (or vice verse mistakingly adding any of the tree) may introduce unexpected behavior which is hard to spot due to the bad readability. MAJOR BENEFIT: Improved readability. MAJOR DISADVANTAGE: Two ways to express the same thing (in compatibility mode). ALTERNATIVES: - Using /*default*/ comments (as often seen) is not an alternative since such comments are not processed by the compiler. - Using a custom-made @Package annotation is feasible (it is what I use now) and can be processed by the compiler using an annotation processor. EXAMPLES SIMPLE EXAMPLE: public class Point { package int x; package int y; } ADVANCED EXAMPLE: package ch.akuhn.util; package class Foo { } DETAILS SPECIFICATION: "package" is already a keyword, introducing it as a new visibility modifier is thus save. To distinguish package visible top-level classes and package declarations, the grammar will need a lookahead of two tokens (I dont know if this is a problem). COMPILATION: Same as now with implicit default visibility. TESTING: Same as now with implicit default visibility. LIBRARY SUPPORT: None. REFLECTIVE APIS: None. OTHER CHANGES: None. MIGRATION: See below, strict vs compatibility mode. COMPATIBILITY: A compiler switch is offered to set either strict or compatibility mode. In strict mode, an error is issued if a member has not visibility modifier. In compatibility mode, members without visibility modifier as treated as default visibile (which is the current semantics of Java). BREAKING CHANGES: None. EXISTING PROGRAMS: Work fine in compatibility mode. REFERENCES EXISTING BUGS: To my best knowledge, none. URL FOR PROTOTYPE (optional): On Mar 3, 2009, at 13:01 , Stephen Colebourne wrote: >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> AUTHOR(S): Adrian Kuhn >> OVERVIEW >> Allow the "default" keyword to be used as modifier for default >> visibility. In strict mode, missing use of default is a warning / >> error, in compatibility mode both the current (ie no default >> keyword) and the new syntax are accepted. >> FEATURE SUMMARY: Use "default" keyword for default visibility. >> MAJOR ADVANTAGE: The missing keyword for default visibility breaks >> the symmetry of visibility modifiers. Since it is the only >> implicit modifier, omitting any of the three explicit modifiers by >> mistake may be the source of unexpected behavior and thus hard to >> track down bugs. (There was an example on a blog post recently, >> but I cannot find it know). >> MAJOR BENEFIT: Symmetry of visibility modifiers is restored. >> MAJOR DISADVANTAGE: Two ways to express the same thing (in >> compatibility mode). >> ALTERNATIVES: Using a comment such as /* default */ is not an >> alternative since such comments are not processed by the compiler. >> EXAMPLES >> public class C { >> default Field f; >> } >> SIMPLE EXAMPLE: See above. >> ADVANCED EXAMPLE: None. >> DETAILS >> SPECIFICATION: "default" is already a keyword and introducing it as >> a new visibility modifier is save, it does not lead to ambiguous >> grammar. >> COMPILATION: Same as now for implicit default visibility. >> TESTING: Same as now for implicit default visibility. >> LIBRARY SUPPORT: None. >> REFLECTIVE APIS: None. >> OTHER CHANGES: None. >> MIGRATION: Compatibility mode allows both, implicit and explicit >> default visibility, to be used at the same time. >> COMPATIBILITY >> BREAKING CHANGES: None. >> EXISTING PROGRAMS: Work fine in compatibility mode. >> REFERENCES >> EXISTING BUGS: To my best knowledge, none. >> URL FOR PROTOTYPE (optional): From jjb at google.com Tue Mar 3 10:03:40 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 10:03:40 -0800 Subject: Simple Resource Clean-up In-Reply-To: References: Message-ID: <17b2302a0903031003w17d5611eo339d4c5ef51ac2b1@mail.gmail.com> Roger, Hi. > > The specification requires that the object in the try () block have a > "close()" method. Wether the method throws any or no exception, or if it > returns a value or no value does not matter. This is a "naming pattern" (of the sort used by serialization and beans). If we need more flexibility than interfaces provide, I believe that we're better off going all the way to annotations (see Item 35 in Effective Java, Second Ed.). This would allow us to use the automatic resource management statement with types whose "dispose" method wasn't named close (such as java.awt.graphics.dispose). This is listed as a "design alternative" at the bottom of my proposal. Here's how I summarize the pros and cons: "[Use of an annotation] allows the use of a different method names (such as destroy and terminate) and eases the use of the new construct with existing resource types. But it is more ?magical? and does not mesh as well with Java?s type system." I do see this as a viable alternative, but with pros and cons. I believe it would be relatively straightforward to retrofit my proposal to use method annotations instead of (or in addition to) an interface. Regards, Josh From neal at gafter.com Tue Mar 3 10:47:31 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 10:47:31 -0800 Subject: Simple Resource Clean-up In-Reply-To: <17b2302a0903031003w17d5611eo339d4c5ef51ac2b1@mail.gmail.com> References: <17b2302a0903031003w17d5611eo339d4c5ef51ac2b1@mail.gmail.com> Message-ID: <15e8b9d20903031047q235815d5i669b93575fefba75@mail.gmail.com> This would be the first instance of an annotation that changes the meaning of the language's primitive constructs. Today, this kind of thing is the role of declaration modifiers. We went to great length to discourage this kind of use of annotations in the past; annotations are to annotate the program text (in a way sometimes visible to libraries), not define it. I understand the reluctance to add new keywords to the language, but I advise against adding annotations as language modifiers (essentially, adding modifiers with an "@" prefix). The fact that this kind of flexibility is required suggests the facility should be provided by libraries rather than hardcoded into the language. On Tue, Mar 3, 2009 at 10:03 AM, Joshua Bloch wrote: > Roger, > > Hi. > > >> >> ? The specification requires that the object in the try () block have a >> "close()" method. ?Wether the method throws any or no exception, or if it >> returns a value or no value does not matter. > > > This is a "naming pattern" (of the sort used by serialization and beans). > ?If we need more flexibility than interfaces provide, I believe that we're > better off going all the way to annotations (see Item 35 in Effective Java, > Second Ed.). ? This would allow us to use the automatic resource management > statement with types whose "dispose" method wasn't named close (such as > java.awt.graphics.dispose). This is listed as a "design alternative" at the > bottom of my proposal. > > Here's how I summarize the pros and cons: "[Use of an annotation] allows the > use of a different method names (such as destroy and terminate) and eases > the use of the new construct with existing resource types. But it is more > ?magical? and does not mesh as well with Java?s type system." ?I do see this > as a viable alternative, but with pros and cons. ?I believe it would be > relatively straightforward to retrofit my proposal to use method annotations > instead of (or in addition to) an interface. > > ? ? ? ? ? Regards, > > ? ? ? ? ? Josh > > From jeremy.manson at gmail.com Tue Mar 3 11:31:59 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 3 Mar 2009 11:31:59 -0800 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49AD1B58.5060305@joda.org> References: <49AABBA2.3040009@joda.org> <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> <49AD1B58.5060305@joda.org> Message-ID: <1631da7d0903031131y6a97059bw45346448dd87c645@mail.gmail.com> On Tue, Mar 3, 2009 at 3:58 AM, Stephen Colebourne wrote: > Jeremy Manson wrote: >>> The principle perceived disadvantage, however, is that it encourages, >>> rather than discourages, the use of null values in APIs. >> >> I would think that the principle disadvantage would be not that it >> encourages use of null values (which, as you point out, is fine in >> some contexts), but that it encourages programmers not to think about >> what happens when there is a null value. > > But that is exactly what already happens today. Most developers are very > poor at thinking through the null consequences of a method - the happy > day scenario is the one focussed on. Right. This is bad, because much of the time, the program cannot tolerate nulls. >> I can easily imagine >> programmers using this all of the time without thinking about it, and >> then being surprised when a null ends up in the wrong place and not >> knowing how it got there. ?Even with a simple example: >> >> public String someFunction(String a, String b) { >> ? String s = a?.concat("foo"); >> ? String t = b?.concat(a); >> ? return myHashMap?.get(t); >> } >> >> Now, someFunction returns null. ?Is it because a was null? ?Or b was >> null? ?Or myHashMap was null? ?Or there was no mapping for t in >> myHashMap? > > Or perhaps it doesn't matter, and thats why the code was written that > way. Null as 'don't know' or 'don't care' is incredibly common. So, we have two cases: 1) I've done something wrong, in which case "." provides useful semantics, because it is fail fast. 2) "Don't know" or "Don't care", in which case "?." doesn't provide useful semantics, but is less typing. Flipping through a few thousand lines' worth of our source files, I see hundreds of examples of #1, and only a couple of examples of #2. Most of the time, we know a priori that we're not doing a null dereference, so we don't need the ?.. This pretty much gels with my intuition about this. Perhaps it is different in EE code? I would be interested to hear a more thorough study of people's source bases. If it is true that #2 is only responsible for a tiny fraction of the cases in general, then it is a little odd to add a programming language feature around it. (By the way, I'm not denying that it is, as you say, common!) Additionally, every time you use ?., you are going to have to think incredibly carefully about whether it is #1 or #2. And I have this sneaking suspicion that most programmers will just sprinkle it liberally all over their code without thinking about it at all. When they get it wrong, that's going to make errors harder to catch. From a design standpoint, I would lean towards forcing people to think about it every time, because they are more likely to get it right that way. >> If you want to cut down on >> extraneous if-testing, I would use JSR-305's Nullity annotations >> instead. > > What does this code do when passed null? > > Foo f = new Foo(null); > int v = f.value; > > public class Foo { > ? public final Integer value; > ? public Foo(@Nonnull Integer value) { > ? ? this.value = value; > ? } > } > > There is a NPE at f.value, not at new Foo(null). > > You would think that you could never construct an instance of Foo with a > val of null, but you can. The @Nonnull annotation doesn't have any real > meaning unless it is checked using a tool, and javac isn't such a tool. > This will be very confusing when you use Foo from another part of your > application and expect the value to be non-null and get a NPE. In fact > the @Nonnull is positvely misleading. I think that providing warnings for these annotations is a very good idea. That's a language change that makes some sense to me, if the semantics can be nailed down. > Basically, you can't rely on JSR-305. The information needs to be > rechecked. Thus, whats the point in using it at all?!! Documentation > perhaps? Annotations are not suitable for handling language level issues > like nulls. I do think that annotations are suitable for handling language level issues, as long as they are checked. For example, @Override has been very useful to me, because my toolchain complains when I add it and am not overriding something. Jeremy From jeremy.manson at gmail.com Tue Mar 3 11:36:51 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 3 Mar 2009 11:36:51 -0800 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <1631da7d0903031131y6a97059bw45346448dd87c645@mail.gmail.com> References: <49AABBA2.3040009@joda.org> <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> <49AD1B58.5060305@joda.org> <1631da7d0903031131y6a97059bw45346448dd87c645@mail.gmail.com> Message-ID: <1631da7d0903031136s71593ddcmfc39036d642ccf4b@mail.gmail.com> On Tue, Mar 3, 2009 at 11:31 AM, Jeremy Manson wrote: > Flipping through a few thousand lines' worth of our source files, I > see hundreds of examples of #1, and only a couple of examples of #2. > Most of the time, we know a priori that we're not doing a null > dereference, so we don't need the ?.. ?This pretty much gels with my > intuition about this. ?Perhaps it is different in EE code? ?I would be > interested to hear a more thorough study of people's source bases. ?If > it is true that #2 is only responsible for a tiny fraction of the > cases in general, then it is a little odd to add a programming > language feature around it. I should add to this that most of the cases I found were things like: if (foo != null) { foo.bar(); } That's not really all that compelling. The really compelling case for this feature is: foo.bar().goo().baz().bif(); where each and everyone needs to be null checked, and you want to abandon the computation if any is null. I didn't see any of these at all, but, as I said, this might be different in EE code. Jeremy From Jonathan.Gibbons at Sun.COM Tue Mar 3 11:52:31 2009 From: Jonathan.Gibbons at Sun.COM (Jonathan Gibbons) Date: Tue, 03 Mar 2009 11:52:31 -0800 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <1631da7d0903031131y6a97059bw45346448dd87c645@mail.gmail.com> References: <49AABBA2.3040009@joda.org> <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> <49AD1B58.5060305@joda.org> <1631da7d0903031131y6a97059bw45346448dd87c645@mail.gmail.com> Message-ID: <2EA71BB2-1B19-4D89-B665-9E3DB40E5090@sun.com> Further down, someone wrote: >> >> You would think that you could never construct an instance of Foo >> with a >> val of null, but you can. The @Nonnull annotation doesn't have any >> real >> meaning unless it is checked using a tool, and javac isn't such a >> tool. Well, javac can run annotations processors, and given JSR308, can run processors on more annotations than can exist today, so I would say that javac is a candidate for the tool you are looking for, provided someone can provide the desired annotation processor. -- Jon On Mar 3, 2009, at 11:31 AM, Jeremy Manson wrote: > On Tue, Mar 3, 2009 at 3:58 AM, Stephen Colebourne > wrote: >> Jeremy Manson wrote: >>>> The principle perceived disadvantage, however, is that it >>>> encourages, >>>> rather than discourages, the use of null values in APIs. >>> >>> I would think that the principle disadvantage would be not that it >>> encourages use of null values (which, as you point out, is fine in >>> some contexts), but that it encourages programmers not to think >>> about >>> what happens when there is a null value. >> >> But that is exactly what already happens today. Most developers are >> very >> poor at thinking through the null consequences of a method - the >> happy >> day scenario is the one focussed on. > > Right. This is bad, because much of the time, the program cannot > tolerate nulls. > >>> I can easily imagine >>> programmers using this all of the time without thinking about it, >>> and >>> then being surprised when a null ends up in the wrong place and not >>> knowing how it got there. Even with a simple example: >>> >>> public String someFunction(String a, String b) { >>> String s = a?.concat("foo"); >>> String t = b?.concat(a); >>> return myHashMap?.get(t); >>> } >>> >>> Now, someFunction returns null. Is it because a was null? Or b was >>> null? Or myHashMap was null? Or there was no mapping for t in >>> myHashMap? >> >> Or perhaps it doesn't matter, and thats why the code was written that >> way. Null as 'don't know' or 'don't care' is incredibly common. > > So, we have two cases: > > 1) I've done something wrong, in which case "." provides useful > semantics, because it is fail fast. > > 2) "Don't know" or "Don't care", in which case "?." doesn't provide > useful semantics, but is less typing. > > Flipping through a few thousand lines' worth of our source files, I > see hundreds of examples of #1, and only a couple of examples of #2. > Most of the time, we know a priori that we're not doing a null > dereference, so we don't need the ?.. This pretty much gels with my > intuition about this. Perhaps it is different in EE code? I would be > interested to hear a more thorough study of people's source bases. If > it is true that #2 is only responsible for a tiny fraction of the > cases in general, then it is a little odd to add a programming > language feature around it. > > (By the way, I'm not denying that it is, as you say, common!) > > Additionally, every time you use ?., you are going to have to think > incredibly carefully about whether it is #1 or #2. And I have this > sneaking suspicion that most programmers will just sprinkle it > liberally all over their code without thinking about it at all. When > they get it wrong, that's going to make errors harder to catch. From > a design standpoint, I would lean towards forcing people to think > about it every time, because they are more likely to get it right that > way. > >>> If you want to cut down on >>> extraneous if-testing, I would use JSR-305's Nullity annotations >>> instead. >> >> What does this code do when passed null? >> >> Foo f = new Foo(null); >> int v = f.value; >> >> public class Foo { >> public final Integer value; >> public Foo(@Nonnull Integer value) { >> this.value = value; >> } >> } >> >> There is a NPE at f.value, not at new Foo(null). >> >> You would think that you could never construct an instance of Foo >> with a >> val of null, but you can. The @Nonnull annotation doesn't have any >> real >> meaning unless it is checked using a tool, and javac isn't such a >> tool. >> This will be very confusing when you use Foo from another part of >> your >> application and expect the value to be non-null and get a NPE. In >> fact >> the @Nonnull is positvely misleading. > > I think that providing warnings for these annotations is a very good > idea. That's a language change that makes some sense to me, if the > semantics can be nailed down. > >> Basically, you can't rely on JSR-305. The information needs to be >> rechecked. Thus, whats the point in using it at all?!! Documentation >> perhaps? Annotations are not suitable for handling language level >> issues >> like nulls. > > I do think that annotations are suitable for handling language level > issues, as long as they are checked. For example, @Override has been > very useful to me, because my toolchain complains when I add it and am > not overriding something. > > Jeremy > From reinier at zwitserloot.com Tue Mar 3 12:05:34 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 3 Mar 2009 21:05:34 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903031459.03331.david.goodenough@linkchoose.co.uk> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> Message-ID: <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> You call that lightweight? How about following the beans spec more to the letter and just generate the addPropertyChangeListener, removePropertyChangeListener, setX(), and get/isX() method in response to seeing a keyword or annotation on a given field. You'll have to work out the details, but that sounds far, far simpler to understand. You'll need to flesh this out, but it would look something like: public class Foo { private property int x; } Which would generate the addPropertyChangeListener, removePropertyChangeListener, setX, getX methods, all public, along with the required infrastructure to make it tick. If you don't like the generation, for example because you want the setter to be package private, you just add the setter in the source file; the keyword will only generate the missing stuff. It doesn't cover every use case, but there's always the alternative of doing whatever people do now with beans. Something you didn't mention in your proposal, by the way. I think there's also a fully fleshed out property proposal (including a 'property' keyword) out there somewhere. Possibly make a way to opt out of generating the property change listener support, and just the getters/setters. --Reinier Zwitserloot On Mar 3, 2009, at 15:59, David Goodenough wrote: > Below is my proposal for Lightweight Properties. I know that the > syntax > change is an abbomination to some people, but I have tried to reduce > this to its absolute minimum, while still getting a significant > benefit. > > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): > > David Goodenough, long time Java user. I can be reached at > david.goodenough at linkchoose.co.uk. > > OVERVIEW > > FEATURE SUMMARY: > > Lightweight Property support > > MAJOR ADVANTAGE: > > Both BeansBinding (whether JSR-295 or others such an JFace or the > JGoodies > binding) and the JPA Criteria API currently require field names (as > Strings) > as arguments, which an IDE/compiler can not check. With this > proposal the > strings would be abandoned, and the IDE/compiler will be able to > check the > correctness of the code. > > MAJOR BENEFIT: > > Manual checking no longer required. This proposal introduces a > simple well > defined IDE/compiler checkable solution. > > MAJOR DISADVANTAGE: > > It is a language change, and this seems to upset some people. > > ALTERNATIVES: > > None really, apart from using another language or continuing to use > String > names. The existing solutions all require String names which are > uncheckable. > > EXAMPLES > > Lets assume we have a POJO called foo, of type Foo with a field bar > of type > Bar, which itself has a field of type Jim called jim. > > There are two forms of lightweight properties:- > > 1) foo#bar would be translated by the compiler into:- > > new Property(foo,"bar"); > > while foo#bar#jim would be translated into:- > > new Property(foo,"bar","jim"); > > 2) Foo#bar would be translated into:- > > new Property(Foo.class,"bar"); > > while Foo#bar#jim would be translated into:- > > new Property(Foo.class,"bar","jim"); > > These two forms create (1) a bound Property, or (2) an unbound one. > Bound > Properties are explicitly bound to a particular instance of a class > (in this > case foo), while unbound Properties are templates which can be > applied to any > instance of class Foo. Actually bound properties can also be used as > unbound > properties, but that is a harmless and useful side effect not a > primary > intent. > > The Property class would need to be added (it is appended below), > and should > be added either to the java.beans package or to the > java.lang.reflect package > (with which is probably has more in common). > > Syntactically a "#" can be placed wherever a "." can be placed > (except inside > a number), and the same checks need to be made (that each field to > the right > of a # is a field in the left hand side) as would be made for a ".". > The only > difference is in field visibility - For the "#" any field is > visible, which > follows the model currently available in the Field class with > getDeclaredFields(). It also follows the model that while a field > might be > private and therefore not directly accessible from outside, getters > and > setters can provide access. > > The Property object provides type safe access to the field in the > form of > getters and setters. These come in pairs, one for bound and the > other for > unbound access. So for bound access no object is required to fetch > the value, > for an unbound object the parent object needs to be specified. So if > we > have:- > > Propertyprop = foo#bar; > > we can later say:- > > Bar b = prop.get(); > > or for an unbound one from a second Foo object foo2:- > > Bar b = prop.get(foo2); > > The getters and setters in the Property object will defer to > explicitly coded > getters and setters if present, otherwise they will use the Field > getter and > setter. > > If a setter is not explicitly coded, the implicit setter will look > for a > PropertyChangeSupport object in the parent object of the rightmost > field and > fire a PropertyChangeEvent to that object. > > There are also two Annotations provided by the Property class, > ReadOnly and > WriteOnly. These stop implicit getters and setters from trying to > read/write > the property. > > Talking of Annotations, this notation can also be used to get at the > Annotations for a field. So to test for the presence of an > Annotation Ann on > Foo.bar we would use:- > > if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > > SIMPLE EXAMPLE: > > To take an example from BeansBinding (taken from Shannon Hickey's > blog):- > > // create a BeanProperty representing a bean's firstName > Property firstP = BeanProperty.create("firstName"); > // Bind Duke's first name to the text property of a Swing JTextField > BeanProperty textP = BeanProperty.create("text"); > Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > firstP, textfield, textP); > binding.bind(); > > > would instead be written:- > > Binding binding = Bindings.createAutoBinding(READ_WRITE, > duke#firstName, textfield#text); > binding.bind(); > > which of course can be checked by the IDE/compiler, and will not > wait until > run time (not even instantiation time) to show up the error. > > ADVANCED EXAMPLE: > > For a JComboBox (or JList or JTable or JTree) there is a need to map > a list of > objects to the value strings (or column contents). For this we need > to have > an unbound Property which can be applied to each element of the list. > > Duke duke; > Listdukes; > BoundComboBox combo = new > BoundComboBox(dukes,Duke#fullname,this#duke); > > and now the combo box will be populated from the list dukes, and the > display > values in the list will be taken from the fullname field of each Duke > element, and the initial value will be set from the local class > field duke > and any changes to the combo box selected element will be reflected > back to > the duke field. > > DETAILS > > SPECIFICATION: > > This proposal adds a new syntactic element, "#", which can be used > in the same > way that "." can be used to qualify fields within a Java object. > > COMPILATION: > > This proposal requires no change to the class files, and is > implemented by a > simple generation of the required instance using the relevant Property > constructor. Obviously the compiler would have to make sure that the > use that > the property object was being put to (in the examples above the left > hand > side of the assignment) had the correct Generic attributes. > > TESTING: > > How can the feature be tested? > > LIBRARY SUPPORT: > > The new Property class is required (see below). > > REFLECTIVE APIS: > > No changes are required to the reflective APIs although it makes > extensive use > of those APIs. > > OTHER CHANGES: > > No other changes are requires. > > MIGRATION: > > Fortunately there is no code that is formally part of J2SE 6 which > uses such > Properties. There are however two proposals which will need it > (BeansBinding > and JPA Criteria API), but neither of these seem to be destined to > be part of > J2SE 7 (BeansBinding seems to have died the death and the Criteria > API would > be part of the next J2EE which will follow J2SE 7), so this will > provide a > base for them to use and no existing code need to be updated. > > There are other extant Beans-Binding libraries, which could be > modified to use > this proposal, but as none of the existing features have been > changed there > is no need to change them (other than for type safety and compiler/IDE > checkability). > > COMPATIBILITY > > BREAKING CHANGES: > > None. This change should not make any existing correct code fail to > compile > or run or change the way in which it compiles/runs. > > EXISTING PROGRAMS: > > No change required to any existing programs > > REFERENCES > > EXISTING BUGS: > > None > > URL FOR PROTOTYPE (optional): > > I do not have the knowledge to make changes to the compiler, and the > only > documentation making such changes concentrated on adding operators not > changes at this level. So there is no prototype of the compiler > part, but the > Property class follows:- > > package java.lang.reflect; > > import java.beans.BeanInfo; > import java.beans.Introspector; > import java.beans.PropertyChangeSupport; > import java.beans.PropertyDescriptor; > import java.lang.reflect.Field; > import java.lang.reflect.Method; > > /** > * Property class > * This is the support class for use with the # notation to provide > lightweight > * Property support for Java. > * > * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > * @licence LPGL V2 : details of which can be found at http://fsf.org. > * @author david.goodenough at linkchoose.co.uk > * > * @param The Parent class for this field > * @param The Type of this field > */ > public class Property { > private C parent; > private Class parentClass; > private Field[] fields; > private PropertyDescriptor[] pd = null; > /** > * Constructor used to create Property objects. The Parent object > may be > * null, but should normally be specified as it can be overridden > anyway. > * @param parent C object that contains the field > * @param field Field describing this field > */ > public Property(C parent, String ... fieldNames) { > this.parent = parent; > this(parent.getClass(), fieldNames); > } > /** > * Constructor for unbound Properties, but also used internally > after > setting > * the parent object by the bound Property objects. > * @param parentClass Class of the parent object > * @param fieldNames String[] of field names > */ > public Property(ClassparentClass, String .. fieldNames) { > this.parentClass = parentClass; > fields = new Field[fieldNames.length]; > pd = new PropertyDescriptor[fieldNames.length]; > outer: for(int index = 0; index < fields.length; index++) { > Field[]dclFields = parentClass.getDeclaredFields(); > for(Field field:dclFields) { > if(field.getName().equals(fieldNames[index])) { > fields[index] = field; > field.setAccessible(true); > try { > BeanInfo beanInfo = > Introspector.getBeanInfo(parent.getClass()); > PropertyDescriptor[]props = > beanInfo.getPropertyDescriptors(); > for(PropertyDescriptor prop : props) { > if(prop.getName().equals(field.getName())) { > pd[index] = prop; > break; > } > } > } catch(Exception e) { /* assume can not find getter/ > setter > */ } > parentClass = field.getType(); > continue outer; > } > } > throw new IllegalArgumentException("Field " + fieldNames[index] + > " not found in class " + > parentClass.getCanonicalName()); > } > } > /** > * Getter from the field in the parent specified when this > Property was > created. > * @see Property.get(C otherParent) > * @return F the value of this field > */ > public F get() { > return get(parent); > } > /** > * Getter with explicit parent. > * This code will check see if this field is WriteOnly, and > complain if it > is. > * It will then see if the use has provided am explicit getter, > and call > that > * if present, otherwise it will just fetch the value through the > Field > provided > * method. > * @param otherParent C parent object > * @return F value of the field > */ > @SuppressWarnings("unchecked") // This should actually not be > needed, > // but the Field.get method is not > typed > public F get(C otherParent) { > Object result = otherParent; > try { > for(int index = 0; index < fields.length; index++) { > > if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > throw new IllegalAccessException( > "Can not get from a WriteOnly field - " + > fields[index].getName()); > Method getter = pd[index] == null ? null : > pd[index].getReadMethod(); > if(getter == null) result = fields[index].get(result); > else result = getter.invoke(result); > } > } catch(Exception e) { > throw new RuntimeException("Should not occur exception", e); > } > return (F)result; > } > /** > * Setter to set the value of the field in the parent object > declared with > the > * Property object > * @param newValue F new value of this field > */ > public void set(F newValue) { > set(parent,newValue); > } > /** > * Setter to set the value of the field to an explicit parent > object. > * If there is a ReadOnly annotation, then we object. If there is > an > explicit > * setter then we use that, otherwise we set the field using the > Field > provided > * set method and if there is a PropertyChangeSupport field, fire a > property > * change event to it. > * We walk our way down the field chain, until we have the last > object and > its > * field, and then we do the set. > * @param parent C explicit parent object > * @param newValue F new value for field in parent > */ > public void set(C parent,F newValue) { > try { > Object last = parent; > int index; > for(index = 0; index < fields.length - 1; index++) { > > if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > throw new IllegalAccessException( > "Can not get from a WriteOnly field - " + > fields[index].getName()); > Method getter = pd[index] == null ? null : > pd[index].getReadMethod(); > if(getter == null) last = fields[index].get(last); > else last = getter.invoke(last); > } > > if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > throw new IllegalAccessException( > "Can not get from a WriteOnly field - " + > fields[index].getName()); > Method setter = pd[index] == null ? null : > pd[index].getWriteMethod(); > if(setter == null) { > PropertyChangeSupport pcs = findPcs(last.getClass()); > fields[index].set(last,newValue); > if(pcs != null) > pcs.firePropertyChange(fields[index].getName(), > newValue, > > fields[index].get(last)); > } else setter.invoke(last,newValue); > } catch(Exception e) { > throw new RuntimeException("Should not occur > exception", e); > } > } > /** > * This is used so that the caller can view the Field name > * @return String field name > */ > public String[] getFieldName() { > String[]names = new String[fields.length]; > for(int index = 0; index < fields.length; index++) { > names[index] = fields[index].getName(); > } > return names; > } > /** > * This method is used to fetch the Field array, which is useful > if you > need to > * access the Annotations of a field. > * @return Field[] the array of Fields describing this Property. > */ > public Field[] getFields() { > return fields; > } > /** > * This private method looks for a PropertyChangeSupport object in > the > class and > * if one is found it will return it. It looks right the way up > the class > tree > * by recurring up the superClasses. > * @param parent Class to check for PropertyChangeSupport fields > * @return PropertyChangeSupport first found object, or null if > not found > */ > private PropertyChangeSupport findPcs(Class parent) { > Field fields[] = parent.getDeclaredFields(); > for(Field field:fields) { > field.setAccessible(true); > try { > if(field.getType() == PropertyChangeSupport.class) > return (PropertyChangeSupport)field.get(parent); > } catch(Exception e) { } > } > // If we did not find it then try the superclass > ClasssuperClass = parent.getSuperclass(); > if(superClass == null) return null; > return findPcs(parent.getClass().getSuperclass()); > } > /** > * This annotation is used to mark a field as WriteOnly, i.e. it > can not > be read. > * This stops the automatic getter operation. > */ > public @interface WriteOnly { > } > /** > * This annotation is used to mark a field as ReadOnly, i.e. it > can not be > written. > * This stops the automatic setter operation. > */ > public @interface ReadOnly { > } > } > From develop4lasu at gmail.com Tue Mar 3 12:17:17 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 3 Mar 2009 21:17:17 +0100 Subject: 'This' type Message-ID: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ OVERVIEW FEATURE SUMMARY: This type add ability to project valid interfaces(classes) for further extending/implementing. 'This' means current interface/class type or something implementing/extending it. MAJOR ADVANTAGE: - Support of interface projecting at interface level. - More readable code structure (interfaces/methods). - Making refactor more enjoyable (much easier). - Discarding request of replacing 'void' with 'this'. - Splitting interfaces to sub-interfaces can become pleasant. - Down casting working properly. - Decreasing number of method signatures in classes/interfaces. MAJOR DISADVANTAGE: - Class 'This' may already exist somewhere in code(?) - As so far, it's not been thought over know if there is point of using it for input parameters. - 'This.class' might be a problem for generics, but generally everything depends on how 'This' is interpreted(personally, I think that it should be generic with arguments)(this.getClass()). ALTERNATIVES: Rewriting each method's signature on every class / interface. EXAMPLES public static interface IB implements Iterable { } public static interface IC implements IB { } Would mean(which is impossible now time): public static interface IC implementsIB, Iterable { } public static interface IA { This write(String s); } public static interface IB extends IA { This write(double value); } public abstract static class CC implements IB { This write(int value){ __ ... __ return this; } } public static class CD extends CC { @Override public This write(double value) { __ ... __ return this; } @Override public This write(String s) { __ ... __ return this; } } public static void main(String[] args) { __ CD object = new CD(); __ object.write("Some").write(3).write(3.11); } Nowdays, the same code would look as: public static interface IA { IA write(String s); } public static interface IB extends IA { IB write(double value); @Override IB write(String s); } public abstract static class CC implements IB { CC write(int value){ __ ... __ return this; } @Override public abstract CC write(double value); @Override public abstract CC write(String s); } public static class CD extends CC { @Override public CD write(double value) { __ ... __ return this; } @Override public CD write(String s) { __ ... __ return this; } __ @Override CD write(int value){ __ ... __ return this; } } DETAILS: SPECIFICATION: (I did not have time to analyze this completely.) COMPILATION: With 'This' type is valid: this null ? extends This 'This' should be considered to be able to appear in: return type(yes). input type(yes/no?). method body(yes?). As generic parameter(yes/only if they appear as return types?). List> would mean This but not less than Container This could be reduced to last superclass COMPATIBILITY Only programs where are class/interface named 'This' used can be problem. REFERENCES Notice that considered document does not contain complete analyze of those solutions and can have some lacks. So if you have some questions/advices that it does not fully fit with Project Coin, post it on my blog to discuss: http://lasu2string.blogspot.com/2009/03/this-type.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Tue Mar 3 12:17:30 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 12:17:30 -0800 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> Message-ID: <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> Joe Darcy sort of ruled out adding property support in project coin in http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size Regards, Neal On Tue, Mar 3, 2009 at 12:05 PM, Reinier Zwitserloot wrote: > You call that lightweight? > > How about following the beans spec more to the letter and just > generate the addPropertyChangeListener, removePropertyChangeListener, > setX(), and get/isX() method in response to seeing a keyword or > annotation on a given field. You'll have to work out the details, but > that sounds far, far simpler to understand. > > You'll need to flesh this out, but it would look something like: > > public class Foo { > ? ?private property int x; > } > > Which would generate the addPropertyChangeListener, > removePropertyChangeListener, setX, getX methods, all public, along > with the required infrastructure to make it tick. If you don't like > the generation, for example because you want the setter to be package > private, you just add the setter in the source file; the keyword will > only generate the missing stuff. It doesn't cover every use case, but > there's always the alternative of doing whatever people do now with > beans. Something you didn't mention in your proposal, by the way. > > I think there's also a fully fleshed out property proposal (including > a 'property' keyword) out there somewhere. > > Possibly make a way to opt out of generating the property change > listener support, and just the getters/setters. > --Reinier Zwitserloot > > > > On Mar 3, 2009, at 15:59, David Goodenough wrote: > >> Below is my proposal for Lightweight Properties. ?I know that the >> syntax >> change is an abbomination to some people, but I have tried to reduce >> this to its absolute minimum, while still getting a significant >> benefit. >> >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): >> >> David Goodenough, long time Java user. I can be reached at >> david.goodenough at linkchoose.co.uk. >> >> OVERVIEW >> >> FEATURE SUMMARY: >> >> Lightweight Property support >> >> MAJOR ADVANTAGE: >> >> Both BeansBinding (whether JSR-295 or others such an JFace or the >> JGoodies >> binding) and the JPA Criteria API currently require field names (as >> Strings) >> as arguments, which an IDE/compiler can not check. With this >> proposal the >> strings would be abandoned, and the IDE/compiler will be able to >> check the >> correctness of the code. >> >> MAJOR BENEFIT: >> >> Manual checking no longer required. This proposal introduces a >> simple well >> defined IDE/compiler checkable solution. >> >> MAJOR DISADVANTAGE: >> >> It is a language change, and this seems to upset some people. >> >> ALTERNATIVES: >> >> None really, apart from using another language or continuing to use >> String >> names. The existing solutions all require String names which are >> uncheckable. >> >> EXAMPLES >> >> Lets assume we have a POJO called foo, of type Foo with a field bar >> of type >> Bar, which itself has a field of type Jim called jim. >> >> There are two forms of lightweight properties:- >> >> 1) foo#bar would be translated by the compiler into:- >> >> ? ? ? new Property(foo,"bar"); >> >> while foo#bar#jim would be translated into:- >> >> ? ? ? new Property(foo,"bar","jim"); >> >> 2) Foo#bar would be translated into:- >> >> ? ? ? new Property(Foo.class,"bar"); >> >> while Foo#bar#jim would be translated into:- >> >> ? ? ? new Property(Foo.class,"bar","jim"); >> >> These two forms create (1) a bound Property, or (2) an unbound one. >> Bound >> Properties are explicitly bound to a particular instance of a class >> (in this >> case foo), while unbound Properties are templates which can be >> applied to any >> instance of class Foo. Actually bound properties can also be used as >> unbound >> properties, but that is a harmless and useful side effect not a >> primary >> intent. >> >> The Property class would need to be added (it is appended below), >> and should >> be added either to the java.beans package or to the >> java.lang.reflect package >> (with which is probably has more in common). >> >> Syntactically a "#" can be placed wherever a "." can be placed >> (except inside >> a number), and the same checks need to be made (that each field to >> the right >> of a # is a field in the left hand side) as would be made for a ".". >> The only >> difference is in field visibility - For the "#" any field is >> visible, which >> follows the model currently available in the Field class with >> getDeclaredFields(). It also follows the model that while a field >> might be >> private and therefore not directly accessible from outside, getters >> and >> setters can provide access. >> >> The Property object provides type safe access to the field in the >> form of >> getters and setters. These come in pairs, one for bound and the >> other for >> unbound access. So for bound access no object is required to fetch >> the value, >> for an unbound object the parent object needs to be specified. So if >> we >> have:- >> >> ? ? ? Propertyprop = foo#bar; >> >> we can later say:- >> >> ? ? ? Bar b = prop.get(); >> >> or for an unbound one from a second Foo object foo2:- >> >> ? ? ? Bar b = prop.get(foo2); >> >> The getters and setters in the Property object will defer to >> explicitly coded >> getters and setters if present, otherwise they will use the Field >> getter and >> setter. >> >> If a setter is not explicitly coded, the implicit setter will look >> for a >> PropertyChangeSupport object in the parent object of the rightmost >> field and >> fire a PropertyChangeEvent to that object. >> >> There are also two Annotations provided by the Property class, >> ReadOnly and >> WriteOnly. These stop implicit getters and setters from trying to >> read/write >> the property. >> >> Talking of Annotations, this notation can also be used to get at the >> Annotations for a field. So to test for the presence of an >> Annotation Ann on >> Foo.bar we would use:- >> >> ? ? ? if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... >> >> SIMPLE EXAMPLE: >> >> To take an example from BeansBinding (taken from Shannon Hickey's >> blog):- >> >> ? ? ? // create a BeanProperty representing a bean's firstName >> ? ? ? Property firstP = BeanProperty.create("firstName"); >> ? ? ? // Bind Duke's first name to the text property of a Swing JTextField >> ? ? ? BeanProperty textP = BeanProperty.create("text"); >> ? ? ? Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstP, textfield, textP); >> ? ? ? binding.bind(); >> >> >> would instead be written:- >> >> ? ? ? Binding binding = Bindings.createAutoBinding(READ_WRITE, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? duke#firstName, textfield#text); >> ? ? ? binding.bind(); >> >> which of course can be checked by the IDE/compiler, and will not >> wait until >> run time (not even instantiation time) to show up the error. >> >> ADVANCED EXAMPLE: >> >> For a JComboBox (or JList or JTable or JTree) there is a need to map >> a list of >> objects to the value strings (or column contents). For this we need >> to have >> an unbound Property which can be applied to each element of the list. >> >> ? ? ? Duke duke; >> ? ? ? Listdukes; >> ? ? ? BoundComboBox combo = new >> BoundComboBox(dukes,Duke#fullname,this#duke); >> >> and now the combo box will be populated from the list dukes, and the >> display >> values in the list will be taken from the fullname field of each Duke >> element, and the initial value will be set from the local class >> field duke >> and any changes to the combo box selected element will be reflected >> back to >> the duke field. >> >> DETAILS >> >> SPECIFICATION: >> >> This proposal adds a new syntactic element, "#", which can be used >> in the same >> way that "." can be used to qualify fields within a Java object. >> >> COMPILATION: >> >> This proposal requires no change to the class files, and is >> implemented by a >> simple generation of the required instance using the relevant Property >> constructor. Obviously the compiler would have to make sure that the >> use that >> the property object was being put to (in the examples above the left >> hand >> side of the assignment) had the correct Generic attributes. >> >> TESTING: >> >> How can the feature be tested? >> >> LIBRARY SUPPORT: >> >> The new Property class is required (see below). >> >> REFLECTIVE APIS: >> >> No changes are required to the reflective APIs although it makes >> extensive use >> of those APIs. >> >> OTHER CHANGES: >> >> No other changes are requires. >> >> MIGRATION: >> >> Fortunately there is no code that is formally part of J2SE 6 which >> uses such >> Properties. There are however two proposals which will need it >> (BeansBinding >> and JPA Criteria API), but neither of these seem to be destined to >> be part of >> J2SE 7 (BeansBinding seems to have died the death and the Criteria >> API would >> be part of the next J2EE which will follow J2SE 7), so this will >> provide a >> base for them to use and no existing code need to be updated. >> >> There are other extant Beans-Binding libraries, which could be >> modified to use >> this proposal, but as none of the existing features have been >> changed there >> is no need to change them (other than for type safety and compiler/IDE >> checkability). >> >> COMPATIBILITY >> >> BREAKING CHANGES: >> >> None. ?This change should not make any existing correct code fail to >> compile >> or run or change the way in which it compiles/runs. >> >> EXISTING PROGRAMS: >> >> No change required to any existing programs >> >> REFERENCES >> >> EXISTING BUGS: >> >> None >> >> URL FOR PROTOTYPE (optional): >> >> I do not have the knowledge to make changes to the compiler, and the >> only >> documentation making such changes concentrated on adding operators not >> changes at this level. So there is no prototype of the compiler >> part, but the >> Property class follows:- >> >> package java.lang.reflect; >> >> import java.beans.BeanInfo; >> import java.beans.Introspector; >> import java.beans.PropertyChangeSupport; >> import java.beans.PropertyDescriptor; >> import java.lang.reflect.Field; >> import java.lang.reflect.Method; >> >> /** >> * Property class >> * This is the support class for use with the # notation to provide >> lightweight >> * Property support for Java. >> * >> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd >> * @licence LPGL V2 : details of which can be found at http://fsf.org. >> * @author david.goodenough at linkchoose.co.uk >> * >> * @param The Parent class for this field >> * @param The Type of this field >> */ >> public class Property { >> ? ?private C parent; >> ? private Class parentClass; >> ? private Field[] fields; >> ? private PropertyDescriptor[] pd = null; >> ? /** >> ? ?* Constructor used to create Property objects. ?The Parent object >> may be >> ? ?* null, but should normally be specified as it can be overridden >> anyway. >> ? ?* @param parent C object that contains the field >> ? ?* @param field Field describing this field >> ? ?*/ >> ? public Property(C parent, String ... fieldNames) { >> ? ? ? this.parent = parent; >> ? ? ? ?this(parent.getClass(), fieldNames); >> ? ? ? ?} >> ? ?/** >> ? ? * Constructor for unbound Properties, but also used internally >> after >> setting >> ? ? * the parent object by the bound Property objects. >> ? ? * @param parentClass Class of the parent object >> ? ? * @param fieldNames String[] of field names >> ? ? */ >> ? ?public Property(ClassparentClass, String .. fieldNames) { >> ? ? ? ?this.parentClass = parentClass; >> ? ? ? fields = new Field[fieldNames.length]; >> ? ? ? pd = new PropertyDescriptor[fieldNames.length]; >> outer: ?for(int index = 0; index < fields.length; index++) { >> ? ? ? ? ? Field[]dclFields = parentClass.getDeclaredFields(); >> ? ? ? ? ? ? ? ? ? for(Field field:dclFields) { >> ? ? ? ? ? ? ? ? ? ? ? if(field.getName().equals(fieldNames[index])) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fields[index] = field; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? field.setAccessible(true); >> ? ? ? ? ? ? ? ? ? ? ? try { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BeanInfo beanInfo = >> Introspector.getBeanInfo(parent.getClass()); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PropertyDescriptor[]props = >> beanInfo.getPropertyDescriptors(); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? for(PropertyDescriptor prop : props) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if(prop.getName().equals(field.getName())) { >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pd[index] = prop; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } catch(Exception e) { /* assume can not find getter/ >> setter >> */ } >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? parentClass = field.getType(); >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? continue outer; >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } >> ? ? ? ? ? ? ? ? ? ? ? } >> ? ? ? throw new IllegalArgumentException("Field " + fieldNames[index] + >> ? ? ? ? ? ? ? ? ? ? ? ? ? " not found in class " + >> parentClass.getCanonicalName()); >> ? ? ? ? ? ? ? } >> ? ? ? } >> ? /** >> ? ?* Getter from the field in the parent specified when this >> Property was >> created. >> ? ?* @see Property.get(C otherParent) >> ? ?* @return F the value of this field >> ? ?*/ >> ? public F get() { >> ? ? ? return get(parent); >> ? ? ? } >> ? /** >> ? ?* Getter with explicit parent. >> ? ?* This code will check see if this field is WriteOnly, and >> complain if it >> is. >> ? ?* It will then see if the use has provided am explicit getter, >> and call >> that >> ? ?* if present, otherwise it will just fetch the value through the >> Field >> provided >> ? ?* method. >> ? ?* @param otherParent C parent object >> ? ?* @return F value of the field >> ? ?*/ >> ? @SuppressWarnings("unchecked") // This should actually not be >> needed, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// but the Field.get method is not >> typed >> ? public F get(C otherParent) { >> ? ? ? Object result = otherParent; >> ? ? ? try { >> ? ? ? ? ? for(int index = 0; index < fields.length; index++) { >> >> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >> ? ? ? ? ? ? ? ? ? throw new IllegalAccessException( >> ? ? ? ? ? ? ? ? ? ? ? "Can not get from a WriteOnly field - " + >> fields[index].getName()); >> ? ? ? ? ? ? ? Method getter = pd[index] == null ? null : >> pd[index].getReadMethod(); >> ? ? ? ? ? ? ? if(getter == null) result = fields[index].get(result); >> ? ? ? ? ? ? ? ? ? else result = getter.invoke(result); >> ? ? ? ? ? ? ? } >> ? ? ? ? ? } catch(Exception e) { >> ? ? ? ? ? ? ? throw new RuntimeException("Should not occur exception", e); >> ? ? ? ? ? ? ? } >> ? ? ? return (F)result; >> ? ? ? } >> ? /** >> ? ?* Setter to set the value of the field in the parent object >> declared with >> the >> ? ?* Property object >> ? ?* @param newValue F new value of this field >> ? ?*/ >> ? public void set(F newValue) { >> ? ? ? set(parent,newValue); >> ? ? ? } >> ? /** >> ? ?* Setter to set the value of the field to an explicit parent >> object. >> ? ?* If there is a ReadOnly annotation, then we object. ?If there is >> an >> explicit >> ? ?* setter then we use that, otherwise we set the field using the >> Field >> provided >> ? ?* set method and if there is a PropertyChangeSupport field, fire a >> property >> ? ?* change event to it. >> ? ?* We walk our way down the field chain, until we have the last >> object and >> its >> ? ?* field, and then we do the set. >> ? ?* @param parent C explicit parent object >> ? ?* @param newValue F new value for field in parent >> ? ?*/ >> ? public void set(C parent,F newValue) { >> ? ? ? try { >> ? ? ? ? ? Object last = parent; >> ? ? ? ? ? int index; >> ? ? ? ? ? for(index = 0; index < fields.length - 1; index++) { >> >> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >> ? ? ? ? ? ? ? ? ? throw new IllegalAccessException( >> ? ? ? ? ? ? ? ? ? ? ? "Can not get from a WriteOnly field - " + >> ? ? ? ? ? ? ? ? ? ? ? fields[index].getName()); >> ? ? ? ? ? ? ? Method getter = pd[index] == null ? null : >> pd[index].getReadMethod(); >> ? ? ? ? ? ? ? if(getter == null) last = fields[index].get(last); >> ? ? ? ? ? ? ? else last = getter.invoke(last); >> ? ? ? ? ? ? ? } >> >> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) >> ? ? ? ? ? ? ? throw new IllegalAccessException( >> ? ? ? ? ? ? ? ? ? "Can not get from a WriteOnly field - " + >> fields[index].getName()); >> ? ? ? ? ? ? ? Method setter = pd[index] == null ? null : >> pd[index].getWriteMethod(); >> ? ? ? ? ? ? ? if(setter == null) { >> ? ? ? ? ? ? ? ? ? PropertyChangeSupport pcs = findPcs(last.getClass()); >> ? ? ? ? ? ? ? ? ? fields[index].set(last,newValue); >> ? ? ? ? ? ? ? if(pcs != null) >> pcs.firePropertyChange(fields[index].getName(), >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? newValue, >> >> fields[index].get(last)); >> ? ? ? ? ? ? ? } else setter.invoke(last,newValue); >> ? ? ? ? ? } catch(Exception e) { >> ? ? ? ? ? ? ? throw new RuntimeException("Should not occur >> exception", e); >> ? ? ? ? ? ? ? } >> ? ? ? } >> ? /** >> ? ?* This is used so that the caller can view the Field name >> ? ?* @return String field name >> ? ?*/ >> ? public String[] getFieldName() { >> ? ? ? String[]names = new String[fields.length]; >> ? ? ? for(int index = 0; index < fields.length; index++) { >> ? ? ? ? ? names[index] = fields[index].getName(); >> ? ? ? ? ? } >> ? ? ? return names; >> ? ? ? } >> ? ?/** >> ? ? * This method is used to fetch the Field array, which is useful >> if you >> need to >> ? ? * access the Annotations of a field. >> ? ? * @return Field[] the array of Fields describing this Property. >> ? ? */ >> ? ?public Field[] getFields() { >> ? ? ? ?return fields; >> ? ? ? ?} >> ? /** >> ? ?* This private method looks for a PropertyChangeSupport object in >> the >> class and >> ? ?* if one is found it will return it. ?It looks right the way up >> the class >> tree >> ? ?* by recurring up the superClasses. >> ? ?* @param parent Class to check for PropertyChangeSupport fields >> ? ?* @return PropertyChangeSupport first found object, or null if >> not found >> ? ?*/ >> ? private PropertyChangeSupport findPcs(Class parent) { >> ? ? ? Field fields[] = parent.getDeclaredFields(); >> ? ? ? for(Field field:fields) { >> ? ? ? ? ? field.setAccessible(true); >> ? ? ? ? ? try { >> ? ? ? ? ? ? ? if(field.getType() == PropertyChangeSupport.class) >> ? ? ? ? ? ? ? ? ? return (PropertyChangeSupport)field.get(parent); >> ? ? ? ? ? ? ? } catch(Exception e) { } >> ? ? ? ? ? } >> ? ? ? // If we did not find it then try the superclass >> ? ? ? ClasssuperClass = parent.getSuperclass(); >> ? ? ? if(superClass == null) return null; >> ? ? ? return findPcs(parent.getClass().getSuperclass()); >> ? ? ? } >> ? /** >> ? ?* This annotation is used to mark a field as WriteOnly, i.e. it >> can not >> be read. >> ? ?* This stops the automatic getter operation. >> ? ?*/ >> ? public @interface WriteOnly { >> ? ? ? } >> ? /** >> ? ?* This annotation is used to mark a field as ReadOnly, i.e. it >> can not be >> written. >> ? ?* This stops the automatic setter operation. >> ? ?*/ >> ? public @interface ReadOnly { >> ? ? ? } >> ? } >> > > > From neal at gafter.com Tue Mar 3 12:25:54 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 12:25:54 -0800 Subject: 'This' type In-Reply-To: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> Message-ID: <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> I'd love to see the specification, in particular the subtyping rules and modifications to type inference. Once those are in place, I'd like to see an argument that this feature leaves the generic type system sound (i.e. there are no ClassCastExceptions unless there are casts or warnings in the source code). As described in http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size almost any type system change is likely out of scope for project coin. On Tue, Mar 3, 2009 at 12:17 PM, Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ > > OVERVIEW > > FEATURE SUMMARY: > This type add ability to project valid interfaces(classes) for further > extending/implementing. 'This' means current interface/class type or > something implementing/extending it. > > > > MAJOR ADVANTAGE: > - Support of interface projecting at interface level. > - More readable code structure (interfaces/methods). > - Making refactor more enjoyable (much easier). > - Discarding request of replacing 'void' with 'this'. > - Splitting interfaces to sub-interfaces can become pleasant. > - Down casting working properly. > - Decreasing number of method signatures in classes/interfaces. > > > MAJOR DISADVANTAGE: > - Class 'This' may already exist somewhere in code(?) > - As so far, it's not been thought over know if there is point of using it > for input parameters. > - 'This.class' might be a problem for generics, but generally everything > depends on how 'This' is interpreted(personally, I think that it should be > generic with arguments)(this.getClass()). > > ALTERNATIVES: > Rewriting each method's signature on every class / interface. > > EXAMPLES > ?public static interface IB implements Iterable { > ?} > > ?public static interface IC implements IB { > ?} > > Would mean(which is impossible now time): > ?public static interface IC implementsIB, Iterable { > ?} > > public static interface IA { > ?This write(String s); > ?} > > ?public static interface IB extends IA { > ?This write(double value); > ?} > > ?public abstract static class CC implements IB { > ?This write(int value){ > __ ?... > __ ?return this; > ?} > ?} > > ?public static class CD extends CC { > ?@Override > ?public This write(double value) { > __ ?... > __ ?return this; > ?} > ?@Override > ?public This write(String s) { > __ ?... > __ ?return this; > ?} > ?} > > ?public static void main(String[] args) { > __ ?CD object = new CD(); > __ ?object.write("Some").write(3).write(3.11); > ?} > > > Nowdays, the same code would look as: > public static interface IA { > ?IA write(String s); > ?} > > ?public static interface IB extends IA { > ?IB write(double value); > ?@Override > ?IB write(String s); > ?} > > ?public abstract static class CC implements IB { > ?CC write(int value){ > __ ?... > __ ?return this; > ?} > > ?@Override > ?public abstract CC write(double value); > > ?@Override > ?public abstract CC write(String s); > ?} > > ?public static class CD extends CC { > ?@Override > ?public CD write(double value) { > __ ?... > __ ?return this; > ?} > ?@Override > ?public CD write(String s) { > __ ?... > __ ?return this; > ?} > __ ?@Override > ?CD write(int value){ > __ ?... > __ ?return this; > ?} > ?} > > DETAILS: > > SPECIFICATION: > (I did not have time to analyze this completely.) > > COMPILATION: > With 'This' type is valid: > this > null > ? extends This > > 'This' should be considered to be able to appear in: > return type(yes). > input type(yes/no?). > method body(yes?). > As generic parameter(yes/only if they appear as return types?). > > List> would mean This but not less than > Container > > This could be reduced to last superclass > > COMPATIBILITY > > Only programs where are class/interface named 'This' used can be problem. > > REFERENCES > > Notice that considered document does not contain complete analyze of those > solutions and can have some lacks. So if you have some questions/advices > that it does not fully fit with Project Coin, post it on my blog to discuss: > http://lasu2string.blogspot.com/2009/03/this-type.html > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From develop4lasu at gmail.com Tue Mar 3 12:40:10 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 3 Mar 2009 21:40:10 +0100 Subject: 'This' type In-Reply-To: <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> Message-ID: <28bca0ff0903031240v513be89fk8796a76fc8faffa7@mail.gmail.com> W dniu 3 marca 2009 21:25 u?ytkownik Neal Gafter napisa?: > I'd love to see the specification, in particular the subtyping rules > and modifications to type inference. Once those are in place, I'd > like to see an argument that this feature leaves the generic type > system sound (i.e. there are no ClassCastExceptions unless there are > casts or warnings in the source code). As described in > http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > almost any type system change is likely out of scope for project coin. > > > If we think about it onlt as extension for return types it's quite easy. interface IA{ This method(); } interface IB extends IA { } now: static void some(IB x){ __ x.method() : return type is IB as This for IB; __ ((IA)x).method() : return type is visible as IA as This for IA; } If u have some doubts, just mail the sample (I do not see any reason for valid code to make ClassCastExceptions to appear). -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Tue Mar 3 12:55:04 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 12:55:04 -0800 Subject: 'This' type In-Reply-To: <28bca0ff0903031240v513be89fk8796a76fc8faffa7@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> <28bca0ff0903031240v513be89fk8796a76fc8faffa7@mail.gmail.com> Message-ID: <15e8b9d20903031255i70d719dbgd9f3615c3abe7f11@mail.gmail.com> Not seeing a problem is not the same thing as demonstrating that no problem can occur. One set of problems arise when you use "This" in a superclass type argument, as you did in an example. I simply don't know what subtype relationships that creates. interface A extends Collection {} After this, is A a subtype of Collection
? On Tue, Mar 3, 2009 at 12:40 PM, Marek Kozie? wrote: > If we think about it onlt as extension for return types it's quite easy. > > interface IA{ This method(); } > > interface IB extends IA { } > now: > > static void some(IB x){ > > __ x.method() : return type is IB as This for IB; > > __ ((IA)x).method() : return type is visible as IA as This for IA; > > } > If u have some doubts, just mail the sample (I do not see any reason for > valid code to make ClassCastExceptions to appear). > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From david.goodenough at linkchoose.co.uk Tue Mar 3 13:00:40 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 3 Mar 2009 21:00:40 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> Message-ID: <200903032100.42422.david.goodenough@linkchoose.co.uk> That is why I tried to reduce the problem to a really small one. Just one small substitution in the compiler and one small class. Its much smaller than some of the other suggestions for Coin. David On Tuesday 03 March 2009, Neal Gafter wrote: > Joe Darcy sort of ruled out adding property support in project coin in > http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > > Regards, > Neal > > On Tue, Mar 3, 2009 at 12:05 PM, Reinier Zwitserloot > > wrote: > > You call that lightweight? > > > > How about following the beans spec more to the letter and just > > generate the addPropertyChangeListener, removePropertyChangeListener, > > setX(), and get/isX() method in response to seeing a keyword or > > annotation on a given field. You'll have to work out the details, but > > that sounds far, far simpler to understand. > > > > You'll need to flesh this out, but it would look something like: > > > > public class Foo { > > ? ?private property int x; > > } > > > > Which would generate the addPropertyChangeListener, > > removePropertyChangeListener, setX, getX methods, all public, along > > with the required infrastructure to make it tick. If you don't like > > the generation, for example because you want the setter to be package > > private, you just add the setter in the source file; the keyword will > > only generate the missing stuff. It doesn't cover every use case, but > > there's always the alternative of doing whatever people do now with > > beans. Something you didn't mention in your proposal, by the way. > > > > I think there's also a fully fleshed out property proposal (including > > a 'property' keyword) out there somewhere. > > > > Possibly make a way to opt out of generating the property change > > listener support, and just the getters/setters. > > --Reinier Zwitserloot > > > > On Mar 3, 2009, at 15:59, David Goodenough wrote: > >> Below is my proposal for Lightweight Properties. ?I know that the > >> syntax > >> change is an abbomination to some people, but I have tried to reduce > >> this to its absolute minimum, while still getting a significant > >> benefit. > >> > >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >> > >> AUTHOR(S): > >> > >> David Goodenough, long time Java user. I can be reached at > >> david.goodenough at linkchoose.co.uk. > >> > >> OVERVIEW > >> > >> FEATURE SUMMARY: > >> > >> Lightweight Property support > >> > >> MAJOR ADVANTAGE: > >> > >> Both BeansBinding (whether JSR-295 or others such an JFace or the > >> JGoodies > >> binding) and the JPA Criteria API currently require field names (as > >> Strings) > >> as arguments, which an IDE/compiler can not check. With this > >> proposal the > >> strings would be abandoned, and the IDE/compiler will be able to > >> check the > >> correctness of the code. > >> > >> MAJOR BENEFIT: > >> > >> Manual checking no longer required. This proposal introduces a > >> simple well > >> defined IDE/compiler checkable solution. > >> > >> MAJOR DISADVANTAGE: > >> > >> It is a language change, and this seems to upset some people. > >> > >> ALTERNATIVES: > >> > >> None really, apart from using another language or continuing to use > >> String > >> names. The existing solutions all require String names which are > >> uncheckable. > >> > >> EXAMPLES > >> > >> Lets assume we have a POJO called foo, of type Foo with a field bar > >> of type > >> Bar, which itself has a field of type Jim called jim. > >> > >> There are two forms of lightweight properties:- > >> > >> 1) foo#bar would be translated by the compiler into:- > >> > >> ? ? ? new Property(foo,"bar"); > >> > >> while foo#bar#jim would be translated into:- > >> > >> ? ? ? new Property(foo,"bar","jim"); > >> > >> 2) Foo#bar would be translated into:- > >> > >> ? ? ? new Property(Foo.class,"bar"); > >> > >> while Foo#bar#jim would be translated into:- > >> > >> ? ? ? new Property(Foo.class,"bar","jim"); > >> > >> These two forms create (1) a bound Property, or (2) an unbound one. > >> Bound > >> Properties are explicitly bound to a particular instance of a class > >> (in this > >> case foo), while unbound Properties are templates which can be > >> applied to any > >> instance of class Foo. Actually bound properties can also be used as > >> unbound > >> properties, but that is a harmless and useful side effect not a > >> primary > >> intent. > >> > >> The Property class would need to be added (it is appended below), > >> and should > >> be added either to the java.beans package or to the > >> java.lang.reflect package > >> (with which is probably has more in common). > >> > >> Syntactically a "#" can be placed wherever a "." can be placed > >> (except inside > >> a number), and the same checks need to be made (that each field to > >> the right > >> of a # is a field in the left hand side) as would be made for a ".". > >> The only > >> difference is in field visibility - For the "#" any field is > >> visible, which > >> follows the model currently available in the Field class with > >> getDeclaredFields(). It also follows the model that while a field > >> might be > >> private and therefore not directly accessible from outside, getters > >> and > >> setters can provide access. > >> > >> The Property object provides type safe access to the field in the > >> form of > >> getters and setters. These come in pairs, one for bound and the > >> other for > >> unbound access. So for bound access no object is required to fetch > >> the value, > >> for an unbound object the parent object needs to be specified. So if > >> we > >> have:- > >> > >> ? ? ? Propertyprop = foo#bar; > >> > >> we can later say:- > >> > >> ? ? ? Bar b = prop.get(); > >> > >> or for an unbound one from a second Foo object foo2:- > >> > >> ? ? ? Bar b = prop.get(foo2); > >> > >> The getters and setters in the Property object will defer to > >> explicitly coded > >> getters and setters if present, otherwise they will use the Field > >> getter and > >> setter. > >> > >> If a setter is not explicitly coded, the implicit setter will look > >> for a > >> PropertyChangeSupport object in the parent object of the rightmost > >> field and > >> fire a PropertyChangeEvent to that object. > >> > >> There are also two Annotations provided by the Property class, > >> ReadOnly and > >> WriteOnly. These stop implicit getters and setters from trying to > >> read/write > >> the property. > >> > >> Talking of Annotations, this notation can also be used to get at the > >> Annotations for a field. So to test for the presence of an > >> Annotation Ann on > >> Foo.bar we would use:- > >> > >> ? ? ? if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >> > >> SIMPLE EXAMPLE: > >> > >> To take an example from BeansBinding (taken from Shannon Hickey's > >> blog):- > >> > >> ? ? ? // create a BeanProperty representing a bean's firstName > >> ? ? ? Property firstP = BeanProperty.create("firstName"); > >> ? ? ? // Bind Duke's first name to the text property of a Swing > >> JTextField BeanProperty textP = BeanProperty.create("text"); > >> ? ? ? Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstP, textfield, textP); > >> ? ? ? binding.bind(); > >> > >> > >> would instead be written:- > >> > >> ? ? ? Binding binding = Bindings.createAutoBinding(READ_WRITE, > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? duke#firstName, textfield#text); > >> ? ? ? binding.bind(); > >> > >> which of course can be checked by the IDE/compiler, and will not > >> wait until > >> run time (not even instantiation time) to show up the error. > >> > >> ADVANCED EXAMPLE: > >> > >> For a JComboBox (or JList or JTable or JTree) there is a need to map > >> a list of > >> objects to the value strings (or column contents). For this we need > >> to have > >> an unbound Property which can be applied to each element of the list. > >> > >> ? ? ? Duke duke; > >> ? ? ? Listdukes; > >> ? ? ? BoundComboBox combo = new > >> BoundComboBox(dukes,Duke#fullname,this#duke); > >> > >> and now the combo box will be populated from the list dukes, and the > >> display > >> values in the list will be taken from the fullname field of each Duke > >> element, and the initial value will be set from the local class > >> field duke > >> and any changes to the combo box selected element will be reflected > >> back to > >> the duke field. > >> > >> DETAILS > >> > >> SPECIFICATION: > >> > >> This proposal adds a new syntactic element, "#", which can be used > >> in the same > >> way that "." can be used to qualify fields within a Java object. > >> > >> COMPILATION: > >> > >> This proposal requires no change to the class files, and is > >> implemented by a > >> simple generation of the required instance using the relevant Property > >> constructor. Obviously the compiler would have to make sure that the > >> use that > >> the property object was being put to (in the examples above the left > >> hand > >> side of the assignment) had the correct Generic attributes. > >> > >> TESTING: > >> > >> How can the feature be tested? > >> > >> LIBRARY SUPPORT: > >> > >> The new Property class is required (see below). > >> > >> REFLECTIVE APIS: > >> > >> No changes are required to the reflective APIs although it makes > >> extensive use > >> of those APIs. > >> > >> OTHER CHANGES: > >> > >> No other changes are requires. > >> > >> MIGRATION: > >> > >> Fortunately there is no code that is formally part of J2SE 6 which > >> uses such > >> Properties. There are however two proposals which will need it > >> (BeansBinding > >> and JPA Criteria API), but neither of these seem to be destined to > >> be part of > >> J2SE 7 (BeansBinding seems to have died the death and the Criteria > >> API would > >> be part of the next J2EE which will follow J2SE 7), so this will > >> provide a > >> base for them to use and no existing code need to be updated. > >> > >> There are other extant Beans-Binding libraries, which could be > >> modified to use > >> this proposal, but as none of the existing features have been > >> changed there > >> is no need to change them (other than for type safety and compiler/IDE > >> checkability). > >> > >> COMPATIBILITY > >> > >> BREAKING CHANGES: > >> > >> None. ?This change should not make any existing correct code fail to > >> compile > >> or run or change the way in which it compiles/runs. > >> > >> EXISTING PROGRAMS: > >> > >> No change required to any existing programs > >> > >> REFERENCES > >> > >> EXISTING BUGS: > >> > >> None > >> > >> URL FOR PROTOTYPE (optional): > >> > >> I do not have the knowledge to make changes to the compiler, and the > >> only > >> documentation making such changes concentrated on adding operators not > >> changes at this level. So there is no prototype of the compiler > >> part, but the > >> Property class follows:- > >> > >> package java.lang.reflect; > >> > >> import java.beans.BeanInfo; > >> import java.beans.Introspector; > >> import java.beans.PropertyChangeSupport; > >> import java.beans.PropertyDescriptor; > >> import java.lang.reflect.Field; > >> import java.lang.reflect.Method; > >> > >> /** > >> * Property class > >> * This is the support class for use with the # notation to provide > >> lightweight > >> * Property support for Java. > >> * > >> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >> * @licence LPGL V2 : details of which can be found at http://fsf.org. > >> * @author david.goodenough at linkchoose.co.uk > >> * > >> * @param The Parent class for this field > >> * @param The Type of this field > >> */ > >> public class Property { > >> ? ?private C parent; > >> ? private Class parentClass; > >> ? private Field[] fields; > >> ? private PropertyDescriptor[] pd = null; > >> ? /** > >> ? ?* Constructor used to create Property objects. ?The Parent object > >> may be > >> ? ?* null, but should normally be specified as it can be overridden > >> anyway. > >> ? ?* @param parent C object that contains the field > >> ? ?* @param field Field describing this field > >> ? ?*/ > >> ? public Property(C parent, String ... fieldNames) { > >> ? ? ? this.parent = parent; > >> ? ? ? ?this(parent.getClass(), fieldNames); > >> ? ? ? ?} > >> ? ?/** > >> ? ? * Constructor for unbound Properties, but also used internally > >> after > >> setting > >> ? ? * the parent object by the bound Property objects. > >> ? ? * @param parentClass Class of the parent object > >> ? ? * @param fieldNames String[] of field names > >> ? ? */ > >> ? ?public Property(ClassparentClass, String .. fieldNames) { > >> ? ? ? ?this.parentClass = parentClass; > >> ? ? ? fields = new Field[fieldNames.length]; > >> ? ? ? pd = new PropertyDescriptor[fieldNames.length]; > >> outer: ?for(int index = 0; index < fields.length; index++) { > >> ? ? ? ? ? Field[]dclFields = parentClass.getDeclaredFields(); > >> ? ? ? ? ? ? ? ? ? for(Field field:dclFields) { > >> ? ? ? ? ? ? ? ? ? ? ? if(field.getName().equals(fieldNames[index])) { > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fields[index] = field; > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? field.setAccessible(true); > >> ? ? ? ? ? ? ? ? ? ? ? try { > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BeanInfo beanInfo = > >> Introspector.getBeanInfo(parent.getClass()); > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PropertyDescriptor[]props = > >> beanInfo.getPropertyDescriptors(); > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? for(PropertyDescriptor prop : props) { > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > >> if(prop.getName().equals(field.getName())) { pd[index] = prop; break; > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } catch(Exception e) { /* assume can not > >> find getter/ setter > >> */ } > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? parentClass = field.getType(); > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? continue outer; > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } > >> ? ? ? ? ? ? ? ? ? ? ? } > >> ? ? ? throw new IllegalArgumentException("Field " + fieldNames[index] + > >> ? ? ? ? ? ? ? ? ? ? ? ? ? " not found in class " + > >> parentClass.getCanonicalName()); > >> ? ? ? ? ? ? ? } > >> ? ? ? } > >> ? /** > >> ? ?* Getter from the field in the parent specified when this > >> Property was > >> created. > >> ? ?* @see Property.get(C otherParent) > >> ? ?* @return F the value of this field > >> ? ?*/ > >> ? public F get() { > >> ? ? ? return get(parent); > >> ? ? ? } > >> ? /** > >> ? ?* Getter with explicit parent. > >> ? ?* This code will check see if this field is WriteOnly, and > >> complain if it > >> is. > >> ? ?* It will then see if the use has provided am explicit getter, > >> and call > >> that > >> ? ?* if present, otherwise it will just fetch the value through the > >> Field > >> provided > >> ? ?* method. > >> ? ?* @param otherParent C parent object > >> ? ?* @return F value of the field > >> ? ?*/ > >> ? @SuppressWarnings("unchecked") // This should actually not be > >> needed, > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// but the Field.get method is not > >> typed > >> ? public F get(C otherParent) { > >> ? ? ? Object result = otherParent; > >> ? ? ? try { > >> ? ? ? ? ? for(int index = 0; index < fields.length; index++) { > >> > >> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >> ? ? ? ? ? ? ? ? ? throw new IllegalAccessException( > >> ? ? ? ? ? ? ? ? ? ? ? "Can not get from a WriteOnly field - " + > >> fields[index].getName()); > >> ? ? ? ? ? ? ? Method getter = pd[index] == null ? null : > >> pd[index].getReadMethod(); > >> ? ? ? ? ? ? ? if(getter == null) result = fields[index].get(result); > >> ? ? ? ? ? ? ? ? ? else result = getter.invoke(result); > >> ? ? ? ? ? ? ? } > >> ? ? ? ? ? } catch(Exception e) { > >> ? ? ? ? ? ? ? throw new RuntimeException("Should not occur exception", > >> e); } > >> ? ? ? return (F)result; > >> ? ? ? } > >> ? /** > >> ? ?* Setter to set the value of the field in the parent object > >> declared with > >> the > >> ? ?* Property object > >> ? ?* @param newValue F new value of this field > >> ? ?*/ > >> ? public void set(F newValue) { > >> ? ? ? set(parent,newValue); > >> ? ? ? } > >> ? /** > >> ? ?* Setter to set the value of the field to an explicit parent > >> object. > >> ? ?* If there is a ReadOnly annotation, then we object. ?If there is > >> an > >> explicit > >> ? ?* setter then we use that, otherwise we set the field using the > >> Field > >> provided > >> ? ?* set method and if there is a PropertyChangeSupport field, fire a > >> property > >> ? ?* change event to it. > >> ? ?* We walk our way down the field chain, until we have the last > >> object and > >> its > >> ? ?* field, and then we do the set. > >> ? ?* @param parent C explicit parent object > >> ? ?* @param newValue F new value for field in parent > >> ? ?*/ > >> ? public void set(C parent,F newValue) { > >> ? ? ? try { > >> ? ? ? ? ? Object last = parent; > >> ? ? ? ? ? int index; > >> ? ? ? ? ? for(index = 0; index < fields.length - 1; index++) { > >> > >> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >> ? ? ? ? ? ? ? ? ? throw new IllegalAccessException( > >> ? ? ? ? ? ? ? ? ? ? ? "Can not get from a WriteOnly field - " + > >> ? ? ? ? ? ? ? ? ? ? ? fields[index].getName()); > >> ? ? ? ? ? ? ? Method getter = pd[index] == null ? null : > >> pd[index].getReadMethod(); > >> ? ? ? ? ? ? ? if(getter == null) last = fields[index].get(last); > >> ? ? ? ? ? ? ? else last = getter.invoke(last); > >> ? ? ? ? ? ? ? } > >> > >> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >> ? ? ? ? ? ? ? throw new IllegalAccessException( > >> ? ? ? ? ? ? ? ? ? "Can not get from a WriteOnly field - " + > >> fields[index].getName()); > >> ? ? ? ? ? ? ? Method setter = pd[index] == null ? null : > >> pd[index].getWriteMethod(); > >> ? ? ? ? ? ? ? if(setter == null) { > >> ? ? ? ? ? ? ? ? ? PropertyChangeSupport pcs = findPcs(last.getClass()); > >> ? ? ? ? ? ? ? ? ? fields[index].set(last,newValue); > >> ? ? ? ? ? ? ? if(pcs != null) > >> pcs.firePropertyChange(fields[index].getName(), > >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? newValue, > >> > >> fields[index].get(last)); > >> ? ? ? ? ? ? ? } else setter.invoke(last,newValue); > >> ? ? ? ? ? } catch(Exception e) { > >> ? ? ? ? ? ? ? throw new RuntimeException("Should not occur > >> exception", e); > >> ? ? ? ? ? ? ? } > >> ? ? ? } > >> ? /** > >> ? ?* This is used so that the caller can view the Field name > >> ? ?* @return String field name > >> ? ?*/ > >> ? public String[] getFieldName() { > >> ? ? ? String[]names = new String[fields.length]; > >> ? ? ? for(int index = 0; index < fields.length; index++) { > >> ? ? ? ? ? names[index] = fields[index].getName(); > >> ? ? ? ? ? } > >> ? ? ? return names; > >> ? ? ? } > >> ? ?/** > >> ? ? * This method is used to fetch the Field array, which is useful > >> if you > >> need to > >> ? ? * access the Annotations of a field. > >> ? ? * @return Field[] the array of Fields describing this Property. > >> ? ? */ > >> ? ?public Field[] getFields() { > >> ? ? ? ?return fields; > >> ? ? ? ?} > >> ? /** > >> ? ?* This private method looks for a PropertyChangeSupport object in > >> the > >> class and > >> ? ?* if one is found it will return it. ?It looks right the way up > >> the class > >> tree > >> ? ?* by recurring up the superClasses. > >> ? ?* @param parent Class to check for PropertyChangeSupport fields > >> ? ?* @return PropertyChangeSupport first found object, or null if > >> not found > >> ? ?*/ > >> ? private PropertyChangeSupport findPcs(Class parent) { > >> ? ? ? Field fields[] = parent.getDeclaredFields(); > >> ? ? ? for(Field field:fields) { > >> ? ? ? ? ? field.setAccessible(true); > >> ? ? ? ? ? try { > >> ? ? ? ? ? ? ? if(field.getType() == PropertyChangeSupport.class) > >> ? ? ? ? ? ? ? ? ? return (PropertyChangeSupport)field.get(parent); > >> ? ? ? ? ? ? ? } catch(Exception e) { } > >> ? ? ? ? ? } > >> ? ? ? // If we did not find it then try the superclass > >> ? ? ? ClasssuperClass = parent.getSuperclass(); > >> ? ? ? if(superClass == null) return null; > >> ? ? ? return findPcs(parent.getClass().getSuperclass()); > >> ? ? ? } > >> ? /** > >> ? ?* This annotation is used to mark a field as WriteOnly, i.e. it > >> can not > >> be read. > >> ? ?* This stops the automatic getter operation. > >> ? ?*/ > >> ? public @interface WriteOnly { > >> ? ? ? } > >> ? /** > >> ? ?* This annotation is used to mark a field as ReadOnly, i.e. it > >> can not be > >> written. > >> ? ?* This stops the automatic setter operation. > >> ? ?*/ > >> ? public @interface ReadOnly { > >> ? ? ? } > >> ? } From david.goodenough at linkchoose.co.uk Tue Mar 3 13:04:58 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 3 Mar 2009 21:04:58 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> Message-ID: <200903032104.58445.david.goodenough@linkchoose.co.uk> Yes I do. What you propose is much more invasive. Look at it again and maybe you will see the Light(ness). David On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > You call that lightweight? > > How about following the beans spec more to the letter and just > generate the addPropertyChangeListener, removePropertyChangeListener, > setX(), and get/isX() method in response to seeing a keyword or > annotation on a given field. You'll have to work out the details, but > that sounds far, far simpler to understand. > > You'll need to flesh this out, but it would look something like: > > public class Foo { > private property int x; > } > > Which would generate the addPropertyChangeListener, > removePropertyChangeListener, setX, getX methods, all public, along > with the required infrastructure to make it tick. If you don't like > the generation, for example because you want the setter to be package > private, you just add the setter in the source file; the keyword will > only generate the missing stuff. It doesn't cover every use case, but > there's always the alternative of doing whatever people do now with > beans. Something you didn't mention in your proposal, by the way. > > I think there's also a fully fleshed out property proposal (including > a 'property' keyword) out there somewhere. > > Possibly make a way to opt out of generating the property change > listener support, and just the getters/setters. > --Reinier Zwitserloot > > On Mar 3, 2009, at 15:59, David Goodenough wrote: > > Below is my proposal for Lightweight Properties. I know that the > > syntax > > change is an abbomination to some people, but I have tried to reduce > > this to its absolute minimum, while still getting a significant > > benefit. > > > > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > > > AUTHOR(S): > > > > David Goodenough, long time Java user. I can be reached at > > david.goodenough at linkchoose.co.uk. > > > > OVERVIEW > > > > FEATURE SUMMARY: > > > > Lightweight Property support > > > > MAJOR ADVANTAGE: > > > > Both BeansBinding (whether JSR-295 or others such an JFace or the > > JGoodies > > binding) and the JPA Criteria API currently require field names (as > > Strings) > > as arguments, which an IDE/compiler can not check. With this > > proposal the > > strings would be abandoned, and the IDE/compiler will be able to > > check the > > correctness of the code. > > > > MAJOR BENEFIT: > > > > Manual checking no longer required. This proposal introduces a > > simple well > > defined IDE/compiler checkable solution. > > > > MAJOR DISADVANTAGE: > > > > It is a language change, and this seems to upset some people. > > > > ALTERNATIVES: > > > > None really, apart from using another language or continuing to use > > String > > names. The existing solutions all require String names which are > > uncheckable. > > > > EXAMPLES > > > > Lets assume we have a POJO called foo, of type Foo with a field bar > > of type > > Bar, which itself has a field of type Jim called jim. > > > > There are two forms of lightweight properties:- > > > > 1) foo#bar would be translated by the compiler into:- > > > > new Property(foo,"bar"); > > > > while foo#bar#jim would be translated into:- > > > > new Property(foo,"bar","jim"); > > > > 2) Foo#bar would be translated into:- > > > > new Property(Foo.class,"bar"); > > > > while Foo#bar#jim would be translated into:- > > > > new Property(Foo.class,"bar","jim"); > > > > These two forms create (1) a bound Property, or (2) an unbound one. > > Bound > > Properties are explicitly bound to a particular instance of a class > > (in this > > case foo), while unbound Properties are templates which can be > > applied to any > > instance of class Foo. Actually bound properties can also be used as > > unbound > > properties, but that is a harmless and useful side effect not a > > primary > > intent. > > > > The Property class would need to be added (it is appended below), > > and should > > be added either to the java.beans package or to the > > java.lang.reflect package > > (with which is probably has more in common). > > > > Syntactically a "#" can be placed wherever a "." can be placed > > (except inside > > a number), and the same checks need to be made (that each field to > > the right > > of a # is a field in the left hand side) as would be made for a ".". > > The only > > difference is in field visibility - For the "#" any field is > > visible, which > > follows the model currently available in the Field class with > > getDeclaredFields(). It also follows the model that while a field > > might be > > private and therefore not directly accessible from outside, getters > > and > > setters can provide access. > > > > The Property object provides type safe access to the field in the > > form of > > getters and setters. These come in pairs, one for bound and the > > other for > > unbound access. So for bound access no object is required to fetch > > the value, > > for an unbound object the parent object needs to be specified. So if > > we > > have:- > > > > Propertyprop = foo#bar; > > > > we can later say:- > > > > Bar b = prop.get(); > > > > or for an unbound one from a second Foo object foo2:- > > > > Bar b = prop.get(foo2); > > > > The getters and setters in the Property object will defer to > > explicitly coded > > getters and setters if present, otherwise they will use the Field > > getter and > > setter. > > > > If a setter is not explicitly coded, the implicit setter will look > > for a > > PropertyChangeSupport object in the parent object of the rightmost > > field and > > fire a PropertyChangeEvent to that object. > > > > There are also two Annotations provided by the Property class, > > ReadOnly and > > WriteOnly. These stop implicit getters and setters from trying to > > read/write > > the property. > > > > Talking of Annotations, this notation can also be used to get at the > > Annotations for a field. So to test for the presence of an > > Annotation Ann on > > Foo.bar we would use:- > > > > if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > > > > SIMPLE EXAMPLE: > > > > To take an example from BeansBinding (taken from Shannon Hickey's > > blog):- > > > > // create a BeanProperty representing a bean's firstName > > Property firstP = BeanProperty.create("firstName"); > > // Bind Duke's first name to the text property of a Swing JTextField > > BeanProperty textP = BeanProperty.create("text"); > > Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > > firstP, textfield, textP); > > binding.bind(); > > > > > > would instead be written:- > > > > Binding binding = Bindings.createAutoBinding(READ_WRITE, > > duke#firstName, textfield#text); > > binding.bind(); > > > > which of course can be checked by the IDE/compiler, and will not > > wait until > > run time (not even instantiation time) to show up the error. > > > > ADVANCED EXAMPLE: > > > > For a JComboBox (or JList or JTable or JTree) there is a need to map > > a list of > > objects to the value strings (or column contents). For this we need > > to have > > an unbound Property which can be applied to each element of the list. > > > > Duke duke; > > Listdukes; > > BoundComboBox combo = new > > BoundComboBox(dukes,Duke#fullname,this#duke); > > > > and now the combo box will be populated from the list dukes, and the > > display > > values in the list will be taken from the fullname field of each Duke > > element, and the initial value will be set from the local class > > field duke > > and any changes to the combo box selected element will be reflected > > back to > > the duke field. > > > > DETAILS > > > > SPECIFICATION: > > > > This proposal adds a new syntactic element, "#", which can be used > > in the same > > way that "." can be used to qualify fields within a Java object. > > > > COMPILATION: > > > > This proposal requires no change to the class files, and is > > implemented by a > > simple generation of the required instance using the relevant Property > > constructor. Obviously the compiler would have to make sure that the > > use that > > the property object was being put to (in the examples above the left > > hand > > side of the assignment) had the correct Generic attributes. > > > > TESTING: > > > > How can the feature be tested? > > > > LIBRARY SUPPORT: > > > > The new Property class is required (see below). > > > > REFLECTIVE APIS: > > > > No changes are required to the reflective APIs although it makes > > extensive use > > of those APIs. > > > > OTHER CHANGES: > > > > No other changes are requires. > > > > MIGRATION: > > > > Fortunately there is no code that is formally part of J2SE 6 which > > uses such > > Properties. There are however two proposals which will need it > > (BeansBinding > > and JPA Criteria API), but neither of these seem to be destined to > > be part of > > J2SE 7 (BeansBinding seems to have died the death and the Criteria > > API would > > be part of the next J2EE which will follow J2SE 7), so this will > > provide a > > base for them to use and no existing code need to be updated. > > > > There are other extant Beans-Binding libraries, which could be > > modified to use > > this proposal, but as none of the existing features have been > > changed there > > is no need to change them (other than for type safety and compiler/IDE > > checkability). > > > > COMPATIBILITY > > > > BREAKING CHANGES: > > > > None. This change should not make any existing correct code fail to > > compile > > or run or change the way in which it compiles/runs. > > > > EXISTING PROGRAMS: > > > > No change required to any existing programs > > > > REFERENCES > > > > EXISTING BUGS: > > > > None > > > > URL FOR PROTOTYPE (optional): > > > > I do not have the knowledge to make changes to the compiler, and the > > only > > documentation making such changes concentrated on adding operators not > > changes at this level. So there is no prototype of the compiler > > part, but the > > Property class follows:- > > > > package java.lang.reflect; > > > > import java.beans.BeanInfo; > > import java.beans.Introspector; > > import java.beans.PropertyChangeSupport; > > import java.beans.PropertyDescriptor; > > import java.lang.reflect.Field; > > import java.lang.reflect.Method; > > > > /** > > * Property class > > * This is the support class for use with the # notation to provide > > lightweight > > * Property support for Java. > > * > > * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > > * @licence LPGL V2 : details of which can be found at http://fsf.org. > > * @author david.goodenough at linkchoose.co.uk > > * > > * @param The Parent class for this field > > * @param The Type of this field > > */ > > public class Property { > > private C parent; > > private Class parentClass; > > private Field[] fields; > > private PropertyDescriptor[] pd = null; > > /** > > * Constructor used to create Property objects. The Parent object > > may be > > * null, but should normally be specified as it can be overridden > > anyway. > > * @param parent C object that contains the field > > * @param field Field describing this field > > */ > > public Property(C parent, String ... fieldNames) { > > this.parent = parent; > > this(parent.getClass(), fieldNames); > > } > > /** > > * Constructor for unbound Properties, but also used internally > > after > > setting > > * the parent object by the bound Property objects. > > * @param parentClass Class of the parent object > > * @param fieldNames String[] of field names > > */ > > public Property(ClassparentClass, String .. fieldNames) { > > this.parentClass = parentClass; > > fields = new Field[fieldNames.length]; > > pd = new PropertyDescriptor[fieldNames.length]; > > outer: for(int index = 0; index < fields.length; index++) { > > Field[]dclFields = parentClass.getDeclaredFields(); > > for(Field field:dclFields) { > > if(field.getName().equals(fieldNames[index])) { > > fields[index] = field; > > field.setAccessible(true); > > try { > > BeanInfo beanInfo = > > Introspector.getBeanInfo(parent.getClass()); > > PropertyDescriptor[]props = > > beanInfo.getPropertyDescriptors(); > > for(PropertyDescriptor prop : props) { > > if(prop.getName().equals(field.getName())) { > > pd[index] = prop; > > break; > > } > > } > > } catch(Exception e) { /* assume can not find getter/ > > setter > > */ } > > parentClass = field.getType(); > > continue outer; > > } > > } > > throw new IllegalArgumentException("Field " + fieldNames[index] + > > " not found in class " + > > parentClass.getCanonicalName()); > > } > > } > > /** > > * Getter from the field in the parent specified when this > > Property was > > created. > > * @see Property.get(C otherParent) > > * @return F the value of this field > > */ > > public F get() { > > return get(parent); > > } > > /** > > * Getter with explicit parent. > > * This code will check see if this field is WriteOnly, and > > complain if it > > is. > > * It will then see if the use has provided am explicit getter, > > and call > > that > > * if present, otherwise it will just fetch the value through the > > Field > > provided > > * method. > > * @param otherParent C parent object > > * @return F value of the field > > */ > > @SuppressWarnings("unchecked") // This should actually not be > > needed, > > // but the Field.get method is not > > typed > > public F get(C otherParent) { > > Object result = otherParent; > > try { > > for(int index = 0; index < fields.length; index++) { > > > > if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > > throw new IllegalAccessException( > > "Can not get from a WriteOnly field - " + > > fields[index].getName()); > > Method getter = pd[index] == null ? null : > > pd[index].getReadMethod(); > > if(getter == null) result = fields[index].get(result); > > else result = getter.invoke(result); > > } > > } catch(Exception e) { > > throw new RuntimeException("Should not occur exception", e); > > } > > return (F)result; > > } > > /** > > * Setter to set the value of the field in the parent object > > declared with > > the > > * Property object > > * @param newValue F new value of this field > > */ > > public void set(F newValue) { > > set(parent,newValue); > > } > > /** > > * Setter to set the value of the field to an explicit parent > > object. > > * If there is a ReadOnly annotation, then we object. If there is > > an > > explicit > > * setter then we use that, otherwise we set the field using the > > Field > > provided > > * set method and if there is a PropertyChangeSupport field, fire a > > property > > * change event to it. > > * We walk our way down the field chain, until we have the last > > object and > > its > > * field, and then we do the set. > > * @param parent C explicit parent object > > * @param newValue F new value for field in parent > > */ > > public void set(C parent,F newValue) { > > try { > > Object last = parent; > > int index; > > for(index = 0; index < fields.length - 1; index++) { > > > > if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > > throw new IllegalAccessException( > > "Can not get from a WriteOnly field - " + > > fields[index].getName()); > > Method getter = pd[index] == null ? null : > > pd[index].getReadMethod(); > > if(getter == null) last = fields[index].get(last); > > else last = getter.invoke(last); > > } > > > > if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > > throw new IllegalAccessException( > > "Can not get from a WriteOnly field - " + > > fields[index].getName()); > > Method setter = pd[index] == null ? null : > > pd[index].getWriteMethod(); > > if(setter == null) { > > PropertyChangeSupport pcs = findPcs(last.getClass()); > > fields[index].set(last,newValue); > > if(pcs != null) > > pcs.firePropertyChange(fields[index].getName(), > > newValue, > > > > fields[index].get(last)); > > } else setter.invoke(last,newValue); > > } catch(Exception e) { > > throw new RuntimeException("Should not occur > > exception", e); > > } > > } > > /** > > * This is used so that the caller can view the Field name > > * @return String field name > > */ > > public String[] getFieldName() { > > String[]names = new String[fields.length]; > > for(int index = 0; index < fields.length; index++) { > > names[index] = fields[index].getName(); > > } > > return names; > > } > > /** > > * This method is used to fetch the Field array, which is useful > > if you > > need to > > * access the Annotations of a field. > > * @return Field[] the array of Fields describing this Property. > > */ > > public Field[] getFields() { > > return fields; > > } > > /** > > * This private method looks for a PropertyChangeSupport object in > > the > > class and > > * if one is found it will return it. It looks right the way up > > the class > > tree > > * by recurring up the superClasses. > > * @param parent Class to check for PropertyChangeSupport fields > > * @return PropertyChangeSupport first found object, or null if > > not found > > */ > > private PropertyChangeSupport findPcs(Class parent) { > > Field fields[] = parent.getDeclaredFields(); > > for(Field field:fields) { > > field.setAccessible(true); > > try { > > if(field.getType() == PropertyChangeSupport.class) > > return (PropertyChangeSupport)field.get(parent); > > } catch(Exception e) { } > > } > > // If we did not find it then try the superclass > > ClasssuperClass = parent.getSuperclass(); > > if(superClass == null) return null; > > return findPcs(parent.getClass().getSuperclass()); > > } > > /** > > * This annotation is used to mark a field as WriteOnly, i.e. it > > can not > > be read. > > * This stops the automatic getter operation. > > */ > > public @interface WriteOnly { > > } > > /** > > * This annotation is used to mark a field as ReadOnly, i.e. it > > can not be > > written. > > * This stops the automatic setter operation. > > */ > > public @interface ReadOnly { > > } > > } From reinier at zwitserloot.com Tue Mar 3 13:15:48 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 3 Mar 2009 22:15:48 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903032104.58445.david.goodenough@linkchoose.co.uk> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> <200903032104.58445.david.goodenough@linkchoose.co.uk> Message-ID: <974754BA-9815-4C98-B868-3D793AFEF79A@zwitserloot.com> The language change required for your proposal is indeed lighter, but to understand it, it is seems a lot more complicated. Also, it would be infeasible to introduce a 'lightweight' (according to anyone's definition) proposal now that is lacking in certain aspects, and then fix it later, unless that fix is syntactically very similar and backwards- and migration compatible. That's the major beef I have with this proposal: It effectively shuts the door on any other property proposal. In my view, a proposal solves the problem properly, or shouldn't be added at all; no quick hacky fixes that aren't part of a planned evolution path to a complete solution. If you can highlight how a complete properties proposal will seamlessly work with your syntax, I'm more inclined to like it. --Reinier Zwitserloot On Mar 3, 2009, at 22:04, David Goodenough wrote: > Yes I do. What you propose is much more invasive. Look at it > again and maybe you will see the Light(ness). > > David > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: >> You call that lightweight? >> >> How about following the beans spec more to the letter and just >> generate the addPropertyChangeListener, removePropertyChangeListener, >> setX(), and get/isX() method in response to seeing a keyword or >> annotation on a given field. You'll have to work out the details, but >> that sounds far, far simpler to understand. >> >> You'll need to flesh this out, but it would look something like: >> >> public class Foo { >> private property int x; >> } >> >> Which would generate the addPropertyChangeListener, >> removePropertyChangeListener, setX, getX methods, all public, along >> with the required infrastructure to make it tick. If you don't like >> the generation, for example because you want the setter to be package >> private, you just add the setter in the source file; the keyword will >> only generate the missing stuff. It doesn't cover every use case, but >> there's always the alternative of doing whatever people do now with >> beans. Something you didn't mention in your proposal, by the way. >> >> I think there's also a fully fleshed out property proposal (including >> a 'property' keyword) out there somewhere. >> >> Possibly make a way to opt out of generating the property change >> listener support, and just the getters/setters. >> --Reinier Zwitserloot >> >> On Mar 3, 2009, at 15:59, David Goodenough wrote: >>> Below is my proposal for Lightweight Properties. I know that the >>> syntax >>> change is an abbomination to some people, but I have tried to reduce >>> this to its absolute minimum, while still getting a significant >>> benefit. >>> >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>> >>> AUTHOR(S): >>> >>> David Goodenough, long time Java user. I can be reached at >>> david.goodenough at linkchoose.co.uk. >>> >>> OVERVIEW >>> >>> FEATURE SUMMARY: >>> >>> Lightweight Property support >>> >>> MAJOR ADVANTAGE: >>> >>> Both BeansBinding (whether JSR-295 or others such an JFace or the >>> JGoodies >>> binding) and the JPA Criteria API currently require field names (as >>> Strings) >>> as arguments, which an IDE/compiler can not check. With this >>> proposal the >>> strings would be abandoned, and the IDE/compiler will be able to >>> check the >>> correctness of the code. >>> >>> MAJOR BENEFIT: >>> >>> Manual checking no longer required. This proposal introduces a >>> simple well >>> defined IDE/compiler checkable solution. >>> >>> MAJOR DISADVANTAGE: >>> >>> It is a language change, and this seems to upset some people. >>> >>> ALTERNATIVES: >>> >>> None really, apart from using another language or continuing to use >>> String >>> names. The existing solutions all require String names which are >>> uncheckable. >>> >>> EXAMPLES >>> >>> Lets assume we have a POJO called foo, of type Foo with a field bar >>> of type >>> Bar, which itself has a field of type Jim called jim. >>> >>> There are two forms of lightweight properties:- >>> >>> 1) foo#bar would be translated by the compiler into:- >>> >>> new Property(foo,"bar"); >>> >>> while foo#bar#jim would be translated into:- >>> >>> new Property(foo,"bar","jim"); >>> >>> 2) Foo#bar would be translated into:- >>> >>> new Property(Foo.class,"bar"); >>> >>> while Foo#bar#jim would be translated into:- >>> >>> new Property(Foo.class,"bar","jim"); >>> >>> These two forms create (1) a bound Property, or (2) an unbound one. >>> Bound >>> Properties are explicitly bound to a particular instance of a class >>> (in this >>> case foo), while unbound Properties are templates which can be >>> applied to any >>> instance of class Foo. Actually bound properties can also be used as >>> unbound >>> properties, but that is a harmless and useful side effect not a >>> primary >>> intent. >>> >>> The Property class would need to be added (it is appended below), >>> and should >>> be added either to the java.beans package or to the >>> java.lang.reflect package >>> (with which is probably has more in common). >>> >>> Syntactically a "#" can be placed wherever a "." can be placed >>> (except inside >>> a number), and the same checks need to be made (that each field to >>> the right >>> of a # is a field in the left hand side) as would be made for a ".". >>> The only >>> difference is in field visibility - For the "#" any field is >>> visible, which >>> follows the model currently available in the Field class with >>> getDeclaredFields(). It also follows the model that while a field >>> might be >>> private and therefore not directly accessible from outside, getters >>> and >>> setters can provide access. >>> >>> The Property object provides type safe access to the field in the >>> form of >>> getters and setters. These come in pairs, one for bound and the >>> other for >>> unbound access. So for bound access no object is required to fetch >>> the value, >>> for an unbound object the parent object needs to be specified. So if >>> we >>> have:- >>> >>> Propertyprop = foo#bar; >>> >>> we can later say:- >>> >>> Bar b = prop.get(); >>> >>> or for an unbound one from a second Foo object foo2:- >>> >>> Bar b = prop.get(foo2); >>> >>> The getters and setters in the Property object will defer to >>> explicitly coded >>> getters and setters if present, otherwise they will use the Field >>> getter and >>> setter. >>> >>> If a setter is not explicitly coded, the implicit setter will look >>> for a >>> PropertyChangeSupport object in the parent object of the rightmost >>> field and >>> fire a PropertyChangeEvent to that object. >>> >>> There are also two Annotations provided by the Property class, >>> ReadOnly and >>> WriteOnly. These stop implicit getters and setters from trying to >>> read/write >>> the property. >>> >>> Talking of Annotations, this notation can also be used to get at the >>> Annotations for a field. So to test for the presence of an >>> Annotation Ann on >>> Foo.bar we would use:- >>> >>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... >>> >>> SIMPLE EXAMPLE: >>> >>> To take an example from BeansBinding (taken from Shannon Hickey's >>> blog):- >>> >>> // create a BeanProperty representing a bean's firstName >>> Property firstP = BeanProperty.create("firstName"); >>> // Bind Duke's first name to the text property of a Swing >>> JTextField >>> BeanProperty textP = BeanProperty.create("text"); >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, >>> firstP, textfield, textP); >>> binding.bind(); >>> >>> >>> would instead be written:- >>> >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, >>> duke#firstName, textfield#text); >>> binding.bind(); >>> >>> which of course can be checked by the IDE/compiler, and will not >>> wait until >>> run time (not even instantiation time) to show up the error. >>> >>> ADVANCED EXAMPLE: >>> >>> For a JComboBox (or JList or JTable or JTree) there is a need to map >>> a list of >>> objects to the value strings (or column contents). For this we need >>> to have >>> an unbound Property which can be applied to each element of the >>> list. >>> >>> Duke duke; >>> Listdukes; >>> BoundComboBox combo = new >>> BoundComboBox(dukes,Duke#fullname,this#duke); >>> >>> and now the combo box will be populated from the list dukes, and the >>> display >>> values in the list will be taken from the fullname field of each >>> Duke >>> element, and the initial value will be set from the local class >>> field duke >>> and any changes to the combo box selected element will be reflected >>> back to >>> the duke field. >>> >>> DETAILS >>> >>> SPECIFICATION: >>> >>> This proposal adds a new syntactic element, "#", which can be used >>> in the same >>> way that "." can be used to qualify fields within a Java object. >>> >>> COMPILATION: >>> >>> This proposal requires no change to the class files, and is >>> implemented by a >>> simple generation of the required instance using the relevant >>> Property >>> constructor. Obviously the compiler would have to make sure that the >>> use that >>> the property object was being put to (in the examples above the left >>> hand >>> side of the assignment) had the correct Generic attributes. >>> >>> TESTING: >>> >>> How can the feature be tested? >>> >>> LIBRARY SUPPORT: >>> >>> The new Property class is required (see below). >>> >>> REFLECTIVE APIS: >>> >>> No changes are required to the reflective APIs although it makes >>> extensive use >>> of those APIs. >>> >>> OTHER CHANGES: >>> >>> No other changes are requires. >>> >>> MIGRATION: >>> >>> Fortunately there is no code that is formally part of J2SE 6 which >>> uses such >>> Properties. There are however two proposals which will need it >>> (BeansBinding >>> and JPA Criteria API), but neither of these seem to be destined to >>> be part of >>> J2SE 7 (BeansBinding seems to have died the death and the Criteria >>> API would >>> be part of the next J2EE which will follow J2SE 7), so this will >>> provide a >>> base for them to use and no existing code need to be updated. >>> >>> There are other extant Beans-Binding libraries, which could be >>> modified to use >>> this proposal, but as none of the existing features have been >>> changed there >>> is no need to change them (other than for type safety and compiler/ >>> IDE >>> checkability). >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: >>> >>> None. This change should not make any existing correct code fail to >>> compile >>> or run or change the way in which it compiles/runs. >>> >>> EXISTING PROGRAMS: >>> >>> No change required to any existing programs >>> >>> REFERENCES >>> >>> EXISTING BUGS: >>> >>> None >>> >>> URL FOR PROTOTYPE (optional): >>> >>> I do not have the knowledge to make changes to the compiler, and the >>> only >>> documentation making such changes concentrated on adding operators >>> not >>> changes at this level. So there is no prototype of the compiler >>> part, but the >>> Property class follows:- >>> >>> package java.lang.reflect; >>> >>> import java.beans.BeanInfo; >>> import java.beans.Introspector; >>> import java.beans.PropertyChangeSupport; >>> import java.beans.PropertyDescriptor; >>> import java.lang.reflect.Field; >>> import java.lang.reflect.Method; >>> >>> /** >>> * Property class >>> * This is the support class for use with the # notation to provide >>> lightweight >>> * Property support for Java. >>> * >>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd >>> * @licence LPGL V2 : details of which can be found at http:// >>> fsf.org. >>> * @author david.goodenough at linkchoose.co.uk >>> * >>> * @param The Parent class for this field >>> * @param The Type of this field >>> */ >>> public class Property { >>> private C parent; >>> private Class parentClass; >>> private Field[] fields; >>> private PropertyDescriptor[] pd = null; >>> /** >>> * Constructor used to create Property objects. The Parent object >>> may be >>> * null, but should normally be specified as it can be overridden >>> anyway. >>> * @param parent C object that contains the field >>> * @param field Field describing this field >>> */ >>> public Property(C parent, String ... fieldNames) { >>> this.parent = parent; >>> this(parent.getClass(), fieldNames); >>> } >>> /** >>> * Constructor for unbound Properties, but also used internally >>> after >>> setting >>> * the parent object by the bound Property objects. >>> * @param parentClass Class of the parent object >>> * @param fieldNames String[] of field names >>> */ >>> public Property(ClassparentClass, String .. fieldNames) { >>> this.parentClass = parentClass; >>> fields = new Field[fieldNames.length]; >>> pd = new PropertyDescriptor[fieldNames.length]; >>> outer: for(int index = 0; index < fields.length; index++) { >>> Field[]dclFields = parentClass.getDeclaredFields(); >>> for(Field field:dclFields) { >>> if(field.getName().equals(fieldNames[index])) { >>> fields[index] = field; >>> field.setAccessible(true); >>> try { >>> BeanInfo beanInfo = >>> Introspector.getBeanInfo(parent.getClass()); >>> PropertyDescriptor[]props = >>> beanInfo.getPropertyDescriptors(); >>> for(PropertyDescriptor prop : props) { >>> if(prop.getName().equals(field.getName())) { >>> pd[index] = prop; >>> break; >>> } >>> } >>> } catch(Exception e) { /* assume can not find getter/ >>> setter >>> */ } >>> parentClass = field.getType(); >>> continue outer; >>> } >>> } >>> throw new IllegalArgumentException("Field " + fieldNames[index] + >>> " not found in class " + >>> parentClass.getCanonicalName()); >>> } >>> } >>> /** >>> * Getter from the field in the parent specified when this >>> Property was >>> created. >>> * @see Property.get(C otherParent) >>> * @return F the value of this field >>> */ >>> public F get() { >>> return get(parent); >>> } >>> /** >>> * Getter with explicit parent. >>> * This code will check see if this field is WriteOnly, and >>> complain if it >>> is. >>> * It will then see if the use has provided am explicit getter, >>> and call >>> that >>> * if present, otherwise it will just fetch the value through the >>> Field >>> provided >>> * method. >>> * @param otherParent C parent object >>> * @return F value of the field >>> */ >>> @SuppressWarnings("unchecked") // This should actually not be >>> needed, >>> // but the Field.get method is not >>> typed >>> public F get(C otherParent) { >>> Object result = otherParent; >>> try { >>> for(int index = 0; index < fields.length; index++) { >>> >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >>> throw new IllegalAccessException( >>> "Can not get from a WriteOnly field - " + >>> fields[index].getName()); >>> Method getter = pd[index] == null ? null : >>> pd[index].getReadMethod(); >>> if(getter == null) result = fields[index].get(result); >>> else result = getter.invoke(result); >>> } >>> } catch(Exception e) { >>> throw new RuntimeException("Should not occur exception", e); >>> } >>> return (F)result; >>> } >>> /** >>> * Setter to set the value of the field in the parent object >>> declared with >>> the >>> * Property object >>> * @param newValue F new value of this field >>> */ >>> public void set(F newValue) { >>> set(parent,newValue); >>> } >>> /** >>> * Setter to set the value of the field to an explicit parent >>> object. >>> * If there is a ReadOnly annotation, then we object. If there is >>> an >>> explicit >>> * setter then we use that, otherwise we set the field using the >>> Field >>> provided >>> * set method and if there is a PropertyChangeSupport field, fire a >>> property >>> * change event to it. >>> * We walk our way down the field chain, until we have the last >>> object and >>> its >>> * field, and then we do the set. >>> * @param parent C explicit parent object >>> * @param newValue F new value for field in parent >>> */ >>> public void set(C parent,F newValue) { >>> try { >>> Object last = parent; >>> int index; >>> for(index = 0; index < fields.length - 1; index++) { >>> >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >>> throw new IllegalAccessException( >>> "Can not get from a WriteOnly field - " + >>> fields[index].getName()); >>> Method getter = pd[index] == null ? null : >>> pd[index].getReadMethod(); >>> if(getter == null) last = fields[index].get(last); >>> else last = getter.invoke(last); >>> } >>> >>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) >>> throw new IllegalAccessException( >>> "Can not get from a WriteOnly field - " + >>> fields[index].getName()); >>> Method setter = pd[index] == null ? null : >>> pd[index].getWriteMethod(); >>> if(setter == null) { >>> PropertyChangeSupport pcs = findPcs(last.getClass()); >>> fields[index].set(last,newValue); >>> if(pcs != null) >>> pcs.firePropertyChange(fields[index].getName(), >>> newValue, >>> >>> fields[index].get(last)); >>> } else setter.invoke(last,newValue); >>> } catch(Exception e) { >>> throw new RuntimeException("Should not occur >>> exception", e); >>> } >>> } >>> /** >>> * This is used so that the caller can view the Field name >>> * @return String field name >>> */ >>> public String[] getFieldName() { >>> String[]names = new String[fields.length]; >>> for(int index = 0; index < fields.length; index++) { >>> names[index] = fields[index].getName(); >>> } >>> return names; >>> } >>> /** >>> * This method is used to fetch the Field array, which is useful >>> if you >>> need to >>> * access the Annotations of a field. >>> * @return Field[] the array of Fields describing this Property. >>> */ >>> public Field[] getFields() { >>> return fields; >>> } >>> /** >>> * This private method looks for a PropertyChangeSupport object in >>> the >>> class and >>> * if one is found it will return it. It looks right the way up >>> the class >>> tree >>> * by recurring up the superClasses. >>> * @param parent Class to check for PropertyChangeSupport fields >>> * @return PropertyChangeSupport first found object, or null if >>> not found >>> */ >>> private PropertyChangeSupport findPcs(Class parent) { >>> Field fields[] = parent.getDeclaredFields(); >>> for(Field field:fields) { >>> field.setAccessible(true); >>> try { >>> if(field.getType() == PropertyChangeSupport.class) >>> return (PropertyChangeSupport)field.get(parent); >>> } catch(Exception e) { } >>> } >>> // If we did not find it then try the superclass >>> ClasssuperClass = parent.getSuperclass(); >>> if(superClass == null) return null; >>> return findPcs(parent.getClass().getSuperclass()); >>> } >>> /** >>> * This annotation is used to mark a field as WriteOnly, i.e. it >>> can not >>> be read. >>> * This stops the automatic getter operation. >>> */ >>> public @interface WriteOnly { >>> } >>> /** >>> * This annotation is used to mark a field as ReadOnly, i.e. it >>> can not be >>> written. >>> * This stops the automatic setter operation. >>> */ >>> public @interface ReadOnly { >>> } >>> } > > > From develop4lasu at gmail.com Tue Mar 3 13:18:49 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 3 Mar 2009 22:18:49 +0100 Subject: 'This' type In-Reply-To: <15e8b9d20903031255i70d719dbgd9f3615c3abe7f11@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> <28bca0ff0903031240v513be89fk8796a76fc8faffa7@mail.gmail.com> <15e8b9d20903031255i70d719dbgd9f3615c3abe7f11@mail.gmail.com> Message-ID: <28bca0ff0903031318h4bbc5d55m734732246de48e0f@mail.gmail.com> W dniu 3 marca 2009 21:55 u?ytkownik Neal Gafter napisa?: > Not seeing a problem is not the same thing as demonstrating that no > problem can occur. One set of problems arise when you use "This" in a > superclass type argument, as you did in an example. I simply don't > know what subtype relationships that creates. > > interface A extends Collection {} > > After this, is A a subtype of Collection? > > On Tue, Mar 3, 2009 at 12:40 PM, Marek Kozie? > wrote: > > If we think about it onlt as extension for return types it's quite easy. > > > > interface IA{ This method(); } > > > > interface IB extends IA { } > > now: > > > > static void some(IB x){ > > > > __ x.method() : return type is IB as This for IB; > > > > __ ((IA)x).method() : return type is visible as IA as This for IA; > > > > } > > If u have some doubts, just mail the sample (I do not see any reason for > > valid code to make ClassCastExceptions to appear). > > > > -- > > Pozdrowionka. / Regards. > > Lasu aka Marek Kozie? > > > > http://lasu2string.blogspot.com/ > > > > > Oh. I get it now. Yes A is a subtype of Collection but after B extends A B will be Collection from B point of view B will be Collection from A point of view In base relation is same as one created by overloaded methods. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Tue Mar 3 13:26:25 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 13:26:25 -0800 Subject: 'This' type In-Reply-To: <28bca0ff0903031318h4bbc5d55m734732246de48e0f@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> <28bca0ff0903031240v513be89fk8796a76fc8faffa7@mail.gmail.com> <15e8b9d20903031255i70d719dbgd9f3615c3abe7f11@mail.gmail.com> <28bca0ff0903031318h4bbc5d55m734732246de48e0f@mail.gmail.com> Message-ID: <15e8b9d20903031326w47d9bd19ga446312ecc404151@mail.gmail.com> On Tue, Mar 3, 2009 at 1:18 PM, Marek Kozie? wrote: > Oh. > > I get it now. > > Yes A is a subtype of Collection > > but after > > B extends A > > B will be Collection from B point of view > > B will be Collection from A point of view > > In base relation is same as one created by overloaded methods. So if we have a class C that is a sibling of B (a child of A), then from A's point of view we can place a C into the collection (because C is a subtype of A). But then from B's point of view the collection should contain only Bs and not any Cs. So when B pulls something out of the collection we could get a ClassCastException. That's the kind of thing you need to demonstrate can't happen in order to show this change is a sound extension of the type system. From reinier at zwitserloot.com Tue Mar 3 13:33:15 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 3 Mar 2009 22:33:15 +0100 Subject: PROPOSAL: Static Methods in Interfaces Message-ID: Static Methods in Interfaces. See attachment for full proposal in HTML. You can also just look here: http://tinyurl.com/static-methods-in-interfaces -------------- next part -------------- --Reinier Zwitserloot From develop4lasu at gmail.com Tue Mar 3 13:42:47 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 3 Mar 2009 22:42:47 +0100 Subject: 'This' type In-Reply-To: <15e8b9d20903031326w47d9bd19ga446312ecc404151@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <15e8b9d20903031225l854aaccs90a18038d9e09038@mail.gmail.com> <28bca0ff0903031240v513be89fk8796a76fc8faffa7@mail.gmail.com> <15e8b9d20903031255i70d719dbgd9f3615c3abe7f11@mail.gmail.com> <28bca0ff0903031318h4bbc5d55m734732246de48e0f@mail.gmail.com> <15e8b9d20903031326w47d9bd19ga446312ecc404151@mail.gmail.com> Message-ID: <28bca0ff0903031342w57415d86j90749f5bd4dc0f3c@mail.gmail.com> W dniu 3 marca 2009 22:26 u?ytkownik Neal Gafter napisa?: > On Tue, Mar 3, 2009 at 1:18 PM, Marek Kozie? > wrote: > > Oh. > > > > I get it now. > > > > Yes A is a subtype of Collection > > > > but after > > > > B extends A > > > > B will be Collection from B point of view > > > > B will be Collection from A point of view > > > > In base relation is same as one created by overloaded methods. > > So if we have a class C that is a sibling of B (a child of A), then > from A's point of view we can place a C into the collection (because C > is a subtype of A). But then from B's point of view the collection > should contain only Bs and not any Cs. So when B pulls something out > of the collection we could get a ClassCastException. > > That's the kind of thing you need to demonstrate can't happen in order > to show this change is a sound extension of the type system. > That's the reason why I wander if 'This' should be allowed as input parameter type(what conditions should be respected ...). In basic it's designed for return types and return type parameters. But notice that B b ; A a=b; would be invalid while this comes from generic rules(extends would be partial). -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Tue Mar 3 14:00:27 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 3 Mar 2009 22:00:27 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <974754BA-9815-4C98-B868-3D793AFEF79A@zwitserloot.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <200903032104.58445.david.goodenough@linkchoose.co.uk> <974754BA-9815-4C98-B868-3D793AFEF79A@zwitserloot.com> Message-ID: <200903032200.28367.david.goodenough@linkchoose.co.uk> Well that depends on what you mean by a complete proposal. There are two parts to the use of Properties. There is the framework side, inside BeansBinding or JPA and then there is the consumer side, the application code. My proposal is very simple on the consumer side (the only bit needed is the # notation). You can use clasical getters and setters (a nuisance but everyone understands them), or the simple getter/setter mechanism that my Property provides. So for the consumer my proposal is real simple. All you need do is add (either explicity or by byte code enhancement) a PropertyChangeSupport object and the relevant methods and you are home and dry. For the Frameworks, well you only write them once. Even so something nice and simple appeals and my proposal is simple. It may not be Beans as we know it, but they never were integrated properly into Java. But its really not that dissimilar just slightly different. So other than a little sytactic sugar (not having to code the PropertyChangeSupport object) we have not really lost anything of the "full" solution. Having a Bound annotation which would add this under the covers with a byte code enhancer would not be difficult. The implicit getters and setters come with the package. So the question to be asked whether a fuller solution is really needed. David On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > The language change required for your proposal is indeed lighter, but > to understand it, it is seems a lot more complicated. > > Also, it would be infeasible to introduce a 'lightweight' (according > to anyone's definition) proposal now that is lacking in certain > aspects, and then fix it later, unless that fix is syntactically very > similar and backwards- and migration compatible. That's the major beef > I have with this proposal: It effectively shuts the door on any other > property proposal. In my view, a proposal solves the problem properly, > or shouldn't be added at all; no quick hacky fixes that aren't part of > a planned evolution path to a complete solution. > > If you can highlight how a complete properties proposal will > seamlessly work with your syntax, I'm more inclined to like it. > > --Reinier Zwitserloot > > On Mar 3, 2009, at 22:04, David Goodenough wrote: > > Yes I do. What you propose is much more invasive. Look at it > > again and maybe you will see the Light(ness). > > > > David > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >> You call that lightweight? > >> > >> How about following the beans spec more to the letter and just > >> generate the addPropertyChangeListener, removePropertyChangeListener, > >> setX(), and get/isX() method in response to seeing a keyword or > >> annotation on a given field. You'll have to work out the details, but > >> that sounds far, far simpler to understand. > >> > >> You'll need to flesh this out, but it would look something like: > >> > >> public class Foo { > >> private property int x; > >> } > >> > >> Which would generate the addPropertyChangeListener, > >> removePropertyChangeListener, setX, getX methods, all public, along > >> with the required infrastructure to make it tick. If you don't like > >> the generation, for example because you want the setter to be package > >> private, you just add the setter in the source file; the keyword will > >> only generate the missing stuff. It doesn't cover every use case, but > >> there's always the alternative of doing whatever people do now with > >> beans. Something you didn't mention in your proposal, by the way. > >> > >> I think there's also a fully fleshed out property proposal (including > >> a 'property' keyword) out there somewhere. > >> > >> Possibly make a way to opt out of generating the property change > >> listener support, and just the getters/setters. > >> --Reinier Zwitserloot > >> > >> On Mar 3, 2009, at 15:59, David Goodenough wrote: > >>> Below is my proposal for Lightweight Properties. I know that the > >>> syntax > >>> change is an abbomination to some people, but I have tried to reduce > >>> this to its absolute minimum, while still getting a significant > >>> benefit. > >>> > >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >>> > >>> AUTHOR(S): > >>> > >>> David Goodenough, long time Java user. I can be reached at > >>> david.goodenough at linkchoose.co.uk. > >>> > >>> OVERVIEW > >>> > >>> FEATURE SUMMARY: > >>> > >>> Lightweight Property support > >>> > >>> MAJOR ADVANTAGE: > >>> > >>> Both BeansBinding (whether JSR-295 or others such an JFace or the > >>> JGoodies > >>> binding) and the JPA Criteria API currently require field names (as > >>> Strings) > >>> as arguments, which an IDE/compiler can not check. With this > >>> proposal the > >>> strings would be abandoned, and the IDE/compiler will be able to > >>> check the > >>> correctness of the code. > >>> > >>> MAJOR BENEFIT: > >>> > >>> Manual checking no longer required. This proposal introduces a > >>> simple well > >>> defined IDE/compiler checkable solution. > >>> > >>> MAJOR DISADVANTAGE: > >>> > >>> It is a language change, and this seems to upset some people. > >>> > >>> ALTERNATIVES: > >>> > >>> None really, apart from using another language or continuing to use > >>> String > >>> names. The existing solutions all require String names which are > >>> uncheckable. > >>> > >>> EXAMPLES > >>> > >>> Lets assume we have a POJO called foo, of type Foo with a field bar > >>> of type > >>> Bar, which itself has a field of type Jim called jim. > >>> > >>> There are two forms of lightweight properties:- > >>> > >>> 1) foo#bar would be translated by the compiler into:- > >>> > >>> new Property(foo,"bar"); > >>> > >>> while foo#bar#jim would be translated into:- > >>> > >>> new Property(foo,"bar","jim"); > >>> > >>> 2) Foo#bar would be translated into:- > >>> > >>> new Property(Foo.class,"bar"); > >>> > >>> while Foo#bar#jim would be translated into:- > >>> > >>> new Property(Foo.class,"bar","jim"); > >>> > >>> These two forms create (1) a bound Property, or (2) an unbound one. > >>> Bound > >>> Properties are explicitly bound to a particular instance of a class > >>> (in this > >>> case foo), while unbound Properties are templates which can be > >>> applied to any > >>> instance of class Foo. Actually bound properties can also be used as > >>> unbound > >>> properties, but that is a harmless and useful side effect not a > >>> primary > >>> intent. > >>> > >>> The Property class would need to be added (it is appended below), > >>> and should > >>> be added either to the java.beans package or to the > >>> java.lang.reflect package > >>> (with which is probably has more in common). > >>> > >>> Syntactically a "#" can be placed wherever a "." can be placed > >>> (except inside > >>> a number), and the same checks need to be made (that each field to > >>> the right > >>> of a # is a field in the left hand side) as would be made for a ".". > >>> The only > >>> difference is in field visibility - For the "#" any field is > >>> visible, which > >>> follows the model currently available in the Field class with > >>> getDeclaredFields(). It also follows the model that while a field > >>> might be > >>> private and therefore not directly accessible from outside, getters > >>> and > >>> setters can provide access. > >>> > >>> The Property object provides type safe access to the field in the > >>> form of > >>> getters and setters. These come in pairs, one for bound and the > >>> other for > >>> unbound access. So for bound access no object is required to fetch > >>> the value, > >>> for an unbound object the parent object needs to be specified. So if > >>> we > >>> have:- > >>> > >>> Propertyprop = foo#bar; > >>> > >>> we can later say:- > >>> > >>> Bar b = prop.get(); > >>> > >>> or for an unbound one from a second Foo object foo2:- > >>> > >>> Bar b = prop.get(foo2); > >>> > >>> The getters and setters in the Property object will defer to > >>> explicitly coded > >>> getters and setters if present, otherwise they will use the Field > >>> getter and > >>> setter. > >>> > >>> If a setter is not explicitly coded, the implicit setter will look > >>> for a > >>> PropertyChangeSupport object in the parent object of the rightmost > >>> field and > >>> fire a PropertyChangeEvent to that object. > >>> > >>> There are also two Annotations provided by the Property class, > >>> ReadOnly and > >>> WriteOnly. These stop implicit getters and setters from trying to > >>> read/write > >>> the property. > >>> > >>> Talking of Annotations, this notation can also be used to get at the > >>> Annotations for a field. So to test for the presence of an > >>> Annotation Ann on > >>> Foo.bar we would use:- > >>> > >>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >>> > >>> SIMPLE EXAMPLE: > >>> > >>> To take an example from BeansBinding (taken from Shannon Hickey's > >>> blog):- > >>> > >>> // create a BeanProperty representing a bean's firstName > >>> Property firstP = BeanProperty.create("firstName"); > >>> // Bind Duke's first name to the text property of a Swing > >>> JTextField > >>> BeanProperty textP = BeanProperty.create("text"); > >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > >>> firstP, textfield, textP); > >>> binding.bind(); > >>> > >>> > >>> would instead be written:- > >>> > >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>> duke#firstName, textfield#text); > >>> binding.bind(); > >>> > >>> which of course can be checked by the IDE/compiler, and will not > >>> wait until > >>> run time (not even instantiation time) to show up the error. > >>> > >>> ADVANCED EXAMPLE: > >>> > >>> For a JComboBox (or JList or JTable or JTree) there is a need to map > >>> a list of > >>> objects to the value strings (or column contents). For this we need > >>> to have > >>> an unbound Property which can be applied to each element of the > >>> list. > >>> > >>> Duke duke; > >>> Listdukes; > >>> BoundComboBox combo = new > >>> BoundComboBox(dukes,Duke#fullname,this#duke); > >>> > >>> and now the combo box will be populated from the list dukes, and the > >>> display > >>> values in the list will be taken from the fullname field of each > >>> Duke > >>> element, and the initial value will be set from the local class > >>> field duke > >>> and any changes to the combo box selected element will be reflected > >>> back to > >>> the duke field. > >>> > >>> DETAILS > >>> > >>> SPECIFICATION: > >>> > >>> This proposal adds a new syntactic element, "#", which can be used > >>> in the same > >>> way that "." can be used to qualify fields within a Java object. > >>> > >>> COMPILATION: > >>> > >>> This proposal requires no change to the class files, and is > >>> implemented by a > >>> simple generation of the required instance using the relevant > >>> Property > >>> constructor. Obviously the compiler would have to make sure that the > >>> use that > >>> the property object was being put to (in the examples above the left > >>> hand > >>> side of the assignment) had the correct Generic attributes. > >>> > >>> TESTING: > >>> > >>> How can the feature be tested? > >>> > >>> LIBRARY SUPPORT: > >>> > >>> The new Property class is required (see below). > >>> > >>> REFLECTIVE APIS: > >>> > >>> No changes are required to the reflective APIs although it makes > >>> extensive use > >>> of those APIs. > >>> > >>> OTHER CHANGES: > >>> > >>> No other changes are requires. > >>> > >>> MIGRATION: > >>> > >>> Fortunately there is no code that is formally part of J2SE 6 which > >>> uses such > >>> Properties. There are however two proposals which will need it > >>> (BeansBinding > >>> and JPA Criteria API), but neither of these seem to be destined to > >>> be part of > >>> J2SE 7 (BeansBinding seems to have died the death and the Criteria > >>> API would > >>> be part of the next J2EE which will follow J2SE 7), so this will > >>> provide a > >>> base for them to use and no existing code need to be updated. > >>> > >>> There are other extant Beans-Binding libraries, which could be > >>> modified to use > >>> this proposal, but as none of the existing features have been > >>> changed there > >>> is no need to change them (other than for type safety and compiler/ > >>> IDE > >>> checkability). > >>> > >>> COMPATIBILITY > >>> > >>> BREAKING CHANGES: > >>> > >>> None. This change should not make any existing correct code fail to > >>> compile > >>> or run or change the way in which it compiles/runs. > >>> > >>> EXISTING PROGRAMS: > >>> > >>> No change required to any existing programs > >>> > >>> REFERENCES > >>> > >>> EXISTING BUGS: > >>> > >>> None > >>> > >>> URL FOR PROTOTYPE (optional): > >>> > >>> I do not have the knowledge to make changes to the compiler, and the > >>> only > >>> documentation making such changes concentrated on adding operators > >>> not > >>> changes at this level. So there is no prototype of the compiler > >>> part, but the > >>> Property class follows:- > >>> > >>> package java.lang.reflect; > >>> > >>> import java.beans.BeanInfo; > >>> import java.beans.Introspector; > >>> import java.beans.PropertyChangeSupport; > >>> import java.beans.PropertyDescriptor; > >>> import java.lang.reflect.Field; > >>> import java.lang.reflect.Method; > >>> > >>> /** > >>> * Property class > >>> * This is the support class for use with the # notation to provide > >>> lightweight > >>> * Property support for Java. > >>> * > >>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >>> * @licence LPGL V2 : details of which can be found at http:// > >>> fsf.org. > >>> * @author david.goodenough at linkchoose.co.uk > >>> * > >>> * @param The Parent class for this field > >>> * @param The Type of this field > >>> */ > >>> public class Property { > >>> private C parent; > >>> private Class parentClass; > >>> private Field[] fields; > >>> private PropertyDescriptor[] pd = null; > >>> /** > >>> * Constructor used to create Property objects. The Parent object > >>> may be > >>> * null, but should normally be specified as it can be overridden > >>> anyway. > >>> * @param parent C object that contains the field > >>> * @param field Field describing this field > >>> */ > >>> public Property(C parent, String ... fieldNames) { > >>> this.parent = parent; > >>> this(parent.getClass(), fieldNames); > >>> } > >>> /** > >>> * Constructor for unbound Properties, but also used internally > >>> after > >>> setting > >>> * the parent object by the bound Property objects. > >>> * @param parentClass Class of the parent object > >>> * @param fieldNames String[] of field names > >>> */ > >>> public Property(ClassparentClass, String .. fieldNames) { > >>> this.parentClass = parentClass; > >>> fields = new Field[fieldNames.length]; > >>> pd = new PropertyDescriptor[fieldNames.length]; > >>> outer: for(int index = 0; index < fields.length; index++) { > >>> Field[]dclFields = parentClass.getDeclaredFields(); > >>> for(Field field:dclFields) { > >>> if(field.getName().equals(fieldNames[index])) { > >>> fields[index] = field; > >>> field.setAccessible(true); > >>> try { > >>> BeanInfo beanInfo = > >>> Introspector.getBeanInfo(parent.getClass()); > >>> PropertyDescriptor[]props = > >>> beanInfo.getPropertyDescriptors(); > >>> for(PropertyDescriptor prop : props) { > >>> if(prop.getName().equals(field.getName())) { > >>> pd[index] = prop; > >>> break; > >>> } > >>> } > >>> } catch(Exception e) { /* assume can not find getter/ > >>> setter > >>> */ } > >>> parentClass = field.getType(); > >>> continue outer; > >>> } > >>> } > >>> throw new IllegalArgumentException("Field " + fieldNames[index] + > >>> " not found in class " + > >>> parentClass.getCanonicalName()); > >>> } > >>> } > >>> /** > >>> * Getter from the field in the parent specified when this > >>> Property was > >>> created. > >>> * @see Property.get(C otherParent) > >>> * @return F the value of this field > >>> */ > >>> public F get() { > >>> return get(parent); > >>> } > >>> /** > >>> * Getter with explicit parent. > >>> * This code will check see if this field is WriteOnly, and > >>> complain if it > >>> is. > >>> * It will then see if the use has provided am explicit getter, > >>> and call > >>> that > >>> * if present, otherwise it will just fetch the value through the > >>> Field > >>> provided > >>> * method. > >>> * @param otherParent C parent object > >>> * @return F value of the field > >>> */ > >>> @SuppressWarnings("unchecked") // This should actually not be > >>> needed, > >>> // but the Field.get method is not > >>> typed > >>> public F get(C otherParent) { > >>> Object result = otherParent; > >>> try { > >>> for(int index = 0; index < fields.length; index++) { > >>> > >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>> throw new IllegalAccessException( > >>> "Can not get from a WriteOnly field - " + > >>> fields[index].getName()); > >>> Method getter = pd[index] == null ? null : > >>> pd[index].getReadMethod(); > >>> if(getter == null) result = fields[index].get(result); > >>> else result = getter.invoke(result); > >>> } > >>> } catch(Exception e) { > >>> throw new RuntimeException("Should not occur exception", e); > >>> } > >>> return (F)result; > >>> } > >>> /** > >>> * Setter to set the value of the field in the parent object > >>> declared with > >>> the > >>> * Property object > >>> * @param newValue F new value of this field > >>> */ > >>> public void set(F newValue) { > >>> set(parent,newValue); > >>> } > >>> /** > >>> * Setter to set the value of the field to an explicit parent > >>> object. > >>> * If there is a ReadOnly annotation, then we object. If there is > >>> an > >>> explicit > >>> * setter then we use that, otherwise we set the field using the > >>> Field > >>> provided > >>> * set method and if there is a PropertyChangeSupport field, fire a > >>> property > >>> * change event to it. > >>> * We walk our way down the field chain, until we have the last > >>> object and > >>> its > >>> * field, and then we do the set. > >>> * @param parent C explicit parent object > >>> * @param newValue F new value for field in parent > >>> */ > >>> public void set(C parent,F newValue) { > >>> try { > >>> Object last = parent; > >>> int index; > >>> for(index = 0; index < fields.length - 1; index++) { > >>> > >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>> throw new IllegalAccessException( > >>> "Can not get from a WriteOnly field - " + > >>> fields[index].getName()); > >>> Method getter = pd[index] == null ? null : > >>> pd[index].getReadMethod(); > >>> if(getter == null) last = fields[index].get(last); > >>> else last = getter.invoke(last); > >>> } > >>> > >>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >>> throw new IllegalAccessException( > >>> "Can not get from a WriteOnly field - " + > >>> fields[index].getName()); > >>> Method setter = pd[index] == null ? null : > >>> pd[index].getWriteMethod(); > >>> if(setter == null) { > >>> PropertyChangeSupport pcs = findPcs(last.getClass()); > >>> fields[index].set(last,newValue); > >>> if(pcs != null) > >>> pcs.firePropertyChange(fields[index].getName(), > >>> newValue, > >>> > >>> fields[index].get(last)); > >>> } else setter.invoke(last,newValue); > >>> } catch(Exception e) { > >>> throw new RuntimeException("Should not occur > >>> exception", e); > >>> } > >>> } > >>> /** > >>> * This is used so that the caller can view the Field name > >>> * @return String field name > >>> */ > >>> public String[] getFieldName() { > >>> String[]names = new String[fields.length]; > >>> for(int index = 0; index < fields.length; index++) { > >>> names[index] = fields[index].getName(); > >>> } > >>> return names; > >>> } > >>> /** > >>> * This method is used to fetch the Field array, which is useful > >>> if you > >>> need to > >>> * access the Annotations of a field. > >>> * @return Field[] the array of Fields describing this Property. > >>> */ > >>> public Field[] getFields() { > >>> return fields; > >>> } > >>> /** > >>> * This private method looks for a PropertyChangeSupport object in > >>> the > >>> class and > >>> * if one is found it will return it. It looks right the way up > >>> the class > >>> tree > >>> * by recurring up the superClasses. > >>> * @param parent Class to check for PropertyChangeSupport fields > >>> * @return PropertyChangeSupport first found object, or null if > >>> not found > >>> */ > >>> private PropertyChangeSupport findPcs(Class parent) { > >>> Field fields[] = parent.getDeclaredFields(); > >>> for(Field field:fields) { > >>> field.setAccessible(true); > >>> try { > >>> if(field.getType() == PropertyChangeSupport.class) > >>> return (PropertyChangeSupport)field.get(parent); > >>> } catch(Exception e) { } > >>> } > >>> // If we did not find it then try the superclass > >>> ClasssuperClass = parent.getSuperclass(); > >>> if(superClass == null) return null; > >>> return findPcs(parent.getClass().getSuperclass()); > >>> } > >>> /** > >>> * This annotation is used to mark a field as WriteOnly, i.e. it > >>> can not > >>> be read. > >>> * This stops the automatic getter operation. > >>> */ > >>> public @interface WriteOnly { > >>> } > >>> /** > >>> * This annotation is used to mark a field as ReadOnly, i.e. it > >>> can not be > >>> written. > >>> * This stops the automatic setter operation. > >>> */ > >>> public @interface ReadOnly { > >>> } > >>> } From develop4lasu at gmail.com Tue Mar 3 14:05:26 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 3 Mar 2009 23:05:26 +0100 Subject: 'This' type In-Reply-To: <16ADB29F-AD69-443D-8C3F-DC25175E6D21@gmx.ch> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <16ADB29F-AD69-443D-8C3F-DC25175E6D21@gmx.ch> Message-ID: <28bca0ff0903031405m6c1c21d0n5359d3eea78a0952@mail.gmail.com> 2009/3/3 Adrian Kuhn > On Mar 3, 2009, at 21:17 , Marek Kozie? wrote: > > ALTERNATIVES: >> Rewriting each method's signature on every class / interface. >> > > Using self-bound generics, such as > > abstract class A> { > abstract Self self(); > } > > class B extends A { > B self(); > } > > class C extends A { > C self(); > } > > This is used in java.lang.Enum for example. > > See also http://www.artima.com/forums/flat.jsp?forum=106&thread=136394 > > --AA Thanks for good sample. Although 'This' could bring relation for generics, or maybe we should think about possibility of defining relations for generics. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Tue Mar 3 14:21:50 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 03 Mar 2009 14:21:50 -0800 Subject: 'This' type In-Reply-To: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> Message-ID: <49ADAD7E.4090803@sun.com> Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ > > OVERVIEW > > FEATURE SUMMARY: > This type add ability to project valid interfaces(classes) for further > extending/implementing. 'This' means current interface/class type or > something implementing/extending it. > [snip] > DETAILS: > > SPECIFICATION: > (I did not have time to analyze this completely.) > The Project Coin mailing list is not an alternate forum to submit requests for enhancements of the Java specification. Rather, it is a venue for the analysis and refinement of thought-through proposals to change the language. If one is not willing or able to work through implications of the proposal, it it not appropriate to be sent to the list. > REFERENCES > > Notice that considered document does not contain complete analyze of those > solutions and can have some lacks. So if you have some questions/advices > that it does not fully fit with Project Coin, post it on my blog to discuss: > http://lasu2string.blogspot.com/2009/03/this-type.html > Generally the discussion of proposals sent to Project Coin should occur on the Project Coin list. Besides making the current status of proposals easier to track, various parties have expressed interest in why previous language design decisions were made and having all the traffic on Project Coin makes that retrospective analysis possible. -Joe From philvarner at gmail.com Tue Mar 3 14:36:44 2009 From: philvarner at gmail.com (Phil Varner) Date: Tue, 3 Mar 2009 14:36:44 -0800 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: <49ACF691.5090104@paradise.net.nz> References: <49ACF691.5090104@paradise.net.nz> Message-ID: Thanks for the pointer to the bug. One advantage of the syntax "import Sqldate = java.sql.Date;" is that it wouldn't require a keyword addition. It does give a nice "is equivalent to" reading, but also introduces an overloaded meaning for '='. I'm reluctant to include generified types, since, as you say, this should probably be part of a more complete solution. The package alias idea is interesting. I think a more "complete" type aliases proposal is an excellent idea for a separate coin. Were you thinking of something that was included in the type system (as in Haskell) or just a compiler transform? --Phil On Tue, Mar 3, 2009 at 1:21 AM, Bruce Chapman wrote: > My 2 cents: > > This partially covers the need for type aliases, but not for generic > types (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4983159), if > we are going to introduce aliases it should cover the generic case as well. > > An alternative syntax to avoid the 'as' keyword could be > > "import Sqldate = java.sql.Date;" > > Either syntax could probably cover the generic type alias case as well, > however I am not sure if an "import" statement is the right way to do that. > > I liked your examples, some are very compelling. > > An alternative mechanism that preserves the simple names might be to > alias the package rather than aliasing the type. > eg > import ju=java.util; // or import package ju=java.util; > import js=java.sql; > > js.Date date = new js.Date(new ju.Date); > > > That gets further away from solving the generics alias issue, which > might be a good thing : it leaves it easier to do a complete type > aliases solution as a separate issue. ?(IS anyone working on a type > aliases proposal for coin?) > > Bruce > > > Phil Varner wrote: >> Import Aliases for Classes and Static Methods >> >> http://docs.google.com/Doc?id=dgx74dt7_19dxnspbhj >> >> AUTHOR: Phil Varner >> >> OVERVIEW >> >> FEATURE SUMMARY: The import aliases feature allows a user to provide >> an alias underwhich an imported class or statically imported method >> must be referred to in the containing source file. ? An example of the >> use of this feature is "import java.sql.Date as SqlDate;" >> >> MAJOR ADVANTAGE: This feature would allow easier use of multiple >> classes which have the same name but different packages to be used in >> the same source file. >> >> MAJOR BENEFIT: This will prevent the necessity of fully-qualifiying >> all class references when there is a name collision, leading to more >> readable code. >> >> MAJOR DISADVANTAGE: ?This will introduce an extra level of indirection >> when determing the source of a given class or method, introduce a new >> keyword 'as', and will require changes to IDE code completion >> functionality. >> >> ALTERNATIVES: In some cases, a nested class can be created which >> trivially derives a class involved in the name collision. ?For a >> method, a wrapper method can be created in the source file. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> >> Example #1, duplicate class name >> >> Current code: >> >> new java.sql.Date(new java.util.Date()); >> >> New code: >> >> import java.sql.Date as SqlDate; >> import java.util.Date as UtilDate; >> >> new SqlDate(new UtilDate()); >> >> Example #2, statically imported method alias >> >> Current code: >> >> import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName; >> >> public static int mrlacsmn(final int arg1, final String arg2){ >> ? ? return myReallyLongAndComplicatedStaticMethodName(arg1, arg2); >> } >> >> mrlacsmn(1, a); >> >> New code: >> >> import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName >> as mrlacsmn; >> >> mrlacsmn(1, a); >> >> ADVANCED EXAMPLE: >> >> Example #3 >> >> Translation of persistent formats between similar APIs. >> >> In many domains, it is not uncommon to have two different APIs with >> classes with the same name. ?For example, in a production rules API, >> one may have classes "RuleSet" and "Rule". ?When attempting to use the >> API to translate between these these APIs, it must be decided that one >> is fully-qualified and one is not. ?This can lead to code like: >> >> com.example.foo.bar.sdk.RuleSet srcRuleSet = ...; >> com.example.foo.bar.sdk2.RuleSet dstRuleSet = new >> com.example.foo.bar.sdk2.RuleSet(); >> migrate(srcRuleSet, dstRuleSet); >> ... >> >> private static void migrate(com.example.foo.bar.sdk.RuleSet srcRuleSet, >> ? ? ? ? ? ? ? ? ? ? ? ? com.example.foo.bar.sdk2.RuleSet dstRuleSet){ >> ... >> } >> >> Note that it is good practice here not to import either class because >> it is too easy to accidentally misuse constants and static methods. >> >> With the 'as' syntax, one could instead write the far less verbose and >> more readible: >> >> import com.example.foo.bar.sdk.RuleSet as SrcRuleSet; >> import com.example.foo.bar.sdk2.RuleSet as DstRuleSet; >> >> ... >> >> SrcRuleSet srcRuleSet = ...; >> DstRuleSet destRuleSet = new DstRuleSet(); >> migrate(srcRuleSet, dstRuleSet); >> >> ... >> >> private static void migrate(SrcRuleSet srcRuleSet, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? DstRuleSet dstRuleSet){ >> ... >> } >> >> Example #4 >> >> Ensuring correct method selection when static importing overloaded methods. >> >> Current code: >> import static org.testng.Assert.assertEquals; >> >> public static int aeo(Object arg1, Object arg2){ >> ? ? assertEquals(arg1, arg2); >> } >> >> public static int aec(Collection arg1, Collection arg2){ >> ? ? assertEquals(arg1, arg2); >> } >> >> aeo(obj1, obj2); >> aec(list1, list2); >> >> New code: >> >> import static org.testng.Assert.assertEquals(Object, Object) as aeo; >> import static org.testng.Assert.assertEquals(Collection, Collection) as aec; >> >> aeo(obj1, obj2); >> aec(list1, list2); >> >> Note: it is possible that this sort of method selection is beyond the >> scope of a COIN proposal >> >> DETAILS >> >> SPECIFICATION: >> >> Grammar >> >> modification (JLS 3.9): >> Keyword: >> ? ? as >> ? ? ... >> >> modification (JLS 7.5): >> ImportDeclaration: >> ? ? SingleTypeImportDeclarationWithAlias >> ? ? SingleStaticImportDeclarationWithAlias >> ? ? ... >> >> addition: >> SingleTypeImportDeclarationWithAlias: >> ? ? import TypeName as Identifier; >> >> addition: >> SingleStaticImportDeclarationWithAlias: >> ? ? import static TypeName . Identifier as Identifier; >> >> >> Note that this would explicitly forbid wildcard imports from being aliased. >> >> There are no known effects on the type system or meaning of >> expressions and statements in the Java Programming Language. >> >> COMPILATION: This feature would be a compile-time transform. ?It would >> only affect the way in which a non-fully qualified class or method >> name was resolved to a fully-qualified class or method name. >> >> TESTING: This change would be tested in a manner similar how how the >> existing code which resolves the fully-qualified names of classes and >> methods is tested. >> >> LIBRARY SUPPORT: No change >> >> REFLECTIVE APIS: No change >> >> OTHER CHANGES: No change >> >> MIGRATION: This change is backwards-compatible with existing code. >> >> COMPATIBILITY >> >> BREAKING CHANGES: No change >> >> EXISTING PROGRAMS: No change >> >> REFERENCES >> >> EXISTING BUGS: None at present >> >> URL FOR PROTOTYPE (optional): None at present >> >> > > > > -- Machines might be interesting, but people are fascinating. -- K.P. From cadenza at paradise.net.nz Tue Mar 3 13:07:17 2009 From: cadenza at paradise.net.nz (cadenza at paradise.net.nz) Date: Wed, 04 Mar 2009 10:07:17 +1300 (NZDT) Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49AD1B58.5060305@joda.org> References: <49AABBA2.3040009@joda.org> <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> <49AD1B58.5060305@joda.org> Message-ID: <1236114437.49ad9c05d493c@www.paradise.net.nz> > This will be very confusing when you use Foo from another part of your > application and expect the value to be non-null and get a NPE. In fact > the @Nonnull is positvely misleading. > > Basically, you can't rely on JSR-305. The information needs to be > rechecked. Thus, whats the point in using it at all?!! Documentation > perhaps? Annotations are not suitable for handling language level issues > > like nulls. An annotation processor visible to javac could perform the @nonNull check and cause the compilation to fail. JSR-305 defines a standard set of annotations with precise defined meaning so that tools don't need to define their own, and so you don't need to change your code when you change the tooling. That has great value. With the annotations standardised the tooling will follow, no doubt some will be implemented as though they are part of javac, and some will not. Bruce Quoting Stephen Colebourne : > Jeremy Manson wrote: > >> The principle perceived disadvantage, however, is that it > encourages, > >> rather than discourages, the use of null values in APIs. > > > > I would think that the principle disadvantage would be not that it > > encourages use of null values (which, as you point out, is fine in > > some contexts), but that it encourages programmers not to think about > > what happens when there is a null value. > > But that is exactly what already happens today. Most developers are very > > poor at thinking through the null consequences of a method - the happy > day scenario is the one focussed on. > > > I can easily imagine > > programmers using this all of the time without thinking about it, and > > then being surprised when a null ends up in the wrong place and not > > knowing how it got there. Even with a simple example: > > > > public String someFunction(String a, String b) { > > String s = a?.concat("foo"); > > String t = b?.concat(a); > > return myHashMap?.get(t); > > } > > > > Now, someFunction returns null. Is it because a was null? Or b was > > null? Or myHashMap was null? Or there was no mapping for t in > > myHashMap? > > Or perhaps it doesn't matter, and thats why the code was written that > way. Null as 'don't know' or 'don't care' is incredibly common. > > > If you want to cut down on > > extraneous if-testing, I would use JSR-305's Nullity annotations > > instead. > > What does this code do when passed null? > > Foo f = new Foo(null); > int v = f.value; > > public class Foo { > public final Integer value; > public Foo(@Nonnull Integer value) { > this.value = value; > } > } > > There is a NPE at f.value, not at new Foo(null). > > You would think that you could never construct an instance of Foo with a > > val of null, but you can. The @Nonnull annotation doesn't have any real > > meaning unless it is checked using a tool, and javac isn't such a tool. > > This will be very confusing when you use Foo from another part of your > application and expect the value to be non-null and get a NPE. In fact > the @Nonnull is positvely misleading. > > Basically, you can't rely on JSR-305. The information needs to be > rechecked. Thus, whats the point in using it at all?!! Documentation > perhaps? Annotations are not suitable for handling language level issues > > like nulls. > > Stephen > > From thorsten at vanellen.de Tue Mar 3 13:18:54 2009 From: thorsten at vanellen.de (Thorsten van Ellen) Date: Tue, 03 Mar 2009 22:18:54 +0100 Subject: Automatic Resource Management and Simple Resource Clean-up Message-ID: <49AD9EBE.5010808@vanellen.de> Josh, Neal and Roger! I have had this idea also for a long time. I think it is in a "tradition" of java of suppressing typical programming errors. A good example for the tradition is automatic memory management and garbage collection that is a very complex mechanism to avoid one very typical programming error. Management of resources other than memory usually is really as buggy as memory management. My observation is that resource management is one of the most frequent bug pattern I know of. Look at any project: you hardly find correct optimal implemented examples and you nearly always find bugs in every non trivial project. Analysing/finding the bug often is very difficult like finding memory management bugs. It seems to me, the feature benefit is worth some more effort. The effort of thinking a bit more about it might be not too much, especially if your heading toward a "minimal" solution like "simple clean up", but I don't know what is "affordable" in jdk7-schedule. Just to put in some additional/new ideas and to "make the cake bigger" before it is reduced to the optimal solution ("brain-storming", sometimes thinkind around a corner helps): Both proposed solutions might have problems with resource management, that is distributed/shared/spread between two or more separated methods. Such problems might be solved with a kind of GOF-"pattern", interfaces and a tiny "resource management library". And there exist even more complicated resource management problems like ACID database transactions that do not only have one "close"-operation but two (commit and rollback) and a more complex decision process between those. But regarding these additional ideas may also be counterproductive for a tiny language modification that solves 98 % of the typical bugs and therefore may also be ignored! Best regards Thorsten van Ellen From akuhn at gmx.ch Tue Mar 3 13:51:11 2009 From: akuhn at gmx.ch (Adrian Kuhn) Date: Tue, 3 Mar 2009 22:51:11 +0100 Subject: 'This' type In-Reply-To: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> Message-ID: <16ADB29F-AD69-443D-8C3F-DC25175E6D21@gmx.ch> On Mar 3, 2009, at 21:17 , Marek Kozie? wrote: > ALTERNATIVES: > Rewriting each method's signature on every class / interface. Using self-bound generics, such as abstract class A> { abstract Self self(); } class B extends A { B self(); } class C extends A { C self(); } This is used in java.lang.Enum for example. See also http://www.artima.com/forums/flat.jsp?forum=106&thread=136394 --AA From Joe.Darcy at Sun.COM Tue Mar 3 17:29:28 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 03 Mar 2009 17:29:28 -0800 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <29B06FDC-80AB-46E0-AABB-C97F9F9AF405@zwitserloot.com> <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> Message-ID: <49ADD978.3080804@sun.com> Neal Gafter wrote: > Joe Darcy sort of ruled out adding property support in project coin in > http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > Correct; properties (and closures and reified generics) are examples of changes out of scope for Project Coin. -Joe > Regards, > Neal > > On Tue, Mar 3, 2009 at 12:05 PM, Reinier Zwitserloot > wrote: > >> You call that lightweight? >> >> How about following the beans spec more to the letter and just >> generate the addPropertyChangeListener, removePropertyChangeListener, >> setX(), and get/isX() method in response to seeing a keyword or >> annotation on a given field. You'll have to work out the details, but >> that sounds far, far simpler to understand. >> >> You'll need to flesh this out, but it would look something like: >> >> public class Foo { >> private property int x; >> } >> >> Which would generate the addPropertyChangeListener, >> removePropertyChangeListener, setX, getX methods, all public, along >> with the required infrastructure to make it tick. If you don't like >> the generation, for example because you want the setter to be package >> private, you just add the setter in the source file; the keyword will >> only generate the missing stuff. It doesn't cover every use case, but >> there's always the alternative of doing whatever people do now with >> beans. Something you didn't mention in your proposal, by the way. >> >> I think there's also a fully fleshed out property proposal (including >> a 'property' keyword) out there somewhere. >> >> Possibly make a way to opt out of generating the property change >> listener support, and just the getters/setters. >> --Reinier Zwitserloot >> >> >> >> On Mar 3, 2009, at 15:59, David Goodenough wrote: >> >> >>> Below is my proposal for Lightweight Properties. I know that the >>> syntax >>> change is an abbomination to some people, but I have tried to reduce >>> this to its absolute minimum, while still getting a significant >>> benefit. >>> >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>> >>> AUTHOR(S): >>> >>> David Goodenough, long time Java user. I can be reached at >>> david.goodenough at linkchoose.co.uk. >>> >>> OVERVIEW >>> >>> FEATURE SUMMARY: >>> >>> Lightweight Property support >>> >>> MAJOR ADVANTAGE: >>> >>> Both BeansBinding (whether JSR-295 or others such an JFace or the >>> JGoodies >>> binding) and the JPA Criteria API currently require field names (as >>> Strings) >>> as arguments, which an IDE/compiler can not check. With this >>> proposal the >>> strings would be abandoned, and the IDE/compiler will be able to >>> check the >>> correctness of the code. >>> >>> MAJOR BENEFIT: >>> >>> Manual checking no longer required. This proposal introduces a >>> simple well >>> defined IDE/compiler checkable solution. >>> >>> MAJOR DISADVANTAGE: >>> >>> It is a language change, and this seems to upset some people. >>> >>> ALTERNATIVES: >>> >>> None really, apart from using another language or continuing to use >>> String >>> names. The existing solutions all require String names which are >>> uncheckable. >>> >>> EXAMPLES >>> >>> Lets assume we have a POJO called foo, of type Foo with a field bar >>> of type >>> Bar, which itself has a field of type Jim called jim. >>> >>> There are two forms of lightweight properties:- >>> >>> 1) foo#bar would be translated by the compiler into:- >>> >>> new Property(foo,"bar"); >>> >>> while foo#bar#jim would be translated into:- >>> >>> new Property(foo,"bar","jim"); >>> >>> 2) Foo#bar would be translated into:- >>> >>> new Property(Foo.class,"bar"); >>> >>> while Foo#bar#jim would be translated into:- >>> >>> new Property(Foo.class,"bar","jim"); >>> >>> These two forms create (1) a bound Property, or (2) an unbound one. >>> Bound >>> Properties are explicitly bound to a particular instance of a class >>> (in this >>> case foo), while unbound Properties are templates which can be >>> applied to any >>> instance of class Foo. Actually bound properties can also be used as >>> unbound >>> properties, but that is a harmless and useful side effect not a >>> primary >>> intent. >>> >>> The Property class would need to be added (it is appended below), >>> and should >>> be added either to the java.beans package or to the >>> java.lang.reflect package >>> (with which is probably has more in common). >>> >>> Syntactically a "#" can be placed wherever a "." can be placed >>> (except inside >>> a number), and the same checks need to be made (that each field to >>> the right >>> of a # is a field in the left hand side) as would be made for a ".". >>> The only >>> difference is in field visibility - For the "#" any field is >>> visible, which >>> follows the model currently available in the Field class with >>> getDeclaredFields(). It also follows the model that while a field >>> might be >>> private and therefore not directly accessible from outside, getters >>> and >>> setters can provide access. >>> >>> The Property object provides type safe access to the field in the >>> form of >>> getters and setters. These come in pairs, one for bound and the >>> other for >>> unbound access. So for bound access no object is required to fetch >>> the value, >>> for an unbound object the parent object needs to be specified. So if >>> we >>> have:- >>> >>> Propertyprop = foo#bar; >>> >>> we can later say:- >>> >>> Bar b = prop.get(); >>> >>> or for an unbound one from a second Foo object foo2:- >>> >>> Bar b = prop.get(foo2); >>> >>> The getters and setters in the Property object will defer to >>> explicitly coded >>> getters and setters if present, otherwise they will use the Field >>> getter and >>> setter. >>> >>> If a setter is not explicitly coded, the implicit setter will look >>> for a >>> PropertyChangeSupport object in the parent object of the rightmost >>> field and >>> fire a PropertyChangeEvent to that object. >>> >>> There are also two Annotations provided by the Property class, >>> ReadOnly and >>> WriteOnly. These stop implicit getters and setters from trying to >>> read/write >>> the property. >>> >>> Talking of Annotations, this notation can also be used to get at the >>> Annotations for a field. So to test for the presence of an >>> Annotation Ann on >>> Foo.bar we would use:- >>> >>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... >>> >>> SIMPLE EXAMPLE: >>> >>> To take an example from BeansBinding (taken from Shannon Hickey's >>> blog):- >>> >>> // create a BeanProperty representing a bean's firstName >>> Property firstP = BeanProperty.create("firstName"); >>> // Bind Duke's first name to the text property of a Swing JTextField >>> BeanProperty textP = BeanProperty.create("text"); >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, >>> firstP, textfield, textP); >>> binding.bind(); >>> >>> >>> would instead be written:- >>> >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, >>> duke#firstName, textfield#text); >>> binding.bind(); >>> >>> which of course can be checked by the IDE/compiler, and will not >>> wait until >>> run time (not even instantiation time) to show up the error. >>> >>> ADVANCED EXAMPLE: >>> >>> For a JComboBox (or JList or JTable or JTree) there is a need to map >>> a list of >>> objects to the value strings (or column contents). For this we need >>> to have >>> an unbound Property which can be applied to each element of the list. >>> >>> Duke duke; >>> Listdukes; >>> BoundComboBox combo = new >>> BoundComboBox(dukes,Duke#fullname,this#duke); >>> >>> and now the combo box will be populated from the list dukes, and the >>> display >>> values in the list will be taken from the fullname field of each Duke >>> element, and the initial value will be set from the local class >>> field duke >>> and any changes to the combo box selected element will be reflected >>> back to >>> the duke field. >>> >>> DETAILS >>> >>> SPECIFICATION: >>> >>> This proposal adds a new syntactic element, "#", which can be used >>> in the same >>> way that "." can be used to qualify fields within a Java object. >>> >>> COMPILATION: >>> >>> This proposal requires no change to the class files, and is >>> implemented by a >>> simple generation of the required instance using the relevant Property >>> constructor. Obviously the compiler would have to make sure that the >>> use that >>> the property object was being put to (in the examples above the left >>> hand >>> side of the assignment) had the correct Generic attributes. >>> >>> TESTING: >>> >>> How can the feature be tested? >>> >>> LIBRARY SUPPORT: >>> >>> The new Property class is required (see below). >>> >>> REFLECTIVE APIS: >>> >>> No changes are required to the reflective APIs although it makes >>> extensive use >>> of those APIs. >>> >>> OTHER CHANGES: >>> >>> No other changes are requires. >>> >>> MIGRATION: >>> >>> Fortunately there is no code that is formally part of J2SE 6 which >>> uses such >>> Properties. There are however two proposals which will need it >>> (BeansBinding >>> and JPA Criteria API), but neither of these seem to be destined to >>> be part of >>> J2SE 7 (BeansBinding seems to have died the death and the Criteria >>> API would >>> be part of the next J2EE which will follow J2SE 7), so this will >>> provide a >>> base for them to use and no existing code need to be updated. >>> >>> There are other extant Beans-Binding libraries, which could be >>> modified to use >>> this proposal, but as none of the existing features have been >>> changed there >>> is no need to change them (other than for type safety and compiler/IDE >>> checkability). >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: >>> >>> None. This change should not make any existing correct code fail to >>> compile >>> or run or change the way in which it compiles/runs. >>> >>> EXISTING PROGRAMS: >>> >>> No change required to any existing programs >>> >>> REFERENCES >>> >>> EXISTING BUGS: >>> >>> None >>> >>> URL FOR PROTOTYPE (optional): >>> >>> I do not have the knowledge to make changes to the compiler, and the >>> only >>> documentation making such changes concentrated on adding operators not >>> changes at this level. So there is no prototype of the compiler >>> part, but the >>> Property class follows:- >>> >>> package java.lang.reflect; >>> >>> import java.beans.BeanInfo; >>> import java.beans.Introspector; >>> import java.beans.PropertyChangeSupport; >>> import java.beans.PropertyDescriptor; >>> import java.lang.reflect.Field; >>> import java.lang.reflect.Method; >>> >>> /** >>> * Property class >>> * This is the support class for use with the # notation to provide >>> lightweight >>> * Property support for Java. >>> * >>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd >>> * @licence LPGL V2 : details of which can be found at http://fsf.org. >>> * @author david.goodenough at linkchoose.co.uk >>> * >>> * @param The Parent class for this field >>> * @param The Type of this field >>> */ >>> public class Property { >>> private C parent; >>> private Class parentClass; >>> private Field[] fields; >>> private PropertyDescriptor[] pd = null; >>> /** >>> * Constructor used to create Property objects. The Parent object >>> may be >>> * null, but should normally be specified as it can be overridden >>> anyway. >>> * @param parent C object that contains the field >>> * @param field Field describing this field >>> */ >>> public Property(C parent, String ... fieldNames) { >>> this.parent = parent; >>> this(parent.getClass(), fieldNames); >>> } >>> /** >>> * Constructor for unbound Properties, but also used internally >>> after >>> setting >>> * the parent object by the bound Property objects. >>> * @param parentClass Class of the parent object >>> * @param fieldNames String[] of field names >>> */ >>> public Property(ClassparentClass, String .. fieldNames) { >>> this.parentClass = parentClass; >>> fields = new Field[fieldNames.length]; >>> pd = new PropertyDescriptor[fieldNames.length]; >>> outer: for(int index = 0; index < fields.length; index++) { >>> Field[]dclFields = parentClass.getDeclaredFields(); >>> for(Field field:dclFields) { >>> if(field.getName().equals(fieldNames[index])) { >>> fields[index] = field; >>> field.setAccessible(true); >>> try { >>> BeanInfo beanInfo = >>> Introspector.getBeanInfo(parent.getClass()); >>> PropertyDescriptor[]props = >>> beanInfo.getPropertyDescriptors(); >>> for(PropertyDescriptor prop : props) { >>> if(prop.getName().equals(field.getName())) { >>> pd[index] = prop; >>> break; >>> } >>> } >>> } catch(Exception e) { /* assume can not find getter/ >>> setter >>> */ } >>> parentClass = field.getType(); >>> continue outer; >>> } >>> } >>> throw new IllegalArgumentException("Field " + fieldNames[index] + >>> " not found in class " + >>> parentClass.getCanonicalName()); >>> } >>> } >>> /** >>> * Getter from the field in the parent specified when this >>> Property was >>> created. >>> * @see Property.get(C otherParent) >>> * @return F the value of this field >>> */ >>> public F get() { >>> return get(parent); >>> } >>> /** >>> * Getter with explicit parent. >>> * This code will check see if this field is WriteOnly, and >>> complain if it >>> is. >>> * It will then see if the use has provided am explicit getter, >>> and call >>> that >>> * if present, otherwise it will just fetch the value through the >>> Field >>> provided >>> * method. >>> * @param otherParent C parent object >>> * @return F value of the field >>> */ >>> @SuppressWarnings("unchecked") // This should actually not be >>> needed, >>> // but the Field.get method is not >>> typed >>> public F get(C otherParent) { >>> Object result = otherParent; >>> try { >>> for(int index = 0; index < fields.length; index++) { >>> >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >>> throw new IllegalAccessException( >>> "Can not get from a WriteOnly field - " + >>> fields[index].getName()); >>> Method getter = pd[index] == null ? null : >>> pd[index].getReadMethod(); >>> if(getter == null) result = fields[index].get(result); >>> else result = getter.invoke(result); >>> } >>> } catch(Exception e) { >>> throw new RuntimeException("Should not occur exception", e); >>> } >>> return (F)result; >>> } >>> /** >>> * Setter to set the value of the field in the parent object >>> declared with >>> the >>> * Property object >>> * @param newValue F new value of this field >>> */ >>> public void set(F newValue) { >>> set(parent,newValue); >>> } >>> /** >>> * Setter to set the value of the field to an explicit parent >>> object. >>> * If there is a ReadOnly annotation, then we object. If there is >>> an >>> explicit >>> * setter then we use that, otherwise we set the field using the >>> Field >>> provided >>> * set method and if there is a PropertyChangeSupport field, fire a >>> property >>> * change event to it. >>> * We walk our way down the field chain, until we have the last >>> object and >>> its >>> * field, and then we do the set. >>> * @param parent C explicit parent object >>> * @param newValue F new value for field in parent >>> */ >>> public void set(C parent,F newValue) { >>> try { >>> Object last = parent; >>> int index; >>> for(index = 0; index < fields.length - 1; index++) { >>> >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >>> throw new IllegalAccessException( >>> "Can not get from a WriteOnly field - " + >>> fields[index].getName()); >>> Method getter = pd[index] == null ? null : >>> pd[index].getReadMethod(); >>> if(getter == null) last = fields[index].get(last); >>> else last = getter.invoke(last); >>> } >>> >>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) >>> throw new IllegalAccessException( >>> "Can not get from a WriteOnly field - " + >>> fields[index].getName()); >>> Method setter = pd[index] == null ? null : >>> pd[index].getWriteMethod(); >>> if(setter == null) { >>> PropertyChangeSupport pcs = findPcs(last.getClass()); >>> fields[index].set(last,newValue); >>> if(pcs != null) >>> pcs.firePropertyChange(fields[index].getName(), >>> newValue, >>> >>> fields[index].get(last)); >>> } else setter.invoke(last,newValue); >>> } catch(Exception e) { >>> throw new RuntimeException("Should not occur >>> exception", e); >>> } >>> } >>> /** >>> * This is used so that the caller can view the Field name >>> * @return String field name >>> */ >>> public String[] getFieldName() { >>> String[]names = new String[fields.length]; >>> for(int index = 0; index < fields.length; index++) { >>> names[index] = fields[index].getName(); >>> } >>> return names; >>> } >>> /** >>> * This method is used to fetch the Field array, which is useful >>> if you >>> need to >>> * access the Annotations of a field. >>> * @return Field[] the array of Fields describing this Property. >>> */ >>> public Field[] getFields() { >>> return fields; >>> } >>> /** >>> * This private method looks for a PropertyChangeSupport object in >>> the >>> class and >>> * if one is found it will return it. It looks right the way up >>> the class >>> tree >>> * by recurring up the superClasses. >>> * @param parent Class to check for PropertyChangeSupport fields >>> * @return PropertyChangeSupport first found object, or null if >>> not found >>> */ >>> private PropertyChangeSupport findPcs(Class parent) { >>> Field fields[] = parent.getDeclaredFields(); >>> for(Field field:fields) { >>> field.setAccessible(true); >>> try { >>> if(field.getType() == PropertyChangeSupport.class) >>> return (PropertyChangeSupport)field.get(parent); >>> } catch(Exception e) { } >>> } >>> // If we did not find it then try the superclass >>> ClasssuperClass = parent.getSuperclass(); >>> if(superClass == null) return null; >>> return findPcs(parent.getClass().getSuperclass()); >>> } >>> /** >>> * This annotation is used to mark a field as WriteOnly, i.e. it >>> can not >>> be read. >>> * This stops the automatic getter operation. >>> */ >>> public @interface WriteOnly { >>> } >>> /** >>> * This annotation is used to mark a field as ReadOnly, i.e. it >>> can not be >>> written. >>> * This stops the automatic setter operation. >>> */ >>> public @interface ReadOnly { >>> } >>> } >>> >>> >> >> > > From reinier at zwitserloot.com Tue Mar 3 16:09:40 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 4 Mar 2009 01:09:40 +0100 Subject: PROPOSAL: Static Methods in Interfaces Message-ID: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> Apparently the previous version's attachment didn't come through properly, so here's an inline HTML version. Static Methods in Interfaces VERSION This is version 1.0. The latest version can be found at http://tinyurl.com/static-methods-in-interfaces AUTHOR(S): Reinier Zwitserloot Roel Spilker OVERVIEW FEATURE SUMMARY: Static methods are now allowed in interfaces. The static method is defined with a method body in the interface and it exists in the namespace of the interface; it does not imply that implementing classes must implement the method. This feature is especially useful for utility methods that belong with a given interface. For example, many methods in java.util.Collections are specific for a particular interface, such as sort (java.util.List) and unmodifiableMap (java.util.Map). MAJOR ADVANTAGE: Allows maintaining code that 'goes together' in a single file, and helps auto-complete dialogs come up with more relevant operations on any given object. Also improves syntax by using a more specific term (e.g. List) instead of a usually somewhat generic grab bag utility class (e.g. Collections). Also allows interfaces to contain pseudo- constructor, for common tasks and default implementations (e.g. java.io.FileFilter could contain a method to create a new one based on a file extension). This proposal will also offer an easy solution to the current deplorable situation that you need to call on 2 separate utility classes, one of which has no relation to List whatsoever, just to create an immutable List: Collections.unmodifiableList(Arrays.asList(items)) can be replaced with the much more elegant List.of(items) MAJOR BENEFIT: Java (the language) is very strictly namespaced; the default package is discouraged and java does not allow dynamically adding or changing methods at runtime (so called monkey patching). Java also does not support mixins nor multiple inheritance. Therefore, the platform currently lacks a way to meaningfully offer utility methods for interfaces. Instead, kludges such as java.util.Collections exist as a vehicle for these support methods. Furthermore, static methods in interfaces are currently illegal (see JLS Chapter 9.4) so this proposed change does not complicate the language very much. MAJOR DISADVANTAGE: Confusion about the notion that static methods in java in java are not 'virtual' (they are not inherited and cannot be overridden) may cause a programmer to erroneously think a static method in an interface implies it is something an implementing class must implement. However, the mandatory method body should help avoid confusion. Slightly more complex language specification. No opportunity to use the static keyword in interfaces for some sort of factory interface concept (an interface for constructors and static methods). The proposed implementation is also somewhat inconsistent in rare cases compared to static methods in classes. While this inconsistency is a disadvantage, the authors do not believe there's a way to avoid this inconsistency without creating more serious disadvantages ALTERNATIVES: The usual solution to this problem right now is to offer a separate utility class (a class that is not instantiable and contains only static methods) that contain the utility methods, along with a reference in the javadoc of the interface to this utility class. For example, java.util.Collections is the utility class that goes with Map, List, Set and other Java Collections API interfaces. The use case of default / common implementations is currently handled by having an implementing class with a constructor. For example, a new class called java.io.ExtensionFileFilter could be made that takes a String and implements FileFilter. The sugar employed by this proposal is itself also an alternative: Creating a member type class that contains the static methods (With just a backwards and migration compatible API addition, you could make List.Utils.of(items) work in java 1.6 notation (The Utils class is an inner member type to the interface, which is legal, and as it is a class, may contain static methods. EXAMPLES SIMPLE EXAMPLE: public interface Foo { public static void printHello() { System.out.println("Hello, World!"); } } Foo.printHello(); //Prints 'Hello, World! ADVANCED EXAMPLE: package java.util; public interface List extends Collection { int size(); // List's other instance methods public static List of(final T... items) { return new AbstractList() { public T get(int index) { return items[index]; } public int size() { return items.length; } }; } } List list = List.of("foo", "bar"); assert list.get(0).equals("foo"); assert list.size() == 2; DETAILS SPECIFICATION: Java Language Specification changes: JLS Chapter 9.1.4: original: InterfaceMemberDeclaration: ConstantDeclaration AbstractMethodDeclaration ClassDeclaration InterfaceDeclaration ; replacement: InterfaceMemberDeclaration: ConstantDeclaration AbstractMethodDeclaration StaticMethodDeclaration ClassDeclaration InterfaceDeclaration ; JLS Chapter 9.4: original: Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block. replacement: Every non-static method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block. original: Note that a method declarated in an interface must not be declared static, or a compile-time error occurs, because static methods cannot be abstract. replacement: None - this line is removed from the JLS. JLS Chapter 9.5 and 9.6 are bumped to 9.6 and 9.7, respectively, and a new 9.5 is added: 9.5 Static Method Declarations StaticMethodDeclaration: StaticMethodModifiers TypeParametersopt ResultType MethodDeclarator Throwsopt ; StaticMethodModifiers: static MethodModifiers static static MethodModifiers The MethodModifiers are described in ?8.4.3, The access modifier public is discussed in ?6.6. A compile-time error occurs if the same modifier appears more than once in an static method declaration. The static keyword is mandatory. Static method declarations in interfaces are either public or private; protected and package private are not allowed. If no access modifier is specified, the static method is implicitly public, to be consistent with the notion that everything else in an interface, be it a field, an abstract method, or a member type, is implicitly public. Private static methods are allowed to accommodate helper methods. Other than being limited to public and private access, a static interface method is identical to a method declaration in a class (?8.4). During compilation, all static methods are stored in a synthetic inner class called $Methods, which is generated with a private constructor. If that class already exists in the source file, a compile-time error occurs. JLS Chapter 15.12.1: The specification of method invocation forms that invoke static methods are updated to refer to 'class or interface' instead of just 'class', and the following line: If TypeName is the name of an interface rather than a class, then a compile-time error occurs, because this form can invoke only static methods and interfaces have no static methods. is replaced with: If TypeName is the name of an interface rather than a class, then the call is presumed to be for a static method in a synthetic member class of the interface, called $Methods. If the method exists, the class to be searched is denoted by TypeName.$Methods where $Methods is a static inner class of the interface TypeName, literally called "$Methods". COMPILATION: Any interface with static methods is sugared by creating a member class called $Methods which will contain the static methods. The generated $Methods class should also have a private constructor, as they aren't supposed to be instantiable. If the $Methods inner class has been explicitly created in the source file, any static methods in the interface are considered a compile-time error (if the class is present in the source file, the assumption is that the programmer wants to keep manual control of the static methods). For method invocations, currently, an invocation of the form InterfaceName.method(), will result in an immediate compile error. The compiler will instead need to search the $Methods class (if any exists) for the method, and rewrite the call toInterfaceName. $Methods.method() if the method does exist in the $Methods inner class. The method is not inherited by any member types. So, the second 'hello()' call in the following example would result in a compile time error (method not found): public interface Foo { public static void hello() { System.out.println("Hello, World!"); } } public class Bar implements Foo {} Foo.hello(); //works Bar.hello(); //does not work This is an unfortunate inconsistency (if Foo was a class, Bar.hello() would work just fine), but there is no way to adequately recreate this inheritance system with syntax sugar. Even with a more thorough solution (that involves changing the JVM), allowing inheritance of the methods would mean allowing diamond relations (where 1 class implements 2 interfaces, that each have the same static method signature with different implementations. Which one is chosen?). This is principally the reason why this proposal suggests not letting the method be inherited. However, if inheritance is deemed important, the alternate solution is to fix the JVM Specification chapter 2.13 in similar ways as the JLS, and make static methods legal in interfaces. The Type.method() invocation would then require a much broader search and should give up with a compile-time error if a diamond relation is found, listing the conflicting implementations and asking the programmer to choose one. As this proposal breaks the norm on inheritance already, the following syntax is not allowed either, which for static methods in classes is currently legal but flagged as a warning in all popular IDEs and code style checkers: Character c = 'f'; c.isWhiteSpace(' '); //if Character was an interface, this would not be legal. TESTING: This new feature can be tested by applying the existing tests for static method calls to static methods in interfaces. Compilation and class file parsing needs to be expanded to apply tests to read method bodies in interfaces as well as classes. "Finding" the static method inside the $Methods inner class during compilation needs to be tested, which is straight forward. The changes described below to the reflective APIs also need testing, which is also straight forward. LIBRARY SUPPORT: No library support is needed. However, it would be advisable to update various interfaces in the core java APIs with useful static utility methods. Some examples: java.util.List/Map/Set: All methods in java.util.Collections should also be made available on the appropriate java collections API interface. java.io.Closeable: should contain a utility method 'closeAndIgnoreException' (arguably better suited on InputStream instead). java.util.List/Set: Should contain an 'of' method that makes unmodifiable lists and sets via varargs. java.io.FileFilter: Should contain an 'ofExtension(String)' method that creates a FileFilter for the provided extension. REFLECTIVE APIS: Currently, synthetic members are not treated specially by the reflection API. Therefore, this proposal does not require any reflective API changes. However, if transparency of the static method in interfaces proposal is required for the reflection API, the following 4 changes need to be made: There are 3 methods in java.lang.Class which need minor changes: getMethod(), getDeclaredMethods(), and getMethods(). These method finders will need to presume all static methods in a member type called $Methods are considered part of the type itself, and thus need to be returned as well, if the class object represents an interface. Because getDeclaredMethods() doesn't return methods in supertypes, and getMethod()/getMethods() only return accessible members of supertypes, none of these methods need to look in $Methods inner types of supertypes. These methods just need to look in the actual interface represented by the class object for a $Methods. There is one method in java.lang.Method that needs a minor change: the getDeclaringClass() method needs to return the Class object representing the interface, and not the $Methodssynthetic class, when invoked on a static method of an interface. OTHER CHANGES: No changes required. MIGRATION: No migration is needed. However, any java projects that currently employ utility classes (defined as having a private constructor that is not called anywhere in scope) which either return interface types, or take as first parameter an interface type, or both, where all previously mentioned interfaces are in the same package, are likely candidates for moving or copying to the relevant interface. Thus, IDEs can offer refactor advice to perform this task automatically and to find likely candidates. Such a refactor tool would for example identify all methods injava.util.Collections. COMPATIBILITY BREAKING CHANGES: Existing source that already uses an inner type named $Methods in an interface will change semantics when this proposal is implemented, primarily when queried via reflection. Between the vanishingly small odds of both a $Methods already existing and its methods being queried by the reflection API, and the general rule that $ should only be used in type names by compilers, the potential breaking change is hardly worth mentioning. EXISTING PROGRAMS: Existing programs are not affected by this change, other than as described above in the 'breaking changes' section. REFERENCES EXISTING BUGS: None. URL FOR PROTOTYPE (optional): None. From jjb at google.com Tue Mar 3 17:47:52 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 17:47:52 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> Message-ID: <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> I have modified the proposal in light of Mark's example. The only change is that the Disposable interface is no longer parameterized. This eliminates the incompatibility noted by Neal; so far as I know, the revised proposal introduces no incompatibilities. It can be found here: http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh . Happy reading, Josh From jjb at google.com Tue Mar 3 17:22:12 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 17:22:12 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> Message-ID: <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> Mark, Sorry for the delay, and thanks so much for the report! This is an interesting case. It seems unfortunate that DataCacheManagerImpl extends Closeable, given that its close method doesn't throw any checked exceptions. But it got me thinking, and I came to the conclusion that there's no reason for the Disposable interface to be parameterized! Its close method should just throw Exception. Then Closeable and DataCacheManager can both extend Disposable. The Disposable interface won't be terribly useful as a parameter type, but who cares? Its raison d'etre is the automatic resource management statement. In this context, the close method is invoked on a resource using its declared type. That means that it throws whatever exceptions it's declared to throw (as per the desugaring in my proposal). I will modify the proposal accordingly and repost it. I think this is a real improvement! It's both simpler and more broadly applicable. Thanks so much, Josh On Sun, Mar 1, 2009 at 1:54 AM, Mark Mahieu wrote: > > On 28 Feb 2009, at 19:08, Joshua Bloch wrote: > > Neal, >> >> On Sat, Feb 28, 2009 at 7:41 AM, Neal Gafter wrote: >> >> Josh- >>> >>> The compatibility section must document incompatibilities, whether or >>> not you judge them likely to cause problems in practice. >>> >> >> >> Good point. I will add this one. And I am still interested in whether >> anyone can find some code in an existing codebase that tickles this. >> >> > > Josh, > > The worst case I've turned up so far is the following, which would not be > broken by your proposal, but I think it would be restricted in its ability > to take advantage of it without further changes downstream: > > http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/ > javadoc/org/apache/openjpa/datacache/DataCacheManagerImpl.html > > Here, the class DataCacheManagerImpl implements two interfaces, both of > which could logically be retrofitted with Disposable, but doing so would > then break DataCacheManagerImpl since different type arguments would be > needed (Exception and RuntimeException). > > (I think the idea is that an alternative implementation of DataCacheManager > can be specified by the user of this library; it seems quite likely that > these would extend the default DataCacheManagerImpl implementation.) > > Depends on how ticklish you are I guess. For me it's a hint that an > interface may not be the best mechanism. > > Regards, > > Mark > > From neal at gafter.com Tue Mar 3 18:08:12 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 18:08:12 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> Message-ID: <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> Given all the gnashing of teeth over the fact that Closeable's close method throws IOException, I can only imagine the pain that Disposable.close() throwing Exception will cause. On Tue, Mar 3, 2009 at 5:47 PM, Joshua Bloch wrote: > I have modified the proposal in light of Mark's example. ?The only change is > that the Disposable interface is no longer parameterized. ?This eliminates > the incompatibility noted by Neal; so far as I know, the revised proposal > introduces no incompatibilities. It can be found here: > http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh . > ? ? Happy reading, > > ? ? Josh > > From neal at gafter.com Tue Mar 3 18:16:12 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 18:16:12 -0800 Subject: Automatic Resource Management and Simple Resource Clean-up In-Reply-To: <49AD9EBE.5010808@vanellen.de> References: <49AD9EBE.5010808@vanellen.de> Message-ID: <15e8b9d20903031816q64e74c5apf8cb7792f34a46a6@mail.gmail.com> Thorsten- I think you're on the right track when you suggest the resource management library to encapsulate the implementation of proper resource management. A library solution could be flexible enough to handle the more complex cases like transactions too. Regards, Neal On Tue, Mar 3, 2009 at 1:18 PM, Thorsten van Ellen wrote: > Josh, Neal and Roger! > > I have had this idea also for a long time. I think it is in a "tradition" of > java of suppressing typical programming errors. A good example for the tradition > is automatic memory management and garbage collection that is a very complex > mechanism to avoid one very typical programming error. > > Management of resources other than memory usually is really as buggy as memory > management. My observation is that resource management is one of the most > frequent bug pattern I know of. Look at any project: you hardly find correct > optimal implemented examples and you nearly always find bugs in every non > trivial project. Analysing/finding the bug often is very difficult like finding > memory management bugs. > > It seems to me, the feature benefit is worth some more effort. The effort of > thinking a bit more about it might be not too much, especially if your heading > toward a "minimal" solution like "simple clean up", but I don't know what is > "affordable" in jdk7-schedule. > > Just to put in some additional/new ideas and to "make the cake bigger" before it > is reduced to the optimal solution ("brain-storming", sometimes thinkind around > a corner helps): > > Both proposed solutions might have problems with resource management, that is > distributed/shared/spread between two or more separated methods. Such problems > might be solved with a kind of GOF-"pattern", interfaces and a tiny "resource > management library". > > And there exist even more complicated resource management problems like ACID > database transactions that do not only have one "close"-operation but two > (commit and rollback) and a more complex decision process between those. > > But regarding these additional ideas may also be counterproductive for a tiny > language modification that solves 98 % of the typical bugs and therefore may > also be ignored! > > Best regards > > Thorsten van Ellen > > From reinier at zwitserloot.com Tue Mar 3 18:26:13 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 4 Mar 2009 03:26:13 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> Message-ID: <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> The new Disposable idea makes this proposal much cleaner, Josh. I like it. Neal, could you perhaps elaborate on the pain that Disposable is going to cause? Insinuating that proposals are Bad Ideas without any specifics whatsoever seems better suited to some sort of voting cycle. On this mailing list it seems counter-productive to say the least. --Reinier Zwitserloot On Mar 4, 2009, at 03:08, Neal Gafter wrote: > Given all the gnashing of teeth over the fact that Closeable's close > method throws IOException, I can only imagine the pain that > Disposable.close() throwing Exception will cause. > > On Tue, Mar 3, 2009 at 5:47 PM, Joshua Bloch wrote: >> I have modified the proposal in light of Mark's example. The only >> change is >> that the Disposable interface is no longer parameterized. This >> eliminates >> the incompatibility noted by Neal; so far as I know, the revised >> proposal >> introduces no incompatibilities. It can be found here: >> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh . >> Happy reading, >> >> Josh >> >> > From Joe.Darcy at Sun.COM Tue Mar 3 18:28:26 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 03 Mar 2009 18:28:26 -0800 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <1236114437.49ad9c05d493c@www.paradise.net.nz> References: <49AABBA2.3040009@joda.org> <1631da7d0903010948h140c15e9hf1ddef3a0b837c9e@mail.gmail.com> <49AD1B58.5060305@joda.org> <1236114437.49ad9c05d493c@www.paradise.net.nz> Message-ID: <49ADE74A.4060407@sun.com> cadenza at paradise.net.nz wrote: >> This will be very confusing when you use Foo from another part of your >> application and expect the value to be non-null and get a NPE. In fact >> the @Nonnull is positvely misleading. >> >> Basically, you can't rely on JSR-305. The information needs to be >> rechecked. Thus, whats the point in using it at all?!! Documentation >> perhaps? Annotations are not suitable for handling language level issues >> >> like nulls. >> > > An annotation processor visible to javac could perform the @nonNull check and > cause the compilation to fail. > [snip] ... and such checking is done with the Checkers framework associated with JSR 308 that is built on top of annotation processing: http://groups.csail.mit.edu/pag/jsr308/ -Joe From jjb at google.com Tue Mar 3 18:29:08 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 18:29:08 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> Message-ID: <17b2302a0903031829n6cf2d920o7e3fbb1d1838669d@mail.gmail.com> Reiner, On Tue, Mar 3, 2009 at 6:26 PM, Reinier Zwitserloot wrote: > The new Disposable idea makes this proposal much cleaner, Josh. I like > it. > Thanks very much! I slapped myself on the forehead when I thought of it. Sometimes the simplest ideas are the hardest to think of. Josh From reinier at zwitserloot.com Tue Mar 3 15:11:41 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 4 Mar 2009 00:11:41 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903032200.28367.david.goodenough@linkchoose.co.uk> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <200903032104.58445.david.goodenough@linkchoose.co.uk> <974754BA-9815-4C98-B868-3D793AFEF79A@zwitserloot.com> <200903032200.28367.david.goodenough@linkchoose.co.uk> Message-ID: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> But it seems that we _would_ lose a thing or two with this proposal. For example, if a complete properties proposal supports full backwards compatibility and generates getters and setters, then we have a bunch of code around that uses the foo#bar notation, which is by then already outdated, and would in fact get in the way of using foo#bar notation as a shorthand for calling the appropriate getter/setter. I don't know if that is a desired syntax sugar, but the point is: Your proposal would effectively make it impossible to add that later, as it would already be shorthand for creating a Property object. The # and the backtick are the only easily typed symbols that have no meaning whatsoever in java right now. Using one up for an simplified properties proposal is another serious disdvantage. I don't think your proposal makes property support light enough to warrant its inclusion in project coin. That's not to say I have something against properties; on the contrary, I love the idea and I'm very impressed with the way properties work in JavaFX. All the more reason to get it right instead of using a bandage. --Reinier Zwitserloot On Mar 3, 2009, at 23:00, David Goodenough wrote: > Well that depends on what you mean by a complete proposal. > > There are two parts to the use of Properties. There is the framework > side, inside BeansBinding or JPA and then there is the consumer > side, the application code. > > My proposal is very simple on the consumer side (the only bit needed > is the # notation). You can use clasical getters and setters (a > nuisance > but everyone understands them), or the simple getter/setter mechanism > that my Property provides. So for the consumer my proposal is real > simple. All you need do is add (either explicity or by byte code > enhancement) > a PropertyChangeSupport object and the relevant methods and you > are home and dry. > > For the Frameworks, well you only write them once. Even so something > nice and simple appeals and my proposal is simple. > > It may not be Beans as we know it, but they never were integrated > properly into Java. But its really not that dissimilar just slightly > different. > > So other than a little sytactic sugar (not having to code the > PropertyChangeSupport object) we have not really lost anything of > the "full" solution. Having a Bound annotation which would add this > under the > covers with a byte code enhancer would not be difficult. The implicit > getters and setters come with the package. So the question to be > asked whether a fuller solution is really needed. > > David > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: >> The language change required for your proposal is indeed lighter, but >> to understand it, it is seems a lot more complicated. >> >> Also, it would be infeasible to introduce a 'lightweight' (according >> to anyone's definition) proposal now that is lacking in certain >> aspects, and then fix it later, unless that fix is syntactically very >> similar and backwards- and migration compatible. That's the major >> beef >> I have with this proposal: It effectively shuts the door on any other >> property proposal. In my view, a proposal solves the problem >> properly, >> or shouldn't be added at all; no quick hacky fixes that aren't part >> of >> a planned evolution path to a complete solution. >> >> If you can highlight how a complete properties proposal will >> seamlessly work with your syntax, I'm more inclined to like it. >> >> --Reinier Zwitserloot >> >> On Mar 3, 2009, at 22:04, David Goodenough wrote: >>> Yes I do. What you propose is much more invasive. Look at it >>> again and maybe you will see the Light(ness). >>> >>> David >>> >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: >>>> You call that lightweight? >>>> >>>> How about following the beans spec more to the letter and just >>>> generate the addPropertyChangeListener, >>>> removePropertyChangeListener, >>>> setX(), and get/isX() method in response to seeing a keyword or >>>> annotation on a given field. You'll have to work out the details, >>>> but >>>> that sounds far, far simpler to understand. >>>> >>>> You'll need to flesh this out, but it would look something like: >>>> >>>> public class Foo { >>>> private property int x; >>>> } >>>> >>>> Which would generate the addPropertyChangeListener, >>>> removePropertyChangeListener, setX, getX methods, all public, along >>>> with the required infrastructure to make it tick. If you don't like >>>> the generation, for example because you want the setter to be >>>> package >>>> private, you just add the setter in the source file; the keyword >>>> will >>>> only generate the missing stuff. It doesn't cover every use case, >>>> but >>>> there's always the alternative of doing whatever people do now with >>>> beans. Something you didn't mention in your proposal, by the way. >>>> >>>> I think there's also a fully fleshed out property proposal >>>> (including >>>> a 'property' keyword) out there somewhere. >>>> >>>> Possibly make a way to opt out of generating the property change >>>> listener support, and just the getters/setters. >>>> --Reinier Zwitserloot >>>> >>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: >>>>> Below is my proposal for Lightweight Properties. I know that the >>>>> syntax >>>>> change is an abbomination to some people, but I have tried to >>>>> reduce >>>>> this to its absolute minimum, while still getting a significant >>>>> benefit. >>>>> >>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>>>> >>>>> AUTHOR(S): >>>>> >>>>> David Goodenough, long time Java user. I can be reached at >>>>> david.goodenough at linkchoose.co.uk. >>>>> >>>>> OVERVIEW >>>>> >>>>> FEATURE SUMMARY: >>>>> >>>>> Lightweight Property support >>>>> >>>>> MAJOR ADVANTAGE: >>>>> >>>>> Both BeansBinding (whether JSR-295 or others such an JFace or the >>>>> JGoodies >>>>> binding) and the JPA Criteria API currently require field names >>>>> (as >>>>> Strings) >>>>> as arguments, which an IDE/compiler can not check. With this >>>>> proposal the >>>>> strings would be abandoned, and the IDE/compiler will be able to >>>>> check the >>>>> correctness of the code. >>>>> >>>>> MAJOR BENEFIT: >>>>> >>>>> Manual checking no longer required. This proposal introduces a >>>>> simple well >>>>> defined IDE/compiler checkable solution. >>>>> >>>>> MAJOR DISADVANTAGE: >>>>> >>>>> It is a language change, and this seems to upset some people. >>>>> >>>>> ALTERNATIVES: >>>>> >>>>> None really, apart from using another language or continuing to >>>>> use >>>>> String >>>>> names. The existing solutions all require String names which are >>>>> uncheckable. >>>>> >>>>> EXAMPLES >>>>> >>>>> Lets assume we have a POJO called foo, of type Foo with a field >>>>> bar >>>>> of type >>>>> Bar, which itself has a field of type Jim called jim. >>>>> >>>>> There are two forms of lightweight properties:- >>>>> >>>>> 1) foo#bar would be translated by the compiler into:- >>>>> >>>>> new Property(foo,"bar"); >>>>> >>>>> while foo#bar#jim would be translated into:- >>>>> >>>>> new Property(foo,"bar","jim"); >>>>> >>>>> 2) Foo#bar would be translated into:- >>>>> >>>>> new Property(Foo.class,"bar"); >>>>> >>>>> while Foo#bar#jim would be translated into:- >>>>> >>>>> new Property(Foo.class,"bar","jim"); >>>>> >>>>> These two forms create (1) a bound Property, or (2) an unbound >>>>> one. >>>>> Bound >>>>> Properties are explicitly bound to a particular instance of a >>>>> class >>>>> (in this >>>>> case foo), while unbound Properties are templates which can be >>>>> applied to any >>>>> instance of class Foo. Actually bound properties can also be >>>>> used as >>>>> unbound >>>>> properties, but that is a harmless and useful side effect not a >>>>> primary >>>>> intent. >>>>> >>>>> The Property class would need to be added (it is appended below), >>>>> and should >>>>> be added either to the java.beans package or to the >>>>> java.lang.reflect package >>>>> (with which is probably has more in common). >>>>> >>>>> Syntactically a "#" can be placed wherever a "." can be placed >>>>> (except inside >>>>> a number), and the same checks need to be made (that each field to >>>>> the right >>>>> of a # is a field in the left hand side) as would be made for a >>>>> ".". >>>>> The only >>>>> difference is in field visibility - For the "#" any field is >>>>> visible, which >>>>> follows the model currently available in the Field class with >>>>> getDeclaredFields(). It also follows the model that while a field >>>>> might be >>>>> private and therefore not directly accessible from outside, >>>>> getters >>>>> and >>>>> setters can provide access. >>>>> >>>>> The Property object provides type safe access to the field in the >>>>> form of >>>>> getters and setters. These come in pairs, one for bound and the >>>>> other for >>>>> unbound access. So for bound access no object is required to fetch >>>>> the value, >>>>> for an unbound object the parent object needs to be specified. >>>>> So if >>>>> we >>>>> have:- >>>>> >>>>> Propertyprop = foo#bar; >>>>> >>>>> we can later say:- >>>>> >>>>> Bar b = prop.get(); >>>>> >>>>> or for an unbound one from a second Foo object foo2:- >>>>> >>>>> Bar b = prop.get(foo2); >>>>> >>>>> The getters and setters in the Property object will defer to >>>>> explicitly coded >>>>> getters and setters if present, otherwise they will use the Field >>>>> getter and >>>>> setter. >>>>> >>>>> If a setter is not explicitly coded, the implicit setter will look >>>>> for a >>>>> PropertyChangeSupport object in the parent object of the rightmost >>>>> field and >>>>> fire a PropertyChangeEvent to that object. >>>>> >>>>> There are also two Annotations provided by the Property class, >>>>> ReadOnly and >>>>> WriteOnly. These stop implicit getters and setters from trying to >>>>> read/write >>>>> the property. >>>>> >>>>> Talking of Annotations, this notation can also be used to get at >>>>> the >>>>> Annotations for a field. So to test for the presence of an >>>>> Annotation Ann on >>>>> Foo.bar we would use:- >>>>> >>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... >>>>> >>>>> SIMPLE EXAMPLE: >>>>> >>>>> To take an example from BeansBinding (taken from Shannon Hickey's >>>>> blog):- >>>>> >>>>> // create a BeanProperty representing a bean's firstName >>>>> Property firstP = BeanProperty.create("firstName"); >>>>> // Bind Duke's first name to the text property of a Swing >>>>> JTextField >>>>> BeanProperty textP = BeanProperty.create("text"); >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, >>>>> firstP, textfield, textP); >>>>> binding.bind(); >>>>> >>>>> >>>>> would instead be written:- >>>>> >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, >>>>> duke#firstName, textfield#text); >>>>> binding.bind(); >>>>> >>>>> which of course can be checked by the IDE/compiler, and will not >>>>> wait until >>>>> run time (not even instantiation time) to show up the error. >>>>> >>>>> ADVANCED EXAMPLE: >>>>> >>>>> For a JComboBox (or JList or JTable or JTree) there is a need to >>>>> map >>>>> a list of >>>>> objects to the value strings (or column contents). For this we >>>>> need >>>>> to have >>>>> an unbound Property which can be applied to each element of the >>>>> list. >>>>> >>>>> Duke duke; >>>>> Listdukes; >>>>> BoundComboBox combo = new >>>>> BoundComboBox(dukes,Duke#fullname,this#duke); >>>>> >>>>> and now the combo box will be populated from the list dukes, and >>>>> the >>>>> display >>>>> values in the list will be taken from the fullname field of each >>>>> Duke >>>>> element, and the initial value will be set from the local class >>>>> field duke >>>>> and any changes to the combo box selected element will be >>>>> reflected >>>>> back to >>>>> the duke field. >>>>> >>>>> DETAILS >>>>> >>>>> SPECIFICATION: >>>>> >>>>> This proposal adds a new syntactic element, "#", which can be used >>>>> in the same >>>>> way that "." can be used to qualify fields within a Java object. >>>>> >>>>> COMPILATION: >>>>> >>>>> This proposal requires no change to the class files, and is >>>>> implemented by a >>>>> simple generation of the required instance using the relevant >>>>> Property >>>>> constructor. Obviously the compiler would have to make sure that >>>>> the >>>>> use that >>>>> the property object was being put to (in the examples above the >>>>> left >>>>> hand >>>>> side of the assignment) had the correct Generic attributes. >>>>> >>>>> TESTING: >>>>> >>>>> How can the feature be tested? >>>>> >>>>> LIBRARY SUPPORT: >>>>> >>>>> The new Property class is required (see below). >>>>> >>>>> REFLECTIVE APIS: >>>>> >>>>> No changes are required to the reflective APIs although it makes >>>>> extensive use >>>>> of those APIs. >>>>> >>>>> OTHER CHANGES: >>>>> >>>>> No other changes are requires. >>>>> >>>>> MIGRATION: >>>>> >>>>> Fortunately there is no code that is formally part of J2SE 6 which >>>>> uses such >>>>> Properties. There are however two proposals which will need it >>>>> (BeansBinding >>>>> and JPA Criteria API), but neither of these seem to be destined to >>>>> be part of >>>>> J2SE 7 (BeansBinding seems to have died the death and the Criteria >>>>> API would >>>>> be part of the next J2EE which will follow J2SE 7), so this will >>>>> provide a >>>>> base for them to use and no existing code need to be updated. >>>>> >>>>> There are other extant Beans-Binding libraries, which could be >>>>> modified to use >>>>> this proposal, but as none of the existing features have been >>>>> changed there >>>>> is no need to change them (other than for type safety and >>>>> compiler/ >>>>> IDE >>>>> checkability). >>>>> >>>>> COMPATIBILITY >>>>> >>>>> BREAKING CHANGES: >>>>> >>>>> None. This change should not make any existing correct code >>>>> fail to >>>>> compile >>>>> or run or change the way in which it compiles/runs. >>>>> >>>>> EXISTING PROGRAMS: >>>>> >>>>> No change required to any existing programs >>>>> >>>>> REFERENCES >>>>> >>>>> EXISTING BUGS: >>>>> >>>>> None >>>>> >>>>> URL FOR PROTOTYPE (optional): >>>>> >>>>> I do not have the knowledge to make changes to the compiler, and >>>>> the >>>>> only >>>>> documentation making such changes concentrated on adding operators >>>>> not >>>>> changes at this level. So there is no prototype of the compiler >>>>> part, but the >>>>> Property class follows:- >>>>> >>>>> package java.lang.reflect; >>>>> >>>>> import java.beans.BeanInfo; >>>>> import java.beans.Introspector; >>>>> import java.beans.PropertyChangeSupport; >>>>> import java.beans.PropertyDescriptor; >>>>> import java.lang.reflect.Field; >>>>> import java.lang.reflect.Method; >>>>> >>>>> /** >>>>> * Property class >>>>> * This is the support class for use with the # notation to provide >>>>> lightweight >>>>> * Property support for Java. >>>>> * >>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd >>>>> * @licence LPGL V2 : details of which can be found at http:// >>>>> fsf.org. >>>>> * @author david.goodenough at linkchoose.co.uk >>>>> * >>>>> * @param The Parent class for this field >>>>> * @param The Type of this field >>>>> */ >>>>> public class Property { >>>>> private C parent; >>>>> private Class parentClass; >>>>> private Field[] fields; >>>>> private PropertyDescriptor[] pd = null; >>>>> /** >>>>> * Constructor used to create Property objects. The Parent object >>>>> may be >>>>> * null, but should normally be specified as it can be overridden >>>>> anyway. >>>>> * @param parent C object that contains the field >>>>> * @param field Field describing this field >>>>> */ >>>>> public Property(C parent, String ... fieldNames) { >>>>> this.parent = parent; >>>>> this(parent.getClass(), fieldNames); >>>>> } >>>>> /** >>>>> * Constructor for unbound Properties, but also used internally >>>>> after >>>>> setting >>>>> * the parent object by the bound Property objects. >>>>> * @param parentClass Class of the parent object >>>>> * @param fieldNames String[] of field names >>>>> */ >>>>> public Property(ClassparentClass, String .. fieldNames) { >>>>> this.parentClass = parentClass; >>>>> fields = new Field[fieldNames.length]; >>>>> pd = new PropertyDescriptor[fieldNames.length]; >>>>> outer: for(int index = 0; index < fields.length; index++) { >>>>> Field[]dclFields = parentClass.getDeclaredFields(); >>>>> for(Field field:dclFields) { >>>>> if(field.getName().equals(fieldNames[index])) { >>>>> fields[index] = field; >>>>> field.setAccessible(true); >>>>> try { >>>>> BeanInfo beanInfo = >>>>> Introspector.getBeanInfo(parent.getClass()); >>>>> PropertyDescriptor[]props = >>>>> beanInfo.getPropertyDescriptors(); >>>>> for(PropertyDescriptor prop : props) { >>>>> if(prop.getName().equals(field.getName())) { >>>>> pd[index] = prop; >>>>> break; >>>>> } >>>>> } >>>>> } catch(Exception e) { /* assume can not find getter/ >>>>> setter >>>>> */ } >>>>> parentClass = field.getType(); >>>>> continue outer; >>>>> } >>>>> } >>>>> throw new IllegalArgumentException("Field " + fieldNames[index] + >>>>> " not found in class " + >>>>> parentClass.getCanonicalName()); >>>>> } >>>>> } >>>>> /** >>>>> * Getter from the field in the parent specified when this >>>>> Property was >>>>> created. >>>>> * @see Property.get(C otherParent) >>>>> * @return F the value of this field >>>>> */ >>>>> public F get() { >>>>> return get(parent); >>>>> } >>>>> /** >>>>> * Getter with explicit parent. >>>>> * This code will check see if this field is WriteOnly, and >>>>> complain if it >>>>> is. >>>>> * It will then see if the use has provided am explicit getter, >>>>> and call >>>>> that >>>>> * if present, otherwise it will just fetch the value through the >>>>> Field >>>>> provided >>>>> * method. >>>>> * @param otherParent C parent object >>>>> * @return F value of the field >>>>> */ >>>>> @SuppressWarnings("unchecked") // This should actually not be >>>>> needed, >>>>> // but the Field.get method is not >>>>> typed >>>>> public F get(C otherParent) { >>>>> Object result = otherParent; >>>>> try { >>>>> for(int index = 0; index < fields.length; index++) { >>>>> >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >>>>> throw new IllegalAccessException( >>>>> "Can not get from a WriteOnly field - " + >>>>> fields[index].getName()); >>>>> Method getter = pd[index] == null ? null : >>>>> pd[index].getReadMethod(); >>>>> if(getter == null) result = fields[index].get(result); >>>>> else result = getter.invoke(result); >>>>> } >>>>> } catch(Exception e) { >>>>> throw new RuntimeException("Should not occur exception", e); >>>>> } >>>>> return (F)result; >>>>> } >>>>> /** >>>>> * Setter to set the value of the field in the parent object >>>>> declared with >>>>> the >>>>> * Property object >>>>> * @param newValue F new value of this field >>>>> */ >>>>> public void set(F newValue) { >>>>> set(parent,newValue); >>>>> } >>>>> /** >>>>> * Setter to set the value of the field to an explicit parent >>>>> object. >>>>> * If there is a ReadOnly annotation, then we object. If there is >>>>> an >>>>> explicit >>>>> * setter then we use that, otherwise we set the field using the >>>>> Field >>>>> provided >>>>> * set method and if there is a PropertyChangeSupport field, >>>>> fire a >>>>> property >>>>> * change event to it. >>>>> * We walk our way down the field chain, until we have the last >>>>> object and >>>>> its >>>>> * field, and then we do the set. >>>>> * @param parent C explicit parent object >>>>> * @param newValue F new value for field in parent >>>>> */ >>>>> public void set(C parent,F newValue) { >>>>> try { >>>>> Object last = parent; >>>>> int index; >>>>> for(index = 0; index < fields.length - 1; index++) { >>>>> >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) >>>>> throw new IllegalAccessException( >>>>> "Can not get from a WriteOnly field - " + >>>>> fields[index].getName()); >>>>> Method getter = pd[index] == null ? null : >>>>> pd[index].getReadMethod(); >>>>> if(getter == null) last = fields[index].get(last); >>>>> else last = getter.invoke(last); >>>>> } >>>>> >>>>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) >>>>> throw new IllegalAccessException( >>>>> "Can not get from a WriteOnly field - " + >>>>> fields[index].getName()); >>>>> Method setter = pd[index] == null ? null : >>>>> pd[index].getWriteMethod(); >>>>> if(setter == null) { >>>>> PropertyChangeSupport pcs = findPcs(last.getClass()); >>>>> fields[index].set(last,newValue); >>>>> if(pcs != null) >>>>> pcs.firePropertyChange(fields[index].getName(), >>>>> newValue, >>>>> >>>>> fields[index].get(last)); >>>>> } else setter.invoke(last,newValue); >>>>> } catch(Exception e) { >>>>> throw new RuntimeException("Should not occur >>>>> exception", e); >>>>> } >>>>> } >>>>> /** >>>>> * This is used so that the caller can view the Field name >>>>> * @return String field name >>>>> */ >>>>> public String[] getFieldName() { >>>>> String[]names = new String[fields.length]; >>>>> for(int index = 0; index < fields.length; index++) { >>>>> names[index] = fields[index].getName(); >>>>> } >>>>> return names; >>>>> } >>>>> /** >>>>> * This method is used to fetch the Field array, which is useful >>>>> if you >>>>> need to >>>>> * access the Annotations of a field. >>>>> * @return Field[] the array of Fields describing this Property. >>>>> */ >>>>> public Field[] getFields() { >>>>> return fields; >>>>> } >>>>> /** >>>>> * This private method looks for a PropertyChangeSupport object in >>>>> the >>>>> class and >>>>> * if one is found it will return it. It looks right the way up >>>>> the class >>>>> tree >>>>> * by recurring up the superClasses. >>>>> * @param parent Class to check for PropertyChangeSupport fields >>>>> * @return PropertyChangeSupport first found object, or null if >>>>> not found >>>>> */ >>>>> private PropertyChangeSupport findPcs(Class parent) { >>>>> Field fields[] = parent.getDeclaredFields(); >>>>> for(Field field:fields) { >>>>> field.setAccessible(true); >>>>> try { >>>>> if(field.getType() == PropertyChangeSupport.class) >>>>> return (PropertyChangeSupport)field.get(parent); >>>>> } catch(Exception e) { } >>>>> } >>>>> // If we did not find it then try the superclass >>>>> ClasssuperClass = parent.getSuperclass(); >>>>> if(superClass == null) return null; >>>>> return findPcs(parent.getClass().getSuperclass()); >>>>> } >>>>> /** >>>>> * This annotation is used to mark a field as WriteOnly, i.e. it >>>>> can not >>>>> be read. >>>>> * This stops the automatic getter operation. >>>>> */ >>>>> public @interface WriteOnly { >>>>> } >>>>> /** >>>>> * This annotation is used to mark a field as ReadOnly, i.e. it >>>>> can not be >>>>> written. >>>>> * This stops the automatic setter operation. >>>>> */ >>>>> public @interface ReadOnly { >>>>> } >>>>> } > > > From neal at gafter.com Tue Mar 3 18:47:57 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 18:47:57 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> Message-ID: <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> I guess I assumed you were aware why people complain about Closeable.close() throwing IOException. Josh alluded to this when he said that Disposable won't be terribly useful as a parameter type. When you pass it somewhere, the receiver must assume that the close() method throws any Exception, and that forces the receiver to write code to handle the whole Exception hierarchy. I think it's likely that programmers would want to pass a Disposable around so that the receiver can put a region of code under control of the resource (i.e. dispose it when the receiver arrives at some particular point of completion). I'm afraid this would just be trading one set of pain points for another. On Tue, Mar 3, 2009 at 6:26 PM, Reinier Zwitserloot wrote: > The new Disposable idea makes this proposal much cleaner, Josh. I like > it. > > Neal, could you perhaps elaborate on the pain that Disposable is going > to cause? Insinuating that proposals are Bad Ideas without any > specifics whatsoever seems better suited to some sort of voting cycle. > On this mailing list it seems counter-productive to say the least. > > ?--Reinier Zwitserloot > > > > On Mar 4, 2009, at 03:08, Neal Gafter wrote: > >> Given all the gnashing of teeth over the fact that Closeable's close >> method throws IOException, I can only imagine the pain that >> Disposable.close() throwing Exception will cause. >> >> On Tue, Mar 3, 2009 at 5:47 PM, Joshua Bloch wrote: >>> I have modified the proposal in light of Mark's example. ?The only >>> change is >>> that the Disposable interface is no longer parameterized. ?This >>> eliminates >>> the incompatibility noted by Neal; so far as I know, the revised >>> proposal >>> introduces no incompatibilities. It can be found here: >>> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh . >>> ? ? Happy reading, >>> >>> ? ? Josh >>> >>> >> > > > From crazybob at crazybob.org Tue Mar 3 19:16:27 2009 From: crazybob at crazybob.org (Bob Lee) Date: Tue, 3 Mar 2009 19:16:27 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> Message-ID: On Tue, Mar 3, 2009 at 6:47 PM, Neal Gafter wrote: > I guess I assumed you were aware why people complain about > Closeable.close() throwing IOException. Josh alluded to this when he > said that Disposable won't be terribly useful as a parameter type. > When you pass it somewhere, the receiver must assume that the close() > method throws any Exception, and that forces the receiver to write > code to handle the whole Exception hierarchy. I think it's likely > that programmers would want to pass a Disposable around so that the > receiver can put a region of code under control of the resource (i.e. > dispose it when the receiver arrives at some particular point of > completion). I'm afraid this would just be trading one set of pain > points for another. > I think the new Disposable interface will work out very nicely (we could also name it Resource instead, but that can be left for the EG). Bob From markmahieu at googlemail.com Tue Mar 3 19:39:16 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 4 Mar 2009 03:39:16 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> Message-ID: So would APIs be encouraged to define more specific Resource interfaces that narrow the thrown exception types ... interface SQLResource extends Resource { void dispose() throws SQLException { } } interface SWTResource extends Resource { void dispose() throws SWTException { } } etc? Mark On 4 Mar 2009, at 03:16, Bob Lee wrote: > On Tue, Mar 3, 2009 at 6:47 PM, Neal Gafter wrote: > >> I guess I assumed you were aware why people complain about >> Closeable.close() throwing IOException. Josh alluded to this when he >> said that Disposable won't be terribly useful as a parameter type. >> When you pass it somewhere, the receiver must assume that the close() >> method throws any Exception, and that forces the receiver to write >> code to handle the whole Exception hierarchy. I think it's likely >> that programmers would want to pass a Disposable around so that the >> receiver can put a region of code under control of the resource (i.e. >> dispose it when the receiver arrives at some particular point of >> completion). I'm afraid this would just be trading one set of pain >> points for another. >> > > I think the new Disposable interface will work out very nicely (we > could > also name it Resource instead, but that can be left for the EG). > > Bob > From jjb at google.com Tue Mar 3 19:41:18 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 19:41:18 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> Message-ID: <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> Neal, I think you may be missing the point here. The only use of this interface would be to make a type eligible for automatic resource management. It would never be used as a parameter type. There'd be no pain at all associated with it. Josh On Tue, Mar 3, 2009 at 6:47 PM, Neal Gafter wrote: > I guess I assumed you were aware why people complain about > Closeable.close() throwing IOException. Josh alluded to this when he > said that Disposable won't be terribly useful as a parameter type. > When you pass it somewhere, the receiver must assume that the close() > method throws any Exception, and that forces the receiver to write > code to handle the whole Exception hierarchy. I think it's likely > that programmers would want to pass a Disposable around so that the > receiver can put a region of code under control of the resource (i.e. > dispose it when the receiver arrives at some particular point of > completion). I'm afraid this would just be trading one set of pain > points for another. > > On Tue, Mar 3, 2009 at 6:26 PM, Reinier Zwitserloot > wrote: > - Show quoted text - > > The new Disposable idea makes this proposal much cleaner, Josh. I like > > it. > > > > Neal, could you perhaps elaborate on the pain that Disposable is going > > to cause? Insinuating that proposals are Bad Ideas without any > > specifics whatsoever seems better suited to some sort of voting cycle. > > On this mailing list it seems counter-productive to say the least. > > > > --Reinier Zwitserloot > > > > > > > > On Mar 4, 2009, at 03:08, Neal Gafter wrote: > > > >> Given all the gnashing of teeth over the fact that Closeable's close > >> method throws IOException, I can only imagine the pain that > >> Disposable.close() throwing Exception will cause. > >> > >> On Tue, Mar 3, 2009 at 5:47 PM, Joshua Bloch wrote: > >>> I have modified the proposal in light of Mark's example. The only > >>> change is > >>> that the Disposable interface is no longer parameterized. This > >>> eliminates > >>> the incompatibility noted by Neal; so far as I know, the revised > >>> proposal > >>> introduces no incompatibilities. It can be found here: > >>> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh . > >>> Happy reading, > >>> > >>> Josh > >>> > >>> > >> > > > > > > > > From jjb at google.com Tue Mar 3 19:47:07 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 19:47:07 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> Message-ID: <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> Mark, I don't see a compelling need for it. When in doubt, leave it out. Josh On Tue, Mar 3, 2009 at 7:39 PM, Mark Mahieu wrote: > So would APIs be encouraged to define more specific Resource > interfaces that narrow the thrown exception types ... > > interface SQLResource extends Resource { > void dispose() throws SQLException { } > } > > interface SWTResource extends Resource { > void dispose() throws SWTException { } > } > > etc? > I don't think there'd be any reason to do this. From mr at sun.com Tue Mar 3 19:55:01 2009 From: mr at sun.com (Mark Reinhold) Date: Tue, 03 Mar 2009 19:55:01 -0800 Subject: Simple Resource Clean-up In-Reply-To: neal@gafter.com; Tue, 03 Mar 2009 10:47:31 PST; <15e8b9d20903031047q235815d5i669b93575fefba75@mail.gmail.com> Message-ID: <20090304035501.866A4D06B@callebaut.niobe.net> > Date: Tue, 03 Mar 2009 10:47:31 -0800 > From: Neal Gafter > This would be the first instance of an annotation that changes the > meaning of the language's primitive constructs. Today, this kind of > thing is the role of declaration modifiers. We went to great length > to discourage this kind of use of annotations in the past; annotations > are to annotate the program text (in a way sometimes visible to > libraries), not define it. I understand the reluctance to add new > keywords to the language, but I advise against adding annotations as > language modifiers (essentially, adding modifiers with an "@" prefix). I completely agree. Annotations are, well, annotations. > The fact that this kind of flexibility is required suggests the > facility should be provided by libraries rather than hardcoded into > the language. If the only way for a library to support this kind of facility is for closures to be part of JDK 7, then this facility will not be in JDK 7. Now maybe I'm missing something, but unless one is going to recommend that developers use clunky nested classes for this sort of thing then I don't see how to implement this in a library -- absent closures. - Mark From neal at gafter.com Tue Mar 3 20:19:55 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 20:19:55 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> Message-ID: <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> I think you're missing the point, Josh. People do this today with Closeable, because that's the closest interface available that could be used to perform this function, but clients suffer from its exception signature. Disposable is better in one way - it would be retrofitted onto more classes - but much worse in its exception signature. You're saying that there's no pain because you can't use it as a parameter type. I'm saying that is the cause of the pain. The language construct that you're proposing does not supplant this technique of resource management, but the APIs you're proposing to go with it interfere with the technique. On Tue, Mar 3, 2009 at 7:41 PM, Joshua Bloch wrote: > Neal, > I think you may be missing the point here. ?The only use of this interface > would be to make a type eligible for automatic resource management. ?It > would never be used as a parameter type. ?There'd be no pain at all > associated with it. > ?? ? ? ? ?Josh > > On Tue, Mar 3, 2009 at 6:47 PM, Neal Gafter wrote: >> >> I guess I assumed you were aware why people complain about >> Closeable.close() throwing IOException. ?Josh alluded to this when he >> said that Disposable won't be terribly useful as a parameter type. >> When you pass it somewhere, the receiver must assume that the close() >> method throws any Exception, and that forces the receiver to write >> code to handle the whole Exception hierarchy. ?I think it's likely >> that programmers would want to pass a Disposable around so that the >> receiver can put a region of code under control of the resource (i.e. >> dispose it when the receiver arrives at some particular point of >> completion). ?I'm afraid this would just be trading one set of pain >> points for another. >> >> On Tue, Mar 3, 2009 at 6:26 PM, Reinier Zwitserloot >> wrote: >> - Show quoted text - >> > The new Disposable idea makes this proposal much cleaner, Josh. I like >> > it. >> > >> > Neal, could you perhaps elaborate on the pain that Disposable is going >> > to cause? Insinuating that proposals are Bad Ideas without any >> > specifics whatsoever seems better suited to some sort of voting cycle. >> > On this mailing list it seems counter-productive to say the least. >> > >> > ?--Reinier Zwitserloot >> > >> > >> > >> > On Mar 4, 2009, at 03:08, Neal Gafter wrote: >> > >> >> Given all the gnashing of teeth over the fact that Closeable's close >> >> method throws IOException, I can only imagine the pain that >> >> Disposable.close() throwing Exception will cause. >> >> >> >> On Tue, Mar 3, 2009 at 5:47 PM, Joshua Bloch wrote: >> >>> I have modified the proposal in light of Mark's example. ?The only >> >>> change is >> >>> that the Disposable interface is no longer parameterized. ?This >> >>> eliminates >> >>> the incompatibility noted by Neal; so far as I know, the revised >> >>> proposal >> >>> introduces no incompatibilities. It can be found here: >> >>> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh . >> >>> ? ? Happy reading, >> >>> >> >>> ? ? Josh >> >>> >> >>> >> >> >> > >> > >> > >> > > From neal at gafter.com Tue Mar 3 20:24:57 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 20:24:57 -0800 Subject: Simple Resource Clean-up In-Reply-To: <20090304035501.866A4D06B@callebaut.niobe.net> References: <15e8b9d20903031047q235815d5i669b93575fefba75@mail.gmail.com> <20090304035501.866A4D06B@callebaut.niobe.net> Message-ID: <15e8b9d20903032024g3493a915k5c51f04bda2ab692@mail.gmail.com> On Tue, Mar 3, 2009 at 7:55 PM, Mark Reinhold wrote: >> The fact that this kind of flexibility is required suggests the >> facility should be provided by libraries rather than hardcoded into >> the language. > > If the only way for a library to support this kind of facility is for > closures to be part of JDK 7, then this facility will not be in JDK 7. > > Now maybe I'm missing something, but unless one is going to recommend > that developers use clunky nested classes for this sort of thing then > I don't see how to implement this in a library -- absent closures. Right; addressing this set of problems is probably best left until they can be addressed in a more comprehensive way. From crazybob at crazybob.org Tue Mar 3 20:32:51 2009 From: crazybob at crazybob.org (Bob Lee) Date: Tue, 3 Mar 2009 20:32:51 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> Message-ID: Neal, it might help if you cited some specific examples. I've never personally suffered from Closeable's exception signature, and I can't imagine suffering from that of Disposable. I have suffered from the fact that no one seems to close resources correctly, and I'd love to have this feature whether we get closures one day or not. Bob On Tue, Mar 3, 2009 at 8:19 PM, Neal Gafter wrote: > I think you're missing the point, Josh. People do this today with > Closeable, because that's the closest interface available that could > be used to perform this function, but clients suffer from its > exception signature. Disposable is better in one way - it would be > retrofitted onto more classes - but much worse in its exception > signature. You're saying that there's no pain because you can't use > it as a parameter type. I'm saying that is the cause of the pain. > The language construct that you're proposing does not supplant this > technique of resource management, but the APIs you're proposing to go > with it interfere with the technique. > From neal at gafter.com Tue Mar 3 21:00:07 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 21:00:07 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> Message-ID: <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> See http://www.two-sdg.demon.co.uk/curbralan/papers/AnotherTaleOfTwoPatterns.pdf for a discussion of the pattern. With closures in the language, you'd get the possibility of more flexible resource management than is provided by this proposal. For example, you could write APIs to provide convenient support for the use of java.util.concurrent.locks.Lock, java.util.concurrent.locks.ReadWriteLock, transactions that can either be committed or rolled back, etc, without requiring the language commit itself to a single pattern. Worse: a single pattern that we would have to get right in the next ~3 months. These and other resource management patterns in use today simply don't fit into the mold of this proposal. That is a warning sign that a language construct directly encoding the pattern is inappropriate. -Neal On Tue, Mar 3, 2009 at 8:32 PM, Bob Lee wrote: > Neal, it might help if you cited some specific examples. I've never > personally suffered from Closeable's exception signature, and I can't > imagine suffering from that of Disposable. I have suffered from the fact > that no one seems to close resources correctly, and I'd love to have this > feature whether we get closures one day or not. > > Bob > > On Tue, Mar 3, 2009 at 8:19 PM, Neal Gafter wrote: >> >> I think you're missing the point, Josh. ?People do this today with >> Closeable, because that's the closest interface available that could >> be used to perform this function, but clients suffer from its >> exception signature. ?Disposable is better in one way - it would be >> retrofitted onto more classes - but much worse in its exception >> signature. ?You're saying that there's no pain because you can't use >> it as a parameter type. ?I'm saying that is the cause of the pain. >> The language construct that you're proposing does not supplant this >> technique of resource management, but the APIs you're proposing to go >> with it interfere with the technique. > > From crazybob at crazybob.org Tue Mar 3 21:53:38 2009 From: crazybob at crazybob.org (Bob Lee) Date: Tue, 3 Mar 2009 21:53:38 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> Message-ID: On Tue, Mar 3, 2009 at 9:00 PM, Neal Gafter wrote: > See > http://www.two-sdg.demon.co.uk/curbralan/papers/AnotherTaleOfTwoPatterns.pdf > for a discussion of the pattern. It's interesting to note that the author (a supposed expert) doesn't close resources properly, i.e. he lets exceptions from close() eat earlier, likely more informative exceptions. He would definitely benefit from this feature. With closures in the language, you'd > get the possibility of more flexible resource management than is > provided by this proposal. I wouldn't mind having closures one day, but based on the current state of the BGGA proposal, I think I'd like to have Automatic Resource Management either way, preferably sooner rather than later. To help illustrate, can you please show us what this snippet would look like using BGGA closures? 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."); } For example, you could write APIs to > provide convenient support for the use of > java.util.concurrent.locks.Lock, > java.util.concurrent.locks.ReadWriteLock > I'm not too worried about locks. They're significantly simpler than closing I/O resources in that you don't have to worry about unlock() throwing and you don't have to nest the try blocks. Unlike closing I/O resources, most people get locks right (if they use them at all). > , transactions that can either > be committed or rolled back, etc, without requiring the language > commit itself to a single pattern. The current proposal supports existing transaction approaches just fine. Either your API auto-commits (in which case you roll back if someone calls setRollbackOnly() on the resource), or you have to explicitly commit: try (Transaction t = ...; TransactionalResource tr = ...) { // do some stuff w/ tr ... t.commit(); } If you don't commit(), the tx gets rolled back. Honestly though, I don't see too many users leaving framework-based transaction solutions (like @Transactional) behind for this or BGGA closures. Worse: a single pattern that we > would have to get right in the next ~3 months. These and other > resource management patterns in use today simply don't fit into the > mold of this proposal. That is a warning sign that a language > construct directly encoding the pattern is inappropriate. I disagree. I think we know exactly how to close I/O resources already. The only reason there is any debate today is because doing the right thing in the absence of this feature is such a PITA. It's very difficult to do the right thing today; in contrast, this feature makes it easier to do the right thing than the wrong thing. Bob From neal at gafter.com Tue Mar 3 22:13:32 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 22:13:32 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> Message-ID: <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> On Tue, Mar 3, 2009 at 9:53 PM, Bob Lee wrote: > I wouldn't mind having closures one day, but based on the current state of > the BGGA proposal, I think I'd like to have Automatic Resource Management > either way, preferably sooner rather than later. To help illustrate, can you > please show us what this snippet would look like using BGGA closures? > > ? 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."); > ? } It depends on what libraries are provided, but I'd expect it to be something like try { with (InputStream in : new FileInputStream(src)) with (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 ex) { showDialog("Copy failed."); } Looks about as nice, except for the advantage that the semantics don't have to be hardcoded into the language. Can you please show me how to handle the following BGGA example using this proposal: lockWrite(lock) { clientCount++; } lockRead(lock) { return field.getValue(); } From crazybob at crazybob.org Tue Mar 3 22:44:36 2009 From: crazybob at crazybob.org (Bob Lee) Date: Tue, 3 Mar 2009 22:44:36 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> Message-ID: On Tue, Mar 3, 2009 at 10:13 PM, Neal Gafter wrote: > It depends on what libraries are provided, but I'd expect it to be > something like > > try { > with (InputStream in : new FileInputStream(src)) > with (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 ex) { > showDialog("Copy failed."); > } > > Looks about as nice, except for the advantage that the semantics don't > have to be hardcoded into the language. FWIW, the lack of {} after the first with() cause me to take a double take. The BGGA version is verbose and user-unfriendly enough that I'd still want Automatic Resource Management. Closing I/O resources properly is one of the biggest challenges for Java programmers; it deserves a first class solution. Can you please show me how to > handle the following BGGA example using this proposal: > > lockWrite(lock) { > clientCount++; > } > lockRead(lock) { > return field.getValue(); > } You can't, nor does the proposal attempt to address this use case. I'm not personally interested in addressing that use case at this time because it's easy enough to write: writeLock.lock(); clientCount++; writeLock.unlock(); readLock.lock(); try { return field.getValue(); } finally { readLock.unlock(); } and save yourself two allocations and an implicit layer of indirection. Bob From jjb at google.com Tue Mar 3 23:00:55 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 23:00:55 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> Message-ID: <17b2302a0903032300i29b11512u5a6c591f1dcd184a@mail.gmail.com> Neal, > I'd expect it to be something like > > try { > with (InputStream in : new FileInputStream(src)) > with (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 ex) { > showDialog("Copy failed."); > } > > Looks about as nice, No it doesn't. Not even close. In java, the colon in this position would be read by the typical programmer as "in" (e.g., "for each String s in stringList"). What we want (and what my proposal provides) is the equals sign (=), which means assignment. Also you have an extra level of nesting for each variable. This is one of the things that we're trying to get away from with this proposal. A more honest indentation for your syntax would be: try { with (InputStream in : new FileInputStream(src)) { with (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 ex) { showDialog("Copy failed."); } That's three levels off indentation instead of one (more generallly, number of resources + 1, instead of 1). Josh From neal at gafter.com Tue Mar 3 23:23:12 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 23:23:12 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903032300i29b11512u5a6c591f1dcd184a@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> <17b2302a0903032300i29b11512u5a6c591f1dcd184a@mail.gmail.com> Message-ID: <15e8b9d20903032323j6ee0ac5el6dcb2d4726832921@mail.gmail.com> On Tue, Mar 3, 2009 at 11:00 PM, Joshua Bloch wrote: > Neal, >> >> ?I'd expect it to be?something like >> >> try { >> ? ?with (InputStream in : new FileInputStream(src)) >> ? ? ? ? ? ?with (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 ex) { >> ? ?showDialog("Copy failed."); >> } >> >> Looks about as nice, > > No it doesn't. ?Not even close. In java, the colon in this position would be > read by the typical programmer as "in" ?(e.g., "for each String s in > stringList"). Java programmers already know that ":" doesn't mean "in" except after "for"; they do after all somehow manage to understand labels and assert statements. I think it's a stretch to suggest that anyone would be tempted to read it that way except to make this argument. Java programmers tend to see a close paren followed by a semicolon at the end of a line as the end of a statement, but as you can see from Bob's example, they're likely to be confused by this ARM proposal. > What we want (and what my proposal provides) is the equals > sign (=), which means assignment. Clearly, there is far more than a simple assignment going on in this code, or there would be little point in suggesting a new language feature. Therefore relying on the intuition of assignment is also misleading. > Also you have an extra level of nesting > for each variable. Just as one does not add a level of indentation for each successive element in a chain of if-then-else statements, one does not add a level of indentation for each resource being managed. You can certainly elect to use an additional block and an additional level of nesting for each variable if you feel it makes the code more clear, and I know you've been preaching that BGGA control invocations should be written that way, but I find the way I wrote it more clear. From jjb at google.com Tue Mar 3 23:27:05 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 3 Mar 2009 23:27:05 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> Message-ID: <17b2302a0903032327p333492f5l72a1d939e2005b33@mail.gmail.com> Per Joe Darcy's request, I'm including a copy of modified version of the proposal. The text below is properly formatted in this e-mail, but I'm afraid that mailman will eat the formatting:( Automatic Resource Management *AUTHOR: *Joshua Bloch *OVERVIEW* FEATURE SUMMARY: A *resource* is as an object that must be closed manually, such as a java.io.InputStream, OutputStream, Reader, Writer, Formatter; java.nio.Channel; java.net.socket; java.sql.Connection, Statement, ResultSet, or java.awt.Graphics. The *automatic resource management statement* is a form of the try statement that declares one or more resources. The scope of these resource declarations is limited to the statement. When the statement completes, whether normally or abruptly, all of its resources are closed automatically. MAJOR ADVANTAGE: The automatic resource management statement obviates the need for manual resource termination, which has proven ugly and error prone. Even good programmers get it wrong most of the time. For example, Sun?s guide to Persistent Connections (http://tinyurl.com/6b5jc7) gets it wrong in code that claims to be exemplary. Likewise, the solution on page 88 of Bloch and Gafter?s *Java Puzzlers* (Addison-Wesley, 2006) is badly broken, and no one ever noticed. In fact, 2/3 of the uses of the close method in the JDK itself are wrong! The price for failing to terminate resources properly is resource leaks or even outright failures, which may be silent (as in *Java Puzzlers*). Even the ?correct? idioms for manual resource management are deficient: if an exception is thrown in the try block, and another when closing the resource in the finally block, the second exception supplants the first, making it difficult to determine the real cause of the trouble. While it is possible to write code to suppress the second exception in favor of the first, virtually no one does, as it is just too verbose. This is not a theoretical problem; it has greatly complicated the debugging of large systems. A secondary advantage of the automatic resource management construct is that it could emit the code to suppress the uninteresting (second) exception in favor of the interesting (first) one with no effort on the part of the programmer, and no loss to the clarity of the program. Like the for-each statement (introduced in Java 1.5), the automatic resource management statement is a small piece of syntactic sugar with a very high power-to-weight ratio. MAJOR DISADVANTAGE: Like all syntactic sugar, this construct removes a bit of Java?s ?what you see is what you get? character (?transparency?). ALTERNATIVES: The benefits of this proposal cannot be had without a language change. Absent a language change, you must close resources manually. That is why Java?s competitors have automatic resource management constructs (C# has using blocks and C++ has destructors). *EXAMPLES* SIMPLE EXAMPLE: Here is a static method to read the first line of a file, demonstrating the minimal (nearly) correct code to release a single resource today. static String readFirstLineFromFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } } Unfortunately, if the readLine and close invocations both throw exceptions, the latter exception supplants the former. The only practical way around this today would to be to ignore any exception thrown by the close invocation. While this might be reasonable in the case of a Reader or InputStream, it would be disastrous for a Writer or OutputStream. Here?s how it would look with an automatic resource management statement: static String readFirstLineFromFile2(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path)) { return br.readLine(); } } ADVANCED EXAMPLE*:* Here is a static method to make a copy of a file, demonstrating the minimal correct code to release two resources today: static void copy(String src, String dest) throws IOException { InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(dest); try { byte[] buf = new byte[8 * 1024]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally { out.close(); } } finally { in.close(); } } Here?s how it would look with an automatic resource management statement: static void copy(String src, String dest) throws IOException { try (InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest)) { byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } } *DETAILS* * * SPECIFICATION: What follows is not intended to be a formal JLS-quality specification. It emphasizes brevity and clarity over thoroughness. SYNTAX: The production for *TryStatement* in JLS ?14.20 would be extended with this alternative: *TryStatement*: try ( *ResourceDeclarations* ) *Block Catchesopt Finallyopt* *ResourceDeclarations*: *LocalVariableDeclaration* *LocalVariableDeclaration* ; *ResourceDeclarations* * * The type of each *LocalVariableDeclaration* in a *ResourceDeclarations *must be a subtype of Disposable. Such types are known as *resource types*. SEMANTICS and COMPILATION: An automatic resource management statement with a single local variable declaration and no *Finally* or *Catches* would behave as if replaced by the following source code: { final *LocalVariableDeclaration* ; try *Block* finally { *localVar*.close(); // *localVar* is the variable declared in * LocalVariableDeclaration* } } An automatic resource management statement with multiple local variable declarations and no *Finally* or *Catches* would behave as if (recursively) replaced by the following source code: { final *LocalVariableDeclaration* ; // First variable declaration try( *ResourceDeclarations* ) *Block* finally { // Remaining resource declarations *localVar*.close(); // *localVar* is the variable declared in * LocalVariableDeclaration* } } When you initially de-sugar an automatic resource management statement with n resource declarations for n > 1, you get an automatic resource management statement with n-1 resource declarations. After n such replacements, you have n nested try-finally statements, and the de-sugaring is complete. Note that resource declarations are implicitly final. For consistency with existing constructs with implicit modifiers, it is legal (though discouraged) for the programmer to provide an explicit final modifier. Note that the close method is only called on resources whose declarations execute without throwing an exception, and that the first such exception causes the statement to complete abruptly. An automatic resource management statement with a *Finally* or *Catches* would behave as if replaced by the following code (which contains an automatic resource management statement with no *Finally* or*Catches that must be expanded as per the desugaring above*): try { try ( *ResourceDeclarations* ) *Block* } *Finallyopt Catchesopt* These simple semantics solve most of the problems described above, but they leave one problem unsolved: if the *Block* throws one exception, and the automatically generated close invocation throws another, the latter exception supplants the former. This could be corrected by using a slightly more complex de-sugaring for the single-local-variable-declaration form of the construct: { final LocalVariableDeclaration ; boolean #suppressSecondaryException = false; try Block catch (final Throwable #t) { #suppressSecondaryException = true; throw #t; } finally { if (#suppressSecondaryException) try { localVar.close(); } catch(Exception #ignore) { } else localVar.close(); } } The variables #t, #suppressSecondaryException, and #ignore are compiler-generated identifiers that are distinct from one and other, and from any other identifiers (compiler-generated or otherwise) that are in scope (JLS ?6.3) at the point where the automatic resource management statement occurs. This de-sugaring takes advantage of the ability to rethrow a final caught exception, which has been proposed for Java 7. The present proposal does * not* depend on this ability. In its absence, one could use a method such as sneakyThrow (*Java Puzzlers*, Puzzle 43). TYPE SYSTEM: The proposal has no effect on the type system. TESTING: The proposed construct can be tested by writing automatic resource management statements with a number of resources varying from 1 to some upper limit (say 10). Each resource can throw an exception (or not) during initialization, use, or termination. JUnit assertions are added to check that all resources opened are automatically closed, and that the correct exception (if any) is thrown. LIBRARY SUPPORT: A class must implement a designated interface to make it eligible for automatic resource management. An obvious choice would be Closeable, but unfortunately its close method is specified to throw IOException, which precludes its use in a general purpose resource management facility. It is, however, possible to retrofit Closeable with a superinterface: *package** java.lang;* */*** * * A resource that must be closed when it is no longer needed.* * */* *public interface Disposable {* * void close() throws Exception;* *}* package java.io; public interface Closeable *extends Disposable* { void close() throws IOException; } Other existing classes and interfaces can be similarly retrofitted, for example: package java.sql; interface Connection *extends Disposable* { void close() throws SQLException; ... // (and all the other members of the Connection interface) } REFLECTIVE APIS: This proposal has no effect on core reflective APIs. The tree API inside javac ( http://java.sun.com/javase/6/docs/jdk/api/javac/tree/index.html) would require a minor extension. OTHER CHANGES: No other parts of the platform need be to be updated. MIGRATION: Any resource that must be closed manually should be retrofitted to implement the Disposable interface. In the JDK, this includes java.io.Closeable; java.sql.Connection, Statement, and ResultSet. New code using classes that implement Disposable should use automatic resource management statements (for clarity and correctness). Manual resource management in existing code can be replaced by automatic resource management for increased clarity and improved behavior. Given the number of resource management errors observed in existing code, it may be worth the time to do this systematically. It is very easy to do this with any modern IDE, which can search for uses of a method (in this case, Disposable.close()). *COMPATIBILITY* * * BREAKING CHANGES: All previously valid programs remain valid, and their semantics is unaffected. * * EXISTING PROGRAMS: Source and class files of earlier versions are unaffected by the feature. No new overloadings or overridings can occur. *REFERENCES* * * EXISTING BUGS: 4888664, 4364906, 4331290, 4215007, 4120342. *ADDITIONAL FEATURES* Here are several features that might be added to the construct if the expert group deemed it advisable: *Retaining suppressed exceptions* - As described above, the construct simply discards exceptions that are suppressed. It would probably be better to attach them to the exception in whose favor they are being suppressed. This would entail adding two new methods to Throwable, void addSuppressedException(Throwable) and Throwable[] getSuppressedExceptions(). *Ignoring certain **close failures* - One shortcoming of the construct as described is that it does not provide a way for the programmer to indicate that exceptions thrown when closing a resource should be ignored. In the case of the copy method, ideally the program would ignore exceptions thrown when closing the InputStream, but not the OutputStream. There are several ways this could be achieved. *Expressions in place of declarations* - It was suggested that the automatic resource management statement could be defined to allow an expression in place of a variable declaration, permitting the use of preexisting variables. This feature was consciously omitted to make it more difficult to access a closed resource accidentally. *DESIGN ALTERNATIVES* *Modifier in place of block* - An alterative to a block construct is a new modifier that could be added to any local variable declaration for a variable that extends Disposable. This is more flexible and less verbose, but more dissimilar to existing Java language constructs. *Annotation to indicate termination method *- An alternative to the proposed use of the Disposable interface is an annotation on the resource termination method. This allows the use of a different method names (such as destroy and terminate) and eases the use of the new construct with existing resource types. But it is more ?magical? and does not mesh as well with Java?s type system. Edit this page (if you have permission) | Google Docs -- Web word processing, presentations and spreadsheets. From neal at gafter.com Tue Mar 3 23:37:37 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 23:37:37 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> Message-ID: <15e8b9d20903032337q49561f8bj52f67ec093385e97@mail.gmail.com> On Tue, Mar 3, 2009 at 9:53 PM, Bob Lee wrote: >> , transactions that can either >> be committed or rolled back, etc, without requiring the language >> commit itself to a single pattern. > > The current proposal supports existing transaction approaches just fine. > Either your API auto-commits (in which case you roll back if someone calls > setRollbackOnly() on the resource), or you have to explicitly commit: > > ? try (Transaction t = ...; TransactionalResource tr = ...) { > ? ? // do some stuff w/ tr > ? ? ... > ??? t.commit(); > ? } > > If you don't commit(), the tx gets rolled back. Bob- java.sql.Connection has three methods (among others): commit() - to cause the transaction to take effect rollback() - to undo the transaction close() - to close the connection Using the construct as you suggest closes the connection - not necessarily a good idea, and not the point of the example. The point is to commit() when the controlled statement completes normally, and rollback() when it terminates abnormally, without the programmer having to add further boilerplate. BGGA enables frameworks to provide an API that makes this as easy as if a purpose-built statement were available, but the present proposal appears to require boilerplate in each client. From jeremy.manson at gmail.com Tue Mar 3 23:49:39 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 3 Mar 2009 23:49:39 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> Message-ID: <1631da7d0903032349v2d92df07n6c7a7e756a5e42@mail.gmail.com> On Tue, Mar 3, 2009 at 10:13 PM, Neal Gafter wrote: > ?Can you please show me how to > handle the following BGGA example using this proposal: > > lockWrite(lock) { > ? ?clientCount++; > } > lockRead(lock) { > ? ?return field.getValue(); > } > > As a side note to this conversation, directed at any people who will think you can't have this feature with this proposal, regardless of your feelings about the particular merits of accomplishing the same thing with closures, there *is* a way to handle this case: class LockDisposer implements Disposable { private final Lock lock; public LockDisposer(Lock l) { lock = l; lock.lock(); } public void close() { lock.unlock(); } } try (LockDisposer l = new LockDisposer(lock.readLock())) { clientCount++; } try (LockDisposer l = new LockDisposer(lock.writeLock())) { return field.getValue(); } I suspect a LOT of people will be doing something similar to this hack if this proposal is adopted. To make it much cleaner, you could first adjust this proposal so that the try statement can take an expression that returns a Disposable, and then you could adjust the Lock classes so that a) lock() returns this and b) they implement Disposable, at which point you could have: try (lock.readLock().lock()) { clientCount++; } try (lock.writeLock().lock()) { return field.getValue(); } Which is pretty clean. Note that Josh mentioned the possibility of try() taking an expression in his proposal. This is why. Jeremy From neal at gafter.com Tue Mar 3 23:56:29 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 3 Mar 2009 23:56:29 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903032349v2d92df07n6c7a7e756a5e42@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> <1631da7d0903032349v2d92df07n6c7a7e756a5e42@mail.gmail.com> Message-ID: <15e8b9d20903032356s3db82efv141d9e014d315354@mail.gmail.com> On Tue, Mar 3, 2009 at 11:49 PM, Jeremy Manson wrote: > As a side note to this conversation, directed at any people who will > think you can't have this feature with this proposal, regardless of > your feelings about the particular merits of accomplishing the same > thing with closures, there *is* a way to handle this case: > > try (LockDisposer l = new LockDisposer(lock.readLock())) { > ?clientCount++; > } > > try (LockDisposer l = new LockDisposer(lock.writeLock())) { > ?return field.getValue(); > } Yow. I think the cure might be worse than the disease. > I suspect a LOT of people will be doing something similar to this hack > if this proposal is adopted. ?To make it much cleaner, you could first > adjust this proposal so that the try statement can take an expression > that returns a Disposable, and then you could adjust the Lock classes > so that a) lock() returns this and b) they implement Disposable, at > which point you could have: You can't make such changes to existing interfaces without breaking existing code. Changing the signature of lock() breaks existing callers, and adding a close() method (to implement Disposable) breaks existing implementations. From jeremy.manson at gmail.com Wed Mar 4 00:03:51 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Wed, 4 Mar 2009 00:03:51 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032356s3db82efv141d9e014d315354@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> <1631da7d0903032349v2d92df07n6c7a7e756a5e42@mail.gmail.com> <15e8b9d20903032356s3db82efv141d9e014d315354@mail.gmail.com> Message-ID: <1631da7d0903040003wd83e97bj53083703753d1bc8@mail.gmail.com> On Tue, Mar 3, 2009 at 11:56 PM, Neal Gafter wrote: > On Tue, Mar 3, 2009 at 11:49 PM, Jeremy Manson wrote: >> As a side note to this conversation, directed at any people who will >> think you can't have this feature with this proposal, regardless of >> your feelings about the particular merits of accomplishing the same >> thing with closures, there *is* a way to handle this case: >> >> try (LockDisposer l = new LockDisposer(lock.readLock())) { >> ?clientCount++; >> } >> >> try (LockDisposer l = new LockDisposer(lock.writeLock())) { >> ?return field.getValue(); >> } > > Yow. ?I think the cure might be worse than the disease. That's why I suggested changing try() so that it took an expression. The second version was, I think you will admit, much cleaner. >> I suspect a LOT of people will be doing something similar to this hack >> if this proposal is adopted. ?To make it much cleaner, you could first >> adjust this proposal so that the try statement can take an expression >> that returns a Disposable, and then you could adjust the Lock classes >> so that a) lock() returns this and b) they implement Disposable, at >> which point you could have: > > You can't make such changes to existing interfaces without breaking > existing code. ?Changing the signature of lock() breaks existing > callers, and adding a close() method (to implement Disposable) breaks > existing implementations. I'm probably being typically dumb, but I'm not sure how adding a method breaks anything. You don't *have* to change the signature of lock -- just add a new method (call it "disposeLock") that has the required semantics: try (lock.readLock().disposeLock()) { clientCount++; } try (lock.writeLock().disposeLock()) { return field.getValue(); } Jeremy From Joe.Darcy at Sun.COM Wed Mar 4 00:10:55 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 00:10:55 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903032327p333492f5l72a1d939e2005b33@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <17b2302a0903032327p333492f5l72a1d939e2005b33@mail.gmail.com> Message-ID: <49AE378F.7090901@sun.com> Joshua Bloch wrote: > Per Joe Darcy's request, I'm including a copy of modified version of the > proposal. The text below is properly formatted in this e-mail, but I'm > afraid that mailman will eat the formatting:( > Automatic Resource Management > Hello. I've changed the mailman options so HTML should now go through; below will be Josh's proposal in HTML if all has gone as intended. -Joe Automatic Resource Management *AUTHOR: *Joshua Bloch *OVERVIEW* FEATURE SUMMARY: A /resource/ is as an object that must be closed manually, such as a java.io.InputStream, OutputStream, Reader, Writer, Formatter; java.nio.Channel; java.net.socket; java.sql.Connection, Statement, ResultSet, or java.awt.Graphics. The /automatic resource management statement/ is a form of the try statement that declares one or more resources. The scope of these resource declarations is limited to the statement. When the statement completes, whether normally or abruptly, all of its resources are closed automatically. MAJOR ADVANTAGE: The automatic resource management statement obviates the need for manual resource termination, which has proven ugly and error prone. Even good programmers get it wrong most of the time. For example, Sun?s guide to Persistent Connections (http://tinyurl.com/6b5jc7) gets it wrong in code that claims to be exemplary. Likewise, the solution on page 88 of Bloch and Gafter?s /Java Puzzlers/ (Addison-Wesley, 2006) is badly broken, and no one ever noticed. In fact, 2/3 of the uses of the close method in the JDK itself are wrong! The price for failing to terminate resources properly is resource leaks or even outright failures, which may be silent (as in /Java Puzzlers/). Even the ?correct? idioms for manual resource management are deficient: if an exception is thrown in the try block, and another when closing the resource in the finally block, the second exception supplants the first, making it difficult to determine the real cause of the trouble. While it is possible to write code to suppress the second exception in favor of the first, virtually no one does, as it is just too verbose. This is not a theoretical problem; it has greatly complicated the debugging of large systems. A secondary advantage of the automatic resource management construct is that it could emit the code to suppress the uninteresting (second) exception in favor of the interesting (first) one with no effort on the part of the programmer, and no loss to the clarity of the program. Like the for-each statement (introduced in Java 1.5), the automatic resource management statement is a small piece of syntactic sugar with a very high power-to-weight ratio. MAJOR DISADVANTAGE: Like all syntactic sugar, this construct removes a bit of Java?s ?what you see is what you get? character (?transparency?). ALTERNATIVES: The benefits of this proposal cannot be had without a language change. Absent a language change, you must close resources manually. That is why Java?s competitors have automatic resource management constructs (C# has using blocks and C++ has destructors). *EXAMPLES* SIMPLE EXAMPLE: Here is a static method to read the first line of a file, demonstrating the minimal (nearly) correct code to release a single resource today. static String readFirstLineFromFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } } Unfortunately, if the readLine and close invocations both throw exceptions, the latter exception supplants the former. The only practical way around this today would to be to ignore any exception thrown by the close invocation. While this might be reasonable in the case of a Reader or InputStream, it would be disastrous for a Writer or OutputStream. Here?s how it would look with an automatic resource management statement: static String readFirstLineFromFile2(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path)) { return br.readLine(); } } ADVANCED EXAMPLE*:* Here is a static method to make a copy of a file, demonstrating the minimal correct code to release two resources today: static void copy(String src, String dest) throws IOException { InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(dest); try { byte[] buf = new byte[8 * 1024]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally { out.close(); } } finally { in.close(); } } Here?s how it would look with an automatic resource management statement: static void copy(String src, String dest) throws IOException { try (InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest)) { byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } } *DETAILS* * * SPECIFICATION: What follows is not intended to be a formal JLS-quality specification. It emphasizes brevity and clarity over thoroughness. SYNTAX: The production for /TryStatement/ in JLS ?14.20 would be extended with this alternative: /TryStatement/: try ( /ResourceDeclarations/ ) /Block Catches_opt Finally_opt / /ResourceDeclarations/: /LocalVariableDeclaration/ /LocalVariableDeclaration/ ; /ResourceDeclarations/ / / The type of each /LocalVariableDeclaration/ in a /ResourceDeclarations /must be a subtype of Disposable. Such types are known as /resource types/. SEMANTICS and COMPILATION: An automatic resource management statement with a single local variable declaration and no /Finally/ or /Catches/ would behave as if replaced by the following source code: { final /LocalVariableDeclaration/ ; try /Block/ finally { /localVar/.close(); // /localVar/ is the variable declared in /LocalVariableDeclaration/ } } An automatic resource management statement with multiple local variable declarations and no /Finally/ or /Catches/ would behave as if (recursively) replaced by the following source code: { final /LocalVariableDeclaration/ ; // First variable declaration try( /ResourceDeclarations/ ) /Block/ finally { // Remaining resource declarations /localVar/.close(); // /localVar/ is the variable declared in /LocalVariableDeclaration/ } } When you initially de-sugar an automatic resource management statement with n resource declarations for n > 1, you get an automatic resource management statement with n-1 resource declarations. After n such replacements, you have n nested try-finally statements, and the de-sugaring is complete. Note that resource declarations are implicitly final. For consistency with existing constructs with implicit modifiers, it is legal (though discouraged) for the programmer to provide an explicit final modifier. Note that the close method is only called on resources whose declarations execute without throwing an exception, and that the first such exception causes the statement to complete abruptly. An automatic resource management statement with a /Finally/ or /Catches/ would behave as if replaced by the following code (which contains an automatic resource management statement with no /Finally/ or/Catches that must be expanded as per the desugaring above/): try { try ( /ResourceDeclarations/ ) /Block/ } /Finally_opt Catches_opt / These simple semantics solve most of the problems described above, but they leave one problem unsolved: if the /Block/ throws one exception, and the automatically generated close invocation throws another, the latter exception supplants the former. This could be corrected by using a slightly more complex de-sugaring for the single-local-variable-declaration form of the construct: { final LocalVariableDeclaration ; boolean #suppressSecondaryException = false; try Block catch (final Throwable #t) { #suppressSecondaryException = true; throw #t; } finally { if (#suppressSecondaryException) try { localVar.close(); } catch(Exception #ignore) { } else localVar.close(); } } The variables #t, #suppressSecondaryException, and #ignore are compiler-generated identifiers that are distinct from one and other, and from any other identifiers (compiler-generated or otherwise) that are in scope (JLS ?6.3) at the point where the automatic resource management statement occurs. This de-sugaring takes advantage of the ability to rethrow a final caught exception, which has been proposed for Java 7. The present proposal does /not/ depend on this ability. In its absence, one could use a method such as sneakyThrow (/Java Puzzlers/, Puzzle 43). TYPE SYSTEM: The proposal has no effect on the type system. TESTING: The proposed construct can be tested by writing automatic resource management statements with a number of resources varying from 1 to some upper limit (say 10). Each resource can throw an exception (or not) during initialization, use, or termination. JUnit assertions are added to check that all resources opened are automatically closed, and that the correct exception (if any) is thrown. LIBRARY SUPPORT: A class must implement a designated interface to make it eligible for automatic resource management. An obvious choice would be Closeable, but unfortunately its close method is specified to throw IOException, which precludes its use in a general purpose resource management facility. It is, however, possible to retrofit Closeable with a superinterface: *package** java.lang;* */*** * * A resource that must be closed when it is no longer needed.* * */* *public interface Disposable {* * void close() throws Exception;* *}* package java.io; public interface Closeable *extends Disposable* { void close() throws IOException; } Other existing classes and interfaces can be similarly retrofitted, for example: package java.sql; interface Connection *extends Disposable* { void close() throws SQLException; ... // (and all the other members of the Connection interface) } REFLECTIVE APIS: This proposal has no effect on core reflective APIs. The tree API inside javac (http://java.sun.com/javase/6/docs/jdk/api/javac/tree/index.html) would require a minor extension. OTHER CHANGES: No other parts of the platform need be to be updated. MIGRATION: Any resource that must be closed manually should be retrofitted to implement the Disposable interface. In the JDK, this includes java.io.Closeable; java.sql.Connection, Statement, and ResultSet. New code using classes that implement Disposable should use automatic resource management statements (for clarity and correctness). Manual resource management in existing code can be replaced by automatic resource management for increased clarity and improved behavior. Given the number of resource management errors observed in existing code, it may be worth the time to do this systematically. It is very easy to do this with any modern IDE, which can search for uses of a method (in this case, Disposable.close()). *COMPATIBILITY* * * BREAKING CHANGES: All previously valid programs remain valid, and their semantics is unaffected. * * EXISTING PROGRAMS: Source and class files of earlier versions are unaffected by the feature. No new overloadings or overridings can occur. *REFERENCES* * * EXISTING BUGS: 4888664, 4364906, 4331290, 4215007, 4120342. *ADDITIONAL FEATURES* Here are several features that might be added to the construct if the expert group deemed it advisable: *Retaining suppressed exceptions* - As described above, the construct simply discards exceptions that are suppressed. It would probably be better to attach them to the exception in whose favor they are being suppressed. This would entail adding two new methods to Throwable, void addSuppressedException(Throwable) and Throwable[] getSuppressedExceptions(). *Ignoring certain **close failures* - One shortcoming of the construct as described is that it does not provide a way for the programmer to indicate that exceptions thrown when closing a resource should be ignored. In the case of the copy method, ideally the program would ignore exceptions thrown when closing the InputStream, but not the OutputStream. There are several ways this could be achieved. *Expressions in place of declarations* - It was suggested that the automatic resource management statement could be defined to allow an expression in place of a variable declaration, permitting the use of preexisting variables. This feature was consciously omitted to make it more difficult to access a closed resource accidentally. *DESIGN ALTERNATIVES* *Modifier in place of block* - An alterative to a block construct is a new modifier that could be added to any local variable declaration for a variable that extends Disposable. This is more flexible and less verbose, but more dissimilar to existing Java language constructs. *Annotation to indicate termination method *- An alternative to the proposed use of the Disposable interface is an annotation on the resource termination method. This allows the use of a different method names (such as destroy and terminate) and eases the use of the new construct with existing resource types. But it is more ?magical? and does not mesh as well with Java?s type system. From jjb at google.com Wed Mar 4 00:12:53 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 00:12:53 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903040003wd83e97bj53083703753d1bc8@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> <1631da7d0903032349v2d92df07n6c7a7e756a5e42@mail.gmail.com> <15e8b9d20903032356s3db82efv141d9e014d315354@mail.gmail.com> <1631da7d0903040003wd83e97bj53083703753d1bc8@mail.gmail.com> Message-ID: <17b2302a0903040012u7c378912x37968c8941f26dd5@mail.gmail.com> A gentle reminder: this construct was designed for one thing and one thing only: resource management. It was not designed for locking. Java already contains a native construct for locking (synchronized). A very small minority of Java programmers use java.util.concurrent.atomic.Locks. Support for them is not a priority. Nearly all Java programmers use resources such as java.io.InputStream, OutputStream, Reader, Writer, Formatter; java.nio.Channel; java.net.socket; java.sql.Connection, Statement, ResultSet, or java.awt.Graphics. That's what this construct is designed for. Goodnight, Josh On Wed, Mar 4, 2009 at 12:03 AM, Jeremy Manson wrote: > On Tue, Mar 3, 2009 at 11:56 PM, Neal Gafter wrote: > > On Tue, Mar 3, 2009 at 11:49 PM, Jeremy Manson > wrote: > >> As a side note to this conversation, directed at any people who will > >> think you can't have this feature with this proposal, regardless of > >> your feelings about the particular merits of accomplishing the same > >> thing with closures, there *is* a way to handle this case: > >> > >> try (LockDisposer l = new LockDisposer(lock.readLock())) { > >> clientCount++; > >> } > >> > >> try (LockDisposer l = new LockDisposer(lock.writeLock())) { > >> return field.getValue(); > >> } > > > > Yow. I think the cure might be worse than the disease. > > That's why I suggested changing try() so that it took an expression. > The second version was, I think you will admit, much cleaner. > > >> I suspect a LOT of people will be doing something similar to this hack > >> if this proposal is adopted. To make it much cleaner, you could first > >> adjust this proposal so that the try statement can take an expression > >> that returns a Disposable, and then you could adjust the Lock classes > >> so that a) lock() returns this and b) they implement Disposable, at > >> which point you could have: > > > > You can't make such changes to existing interfaces without breaking > > existing code. Changing the signature of lock() breaks existing > > callers, and adding a close() method (to implement Disposable) breaks > > existing implementations. > > I'm probably being typically dumb, but I'm not sure how adding a > method breaks anything. You don't *have* to change the signature of > lock -- just add a new method (call it "disposeLock") that has the > required semantics: > > try (lock.readLock().disposeLock()) { > clientCount++; > } > > try (lock.writeLock().disposeLock()) { > return field.getValue(); > } > > Jeremy > > From crazybob at crazybob.org Wed Mar 4 00:16:39 2009 From: crazybob at crazybob.org (Bob Lee) Date: Wed, 4 Mar 2009 00:16:39 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903032337q49561f8bj52f67ec093385e97@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031941w5e9a0058geba9e693cb938555@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032337q49561f8bj52f67ec093385e97@mail.gmail.com> Message-ID: On Tue, Mar 3, 2009 at 11:37 PM, Neal Gafter wrote: > Bob- > > java.sql.Connection has three methods (among others): > commit() - to cause the transaction to take effect > rollback() - to undo the transaction > close() - to close the connection > > Using the construct as you suggest closes the connection - not > necessarily a good idea, and not the point of the example. The point > is to commit() when the controlled statement completes normally, and > rollback() when it terminates abnormally, without the programmer > having to add further boilerplate. BGGA enables frameworks to provide > an API that makes this as easy as if a purpose-built statement were > available, but the present proposal appears to require boilerplate in > each client. > Neal- Thanks for the tutorial. I've done quite a bit of JDBC and Java EE programming in the past (http://www.manning.com/tate2/), and I'm confident that the Automatic Resource Management proposal suits my needs just fine. :-) Bob From jeremy.manson at gmail.com Wed Mar 4 00:25:52 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Wed, 4 Mar 2009 00:25:52 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903040012u7c378912x37968c8941f26dd5@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903032019v1f967824m7785b87ac4887581@mail.gmail.com> <15e8b9d20903032100s29663ad5td870e0f444cbfc07@mail.gmail.com> <15e8b9d20903032213u2a94f9e1k2459c94fab31c30@mail.gmail.com> <1631da7d0903032349v2d92df07n6c7a7e756a5e42@mail.gmail.com> <15e8b9d20903032356s3db82efv141d9e014d315354@mail.gmail.com> <1631da7d0903040003wd83e97bj53083703753d1bc8@mail.gmail.com> <17b2302a0903040012u7c378912x37968c8941f26dd5@mail.gmail.com> Message-ID: <1631da7d0903040025o66665922ve46ec03af8f0e233@mail.gmail.com> Although this is clear from the proposal, intentions and uses have a way of diverging. As you know, the usage I showed is very similar to C++'s RAII idiom, a very similar abuse of constructors and destructors that uses similar ridiculous wrapper classes. Jeremy On Wed, Mar 4, 2009 at 12:12 AM, Joshua Bloch wrote: > A gentle reminder: this construct was designed for one thing and one thing > only: resource management. ?It was not designed for locking. ?Java already > contains a native construct for locking (synchronized). ?A very small > minority of Java programmers use?java.util.concurrent.atomic.Locks. ?Support > for them is not a priority. ?Nearly all Java programmers use resources such > as?java.io.InputStream,?OutputStream,?Reader,?Writer,?Formatter;?java.nio.Channel;?java.net.socket;?java.sql.Connection,?Statement,?ResultSet, > or?java.awt.Graphics. ?That's what this construct is designed for. > ?? ?Goodnight, > ?? ?Josh > On Wed, Mar 4, 2009 at 12:03 AM, Jeremy Manson > wrote: >> >> On Tue, Mar 3, 2009 at 11:56 PM, Neal Gafter wrote: >> > On Tue, Mar 3, 2009 at 11:49 PM, Jeremy Manson >> > wrote: >> >> As a side note to this conversation, directed at any people who will >> >> think you can't have this feature with this proposal, regardless of >> >> your feelings about the particular merits of accomplishing the same >> >> thing with closures, there *is* a way to handle this case: >> >> >> >> try (LockDisposer l = new LockDisposer(lock.readLock())) { >> >> ?clientCount++; >> >> } >> >> >> >> try (LockDisposer l = new LockDisposer(lock.writeLock())) { >> >> ?return field.getValue(); >> >> } >> > >> > Yow. ?I think the cure might be worse than the disease. >> >> That's why I suggested changing try() so that it took an expression. >> The second version was, I think you will admit, much cleaner. >> >> >> I suspect a LOT of people will be doing something similar to this hack >> >> if this proposal is adopted. ?To make it much cleaner, you could first >> >> adjust this proposal so that the try statement can take an expression >> >> that returns a Disposable, and then you could adjust the Lock classes >> >> so that a) lock() returns this and b) they implement Disposable, at >> >> which point you could have: >> > >> > You can't make such changes to existing interfaces without breaking >> > existing code. ?Changing the signature of lock() breaks existing >> > callers, and adding a close() method (to implement Disposable) breaks >> > existing implementations. >> >> I'm probably being typically dumb, but I'm not sure how adding a >> method breaks anything. You don't *have* to change the signature of >> lock -- just add a new method (call it "disposeLock") that has the >> required semantics: >> >> try (lock.readLock().disposeLock()) { >> ?clientCount++; >> } >> >> try (lock.writeLock().disposeLock()) { >> ?return field.getValue(); >> } >> >> Jeremy >> > > From develop4lasu at gmail.com Wed Mar 4 00:33:30 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 4 Mar 2009 09:33:30 +0100 Subject: 'This' type In-Reply-To: <49ADAD7E.4090803@sun.com> References: <28bca0ff0903031217q318674a4j29b70b40b7ec80f7@mail.gmail.com> <49ADAD7E.4090803@sun.com> Message-ID: <28bca0ff0903040033x4b487d55r602fcd04e34ab479@mail.gmail.com> 2009/3/3 Joseph D. Darcy > > > The Project Coin mailing list is not an alternate forum to submit requests > for enhancements of the Java specification. Rather, it is a venue for the > analysis and refinement of thought-through proposals to change the language. > > If one is not willing or able to work through implications of the proposal, > it it not appropriate to be sent to the list. > > Generally the discussion of proposals sent to Project Coin should occur on > the Project Coin list. Besides making the current status of proposals > easier to track, various parties have expressed interest in why previous > language design decisions were made and having all the traffic on Project > Coin makes that retrospective analysis possible. > > -Joe > Thanks. I'll try to focus on analysis then ;) and bring full analise in time (I just do not have much time now). Refernces: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 http://java.net/cs/user/view/cs_msg/37432 -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Wed Mar 4 01:41:16 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 4 Mar 2009 09:41:16 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <49ADD978.3080804@sun.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> <49ADD978.3080804@sun.com> Message-ID: <200903040941.16335.david.goodenough@linkchoose.co.uk> On Wednesday 04 March 2009, Joseph D. Darcy wrote: > Neal Gafter wrote: > > Joe Darcy sort of ruled out adding property support in project coin in > > http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > > Correct; properties (and closures and reified generics) are examples of > changes out of scope for Project Coin. OK, if it will make easier I will change its name. This is a tiny change, and to rule it out because other more invasive ways of approaching the same subject are big and cause problems is just plain daft. This proposal should be evaluated on its own merits. David > > -Joe > > > Regards, > > Neal > > > > On Tue, Mar 3, 2009 at 12:05 PM, Reinier Zwitserloot > > > > wrote: > >> You call that lightweight? > >> > >> How about following the beans spec more to the letter and just > >> generate the addPropertyChangeListener, removePropertyChangeListener, > >> setX(), and get/isX() method in response to seeing a keyword or > >> annotation on a given field. You'll have to work out the details, but > >> that sounds far, far simpler to understand. > >> > >> You'll need to flesh this out, but it would look something like: > >> > >> public class Foo { > >> private property int x; > >> } > >> > >> Which would generate the addPropertyChangeListener, > >> removePropertyChangeListener, setX, getX methods, all public, along > >> with the required infrastructure to make it tick. If you don't like > >> the generation, for example because you want the setter to be package > >> private, you just add the setter in the source file; the keyword will > >> only generate the missing stuff. It doesn't cover every use case, but > >> there's always the alternative of doing whatever people do now with > >> beans. Something you didn't mention in your proposal, by the way. > >> > >> I think there's also a fully fleshed out property proposal (including > >> a 'property' keyword) out there somewhere. > >> > >> Possibly make a way to opt out of generating the property change > >> listener support, and just the getters/setters. > >> --Reinier Zwitserloot > >> > >> On Mar 3, 2009, at 15:59, David Goodenough wrote: > >>> Below is my proposal for Lightweight Properties. I know that the > >>> syntax > >>> change is an abbomination to some people, but I have tried to reduce > >>> this to its absolute minimum, while still getting a significant > >>> benefit. > >>> > >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >>> > >>> AUTHOR(S): > >>> > >>> David Goodenough, long time Java user. I can be reached at > >>> david.goodenough at linkchoose.co.uk. > >>> > >>> OVERVIEW > >>> > >>> FEATURE SUMMARY: > >>> > >>> Lightweight Property support > >>> > >>> MAJOR ADVANTAGE: > >>> > >>> Both BeansBinding (whether JSR-295 or others such an JFace or the > >>> JGoodies > >>> binding) and the JPA Criteria API currently require field names (as > >>> Strings) > >>> as arguments, which an IDE/compiler can not check. With this > >>> proposal the > >>> strings would be abandoned, and the IDE/compiler will be able to > >>> check the > >>> correctness of the code. > >>> > >>> MAJOR BENEFIT: > >>> > >>> Manual checking no longer required. This proposal introduces a > >>> simple well > >>> defined IDE/compiler checkable solution. > >>> > >>> MAJOR DISADVANTAGE: > >>> > >>> It is a language change, and this seems to upset some people. > >>> > >>> ALTERNATIVES: > >>> > >>> None really, apart from using another language or continuing to use > >>> String > >>> names. The existing solutions all require String names which are > >>> uncheckable. > >>> > >>> EXAMPLES > >>> > >>> Lets assume we have a POJO called foo, of type Foo with a field bar > >>> of type > >>> Bar, which itself has a field of type Jim called jim. > >>> > >>> There are two forms of lightweight properties:- > >>> > >>> 1) foo#bar would be translated by the compiler into:- > >>> > >>> new Property(foo,"bar"); > >>> > >>> while foo#bar#jim would be translated into:- > >>> > >>> new Property(foo,"bar","jim"); > >>> > >>> 2) Foo#bar would be translated into:- > >>> > >>> new Property(Foo.class,"bar"); > >>> > >>> while Foo#bar#jim would be translated into:- > >>> > >>> new Property(Foo.class,"bar","jim"); > >>> > >>> These two forms create (1) a bound Property, or (2) an unbound one. > >>> Bound > >>> Properties are explicitly bound to a particular instance of a class > >>> (in this > >>> case foo), while unbound Properties are templates which can be > >>> applied to any > >>> instance of class Foo. Actually bound properties can also be used as > >>> unbound > >>> properties, but that is a harmless and useful side effect not a > >>> primary > >>> intent. > >>> > >>> The Property class would need to be added (it is appended below), > >>> and should > >>> be added either to the java.beans package or to the > >>> java.lang.reflect package > >>> (with which is probably has more in common). > >>> > >>> Syntactically a "#" can be placed wherever a "." can be placed > >>> (except inside > >>> a number), and the same checks need to be made (that each field to > >>> the right > >>> of a # is a field in the left hand side) as would be made for a ".". > >>> The only > >>> difference is in field visibility - For the "#" any field is > >>> visible, which > >>> follows the model currently available in the Field class with > >>> getDeclaredFields(). It also follows the model that while a field > >>> might be > >>> private and therefore not directly accessible from outside, getters > >>> and > >>> setters can provide access. > >>> > >>> The Property object provides type safe access to the field in the > >>> form of > >>> getters and setters. These come in pairs, one for bound and the > >>> other for > >>> unbound access. So for bound access no object is required to fetch > >>> the value, > >>> for an unbound object the parent object needs to be specified. So if > >>> we > >>> have:- > >>> > >>> Propertyprop = foo#bar; > >>> > >>> we can later say:- > >>> > >>> Bar b = prop.get(); > >>> > >>> or for an unbound one from a second Foo object foo2:- > >>> > >>> Bar b = prop.get(foo2); > >>> > >>> The getters and setters in the Property object will defer to > >>> explicitly coded > >>> getters and setters if present, otherwise they will use the Field > >>> getter and > >>> setter. > >>> > >>> If a setter is not explicitly coded, the implicit setter will look > >>> for a > >>> PropertyChangeSupport object in the parent object of the rightmost > >>> field and > >>> fire a PropertyChangeEvent to that object. > >>> > >>> There are also two Annotations provided by the Property class, > >>> ReadOnly and > >>> WriteOnly. These stop implicit getters and setters from trying to > >>> read/write > >>> the property. > >>> > >>> Talking of Annotations, this notation can also be used to get at the > >>> Annotations for a field. So to test for the presence of an > >>> Annotation Ann on > >>> Foo.bar we would use:- > >>> > >>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >>> > >>> SIMPLE EXAMPLE: > >>> > >>> To take an example from BeansBinding (taken from Shannon Hickey's > >>> blog):- > >>> > >>> // create a BeanProperty representing a bean's firstName > >>> Property firstP = BeanProperty.create("firstName"); > >>> // Bind Duke's first name to the text property of a Swing > >>> JTextField BeanProperty textP = BeanProperty.create("text"); > >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > >>> firstP, textfield, textP); > >>> binding.bind(); > >>> > >>> > >>> would instead be written:- > >>> > >>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>> duke#firstName, textfield#text); > >>> binding.bind(); > >>> > >>> which of course can be checked by the IDE/compiler, and will not > >>> wait until > >>> run time (not even instantiation time) to show up the error. > >>> > >>> ADVANCED EXAMPLE: > >>> > >>> For a JComboBox (or JList or JTable or JTree) there is a need to map > >>> a list of > >>> objects to the value strings (or column contents). For this we need > >>> to have > >>> an unbound Property which can be applied to each element of the list. > >>> > >>> Duke duke; > >>> Listdukes; > >>> BoundComboBox combo = new > >>> BoundComboBox(dukes,Duke#fullname,this#duke); > >>> > >>> and now the combo box will be populated from the list dukes, and the > >>> display > >>> values in the list will be taken from the fullname field of each Duke > >>> element, and the initial value will be set from the local class > >>> field duke > >>> and any changes to the combo box selected element will be reflected > >>> back to > >>> the duke field. > >>> > >>> DETAILS > >>> > >>> SPECIFICATION: > >>> > >>> This proposal adds a new syntactic element, "#", which can be used > >>> in the same > >>> way that "." can be used to qualify fields within a Java object. > >>> > >>> COMPILATION: > >>> > >>> This proposal requires no change to the class files, and is > >>> implemented by a > >>> simple generation of the required instance using the relevant Property > >>> constructor. Obviously the compiler would have to make sure that the > >>> use that > >>> the property object was being put to (in the examples above the left > >>> hand > >>> side of the assignment) had the correct Generic attributes. > >>> > >>> TESTING: > >>> > >>> How can the feature be tested? > >>> > >>> LIBRARY SUPPORT: > >>> > >>> The new Property class is required (see below). > >>> > >>> REFLECTIVE APIS: > >>> > >>> No changes are required to the reflective APIs although it makes > >>> extensive use > >>> of those APIs. > >>> > >>> OTHER CHANGES: > >>> > >>> No other changes are requires. > >>> > >>> MIGRATION: > >>> > >>> Fortunately there is no code that is formally part of J2SE 6 which > >>> uses such > >>> Properties. There are however two proposals which will need it > >>> (BeansBinding > >>> and JPA Criteria API), but neither of these seem to be destined to > >>> be part of > >>> J2SE 7 (BeansBinding seems to have died the death and the Criteria > >>> API would > >>> be part of the next J2EE which will follow J2SE 7), so this will > >>> provide a > >>> base for them to use and no existing code need to be updated. > >>> > >>> There are other extant Beans-Binding libraries, which could be > >>> modified to use > >>> this proposal, but as none of the existing features have been > >>> changed there > >>> is no need to change them (other than for type safety and compiler/IDE > >>> checkability). > >>> > >>> COMPATIBILITY > >>> > >>> BREAKING CHANGES: > >>> > >>> None. This change should not make any existing correct code fail to > >>> compile > >>> or run or change the way in which it compiles/runs. > >>> > >>> EXISTING PROGRAMS: > >>> > >>> No change required to any existing programs > >>> > >>> REFERENCES > >>> > >>> EXISTING BUGS: > >>> > >>> None > >>> > >>> URL FOR PROTOTYPE (optional): > >>> > >>> I do not have the knowledge to make changes to the compiler, and the > >>> only > >>> documentation making such changes concentrated on adding operators not > >>> changes at this level. So there is no prototype of the compiler > >>> part, but the > >>> Property class follows:- > >>> > >>> package java.lang.reflect; > >>> > >>> import java.beans.BeanInfo; > >>> import java.beans.Introspector; > >>> import java.beans.PropertyChangeSupport; > >>> import java.beans.PropertyDescriptor; > >>> import java.lang.reflect.Field; > >>> import java.lang.reflect.Method; > >>> > >>> /** > >>> * Property class > >>> * This is the support class for use with the # notation to provide > >>> lightweight > >>> * Property support for Java. > >>> * > >>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >>> * @licence LPGL V2 : details of which can be found at http://fsf.org. > >>> * @author david.goodenough at linkchoose.co.uk > >>> * > >>> * @param The Parent class for this field > >>> * @param The Type of this field > >>> */ > >>> public class Property { > >>> private C parent; > >>> private Class parentClass; > >>> private Field[] fields; > >>> private PropertyDescriptor[] pd = null; > >>> /** > >>> * Constructor used to create Property objects. The Parent object > >>> may be > >>> * null, but should normally be specified as it can be overridden > >>> anyway. > >>> * @param parent C object that contains the field > >>> * @param field Field describing this field > >>> */ > >>> public Property(C parent, String ... fieldNames) { > >>> this.parent = parent; > >>> this(parent.getClass(), fieldNames); > >>> } > >>> /** > >>> * Constructor for unbound Properties, but also used internally > >>> after > >>> setting > >>> * the parent object by the bound Property objects. > >>> * @param parentClass Class of the parent object > >>> * @param fieldNames String[] of field names > >>> */ > >>> public Property(ClassparentClass, String .. fieldNames) { > >>> this.parentClass = parentClass; > >>> fields = new Field[fieldNames.length]; > >>> pd = new PropertyDescriptor[fieldNames.length]; > >>> outer: for(int index = 0; index < fields.length; index++) { > >>> Field[]dclFields = parentClass.getDeclaredFields(); > >>> for(Field field:dclFields) { > >>> if(field.getName().equals(fieldNames[index])) { > >>> fields[index] = field; > >>> field.setAccessible(true); > >>> try { > >>> BeanInfo beanInfo = > >>> Introspector.getBeanInfo(parent.getClass()); > >>> PropertyDescriptor[]props = > >>> beanInfo.getPropertyDescriptors(); > >>> for(PropertyDescriptor prop : props) { > >>> > >>> if(prop.getName().equals(field.getName())) { pd[index] = prop; break; > >>> } > >>> } > >>> } catch(Exception e) { /* assume can not > >>> find getter/ setter > >>> */ } > >>> parentClass = field.getType(); > >>> continue outer; > >>> } > >>> } > >>> throw new IllegalArgumentException("Field " + fieldNames[index] + > >>> " not found in class " + > >>> parentClass.getCanonicalName()); > >>> } > >>> } > >>> /** > >>> * Getter from the field in the parent specified when this > >>> Property was > >>> created. > >>> * @see Property.get(C otherParent) > >>> * @return F the value of this field > >>> */ > >>> public F get() { > >>> return get(parent); > >>> } > >>> /** > >>> * Getter with explicit parent. > >>> * This code will check see if this field is WriteOnly, and > >>> complain if it > >>> is. > >>> * It will then see if the use has provided am explicit getter, > >>> and call > >>> that > >>> * if present, otherwise it will just fetch the value through the > >>> Field > >>> provided > >>> * method. > >>> * @param otherParent C parent object > >>> * @return F value of the field > >>> */ > >>> @SuppressWarnings("unchecked") // This should actually not be > >>> needed, > >>> // but the Field.get method is not > >>> typed > >>> public F get(C otherParent) { > >>> Object result = otherParent; > >>> try { > >>> for(int index = 0; index < fields.length; index++) { > >>> > >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>> throw new IllegalAccessException( > >>> "Can not get from a WriteOnly field - " + > >>> fields[index].getName()); > >>> Method getter = pd[index] == null ? null : > >>> pd[index].getReadMethod(); > >>> if(getter == null) result = fields[index].get(result); > >>> else result = getter.invoke(result); > >>> } > >>> } catch(Exception e) { > >>> throw new RuntimeException("Should not occur exception", > >>> e); } > >>> return (F)result; > >>> } > >>> /** > >>> * Setter to set the value of the field in the parent object > >>> declared with > >>> the > >>> * Property object > >>> * @param newValue F new value of this field > >>> */ > >>> public void set(F newValue) { > >>> set(parent,newValue); > >>> } > >>> /** > >>> * Setter to set the value of the field to an explicit parent > >>> object. > >>> * If there is a ReadOnly annotation, then we object. If there is > >>> an > >>> explicit > >>> * setter then we use that, otherwise we set the field using the > >>> Field > >>> provided > >>> * set method and if there is a PropertyChangeSupport field, fire a > >>> property > >>> * change event to it. > >>> * We walk our way down the field chain, until we have the last > >>> object and > >>> its > >>> * field, and then we do the set. > >>> * @param parent C explicit parent object > >>> * @param newValue F new value for field in parent > >>> */ > >>> public void set(C parent,F newValue) { > >>> try { > >>> Object last = parent; > >>> int index; > >>> for(index = 0; index < fields.length - 1; index++) { > >>> > >>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>> throw new IllegalAccessException( > >>> "Can not get from a WriteOnly field - " + > >>> fields[index].getName()); > >>> Method getter = pd[index] == null ? null : > >>> pd[index].getReadMethod(); > >>> if(getter == null) last = fields[index].get(last); > >>> else last = getter.invoke(last); > >>> } > >>> > >>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >>> throw new IllegalAccessException( > >>> "Can not get from a WriteOnly field - " + > >>> fields[index].getName()); > >>> Method setter = pd[index] == null ? null : > >>> pd[index].getWriteMethod(); > >>> if(setter == null) { > >>> PropertyChangeSupport pcs = findPcs(last.getClass()); > >>> fields[index].set(last,newValue); > >>> if(pcs != null) > >>> pcs.firePropertyChange(fields[index].getName(), > >>> newValue, > >>> > >>> fields[index].get(last)); > >>> } else setter.invoke(last,newValue); > >>> } catch(Exception e) { > >>> throw new RuntimeException("Should not occur > >>> exception", e); > >>> } > >>> } > >>> /** > >>> * This is used so that the caller can view the Field name > >>> * @return String field name > >>> */ > >>> public String[] getFieldName() { > >>> String[]names = new String[fields.length]; > >>> for(int index = 0; index < fields.length; index++) { > >>> names[index] = fields[index].getName(); > >>> } > >>> return names; > >>> } > >>> /** > >>> * This method is used to fetch the Field array, which is useful > >>> if you > >>> need to > >>> * access the Annotations of a field. > >>> * @return Field[] the array of Fields describing this Property. > >>> */ > >>> public Field[] getFields() { > >>> return fields; > >>> } > >>> /** > >>> * This private method looks for a PropertyChangeSupport object in > >>> the > >>> class and > >>> * if one is found it will return it. It looks right the way up > >>> the class > >>> tree > >>> * by recurring up the superClasses. > >>> * @param parent Class to check for PropertyChangeSupport fields > >>> * @return PropertyChangeSupport first found object, or null if > >>> not found > >>> */ > >>> private PropertyChangeSupport findPcs(Class parent) { > >>> Field fields[] = parent.getDeclaredFields(); > >>> for(Field field:fields) { > >>> field.setAccessible(true); > >>> try { > >>> if(field.getType() == PropertyChangeSupport.class) > >>> return (PropertyChangeSupport)field.get(parent); > >>> } catch(Exception e) { } > >>> } > >>> // If we did not find it then try the superclass > >>> ClasssuperClass = parent.getSuperclass(); > >>> if(superClass == null) return null; > >>> return findPcs(parent.getClass().getSuperclass()); > >>> } > >>> /** > >>> * This annotation is used to mark a field as WriteOnly, i.e. it > >>> can not > >>> be read. > >>> * This stops the automatic getter operation. > >>> */ > >>> public @interface WriteOnly { > >>> } > >>> /** > >>> * This annotation is used to mark a field as ReadOnly, i.e. it > >>> can not be > >>> written. > >>> * This stops the automatic setter operation. > >>> */ > >>> public @interface ReadOnly { > >>> } > >>> } From david.goodenough at linkchoose.co.uk Wed Mar 4 01:49:57 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 4 Mar 2009 09:49:57 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <200903032200.28367.david.goodenough@linkchoose.co.uk> <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> Message-ID: <200903040949.57551.david.goodenough@linkchoose.co.uk> I am not sure that we would loose anything. The important thing is to have an IDE/compiler checkable way of generating Property objects, and having two ways of generating them is not really a problem. My Property object would happily detect either an explicitly generated getter/setter or one generated for you by a property keyword. The property keyword would resolve other things (like the automatic generation of PropertyChangeSupport, and the controlling of visibility) but it is still building on the same basic concept. If you don't want to use # then the work needed for the compiler gets more complicated (I think). One could use a sort of compiler function, so one would say property(foo.bar) and it would modify the function of . inside the function. I really want to find a way to get something into Java 7, otherwise we are looking to Java 8 (which is at least 3 years away if current timescales persist), by which time I suspect that everyone will have gotten bored and gone to find pastures new. David On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > But it seems that we _would_ lose a thing or two with this proposal. > For example, if a complete properties proposal supports full backwards > compatibility and generates getters and setters, then we have a bunch > of code around that uses the foo#bar notation, which is by then > already outdated, and would in fact get in the way of using foo#bar > notation as a shorthand for calling the appropriate getter/setter. I > don't know if that is a desired syntax sugar, but the point is: Your > proposal would effectively make it impossible to add that later, as it > would already be shorthand for creating a Property object. > > The # and the backtick are the only easily typed symbols that have no > meaning whatsoever in java right now. Using one up for an simplified > properties proposal is another serious disdvantage. I don't think your > proposal makes property support light enough to warrant its inclusion > in project coin. That's not to say I have something against > properties; on the contrary, I love the idea and I'm very impressed > with the way properties work in JavaFX. All the more reason to get it > right instead of using a bandage. > > --Reinier Zwitserloot > > On Mar 3, 2009, at 23:00, David Goodenough wrote: > > Well that depends on what you mean by a complete proposal. > > > > There are two parts to the use of Properties. There is the framework > > side, inside BeansBinding or JPA and then there is the consumer > > side, the application code. > > > > My proposal is very simple on the consumer side (the only bit needed > > is the # notation). You can use clasical getters and setters (a > > nuisance > > but everyone understands them), or the simple getter/setter mechanism > > that my Property provides. So for the consumer my proposal is real > > simple. All you need do is add (either explicity or by byte code > > enhancement) > > a PropertyChangeSupport object and the relevant methods and you > > are home and dry. > > > > For the Frameworks, well you only write them once. Even so something > > nice and simple appeals and my proposal is simple. > > > > It may not be Beans as we know it, but they never were integrated > > properly into Java. But its really not that dissimilar just slightly > > different. > > > > So other than a little sytactic sugar (not having to code the > > PropertyChangeSupport object) we have not really lost anything of > > the "full" solution. Having a Bound annotation which would add this > > under the > > covers with a byte code enhancer would not be difficult. The implicit > > getters and setters come with the package. So the question to be > > asked whether a fuller solution is really needed. > > > > David > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >> The language change required for your proposal is indeed lighter, but > >> to understand it, it is seems a lot more complicated. > >> > >> Also, it would be infeasible to introduce a 'lightweight' (according > >> to anyone's definition) proposal now that is lacking in certain > >> aspects, and then fix it later, unless that fix is syntactically very > >> similar and backwards- and migration compatible. That's the major > >> beef > >> I have with this proposal: It effectively shuts the door on any other > >> property proposal. In my view, a proposal solves the problem > >> properly, > >> or shouldn't be added at all; no quick hacky fixes that aren't part > >> of > >> a planned evolution path to a complete solution. > >> > >> If you can highlight how a complete properties proposal will > >> seamlessly work with your syntax, I'm more inclined to like it. > >> > >> --Reinier Zwitserloot > >> > >> On Mar 3, 2009, at 22:04, David Goodenough wrote: > >>> Yes I do. What you propose is much more invasive. Look at it > >>> again and maybe you will see the Light(ness). > >>> > >>> David > >>> > >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >>>> You call that lightweight? > >>>> > >>>> How about following the beans spec more to the letter and just > >>>> generate the addPropertyChangeListener, > >>>> removePropertyChangeListener, > >>>> setX(), and get/isX() method in response to seeing a keyword or > >>>> annotation on a given field. You'll have to work out the details, > >>>> but > >>>> that sounds far, far simpler to understand. > >>>> > >>>> You'll need to flesh this out, but it would look something like: > >>>> > >>>> public class Foo { > >>>> private property int x; > >>>> } > >>>> > >>>> Which would generate the addPropertyChangeListener, > >>>> removePropertyChangeListener, setX, getX methods, all public, along > >>>> with the required infrastructure to make it tick. If you don't like > >>>> the generation, for example because you want the setter to be > >>>> package > >>>> private, you just add the setter in the source file; the keyword > >>>> will > >>>> only generate the missing stuff. It doesn't cover every use case, > >>>> but > >>>> there's always the alternative of doing whatever people do now with > >>>> beans. Something you didn't mention in your proposal, by the way. > >>>> > >>>> I think there's also a fully fleshed out property proposal > >>>> (including > >>>> a 'property' keyword) out there somewhere. > >>>> > >>>> Possibly make a way to opt out of generating the property change > >>>> listener support, and just the getters/setters. > >>>> --Reinier Zwitserloot > >>>> > >>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: > >>>>> Below is my proposal for Lightweight Properties. I know that the > >>>>> syntax > >>>>> change is an abbomination to some people, but I have tried to > >>>>> reduce > >>>>> this to its absolute minimum, while still getting a significant > >>>>> benefit. > >>>>> > >>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >>>>> > >>>>> AUTHOR(S): > >>>>> > >>>>> David Goodenough, long time Java user. I can be reached at > >>>>> david.goodenough at linkchoose.co.uk. > >>>>> > >>>>> OVERVIEW > >>>>> > >>>>> FEATURE SUMMARY: > >>>>> > >>>>> Lightweight Property support > >>>>> > >>>>> MAJOR ADVANTAGE: > >>>>> > >>>>> Both BeansBinding (whether JSR-295 or others such an JFace or the > >>>>> JGoodies > >>>>> binding) and the JPA Criteria API currently require field names > >>>>> (as > >>>>> Strings) > >>>>> as arguments, which an IDE/compiler can not check. With this > >>>>> proposal the > >>>>> strings would be abandoned, and the IDE/compiler will be able to > >>>>> check the > >>>>> correctness of the code. > >>>>> > >>>>> MAJOR BENEFIT: > >>>>> > >>>>> Manual checking no longer required. This proposal introduces a > >>>>> simple well > >>>>> defined IDE/compiler checkable solution. > >>>>> > >>>>> MAJOR DISADVANTAGE: > >>>>> > >>>>> It is a language change, and this seems to upset some people. > >>>>> > >>>>> ALTERNATIVES: > >>>>> > >>>>> None really, apart from using another language or continuing to > >>>>> use > >>>>> String > >>>>> names. The existing solutions all require String names which are > >>>>> uncheckable. > >>>>> > >>>>> EXAMPLES > >>>>> > >>>>> Lets assume we have a POJO called foo, of type Foo with a field > >>>>> bar > >>>>> of type > >>>>> Bar, which itself has a field of type Jim called jim. > >>>>> > >>>>> There are two forms of lightweight properties:- > >>>>> > >>>>> 1) foo#bar would be translated by the compiler into:- > >>>>> > >>>>> new Property(foo,"bar"); > >>>>> > >>>>> while foo#bar#jim would be translated into:- > >>>>> > >>>>> new Property(foo,"bar","jim"); > >>>>> > >>>>> 2) Foo#bar would be translated into:- > >>>>> > >>>>> new Property(Foo.class,"bar"); > >>>>> > >>>>> while Foo#bar#jim would be translated into:- > >>>>> > >>>>> new Property(Foo.class,"bar","jim"); > >>>>> > >>>>> These two forms create (1) a bound Property, or (2) an unbound > >>>>> one. > >>>>> Bound > >>>>> Properties are explicitly bound to a particular instance of a > >>>>> class > >>>>> (in this > >>>>> case foo), while unbound Properties are templates which can be > >>>>> applied to any > >>>>> instance of class Foo. Actually bound properties can also be > >>>>> used as > >>>>> unbound > >>>>> properties, but that is a harmless and useful side effect not a > >>>>> primary > >>>>> intent. > >>>>> > >>>>> The Property class would need to be added (it is appended below), > >>>>> and should > >>>>> be added either to the java.beans package or to the > >>>>> java.lang.reflect package > >>>>> (with which is probably has more in common). > >>>>> > >>>>> Syntactically a "#" can be placed wherever a "." can be placed > >>>>> (except inside > >>>>> a number), and the same checks need to be made (that each field to > >>>>> the right > >>>>> of a # is a field in the left hand side) as would be made for a > >>>>> ".". > >>>>> The only > >>>>> difference is in field visibility - For the "#" any field is > >>>>> visible, which > >>>>> follows the model currently available in the Field class with > >>>>> getDeclaredFields(). It also follows the model that while a field > >>>>> might be > >>>>> private and therefore not directly accessible from outside, > >>>>> getters > >>>>> and > >>>>> setters can provide access. > >>>>> > >>>>> The Property object provides type safe access to the field in the > >>>>> form of > >>>>> getters and setters. These come in pairs, one for bound and the > >>>>> other for > >>>>> unbound access. So for bound access no object is required to fetch > >>>>> the value, > >>>>> for an unbound object the parent object needs to be specified. > >>>>> So if > >>>>> we > >>>>> have:- > >>>>> > >>>>> Propertyprop = foo#bar; > >>>>> > >>>>> we can later say:- > >>>>> > >>>>> Bar b = prop.get(); > >>>>> > >>>>> or for an unbound one from a second Foo object foo2:- > >>>>> > >>>>> Bar b = prop.get(foo2); > >>>>> > >>>>> The getters and setters in the Property object will defer to > >>>>> explicitly coded > >>>>> getters and setters if present, otherwise they will use the Field > >>>>> getter and > >>>>> setter. > >>>>> > >>>>> If a setter is not explicitly coded, the implicit setter will look > >>>>> for a > >>>>> PropertyChangeSupport object in the parent object of the rightmost > >>>>> field and > >>>>> fire a PropertyChangeEvent to that object. > >>>>> > >>>>> There are also two Annotations provided by the Property class, > >>>>> ReadOnly and > >>>>> WriteOnly. These stop implicit getters and setters from trying to > >>>>> read/write > >>>>> the property. > >>>>> > >>>>> Talking of Annotations, this notation can also be used to get at > >>>>> the > >>>>> Annotations for a field. So to test for the presence of an > >>>>> Annotation Ann on > >>>>> Foo.bar we would use:- > >>>>> > >>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >>>>> > >>>>> SIMPLE EXAMPLE: > >>>>> > >>>>> To take an example from BeansBinding (taken from Shannon Hickey's > >>>>> blog):- > >>>>> > >>>>> // create a BeanProperty representing a bean's firstName > >>>>> Property firstP = BeanProperty.create("firstName"); > >>>>> // Bind Duke's first name to the text property of a Swing > >>>>> JTextField > >>>>> BeanProperty textP = BeanProperty.create("text"); > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > >>>>> firstP, textfield, textP); > >>>>> binding.bind(); > >>>>> > >>>>> > >>>>> would instead be written:- > >>>>> > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>>>> duke#firstName, textfield#text); > >>>>> binding.bind(); > >>>>> > >>>>> which of course can be checked by the IDE/compiler, and will not > >>>>> wait until > >>>>> run time (not even instantiation time) to show up the error. > >>>>> > >>>>> ADVANCED EXAMPLE: > >>>>> > >>>>> For a JComboBox (or JList or JTable or JTree) there is a need to > >>>>> map > >>>>> a list of > >>>>> objects to the value strings (or column contents). For this we > >>>>> need > >>>>> to have > >>>>> an unbound Property which can be applied to each element of the > >>>>> list. > >>>>> > >>>>> Duke duke; > >>>>> Listdukes; > >>>>> BoundComboBox combo = new > >>>>> BoundComboBox(dukes,Duke#fullname,this#duke); > >>>>> > >>>>> and now the combo box will be populated from the list dukes, and > >>>>> the > >>>>> display > >>>>> values in the list will be taken from the fullname field of each > >>>>> Duke > >>>>> element, and the initial value will be set from the local class > >>>>> field duke > >>>>> and any changes to the combo box selected element will be > >>>>> reflected > >>>>> back to > >>>>> the duke field. > >>>>> > >>>>> DETAILS > >>>>> > >>>>> SPECIFICATION: > >>>>> > >>>>> This proposal adds a new syntactic element, "#", which can be used > >>>>> in the same > >>>>> way that "." can be used to qualify fields within a Java object. > >>>>> > >>>>> COMPILATION: > >>>>> > >>>>> This proposal requires no change to the class files, and is > >>>>> implemented by a > >>>>> simple generation of the required instance using the relevant > >>>>> Property > >>>>> constructor. Obviously the compiler would have to make sure that > >>>>> the > >>>>> use that > >>>>> the property object was being put to (in the examples above the > >>>>> left > >>>>> hand > >>>>> side of the assignment) had the correct Generic attributes. > >>>>> > >>>>> TESTING: > >>>>> > >>>>> How can the feature be tested? > >>>>> > >>>>> LIBRARY SUPPORT: > >>>>> > >>>>> The new Property class is required (see below). > >>>>> > >>>>> REFLECTIVE APIS: > >>>>> > >>>>> No changes are required to the reflective APIs although it makes > >>>>> extensive use > >>>>> of those APIs. > >>>>> > >>>>> OTHER CHANGES: > >>>>> > >>>>> No other changes are requires. > >>>>> > >>>>> MIGRATION: > >>>>> > >>>>> Fortunately there is no code that is formally part of J2SE 6 which > >>>>> uses such > >>>>> Properties. There are however two proposals which will need it > >>>>> (BeansBinding > >>>>> and JPA Criteria API), but neither of these seem to be destined to > >>>>> be part of > >>>>> J2SE 7 (BeansBinding seems to have died the death and the Criteria > >>>>> API would > >>>>> be part of the next J2EE which will follow J2SE 7), so this will > >>>>> provide a > >>>>> base for them to use and no existing code need to be updated. > >>>>> > >>>>> There are other extant Beans-Binding libraries, which could be > >>>>> modified to use > >>>>> this proposal, but as none of the existing features have been > >>>>> changed there > >>>>> is no need to change them (other than for type safety and > >>>>> compiler/ > >>>>> IDE > >>>>> checkability). > >>>>> > >>>>> COMPATIBILITY > >>>>> > >>>>> BREAKING CHANGES: > >>>>> > >>>>> None. This change should not make any existing correct code > >>>>> fail to > >>>>> compile > >>>>> or run or change the way in which it compiles/runs. > >>>>> > >>>>> EXISTING PROGRAMS: > >>>>> > >>>>> No change required to any existing programs > >>>>> > >>>>> REFERENCES > >>>>> > >>>>> EXISTING BUGS: > >>>>> > >>>>> None > >>>>> > >>>>> URL FOR PROTOTYPE (optional): > >>>>> > >>>>> I do not have the knowledge to make changes to the compiler, and > >>>>> the > >>>>> only > >>>>> documentation making such changes concentrated on adding operators > >>>>> not > >>>>> changes at this level. So there is no prototype of the compiler > >>>>> part, but the > >>>>> Property class follows:- > >>>>> > >>>>> package java.lang.reflect; > >>>>> > >>>>> import java.beans.BeanInfo; > >>>>> import java.beans.Introspector; > >>>>> import java.beans.PropertyChangeSupport; > >>>>> import java.beans.PropertyDescriptor; > >>>>> import java.lang.reflect.Field; > >>>>> import java.lang.reflect.Method; > >>>>> > >>>>> /** > >>>>> * Property class > >>>>> * This is the support class for use with the # notation to provide > >>>>> lightweight > >>>>> * Property support for Java. > >>>>> * > >>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >>>>> * @licence LPGL V2 : details of which can be found at http:// > >>>>> fsf.org. > >>>>> * @author david.goodenough at linkchoose.co.uk > >>>>> * > >>>>> * @param The Parent class for this field > >>>>> * @param The Type of this field > >>>>> */ > >>>>> public class Property { > >>>>> private C parent; > >>>>> private Class parentClass; > >>>>> private Field[] fields; > >>>>> private PropertyDescriptor[] pd = null; > >>>>> /** > >>>>> * Constructor used to create Property objects. The Parent object > >>>>> may be > >>>>> * null, but should normally be specified as it can be overridden > >>>>> anyway. > >>>>> * @param parent C object that contains the field > >>>>> * @param field Field describing this field > >>>>> */ > >>>>> public Property(C parent, String ... fieldNames) { > >>>>> this.parent = parent; > >>>>> this(parent.getClass(), fieldNames); > >>>>> } > >>>>> /** > >>>>> * Constructor for unbound Properties, but also used internally > >>>>> after > >>>>> setting > >>>>> * the parent object by the bound Property objects. > >>>>> * @param parentClass Class of the parent object > >>>>> * @param fieldNames String[] of field names > >>>>> */ > >>>>> public Property(ClassparentClass, String .. fieldNames) { > >>>>> this.parentClass = parentClass; > >>>>> fields = new Field[fieldNames.length]; > >>>>> pd = new PropertyDescriptor[fieldNames.length]; > >>>>> outer: for(int index = 0; index < fields.length; index++) { > >>>>> Field[]dclFields = parentClass.getDeclaredFields(); > >>>>> for(Field field:dclFields) { > >>>>> if(field.getName().equals(fieldNames[index])) { > >>>>> fields[index] = field; > >>>>> field.setAccessible(true); > >>>>> try { > >>>>> BeanInfo beanInfo = > >>>>> Introspector.getBeanInfo(parent.getClass()); > >>>>> PropertyDescriptor[]props = > >>>>> beanInfo.getPropertyDescriptors(); > >>>>> for(PropertyDescriptor prop : props) { > >>>>> if(prop.getName().equals(field.getName())) { > >>>>> pd[index] = prop; > >>>>> break; > >>>>> } > >>>>> } > >>>>> } catch(Exception e) { /* assume can not find getter/ > >>>>> setter > >>>>> */ } > >>>>> parentClass = field.getType(); > >>>>> continue outer; > >>>>> } > >>>>> } > >>>>> throw new IllegalArgumentException("Field " + fieldNames[index] + > >>>>> " not found in class " + > >>>>> parentClass.getCanonicalName()); > >>>>> } > >>>>> } > >>>>> /** > >>>>> * Getter from the field in the parent specified when this > >>>>> Property was > >>>>> created. > >>>>> * @see Property.get(C otherParent) > >>>>> * @return F the value of this field > >>>>> */ > >>>>> public F get() { > >>>>> return get(parent); > >>>>> } > >>>>> /** > >>>>> * Getter with explicit parent. > >>>>> * This code will check see if this field is WriteOnly, and > >>>>> complain if it > >>>>> is. > >>>>> * It will then see if the use has provided am explicit getter, > >>>>> and call > >>>>> that > >>>>> * if present, otherwise it will just fetch the value through the > >>>>> Field > >>>>> provided > >>>>> * method. > >>>>> * @param otherParent C parent object > >>>>> * @return F value of the field > >>>>> */ > >>>>> @SuppressWarnings("unchecked") // This should actually not be > >>>>> needed, > >>>>> // but the Field.get method is not > >>>>> typed > >>>>> public F get(C otherParent) { > >>>>> Object result = otherParent; > >>>>> try { > >>>>> for(int index = 0; index < fields.length; index++) { > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method getter = pd[index] == null ? null : > >>>>> pd[index].getReadMethod(); > >>>>> if(getter == null) result = fields[index].get(result); > >>>>> else result = getter.invoke(result); > >>>>> } > >>>>> } catch(Exception e) { > >>>>> throw new RuntimeException("Should not occur exception", e); > >>>>> } > >>>>> return (F)result; > >>>>> } > >>>>> /** > >>>>> * Setter to set the value of the field in the parent object > >>>>> declared with > >>>>> the > >>>>> * Property object > >>>>> * @param newValue F new value of this field > >>>>> */ > >>>>> public void set(F newValue) { > >>>>> set(parent,newValue); > >>>>> } > >>>>> /** > >>>>> * Setter to set the value of the field to an explicit parent > >>>>> object. > >>>>> * If there is a ReadOnly annotation, then we object. If there is > >>>>> an > >>>>> explicit > >>>>> * setter then we use that, otherwise we set the field using the > >>>>> Field > >>>>> provided > >>>>> * set method and if there is a PropertyChangeSupport field, > >>>>> fire a > >>>>> property > >>>>> * change event to it. > >>>>> * We walk our way down the field chain, until we have the last > >>>>> object and > >>>>> its > >>>>> * field, and then we do the set. > >>>>> * @param parent C explicit parent object > >>>>> * @param newValue F new value for field in parent > >>>>> */ > >>>>> public void set(C parent,F newValue) { > >>>>> try { > >>>>> Object last = parent; > >>>>> int index; > >>>>> for(index = 0; index < fields.length - 1; index++) { > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method getter = pd[index] == null ? null : > >>>>> pd[index].getReadMethod(); > >>>>> if(getter == null) last = fields[index].get(last); > >>>>> else last = getter.invoke(last); > >>>>> } > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method setter = pd[index] == null ? null : > >>>>> pd[index].getWriteMethod(); > >>>>> if(setter == null) { > >>>>> PropertyChangeSupport pcs = findPcs(last.getClass()); > >>>>> fields[index].set(last,newValue); > >>>>> if(pcs != null) > >>>>> pcs.firePropertyChange(fields[index].getName(), > >>>>> newValue, > >>>>> > >>>>> fields[index].get(last)); > >>>>> } else setter.invoke(last,newValue); > >>>>> } catch(Exception e) { > >>>>> throw new RuntimeException("Should not occur > >>>>> exception", e); > >>>>> } > >>>>> } > >>>>> /** > >>>>> * This is used so that the caller can view the Field name > >>>>> * @return String field name > >>>>> */ > >>>>> public String[] getFieldName() { > >>>>> String[]names = new String[fields.length]; > >>>>> for(int index = 0; index < fields.length; index++) { > >>>>> names[index] = fields[index].getName(); > >>>>> } > >>>>> return names; > >>>>> } > >>>>> /** > >>>>> * This method is used to fetch the Field array, which is useful > >>>>> if you > >>>>> need to > >>>>> * access the Annotations of a field. > >>>>> * @return Field[] the array of Fields describing this Property. > >>>>> */ > >>>>> public Field[] getFields() { > >>>>> return fields; > >>>>> } > >>>>> /** > >>>>> * This private method looks for a PropertyChangeSupport object in > >>>>> the > >>>>> class and > >>>>> * if one is found it will return it. It looks right the way up > >>>>> the class > >>>>> tree > >>>>> * by recurring up the superClasses. > >>>>> * @param parent Class to check for PropertyChangeSupport fields > >>>>> * @return PropertyChangeSupport first found object, or null if > >>>>> not found > >>>>> */ > >>>>> private PropertyChangeSupport findPcs(Class parent) { > >>>>> Field fields[] = parent.getDeclaredFields(); > >>>>> for(Field field:fields) { > >>>>> field.setAccessible(true); > >>>>> try { > >>>>> if(field.getType() == PropertyChangeSupport.class) > >>>>> return (PropertyChangeSupport)field.get(parent); > >>>>> } catch(Exception e) { } > >>>>> } > >>>>> // If we did not find it then try the superclass > >>>>> ClasssuperClass = parent.getSuperclass(); > >>>>> if(superClass == null) return null; > >>>>> return findPcs(parent.getClass().getSuperclass()); > >>>>> } > >>>>> /** > >>>>> * This annotation is used to mark a field as WriteOnly, i.e. it > >>>>> can not > >>>>> be read. > >>>>> * This stops the automatic getter operation. > >>>>> */ > >>>>> public @interface WriteOnly { > >>>>> } > >>>>> /** > >>>>> * This annotation is used to mark a field as ReadOnly, i.e. it > >>>>> can not be > >>>>> written. > >>>>> * This stops the automatic setter operation. > >>>>> */ > >>>>> public @interface ReadOnly { > >>>>> } > >>>>> } From forax at univ-mlv.fr Wed Mar 4 04:58:37 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 04 Mar 2009 13:58:37 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> Message-ID: <49AE7AFD.7010609@univ-mlv.fr> Joshua Bloch a ?crit : > Mark, > Sorry for the delay, and thanks so much for the report! This is an > interesting case. It seems unfortunate that DataCacheManagerImpl extends > Closeable, given that its close method doesn't throw any checked exceptions. > But it got me thinking, and I came to the conclusion that there's no reason > for the Disposable interface to be parameterized! Its close method should > just throw Exception. Then Closeable and DataCacheManager can both extend > Disposable. The Disposable interface won't be terribly useful as a parameter > type, but who cares? Its raison d'etre is the automatic resource management > statement. In this context, the close method is invoked on a resource using > its declared type. That means that it throws whatever exceptions it's > declared to throw (as per the desugaring in my proposal). I will modify the > proposal accordingly and repost it. I think this is a real improvement! > It's both simpler and more broadly applicable. > > Thanks so much, > > Josh > There is another way, change the JLS :) In my opinion, the last sentence of section 8.1.5 of the JLS is too restrictive: "A class may not at the same time be a subtype of two interface types which are different invocations of the same generic interface (?9.1.2) , or an invocation of a generic interface and a raw type naming that same generic interface." This sentence is weird because the last part of section 8.1.5 explain how to detect clash between methods from different interfaces by taking a look to their return types. So in case of different interfaces, the compiler have to do a calculation involving the member methods but if interfaces are generics it doesn't do any calculation on member methods. That is not consistent. Note than the detection algorithm is not exactly the same because one can have a clash between bridge methods. I'm proposing to remove the last sentence of section 8.1.5 and replace it by a one saying that if there is of two or more generics super-interfaces, member methods of their raw types should not have the same signature. With theis new rule, the following examples will now compile: interface Duplicate { X duplicate(); } class A implements Duplicate, Duplicate { public Integer duplicate() { return null; } } and interface Disposable { public void dispose() throws E; } class Connection implements Disposable, Disposable { public void dispose() throws IOEXception { } } There is another reason why I don't like the last sentence of section 8.1.5, this sentence is not compatible with section 13.4.4 on binary compatibility: "Changing the direct superclass or the set of direct superinterfaces of a class type will not break compatibility with pre-existing binaries, provided that the total set of superclasses or superinterfaces, respectively, of the class type loses no members." cheers, R?mi From markmahieu at googlemail.com Wed Mar 4 05:36:34 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 4 Mar 2009 13:36:34 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> Message-ID: Josh, Yeah, sorry that email was a bit rubbish. It was 3:30am though - please allow me to try again... As you know some resources are allocated and held for much longer than the duration of a single method call, eventually being released on some trigger condition. I'm not suggesting that ARM should try to cater for this, but I do see Neal's point that there's a common desire to pass such resources around or to hold them somewhere, and given that they are often the same *type* in both scenarios, then if ARM introduced the Disposable interface for its purposes, it would be natural for programmers to want to hold the more long-lived ones in a Collection for later disposal. Now, where I was going with my last email was that a library could include an interface that extends Disposable, refining the exception types thrown: interface SWTDisposable extends Disposable { void close() throws SWTException; } The afore-mentioned programmer could now hold a Collection and have much more appropriate exception types to deal with in their cleanup code. (SWTException is unchecked in real life, but the point's the same). If that turned out to be a sensible convention, then the only responsibility for ARM would be to say, in the javadoc for Disposable, "libraries are encouraged to extend this interface, refining the thrown exceptions...". Now, having mentioned SWT... This fairly typical example, from the official SWT 'snippets' page, would benefit very well from the introduction of ARM or some other resource disposal mechanism: http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/ org/eclipse/swt/snippets/Snippet280.java?view=co So if we look at how the SWT library might be retrofitted to work with ARM, we find this class, which is extended by all the various SWT resource classes: public abstract class Resource { /** * Disposes of the operating system resources associated with this resource. */ void dispose() { // ... } // ... } http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/ reference/api/org/eclipse/swt/graphics/Resource.html OK, well for once the SWT team's aversion to interfaces has an up- side, and we can easily retrofit this with Disposable, calling dispose () from close(). Or can we? public class Path extends Resource { /** * Closes the current sub path by adding to the receiver a line from the current point of the path back to the starting point of the sub path. */ public void close() { // ... } // ... } http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/ reference/api/org/eclipse/swt/graphics/Path.html Square peg, round hole :( Any suggestions? Regards, Mark On 4 Mar 2009, at 03:47, Joshua Bloch wrote: > Mark, > > I don't see a compelling need for it. When in doubt, leave it out. > > Josh > > On Tue, Mar 3, 2009 at 7:39 PM, Mark Mahieu > wrote: > So would APIs be encouraged to define more specific Resource > interfaces that narrow the thrown exception types ... > > interface SQLResource extends Resource { > void dispose() throws SQLException { } > } > > interface SWTResource extends Resource { > void dispose() throws SWTException { } > } > > etc? > > I don't think there'd be any reason to do this. From david.goodenough at linkchoose.co.uk Wed Mar 4 05:38:25 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 4 Mar 2009 13:38:25 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <200903032200.28367.david.goodenough@linkchoose.co.uk> <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> Message-ID: <200903041338.25551.david.goodenough@linkchoose.co.uk> A further thought on the # issue. The . is of course already used in two places, to join an object to its field and to separate fractions from the integer part of a number. The parser can cope with this, so there is no particular reason why it could not cope with other overloading. The test is whether it is obvious to the reader what is going on, and possible for the compiler to tell unambigously which is intended. Just a thought. David On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > But it seems that we _would_ lose a thing or two with this proposal. > For example, if a complete properties proposal supports full backwards > compatibility and generates getters and setters, then we have a bunch > of code around that uses the foo#bar notation, which is by then > already outdated, and would in fact get in the way of using foo#bar > notation as a shorthand for calling the appropriate getter/setter. I > don't know if that is a desired syntax sugar, but the point is: Your > proposal would effectively make it impossible to add that later, as it > would already be shorthand for creating a Property object. > > The # and the backtick are the only easily typed symbols that have no > meaning whatsoever in java right now. Using one up for an simplified > properties proposal is another serious disdvantage. I don't think your > proposal makes property support light enough to warrant its inclusion > in project coin. That's not to say I have something against > properties; on the contrary, I love the idea and I'm very impressed > with the way properties work in JavaFX. All the more reason to get it > right instead of using a bandage. > > --Reinier Zwitserloot > > On Mar 3, 2009, at 23:00, David Goodenough wrote: > > Well that depends on what you mean by a complete proposal. > > > > There are two parts to the use of Properties. There is the framework > > side, inside BeansBinding or JPA and then there is the consumer > > side, the application code. > > > > My proposal is very simple on the consumer side (the only bit needed > > is the # notation). You can use clasical getters and setters (a > > nuisance > > but everyone understands them), or the simple getter/setter mechanism > > that my Property provides. So for the consumer my proposal is real > > simple. All you need do is add (either explicity or by byte code > > enhancement) > > a PropertyChangeSupport object and the relevant methods and you > > are home and dry. > > > > For the Frameworks, well you only write them once. Even so something > > nice and simple appeals and my proposal is simple. > > > > It may not be Beans as we know it, but they never were integrated > > properly into Java. But its really not that dissimilar just slightly > > different. > > > > So other than a little sytactic sugar (not having to code the > > PropertyChangeSupport object) we have not really lost anything of > > the "full" solution. Having a Bound annotation which would add this > > under the > > covers with a byte code enhancer would not be difficult. The implicit > > getters and setters come with the package. So the question to be > > asked whether a fuller solution is really needed. > > > > David > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >> The language change required for your proposal is indeed lighter, but > >> to understand it, it is seems a lot more complicated. > >> > >> Also, it would be infeasible to introduce a 'lightweight' (according > >> to anyone's definition) proposal now that is lacking in certain > >> aspects, and then fix it later, unless that fix is syntactically very > >> similar and backwards- and migration compatible. That's the major > >> beef > >> I have with this proposal: It effectively shuts the door on any other > >> property proposal. In my view, a proposal solves the problem > >> properly, > >> or shouldn't be added at all; no quick hacky fixes that aren't part > >> of > >> a planned evolution path to a complete solution. > >> > >> If you can highlight how a complete properties proposal will > >> seamlessly work with your syntax, I'm more inclined to like it. > >> > >> --Reinier Zwitserloot > >> > >> On Mar 3, 2009, at 22:04, David Goodenough wrote: > >>> Yes I do. What you propose is much more invasive. Look at it > >>> again and maybe you will see the Light(ness). > >>> > >>> David > >>> > >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >>>> You call that lightweight? > >>>> > >>>> How about following the beans spec more to the letter and just > >>>> generate the addPropertyChangeListener, > >>>> removePropertyChangeListener, > >>>> setX(), and get/isX() method in response to seeing a keyword or > >>>> annotation on a given field. You'll have to work out the details, > >>>> but > >>>> that sounds far, far simpler to understand. > >>>> > >>>> You'll need to flesh this out, but it would look something like: > >>>> > >>>> public class Foo { > >>>> private property int x; > >>>> } > >>>> > >>>> Which would generate the addPropertyChangeListener, > >>>> removePropertyChangeListener, setX, getX methods, all public, along > >>>> with the required infrastructure to make it tick. If you don't like > >>>> the generation, for example because you want the setter to be > >>>> package > >>>> private, you just add the setter in the source file; the keyword > >>>> will > >>>> only generate the missing stuff. It doesn't cover every use case, > >>>> but > >>>> there's always the alternative of doing whatever people do now with > >>>> beans. Something you didn't mention in your proposal, by the way. > >>>> > >>>> I think there's also a fully fleshed out property proposal > >>>> (including > >>>> a 'property' keyword) out there somewhere. > >>>> > >>>> Possibly make a way to opt out of generating the property change > >>>> listener support, and just the getters/setters. > >>>> --Reinier Zwitserloot > >>>> > >>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: > >>>>> Below is my proposal for Lightweight Properties. I know that the > >>>>> syntax > >>>>> change is an abbomination to some people, but I have tried to > >>>>> reduce > >>>>> this to its absolute minimum, while still getting a significant > >>>>> benefit. > >>>>> > >>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >>>>> > >>>>> AUTHOR(S): > >>>>> > >>>>> David Goodenough, long time Java user. I can be reached at > >>>>> david.goodenough at linkchoose.co.uk. > >>>>> > >>>>> OVERVIEW > >>>>> > >>>>> FEATURE SUMMARY: > >>>>> > >>>>> Lightweight Property support > >>>>> > >>>>> MAJOR ADVANTAGE: > >>>>> > >>>>> Both BeansBinding (whether JSR-295 or others such an JFace or the > >>>>> JGoodies > >>>>> binding) and the JPA Criteria API currently require field names > >>>>> (as > >>>>> Strings) > >>>>> as arguments, which an IDE/compiler can not check. With this > >>>>> proposal the > >>>>> strings would be abandoned, and the IDE/compiler will be able to > >>>>> check the > >>>>> correctness of the code. > >>>>> > >>>>> MAJOR BENEFIT: > >>>>> > >>>>> Manual checking no longer required. This proposal introduces a > >>>>> simple well > >>>>> defined IDE/compiler checkable solution. > >>>>> > >>>>> MAJOR DISADVANTAGE: > >>>>> > >>>>> It is a language change, and this seems to upset some people. > >>>>> > >>>>> ALTERNATIVES: > >>>>> > >>>>> None really, apart from using another language or continuing to > >>>>> use > >>>>> String > >>>>> names. The existing solutions all require String names which are > >>>>> uncheckable. > >>>>> > >>>>> EXAMPLES > >>>>> > >>>>> Lets assume we have a POJO called foo, of type Foo with a field > >>>>> bar > >>>>> of type > >>>>> Bar, which itself has a field of type Jim called jim. > >>>>> > >>>>> There are two forms of lightweight properties:- > >>>>> > >>>>> 1) foo#bar would be translated by the compiler into:- > >>>>> > >>>>> new Property(foo,"bar"); > >>>>> > >>>>> while foo#bar#jim would be translated into:- > >>>>> > >>>>> new Property(foo,"bar","jim"); > >>>>> > >>>>> 2) Foo#bar would be translated into:- > >>>>> > >>>>> new Property(Foo.class,"bar"); > >>>>> > >>>>> while Foo#bar#jim would be translated into:- > >>>>> > >>>>> new Property(Foo.class,"bar","jim"); > >>>>> > >>>>> These two forms create (1) a bound Property, or (2) an unbound > >>>>> one. > >>>>> Bound > >>>>> Properties are explicitly bound to a particular instance of a > >>>>> class > >>>>> (in this > >>>>> case foo), while unbound Properties are templates which can be > >>>>> applied to any > >>>>> instance of class Foo. Actually bound properties can also be > >>>>> used as > >>>>> unbound > >>>>> properties, but that is a harmless and useful side effect not a > >>>>> primary > >>>>> intent. > >>>>> > >>>>> The Property class would need to be added (it is appended below), > >>>>> and should > >>>>> be added either to the java.beans package or to the > >>>>> java.lang.reflect package > >>>>> (with which is probably has more in common). > >>>>> > >>>>> Syntactically a "#" can be placed wherever a "." can be placed > >>>>> (except inside > >>>>> a number), and the same checks need to be made (that each field to > >>>>> the right > >>>>> of a # is a field in the left hand side) as would be made for a > >>>>> ".". > >>>>> The only > >>>>> difference is in field visibility - For the "#" any field is > >>>>> visible, which > >>>>> follows the model currently available in the Field class with > >>>>> getDeclaredFields(). It also follows the model that while a field > >>>>> might be > >>>>> private and therefore not directly accessible from outside, > >>>>> getters > >>>>> and > >>>>> setters can provide access. > >>>>> > >>>>> The Property object provides type safe access to the field in the > >>>>> form of > >>>>> getters and setters. These come in pairs, one for bound and the > >>>>> other for > >>>>> unbound access. So for bound access no object is required to fetch > >>>>> the value, > >>>>> for an unbound object the parent object needs to be specified. > >>>>> So if > >>>>> we > >>>>> have:- > >>>>> > >>>>> Propertyprop = foo#bar; > >>>>> > >>>>> we can later say:- > >>>>> > >>>>> Bar b = prop.get(); > >>>>> > >>>>> or for an unbound one from a second Foo object foo2:- > >>>>> > >>>>> Bar b = prop.get(foo2); > >>>>> > >>>>> The getters and setters in the Property object will defer to > >>>>> explicitly coded > >>>>> getters and setters if present, otherwise they will use the Field > >>>>> getter and > >>>>> setter. > >>>>> > >>>>> If a setter is not explicitly coded, the implicit setter will look > >>>>> for a > >>>>> PropertyChangeSupport object in the parent object of the rightmost > >>>>> field and > >>>>> fire a PropertyChangeEvent to that object. > >>>>> > >>>>> There are also two Annotations provided by the Property class, > >>>>> ReadOnly and > >>>>> WriteOnly. These stop implicit getters and setters from trying to > >>>>> read/write > >>>>> the property. > >>>>> > >>>>> Talking of Annotations, this notation can also be used to get at > >>>>> the > >>>>> Annotations for a field. So to test for the presence of an > >>>>> Annotation Ann on > >>>>> Foo.bar we would use:- > >>>>> > >>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >>>>> > >>>>> SIMPLE EXAMPLE: > >>>>> > >>>>> To take an example from BeansBinding (taken from Shannon Hickey's > >>>>> blog):- > >>>>> > >>>>> // create a BeanProperty representing a bean's firstName > >>>>> Property firstP = BeanProperty.create("firstName"); > >>>>> // Bind Duke's first name to the text property of a Swing > >>>>> JTextField > >>>>> BeanProperty textP = BeanProperty.create("text"); > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > >>>>> firstP, textfield, textP); > >>>>> binding.bind(); > >>>>> > >>>>> > >>>>> would instead be written:- > >>>>> > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>>>> duke#firstName, textfield#text); > >>>>> binding.bind(); > >>>>> > >>>>> which of course can be checked by the IDE/compiler, and will not > >>>>> wait until > >>>>> run time (not even instantiation time) to show up the error. > >>>>> > >>>>> ADVANCED EXAMPLE: > >>>>> > >>>>> For a JComboBox (or JList or JTable or JTree) there is a need to > >>>>> map > >>>>> a list of > >>>>> objects to the value strings (or column contents). For this we > >>>>> need > >>>>> to have > >>>>> an unbound Property which can be applied to each element of the > >>>>> list. > >>>>> > >>>>> Duke duke; > >>>>> Listdukes; > >>>>> BoundComboBox combo = new > >>>>> BoundComboBox(dukes,Duke#fullname,this#duke); > >>>>> > >>>>> and now the combo box will be populated from the list dukes, and > >>>>> the > >>>>> display > >>>>> values in the list will be taken from the fullname field of each > >>>>> Duke > >>>>> element, and the initial value will be set from the local class > >>>>> field duke > >>>>> and any changes to the combo box selected element will be > >>>>> reflected > >>>>> back to > >>>>> the duke field. > >>>>> > >>>>> DETAILS > >>>>> > >>>>> SPECIFICATION: > >>>>> > >>>>> This proposal adds a new syntactic element, "#", which can be used > >>>>> in the same > >>>>> way that "." can be used to qualify fields within a Java object. > >>>>> > >>>>> COMPILATION: > >>>>> > >>>>> This proposal requires no change to the class files, and is > >>>>> implemented by a > >>>>> simple generation of the required instance using the relevant > >>>>> Property > >>>>> constructor. Obviously the compiler would have to make sure that > >>>>> the > >>>>> use that > >>>>> the property object was being put to (in the examples above the > >>>>> left > >>>>> hand > >>>>> side of the assignment) had the correct Generic attributes. > >>>>> > >>>>> TESTING: > >>>>> > >>>>> How can the feature be tested? > >>>>> > >>>>> LIBRARY SUPPORT: > >>>>> > >>>>> The new Property class is required (see below). > >>>>> > >>>>> REFLECTIVE APIS: > >>>>> > >>>>> No changes are required to the reflective APIs although it makes > >>>>> extensive use > >>>>> of those APIs. > >>>>> > >>>>> OTHER CHANGES: > >>>>> > >>>>> No other changes are requires. > >>>>> > >>>>> MIGRATION: > >>>>> > >>>>> Fortunately there is no code that is formally part of J2SE 6 which > >>>>> uses such > >>>>> Properties. There are however two proposals which will need it > >>>>> (BeansBinding > >>>>> and JPA Criteria API), but neither of these seem to be destined to > >>>>> be part of > >>>>> J2SE 7 (BeansBinding seems to have died the death and the Criteria > >>>>> API would > >>>>> be part of the next J2EE which will follow J2SE 7), so this will > >>>>> provide a > >>>>> base for them to use and no existing code need to be updated. > >>>>> > >>>>> There are other extant Beans-Binding libraries, which could be > >>>>> modified to use > >>>>> this proposal, but as none of the existing features have been > >>>>> changed there > >>>>> is no need to change them (other than for type safety and > >>>>> compiler/ > >>>>> IDE > >>>>> checkability). > >>>>> > >>>>> COMPATIBILITY > >>>>> > >>>>> BREAKING CHANGES: > >>>>> > >>>>> None. This change should not make any existing correct code > >>>>> fail to > >>>>> compile > >>>>> or run or change the way in which it compiles/runs. > >>>>> > >>>>> EXISTING PROGRAMS: > >>>>> > >>>>> No change required to any existing programs > >>>>> > >>>>> REFERENCES > >>>>> > >>>>> EXISTING BUGS: > >>>>> > >>>>> None > >>>>> > >>>>> URL FOR PROTOTYPE (optional): > >>>>> > >>>>> I do not have the knowledge to make changes to the compiler, and > >>>>> the > >>>>> only > >>>>> documentation making such changes concentrated on adding operators > >>>>> not > >>>>> changes at this level. So there is no prototype of the compiler > >>>>> part, but the > >>>>> Property class follows:- > >>>>> > >>>>> package java.lang.reflect; > >>>>> > >>>>> import java.beans.BeanInfo; > >>>>> import java.beans.Introspector; > >>>>> import java.beans.PropertyChangeSupport; > >>>>> import java.beans.PropertyDescriptor; > >>>>> import java.lang.reflect.Field; > >>>>> import java.lang.reflect.Method; > >>>>> > >>>>> /** > >>>>> * Property class > >>>>> * This is the support class for use with the # notation to provide > >>>>> lightweight > >>>>> * Property support for Java. > >>>>> * > >>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >>>>> * @licence LPGL V2 : details of which can be found at http:// > >>>>> fsf.org. > >>>>> * @author david.goodenough at linkchoose.co.uk > >>>>> * > >>>>> * @param The Parent class for this field > >>>>> * @param The Type of this field > >>>>> */ > >>>>> public class Property { > >>>>> private C parent; > >>>>> private Class parentClass; > >>>>> private Field[] fields; > >>>>> private PropertyDescriptor[] pd = null; > >>>>> /** > >>>>> * Constructor used to create Property objects. The Parent object > >>>>> may be > >>>>> * null, but should normally be specified as it can be overridden > >>>>> anyway. > >>>>> * @param parent C object that contains the field > >>>>> * @param field Field describing this field > >>>>> */ > >>>>> public Property(C parent, String ... fieldNames) { > >>>>> this.parent = parent; > >>>>> this(parent.getClass(), fieldNames); > >>>>> } > >>>>> /** > >>>>> * Constructor for unbound Properties, but also used internally > >>>>> after > >>>>> setting > >>>>> * the parent object by the bound Property objects. > >>>>> * @param parentClass Class of the parent object > >>>>> * @param fieldNames String[] of field names > >>>>> */ > >>>>> public Property(ClassparentClass, String .. fieldNames) { > >>>>> this.parentClass = parentClass; > >>>>> fields = new Field[fieldNames.length]; > >>>>> pd = new PropertyDescriptor[fieldNames.length]; > >>>>> outer: for(int index = 0; index < fields.length; index++) { > >>>>> Field[]dclFields = parentClass.getDeclaredFields(); > >>>>> for(Field field:dclFields) { > >>>>> if(field.getName().equals(fieldNames[index])) { > >>>>> fields[index] = field; > >>>>> field.setAccessible(true); > >>>>> try { > >>>>> BeanInfo beanInfo = > >>>>> Introspector.getBeanInfo(parent.getClass()); > >>>>> PropertyDescriptor[]props = > >>>>> beanInfo.getPropertyDescriptors(); > >>>>> for(PropertyDescriptor prop : props) { > >>>>> if(prop.getName().equals(field.getName())) { > >>>>> pd[index] = prop; > >>>>> break; > >>>>> } > >>>>> } > >>>>> } catch(Exception e) { /* assume can not find getter/ > >>>>> setter > >>>>> */ } > >>>>> parentClass = field.getType(); > >>>>> continue outer; > >>>>> } > >>>>> } > >>>>> throw new IllegalArgumentException("Field " + fieldNames[index] + > >>>>> " not found in class " + > >>>>> parentClass.getCanonicalName()); > >>>>> } > >>>>> } > >>>>> /** > >>>>> * Getter from the field in the parent specified when this > >>>>> Property was > >>>>> created. > >>>>> * @see Property.get(C otherParent) > >>>>> * @return F the value of this field > >>>>> */ > >>>>> public F get() { > >>>>> return get(parent); > >>>>> } > >>>>> /** > >>>>> * Getter with explicit parent. > >>>>> * This code will check see if this field is WriteOnly, and > >>>>> complain if it > >>>>> is. > >>>>> * It will then see if the use has provided am explicit getter, > >>>>> and call > >>>>> that > >>>>> * if present, otherwise it will just fetch the value through the > >>>>> Field > >>>>> provided > >>>>> * method. > >>>>> * @param otherParent C parent object > >>>>> * @return F value of the field > >>>>> */ > >>>>> @SuppressWarnings("unchecked") // This should actually not be > >>>>> needed, > >>>>> // but the Field.get method is not > >>>>> typed > >>>>> public F get(C otherParent) { > >>>>> Object result = otherParent; > >>>>> try { > >>>>> for(int index = 0; index < fields.length; index++) { > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method getter = pd[index] == null ? null : > >>>>> pd[index].getReadMethod(); > >>>>> if(getter == null) result = fields[index].get(result); > >>>>> else result = getter.invoke(result); > >>>>> } > >>>>> } catch(Exception e) { > >>>>> throw new RuntimeException("Should not occur exception", e); > >>>>> } > >>>>> return (F)result; > >>>>> } > >>>>> /** > >>>>> * Setter to set the value of the field in the parent object > >>>>> declared with > >>>>> the > >>>>> * Property object > >>>>> * @param newValue F new value of this field > >>>>> */ > >>>>> public void set(F newValue) { > >>>>> set(parent,newValue); > >>>>> } > >>>>> /** > >>>>> * Setter to set the value of the field to an explicit parent > >>>>> object. > >>>>> * If there is a ReadOnly annotation, then we object. If there is > >>>>> an > >>>>> explicit > >>>>> * setter then we use that, otherwise we set the field using the > >>>>> Field > >>>>> provided > >>>>> * set method and if there is a PropertyChangeSupport field, > >>>>> fire a > >>>>> property > >>>>> * change event to it. > >>>>> * We walk our way down the field chain, until we have the last > >>>>> object and > >>>>> its > >>>>> * field, and then we do the set. > >>>>> * @param parent C explicit parent object > >>>>> * @param newValue F new value for field in parent > >>>>> */ > >>>>> public void set(C parent,F newValue) { > >>>>> try { > >>>>> Object last = parent; > >>>>> int index; > >>>>> for(index = 0; index < fields.length - 1; index++) { > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method getter = pd[index] == null ? null : > >>>>> pd[index].getReadMethod(); > >>>>> if(getter == null) last = fields[index].get(last); > >>>>> else last = getter.invoke(last); > >>>>> } > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method setter = pd[index] == null ? null : > >>>>> pd[index].getWriteMethod(); > >>>>> if(setter == null) { > >>>>> PropertyChangeSupport pcs = findPcs(last.getClass()); > >>>>> fields[index].set(last,newValue); > >>>>> if(pcs != null) > >>>>> pcs.firePropertyChange(fields[index].getName(), > >>>>> newValue, > >>>>> > >>>>> fields[index].get(last)); > >>>>> } else setter.invoke(last,newValue); > >>>>> } catch(Exception e) { > >>>>> throw new RuntimeException("Should not occur > >>>>> exception", e); > >>>>> } > >>>>> } > >>>>> /** > >>>>> * This is used so that the caller can view the Field name > >>>>> * @return String field name > >>>>> */ > >>>>> public String[] getFieldName() { > >>>>> String[]names = new String[fields.length]; > >>>>> for(int index = 0; index < fields.length; index++) { > >>>>> names[index] = fields[index].getName(); > >>>>> } > >>>>> return names; > >>>>> } > >>>>> /** > >>>>> * This method is used to fetch the Field array, which is useful > >>>>> if you > >>>>> need to > >>>>> * access the Annotations of a field. > >>>>> * @return Field[] the array of Fields describing this Property. > >>>>> */ > >>>>> public Field[] getFields() { > >>>>> return fields; > >>>>> } > >>>>> /** > >>>>> * This private method looks for a PropertyChangeSupport object in > >>>>> the > >>>>> class and > >>>>> * if one is found it will return it. It looks right the way up > >>>>> the class > >>>>> tree > >>>>> * by recurring up the superClasses. > >>>>> * @param parent Class to check for PropertyChangeSupport fields > >>>>> * @return PropertyChangeSupport first found object, or null if > >>>>> not found > >>>>> */ > >>>>> private PropertyChangeSupport findPcs(Class parent) { > >>>>> Field fields[] = parent.getDeclaredFields(); > >>>>> for(Field field:fields) { > >>>>> field.setAccessible(true); > >>>>> try { > >>>>> if(field.getType() == PropertyChangeSupport.class) > >>>>> return (PropertyChangeSupport)field.get(parent); > >>>>> } catch(Exception e) { } > >>>>> } > >>>>> // If we did not find it then try the superclass > >>>>> ClasssuperClass = parent.getSuperclass(); > >>>>> if(superClass == null) return null; > >>>>> return findPcs(parent.getClass().getSuperclass()); > >>>>> } > >>>>> /** > >>>>> * This annotation is used to mark a field as WriteOnly, i.e. it > >>>>> can not > >>>>> be read. > >>>>> * This stops the automatic getter operation. > >>>>> */ > >>>>> public @interface WriteOnly { > >>>>> } > >>>>> /** > >>>>> * This annotation is used to mark a field as ReadOnly, i.e. it > >>>>> can not be > >>>>> written. > >>>>> * This stops the automatic setter operation. > >>>>> */ > >>>>> public @interface ReadOnly { > >>>>> } > >>>>> } From neal at gafter.com Wed Mar 4 06:47:51 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Mar 2009 06:47:51 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AE7AFD.7010609@univ-mlv.fr> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <49AE7AFD.7010609@univ-mlv.fr> Message-ID: <15e8b9d20903040647n4efbfdag9c8191194b7f9899@mail.gmail.com> Remi- Do you have any evidence that this is a sound extension of the type system? -Neal On Wed, Mar 4, 2009 at 4:58 AM, R?mi Forax wrote: > Joshua Bloch a ?crit : >> Mark, >> Sorry for the delay, and thanks so much for the report! ?This is an >> interesting case. ?It seems unfortunate that DataCacheManagerImpl extends >> Closeable, given that its close method doesn't throw any checked exceptions. >> ?But it got me thinking, and I came to the conclusion that there's no reason >> for the Disposable interface to be parameterized! ?Its close method should >> just throw Exception. ?Then Closeable and DataCacheManager can both extend >> Disposable. The Disposable interface won't be terribly useful as a parameter >> type, but who cares? Its raison d'etre is the ?automatic resource management >> statement. ?In this context, the close method is invoked on a resource using >> its declared type. ?That means that it throws whatever exceptions it's >> declared to throw (as per the desugaring in my proposal). ?I will modify the >> proposal accordingly and repost it. ?I think this is a real improvement! >> ?It's both simpler and more broadly applicable. >> >> ? ? ? ?Thanks so much, >> >> ? ? ? ?Josh >> > There is another way, change the JLS :) > > In my opinion, the last sentence of ?section 8.1.5 of the JLS is too > restrictive: > "A class may not at the same time be a subtype of two interface types which > are different invocations of the same generic interface (?9.1.2) > , > or an invocation > of a generic interface and a raw type naming that same generic interface." > > This sentence is weird because the last part of section 8.1.5 explain > how to detect clash between methods from different interfaces > by taking a look to their return types. > > So in case of different interfaces, the compiler have to do a calculation > involving the member methods but if interfaces are generics > it doesn't do any calculation on member methods. > That is not consistent. > > Note than the detection algorithm is not exactly the same because > one can have a clash between bridge methods. > > I'm proposing to remove the last sentence of section 8.1.5 > and replace it by a one saying that if there is of two or more > generics super-interfaces, member methods of their raw types > should not have the same signature. > > With theis new rule, the following examples will now compile: > > interface Duplicate { > ? ? ? X duplicate(); > ? ?} > > class A implements Duplicate, Duplicate { > ? ?public Integer duplicate() { > ? ? ? return null; > ? ?} > ?} > > ? ?and > > ? ?interface Disposable { > ? ? ?public void dispose() throws E; > ? ?} > > ? ?class Connection implements Disposable, > Disposable { > ? ? ?public void dispose() throws IOEXception { > > ? ? ?} > ? ?} > > > There is another reason why I don't like the last sentence of section 8.1.5, > this sentence is not compatible with section 13.4.4 on binary compatibility: > "Changing the direct superclass or the set of direct superinterfaces of > a class type will not break compatibility > with pre-existing binaries, provided that the total set of superclasses > or superinterfaces, > respectively, of the class type loses no members." > > cheers, > R?mi > > > > > From R.Spilker at topdesk.com Wed Mar 4 02:37:19 2009 From: R.Spilker at topdesk.com (=?us-ascii?Q?Roel_Spilker?=) Date: Wed, 4 Mar 2009 11:37:19 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903040949.57551.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> Message-ID: In your proposal, foo#bar would be translated by the compiler into: new Property(foo,"bar"); But I think you should split your proposal into two parts. The first part is using the Foo#bar syntax to be a field literal for the field "bar" in the type "Foo". This is similar to the FCM proposal (http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc). So it would be a java.lang.reflect.Field literal. The second part would be a proposal to build properties using field literals. I give the field literal proposal a chance to be included. Roel -----Oorspronkelijk bericht----- Van: david.goodenough at linkchoose.co.uk [mailto:coin-dev-bounces at openjdk.java.net] Namens David Goodenough Verzonden: woensdag 4 maart 2009 10:50 Aan: coin-dev at openjdk.java.net Onderwerp: Re: PROPOSAL: Lightweight Properties I am not sure that we would loose anything. The important thing is to have an IDE/compiler checkable way of generating Property objects, and having two ways of generating them is not really a problem. My Property object would happily detect either an explicitly generated getter/setter or one generated for you by a property keyword. The property keyword would resolve other things (like the automatic generation of PropertyChangeSupport, and the controlling of visibility) but it is still building on the same basic concept. If you don't want to use # then the work needed for the compiler gets more complicated (I think). One could use a sort of compiler function, so one would say property(foo.bar) and it would modify the function of . inside the function. I really want to find a way to get something into Java 7, otherwise we are looking to Java 8 (which is at least 3 years away if current timescales persist), by which time I suspect that everyone will have gotten bored and gone to find pastures new. David On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > But it seems that we _would_ lose a thing or two with this proposal. > For example, if a complete properties proposal supports full backwards > compatibility and generates getters and setters, then we have a bunch > of code around that uses the foo#bar notation, which is by then > already outdated, and would in fact get in the way of using foo#bar > notation as a shorthand for calling the appropriate getter/setter. I > don't know if that is a desired syntax sugar, but the point is: Your > proposal would effectively make it impossible to add that later, as it > would already be shorthand for creating a Property object. > > The # and the backtick are the only easily typed symbols that have no > meaning whatsoever in java right now. Using one up for an simplified > properties proposal is another serious disdvantage. I don't think your > proposal makes property support light enough to warrant its inclusion > in project coin. That's not to say I have something against > properties; on the contrary, I love the idea and I'm very impressed > with the way properties work in JavaFX. All the more reason to get it > right instead of using a bandage. > > --Reinier Zwitserloot > > On Mar 3, 2009, at 23:00, David Goodenough wrote: > > Well that depends on what you mean by a complete proposal. > > > > There are two parts to the use of Properties. There is the > > framework side, inside BeansBinding or JPA and then there is the > > consumer side, the application code. > > > > My proposal is very simple on the consumer side (the only bit needed > > is the # notation). You can use clasical getters and setters (a > > nuisance but everyone understands them), or the simple getter/setter > > mechanism that my Property provides. So for the consumer my > > proposal is real simple. All you need do is add (either explicity > > or by byte code > > enhancement) > > a PropertyChangeSupport object and the relevant methods and you are > > home and dry. > > > > For the Frameworks, well you only write them once. Even so > > something nice and simple appeals and my proposal is simple. > > > > It may not be Beans as we know it, but they never were integrated > > properly into Java. But its really not that dissimilar just > > slightly different. > > > > So other than a little sytactic sugar (not having to code the > > PropertyChangeSupport object) we have not really lost anything of > > the "full" solution. Having a Bound annotation which would add this > > under the covers with a byte code enhancer would not be difficult. > > The implicit getters and setters come with the package. So the > > question to be asked whether a fuller solution is really needed. > > > > David > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >> The language change required for your proposal is indeed lighter, > >> but to understand it, it is seems a lot more complicated. > >> > >> Also, it would be infeasible to introduce a 'lightweight' > >> (according to anyone's definition) proposal now that is lacking in > >> certain aspects, and then fix it later, unless that fix is > >> syntactically very similar and backwards- and migration compatible. > >> That's the major beef I have with this proposal: It effectively > >> shuts the door on any other property proposal. In my view, a > >> proposal solves the problem properly, or shouldn't be added at all; > >> no quick hacky fixes that aren't part of a planned evolution path > >> to a complete solution. > >> > >> If you can highlight how a complete properties proposal will > >> seamlessly work with your syntax, I'm more inclined to like it. > >> > >> --Reinier Zwitserloot > >> > >> On Mar 3, 2009, at 22:04, David Goodenough wrote: > >>> Yes I do. What you propose is much more invasive. Look at it > >>> again and maybe you will see the Light(ness). > >>> > >>> David > >>> > >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >>>> You call that lightweight? > >>>> > >>>> How about following the beans spec more to the letter and just > >>>> generate the addPropertyChangeListener, > >>>> removePropertyChangeListener, setX(), and get/isX() method in > >>>> response to seeing a keyword or annotation on a given field. > >>>> You'll have to work out the details, but that sounds far, far > >>>> simpler to understand. > >>>> > >>>> You'll need to flesh this out, but it would look something like: > >>>> > >>>> public class Foo { > >>>> private property int x; > >>>> } > >>>> > >>>> Which would generate the addPropertyChangeListener, > >>>> removePropertyChangeListener, setX, getX methods, all public, > >>>> along with the required infrastructure to make it tick. If you > >>>> don't like the generation, for example because you want the > >>>> setter to be package private, you just add the setter in the > >>>> source file; the keyword will only generate the missing stuff. It > >>>> doesn't cover every use case, but there's always the alternative > >>>> of doing whatever people do now with beans. Something you didn't > >>>> mention in your proposal, by the way. > >>>> > >>>> I think there's also a fully fleshed out property proposal > >>>> (including a 'property' keyword) out there somewhere. > >>>> > >>>> Possibly make a way to opt out of generating the property change > >>>> listener support, and just the getters/setters. > >>>> --Reinier Zwitserloot > >>>> > >>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: > >>>>> Below is my proposal for Lightweight Properties. I know that > >>>>> the syntax change is an abbomination to some people, but I have > >>>>> tried to reduce this to its absolute minimum, while still > >>>>> getting a significant benefit. > >>>>> > >>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >>>>> > >>>>> AUTHOR(S): > >>>>> > >>>>> David Goodenough, long time Java user. I can be reached at > >>>>> david.goodenough at linkchoose.co.uk. > >>>>> > >>>>> OVERVIEW > >>>>> > >>>>> FEATURE SUMMARY: > >>>>> > >>>>> Lightweight Property support > >>>>> > >>>>> MAJOR ADVANTAGE: > >>>>> > >>>>> Both BeansBinding (whether JSR-295 or others such an JFace or > >>>>> the JGoodies > >>>>> binding) and the JPA Criteria API currently require field names > >>>>> (as > >>>>> Strings) > >>>>> as arguments, which an IDE/compiler can not check. With this > >>>>> proposal the strings would be abandoned, and the IDE/compiler > >>>>> will be able to check the correctness of the code. > >>>>> > >>>>> MAJOR BENEFIT: > >>>>> > >>>>> Manual checking no longer required. This proposal introduces a > >>>>> simple well defined IDE/compiler checkable solution. > >>>>> > >>>>> MAJOR DISADVANTAGE: > >>>>> > >>>>> It is a language change, and this seems to upset some people. > >>>>> > >>>>> ALTERNATIVES: > >>>>> > >>>>> None really, apart from using another language or continuing to > >>>>> use String names. The existing solutions all require String > >>>>> names which are uncheckable. > >>>>> > >>>>> EXAMPLES > >>>>> > >>>>> Lets assume we have a POJO called foo, of type Foo with a field > >>>>> bar of type Bar, which itself has a field of type Jim called > >>>>> jim. > >>>>> > >>>>> There are two forms of lightweight properties:- > >>>>> > >>>>> 1) foo#bar would be translated by the compiler into:- > >>>>> > >>>>> new Property(foo,"bar"); > >>>>> > >>>>> while foo#bar#jim would be translated into:- > >>>>> > >>>>> new Property(foo,"bar","jim"); > >>>>> > >>>>> 2) Foo#bar would be translated into:- > >>>>> > >>>>> new Property(Foo.class,"bar"); > >>>>> > >>>>> while Foo#bar#jim would be translated into:- > >>>>> > >>>>> new Property(Foo.class,"bar","jim"); > >>>>> > >>>>> These two forms create (1) a bound Property, or (2) an unbound > >>>>> one. > >>>>> Bound > >>>>> Properties are explicitly bound to a particular instance of a > >>>>> class (in this case foo), while unbound Properties are templates > >>>>> which can be applied to any instance of class Foo. Actually > >>>>> bound properties can also be used as unbound properties, but > >>>>> that is a harmless and useful side effect not a primary intent. > >>>>> > >>>>> The Property class would need to be added (it is appended > >>>>> below), and should be added either to the java.beans package or > >>>>> to the java.lang.reflect package (with which is probably has > >>>>> more in common). > >>>>> > >>>>> Syntactically a "#" can be placed wherever a "." can be placed > >>>>> (except inside a number), and the same checks need to be made > >>>>> (that each field to the right of a # is a field in the left hand > >>>>> side) as would be made for a ".". > >>>>> The only > >>>>> difference is in field visibility - For the "#" any field is > >>>>> visible, which follows the model currently available in the > >>>>> Field class with getDeclaredFields(). It also follows the model > >>>>> that while a field might be private and therefore not directly > >>>>> accessible from outside, getters and setters can provide access. > >>>>> > >>>>> The Property object provides type safe access to the field in > >>>>> the form of getters and setters. These come in pairs, one for > >>>>> bound and the other for unbound access. So for bound access no > >>>>> object is required to fetch the value, for an unbound object the > >>>>> parent object needs to be specified. > >>>>> So if > >>>>> we > >>>>> have:- > >>>>> > >>>>> Propertyprop = foo#bar; > >>>>> > >>>>> we can later say:- > >>>>> > >>>>> Bar b = prop.get(); > >>>>> > >>>>> or for an unbound one from a second Foo object foo2:- > >>>>> > >>>>> Bar b = prop.get(foo2); > >>>>> > >>>>> The getters and setters in the Property object will defer to > >>>>> explicitly coded getters and setters if present, otherwise they > >>>>> will use the Field getter and setter. > >>>>> > >>>>> If a setter is not explicitly coded, the implicit setter will > >>>>> look for a PropertyChangeSupport object in the parent object of > >>>>> the rightmost field and fire a PropertyChangeEvent to that > >>>>> object. > >>>>> > >>>>> There are also two Annotations provided by the Property class, > >>>>> ReadOnly and WriteOnly. These stop implicit getters and setters > >>>>> from trying to read/write the property. > >>>>> > >>>>> Talking of Annotations, this notation can also be used to get at > >>>>> the Annotations for a field. So to test for the presence of an > >>>>> Annotation Ann on Foo.bar we would use:- > >>>>> > >>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >>>>> > >>>>> SIMPLE EXAMPLE: > >>>>> > >>>>> To take an example from BeansBinding (taken from Shannon > >>>>> Hickey's > >>>>> blog):- > >>>>> > >>>>> // create a BeanProperty representing a bean's firstName > >>>>> Property firstP = BeanProperty.create("firstName"); > >>>>> // Bind Duke's first name to the text property of a Swing > >>>>> JTextField > >>>>> BeanProperty textP = BeanProperty.create("text"); > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > >>>>> firstP, textfield, textP); > >>>>> binding.bind(); > >>>>> > >>>>> > >>>>> would instead be written:- > >>>>> > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>>>> duke#firstName, textfield#text); > >>>>> binding.bind(); > >>>>> > >>>>> which of course can be checked by the IDE/compiler, and will not > >>>>> wait until run time (not even instantiation time) to show up the > >>>>> error. > >>>>> > >>>>> ADVANCED EXAMPLE: > >>>>> > >>>>> For a JComboBox (or JList or JTable or JTree) there is a need to > >>>>> map a list of objects to the value strings (or column contents). > >>>>> For this we need to have an unbound Property which can be > >>>>> applied to each element of the list. > >>>>> > >>>>> Duke duke; > >>>>> Listdukes; > >>>>> BoundComboBox combo = new > >>>>> BoundComboBox(dukes,Duke#fullname,this#duke); > >>>>> > >>>>> and now the combo box will be populated from the list dukes, and > >>>>> the display values in the list will be taken from the fullname > >>>>> field of each Duke element, and the initial value will be set > >>>>> from the local class field duke and any changes to the combo box > >>>>> selected element will be reflected back to the duke field. > >>>>> > >>>>> DETAILS > >>>>> > >>>>> SPECIFICATION: > >>>>> > >>>>> This proposal adds a new syntactic element, "#", which can be > >>>>> used in the same way that "." can be used to qualify fields > >>>>> within a Java object. > >>>>> > >>>>> COMPILATION: > >>>>> > >>>>> This proposal requires no change to the class files, and is > >>>>> implemented by a simple generation of the required instance > >>>>> using the relevant Property constructor. Obviously the compiler > >>>>> would have to make sure that the use that the property object > >>>>> was being put to (in the examples above the left hand side of > >>>>> the assignment) had the correct Generic attributes. > >>>>> > >>>>> TESTING: > >>>>> > >>>>> How can the feature be tested? > >>>>> > >>>>> LIBRARY SUPPORT: > >>>>> > >>>>> The new Property class is required (see below). > >>>>> > >>>>> REFLECTIVE APIS: > >>>>> > >>>>> No changes are required to the reflective APIs although it makes > >>>>> extensive use of those APIs. > >>>>> > >>>>> OTHER CHANGES: > >>>>> > >>>>> No other changes are requires. > >>>>> > >>>>> MIGRATION: > >>>>> > >>>>> Fortunately there is no code that is formally part of J2SE 6 > >>>>> which uses such Properties. There are however two proposals > >>>>> which will need it (BeansBinding and JPA Criteria API), but > >>>>> neither of these seem to be destined to be part of J2SE 7 > >>>>> (BeansBinding seems to have died the death and the Criteria API > >>>>> would be part of the next J2EE which will follow J2SE 7), so > >>>>> this will provide a base for them to use and no existing code > >>>>> need to be updated. > >>>>> > >>>>> There are other extant Beans-Binding libraries, which could be > >>>>> modified to use this proposal, but as none of the existing > >>>>> features have been changed there is no need to change them > >>>>> (other than for type safety and compiler/ IDE checkability). > >>>>> > >>>>> COMPATIBILITY > >>>>> > >>>>> BREAKING CHANGES: > >>>>> > >>>>> None. This change should not make any existing correct code > >>>>> fail to compile or run or change the way in which it > >>>>> compiles/runs. > >>>>> > >>>>> EXISTING PROGRAMS: > >>>>> > >>>>> No change required to any existing programs > >>>>> > >>>>> REFERENCES > >>>>> > >>>>> EXISTING BUGS: > >>>>> > >>>>> None > >>>>> > >>>>> URL FOR PROTOTYPE (optional): > >>>>> > >>>>> I do not have the knowledge to make changes to the compiler, and > >>>>> the only documentation making such changes concentrated on > >>>>> adding operators not changes at this level. So there is no > >>>>> prototype of the compiler part, but the Property class follows:- > >>>>> > >>>>> package java.lang.reflect; > >>>>> > >>>>> import java.beans.BeanInfo; > >>>>> import java.beans.Introspector; > >>>>> import java.beans.PropertyChangeSupport; import > >>>>> java.beans.PropertyDescriptor; import java.lang.reflect.Field; > >>>>> import java.lang.reflect.Method; > >>>>> > >>>>> /** > >>>>> * Property class > >>>>> * This is the support class for use with the # notation to > >>>>> provide lightweight > >>>>> * Property support for Java. > >>>>> * > >>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >>>>> * @licence LPGL V2 : details of which can be found at http:// > >>>>> fsf.org. > >>>>> * @author david.goodenough at linkchoose.co.uk > >>>>> * > >>>>> * @param The Parent class for this field > >>>>> * @param The Type of this field */ public class > >>>>> Property { private C parent; private Class parentClass; > >>>>> private Field[] fields; private PropertyDescriptor[] pd = null; > >>>>> /** > >>>>> * Constructor used to create Property objects. The Parent > >>>>> object may be > >>>>> * null, but should normally be specified as it can be > >>>>> overridden anyway. > >>>>> * @param parent C object that contains the field > >>>>> * @param field Field describing this field */ public > >>>>> Property(C parent, String ... fieldNames) { > >>>>> this.parent = parent; > >>>>> this(parent.getClass(), fieldNames); > >>>>> } > >>>>> /** > >>>>> * Constructor for unbound Properties, but also used internally > >>>>> after setting > >>>>> * the parent object by the bound Property objects. > >>>>> * @param parentClass Class of the parent object > >>>>> * @param fieldNames String[] of field names > >>>>> */ > >>>>> public Property(ClassparentClass, String .. fieldNames) { > >>>>> this.parentClass = parentClass; > >>>>> fields = new Field[fieldNames.length]; > >>>>> pd = new PropertyDescriptor[fieldNames.length]; > >>>>> outer: for(int index = 0; index < fields.length; index++) { > >>>>> Field[]dclFields = parentClass.getDeclaredFields(); > >>>>> for(Field field:dclFields) { > >>>>> if(field.getName().equals(fieldNames[index])) { > >>>>> fields[index] = field; > >>>>> field.setAccessible(true); > >>>>> try { > >>>>> BeanInfo beanInfo = > >>>>> Introspector.getBeanInfo(parent.getClass()); > >>>>> PropertyDescriptor[]props = > >>>>> beanInfo.getPropertyDescriptors(); > >>>>> for(PropertyDescriptor prop : props) { > >>>>> if(prop.getName().equals(field.getName())) { > >>>>> pd[index] = prop; > >>>>> break; > >>>>> } > >>>>> } > >>>>> } catch(Exception e) { /* assume can not find getter/ > >>>>> setter */ } > >>>>> parentClass = field.getType(); > >>>>> continue outer; > >>>>> } > >>>>> } > >>>>> throw new IllegalArgumentException("Field " + fieldNames[index] + > >>>>> " not found in class " + > >>>>> parentClass.getCanonicalName()); > >>>>> } > >>>>> } > >>>>> /** > >>>>> * Getter from the field in the parent specified when this > >>>>> Property was created. > >>>>> * @see Property.get(C otherParent) > >>>>> * @return F the value of this field */ public F get() { > >>>>> return get(parent); > >>>>> } > >>>>> /** > >>>>> * Getter with explicit parent. > >>>>> * This code will check see if this field is WriteOnly, and > >>>>> complain if it is. > >>>>> * It will then see if the use has provided am explicit getter, > >>>>> and call that > >>>>> * if present, otherwise it will just fetch the value through > >>>>> the Field provided > >>>>> * method. > >>>>> * @param otherParent C parent object > >>>>> * @return F value of the field > >>>>> */ > >>>>> @SuppressWarnings("unchecked") // This should actually not be > >>>>> needed, > >>>>> // but the Field.get method is > >>>>> not typed public F get(C otherParent) { > >>>>> Object result = otherParent; > >>>>> try { > >>>>> for(int index = 0; index < fields.length; index++) { > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method getter = pd[index] == null ? null : > >>>>> pd[index].getReadMethod(); > >>>>> if(getter == null) result = fields[index].get(result); > >>>>> else result = getter.invoke(result); > >>>>> } > >>>>> } catch(Exception e) { > >>>>> throw new RuntimeException("Should not occur exception", e); > >>>>> } > >>>>> return (F)result; > >>>>> } > >>>>> /** > >>>>> * Setter to set the value of the field in the parent object > >>>>> declared with the > >>>>> * Property object > >>>>> * @param newValue F new value of this field */ public void > >>>>> set(F newValue) { > >>>>> set(parent,newValue); > >>>>> } > >>>>> /** > >>>>> * Setter to set the value of the field to an explicit parent > >>>>> object. > >>>>> * If there is a ReadOnly annotation, then we object. If there > >>>>> is an explicit > >>>>> * setter then we use that, otherwise we set the field using the > >>>>> Field provided > >>>>> * set method and if there is a PropertyChangeSupport field, > >>>>> fire a property > >>>>> * change event to it. > >>>>> * We walk our way down the field chain, until we have the last > >>>>> object and its > >>>>> * field, and then we do the set. > >>>>> * @param parent C explicit parent object > >>>>> * @param newValue F new value for field in parent */ public > >>>>> void set(C parent,F newValue) { > >>>>> try { > >>>>> Object last = parent; > >>>>> int index; > >>>>> for(index = 0; index < fields.length - 1; index++) { > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method getter = pd[index] == null ? null : > >>>>> pd[index].getReadMethod(); > >>>>> if(getter == null) last = fields[index].get(last); > >>>>> else last = getter.invoke(last); > >>>>> } > >>>>> > >>>>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >>>>> throw new IllegalAccessException( > >>>>> "Can not get from a WriteOnly field - " + > >>>>> fields[index].getName()); > >>>>> Method setter = pd[index] == null ? null : > >>>>> pd[index].getWriteMethod(); > >>>>> if(setter == null) { > >>>>> PropertyChangeSupport pcs = findPcs(last.getClass()); > >>>>> fields[index].set(last,newValue); > >>>>> if(pcs != null) > >>>>> pcs.firePropertyChange(fields[index].getName(), > >>>>> newValue, > >>>>> > >>>>> fields[index].get(last)); > >>>>> } else setter.invoke(last,newValue); > >>>>> } catch(Exception e) { > >>>>> throw new RuntimeException("Should not occur > >>>>> exception", e); > >>>>> } > >>>>> } > >>>>> /** > >>>>> * This is used so that the caller can view the Field name > >>>>> * @return String field name > >>>>> */ > >>>>> public String[] getFieldName() { > >>>>> String[]names = new String[fields.length]; > >>>>> for(int index = 0; index < fields.length; index++) { > >>>>> names[index] = fields[index].getName(); > >>>>> } > >>>>> return names; > >>>>> } > >>>>> /** > >>>>> * This method is used to fetch the Field array, which is > >>>>> useful if you need to > >>>>> * access the Annotations of a field. > >>>>> * @return Field[] the array of Fields describing this Property. > >>>>> */ > >>>>> public Field[] getFields() { > >>>>> return fields; > >>>>> } > >>>>> /** > >>>>> * This private method looks for a PropertyChangeSupport object > >>>>> in the class and > >>>>> * if one is found it will return it. It looks right the way up > >>>>> the class tree > >>>>> * by recurring up the superClasses. > >>>>> * @param parent Class to check for PropertyChangeSupport fields > >>>>> * @return PropertyChangeSupport first found object, or null if > >>>>> not found */ private PropertyChangeSupport findPcs(Class > >>>>> parent) { > >>>>> Field fields[] = parent.getDeclaredFields(); > >>>>> for(Field field:fields) { > >>>>> field.setAccessible(true); > >>>>> try { > >>>>> if(field.getType() == PropertyChangeSupport.class) > >>>>> return (PropertyChangeSupport)field.get(parent); > >>>>> } catch(Exception e) { } > >>>>> } > >>>>> // If we did not find it then try the superclass > >>>>> ClasssuperClass = parent.getSuperclass(); > >>>>> if(superClass == null) return null; > >>>>> return findPcs(parent.getClass().getSuperclass()); > >>>>> } > >>>>> /** > >>>>> * This annotation is used to mark a field as WriteOnly, i.e. it > >>>>> can not be read. > >>>>> * This stops the automatic getter operation. > >>>>> */ > >>>>> public @interface WriteOnly { > >>>>> } > >>>>> /** > >>>>> * This annotation is used to mark a field as ReadOnly, i.e. it > >>>>> can not be written. > >>>>> * This stops the automatic setter operation. > >>>>> */ > >>>>> public @interface ReadOnly { > >>>>> } > >>>>> } From Joe.Darcy at Sun.COM Wed Mar 4 07:00:12 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 07:00:12 -0800 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903040941.16335.david.goodenough@linkchoose.co.uk> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <15e8b9d20903031217n632eae0el7ee9cfafdb0c504@mail.gmail.com> <49ADD978.3080804@sun.com> <200903040941.16335.david.goodenough@linkchoose.co.uk> Message-ID: <49AE977C.8040907@sun.com> David Goodenough wrote: > On Wednesday 04 March 2009, Joseph D. Darcy wrote: > >> Neal Gafter wrote: >> >>> Joe Darcy sort of ruled out adding property support in project coin in >>> http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size >>> >> Correct; properties (and closures and reified generics) are examples of >> changes out of scope for Project Coin. >> > > OK, if it will make easier I will change its name. Changing the proposal's name doesn't change what it is! -Joe From forax at univ-mlv.fr Wed Mar 4 07:22:16 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 04 Mar 2009 16:22:16 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903040647n4efbfdag9c8191194b7f9899@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <49AE7AFD.7010609@univ-mlv.fr> <15e8b9d20903040647n4efbfdag9c8191194b7f9899@mail.gmail.com> Message-ID: <49AE9CA8.5020202@univ-mlv.fr> Neal Gafter a ?crit : > Remi- > > Do you have any evidence that this is a sound extension of the type system? > I don't think the rule about generics interfaces is here to ensure that the type system is sound or not. It's about avoiding clash between bridges that as you know contains code. R?mi From david.goodenough at linkchoose.co.uk Wed Mar 4 07:35:51 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 4 Mar 2009 15:35:51 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> Message-ID: <200903041535.53432.david.goodenough@linkchoose.co.uk> On Wednesday 04 March 2009, Roel Spilker wrote: > In your proposal, foo#bar would be translated by the compiler into: new > Property(foo,"bar"); > > But I think you should split your proposal into two parts. The first part > is using the Foo#bar syntax to be a field literal for the field "bar" in > the type "Foo". This is similar to the FCM proposal > (http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc). So it would be a > java.lang.reflect.Field literal. > > The second part would be a proposal to build properties using field > literals. > > I give the field literal proposal a chance to be included. > > Roel > I would not be unhappy with that, if were it possible. But I think that due to the way that Field objects are represented in the class file (in an odd binary format) and then constructed at run time, that this would not be possible. It is important (for things like accessing Annotations) that we get the REAL Field object, and not a partial copy or lookalike. If someone can come up with a way of doing that I would be delighted. David > > > -----Oorspronkelijk bericht----- > Van: david.goodenough at linkchoose.co.uk > [mailto:coin-dev-bounces at openjdk.java.net] Namens David Goodenough > Verzonden: woensdag 4 maart 2009 10:50 > Aan: coin-dev at openjdk.java.net > Onderwerp: Re: PROPOSAL: Lightweight Properties > > I am not sure that we would loose anything. The important thing is to have > an IDE/compiler checkable way of generating Property objects, and having > two ways of generating them is not really a problem. My Property object > would happily detect either an explicitly generated getter/setter or one > generated for you by a property keyword. The property keyword would > resolve other things (like the automatic generation of > PropertyChangeSupport, and the controlling of visibility) but it is still > building on the same basic concept. > > If you don't want to use # then the work needed for the compiler gets more > complicated (I think). One could use a sort of compiler function, so one > would say property(foo.bar) and it would modify the function of . inside > the function. > > I really want to find a way to get something into Java 7, otherwise we are > looking to Java 8 (which is at least 3 years away if current timescales > persist), by which time I suspect that everyone will have gotten bored and > gone to find pastures new. > > David > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > > But it seems that we _would_ lose a thing or two with this proposal. > > For example, if a complete properties proposal supports full backwards > > compatibility and generates getters and setters, then we have a bunch > > of code around that uses the foo#bar notation, which is by then > > already outdated, and would in fact get in the way of using foo#bar > > notation as a shorthand for calling the appropriate getter/setter. I > > don't know if that is a desired syntax sugar, but the point is: Your > > proposal would effectively make it impossible to add that later, as it > > would already be shorthand for creating a Property object. > > > > The # and the backtick are the only easily typed symbols that have no > > meaning whatsoever in java right now. Using one up for an simplified > > properties proposal is another serious disdvantage. I don't think your > > proposal makes property support light enough to warrant its inclusion > > in project coin. That's not to say I have something against > > properties; on the contrary, I love the idea and I'm very impressed > > with the way properties work in JavaFX. All the more reason to get it > > right instead of using a bandage. > > > > --Reinier Zwitserloot > > > > On Mar 3, 2009, at 23:00, David Goodenough wrote: > > > Well that depends on what you mean by a complete proposal. > > > > > > There are two parts to the use of Properties. There is the > > > framework side, inside BeansBinding or JPA and then there is the > > > consumer side, the application code. > > > > > > My proposal is very simple on the consumer side (the only bit needed > > > is the # notation). You can use clasical getters and setters (a > > > nuisance but everyone understands them), or the simple getter/setter > > > mechanism that my Property provides. So for the consumer my > > > proposal is real simple. All you need do is add (either explicity > > > or by byte code > > > enhancement) > > > a PropertyChangeSupport object and the relevant methods and you are > > > home and dry. > > > > > > For the Frameworks, well you only write them once. Even so > > > something nice and simple appeals and my proposal is simple. > > > > > > It may not be Beans as we know it, but they never were integrated > > > properly into Java. But its really not that dissimilar just > > > slightly different. > > > > > > So other than a little sytactic sugar (not having to code the > > > PropertyChangeSupport object) we have not really lost anything of > > > the "full" solution. Having a Bound annotation which would add this > > > under the covers with a byte code enhancer would not be difficult. > > > The implicit getters and setters come with the package. So the > > > question to be asked whether a fuller solution is really needed. > > > > > > David > > > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > > >> The language change required for your proposal is indeed lighter, > > >> but to understand it, it is seems a lot more complicated. > > >> > > >> Also, it would be infeasible to introduce a 'lightweight' > > >> (according to anyone's definition) proposal now that is lacking in > > >> certain aspects, and then fix it later, unless that fix is > > >> syntactically very similar and backwards- and migration compatible. > > >> That's the major beef I have with this proposal: It effectively > > >> shuts the door on any other property proposal. In my view, a > > >> proposal solves the problem properly, or shouldn't be added at all; > > >> no quick hacky fixes that aren't part of a planned evolution path > > >> to a complete solution. > > >> > > >> If you can highlight how a complete properties proposal will > > >> seamlessly work with your syntax, I'm more inclined to like it. > > >> > > >> --Reinier Zwitserloot > > >> > > >> On Mar 3, 2009, at 22:04, David Goodenough wrote: > > >>> Yes I do. What you propose is much more invasive. Look at it > > >>> again and maybe you will see the Light(ness). > > >>> > > >>> David > > >>> > > >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > > >>>> You call that lightweight? > > >>>> > > >>>> How about following the beans spec more to the letter and just > > >>>> generate the addPropertyChangeListener, > > >>>> removePropertyChangeListener, setX(), and get/isX() method in > > >>>> response to seeing a keyword or annotation on a given field. > > >>>> You'll have to work out the details, but that sounds far, far > > >>>> simpler to understand. > > >>>> > > >>>> You'll need to flesh this out, but it would look something like: > > >>>> > > >>>> public class Foo { > > >>>> private property int x; > > >>>> } > > >>>> > > >>>> Which would generate the addPropertyChangeListener, > > >>>> removePropertyChangeListener, setX, getX methods, all public, > > >>>> along with the required infrastructure to make it tick. If you > > >>>> don't like the generation, for example because you want the > > >>>> setter to be package private, you just add the setter in the > > >>>> source file; the keyword will only generate the missing stuff. It > > >>>> doesn't cover every use case, but there's always the alternative > > >>>> of doing whatever people do now with beans. Something you didn't > > >>>> mention in your proposal, by the way. > > >>>> > > >>>> I think there's also a fully fleshed out property proposal > > >>>> (including a 'property' keyword) out there somewhere. > > >>>> > > >>>> Possibly make a way to opt out of generating the property change > > >>>> listener support, and just the getters/setters. > > >>>> --Reinier Zwitserloot > > >>>> > > >>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: > > >>>>> Below is my proposal for Lightweight Properties. I know that > > >>>>> the syntax change is an abbomination to some people, but I have > > >>>>> tried to reduce this to its absolute minimum, while still > > >>>>> getting a significant benefit. > > >>>>> > > >>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > >>>>> > > >>>>> AUTHOR(S): > > >>>>> > > >>>>> David Goodenough, long time Java user. I can be reached at > > >>>>> david.goodenough at linkchoose.co.uk. > > >>>>> > > >>>>> OVERVIEW > > >>>>> > > >>>>> FEATURE SUMMARY: > > >>>>> > > >>>>> Lightweight Property support > > >>>>> > > >>>>> MAJOR ADVANTAGE: > > >>>>> > > >>>>> Both BeansBinding (whether JSR-295 or others such an JFace or > > >>>>> the JGoodies > > >>>>> binding) and the JPA Criteria API currently require field names > > >>>>> (as > > >>>>> Strings) > > >>>>> as arguments, which an IDE/compiler can not check. With this > > >>>>> proposal the strings would be abandoned, and the IDE/compiler > > >>>>> will be able to check the correctness of the code. > > >>>>> > > >>>>> MAJOR BENEFIT: > > >>>>> > > >>>>> Manual checking no longer required. This proposal introduces a > > >>>>> simple well defined IDE/compiler checkable solution. > > >>>>> > > >>>>> MAJOR DISADVANTAGE: > > >>>>> > > >>>>> It is a language change, and this seems to upset some people. > > >>>>> > > >>>>> ALTERNATIVES: > > >>>>> > > >>>>> None really, apart from using another language or continuing to > > >>>>> use String names. The existing solutions all require String > > >>>>> names which are uncheckable. > > >>>>> > > >>>>> EXAMPLES > > >>>>> > > >>>>> Lets assume we have a POJO called foo, of type Foo with a field > > >>>>> bar of type Bar, which itself has a field of type Jim called > > >>>>> jim. > > >>>>> > > >>>>> There are two forms of lightweight properties:- > > >>>>> > > >>>>> 1) foo#bar would be translated by the compiler into:- > > >>>>> > > >>>>> new Property(foo,"bar"); > > >>>>> > > >>>>> while foo#bar#jim would be translated into:- > > >>>>> > > >>>>> new Property(foo,"bar","jim"); > > >>>>> > > >>>>> 2) Foo#bar would be translated into:- > > >>>>> > > >>>>> new Property(Foo.class,"bar"); > > >>>>> > > >>>>> while Foo#bar#jim would be translated into:- > > >>>>> > > >>>>> new Property(Foo.class,"bar","jim"); > > >>>>> > > >>>>> These two forms create (1) a bound Property, or (2) an unbound > > >>>>> one. > > >>>>> Bound > > >>>>> Properties are explicitly bound to a particular instance of a > > >>>>> class (in this case foo), while unbound Properties are templates > > >>>>> which can be applied to any instance of class Foo. Actually > > >>>>> bound properties can also be used as unbound properties, but > > >>>>> that is a harmless and useful side effect not a primary intent. > > >>>>> > > >>>>> The Property class would need to be added (it is appended > > >>>>> below), and should be added either to the java.beans package or > > >>>>> to the java.lang.reflect package (with which is probably has > > >>>>> more in common). > > >>>>> > > >>>>> Syntactically a "#" can be placed wherever a "." can be placed > > >>>>> (except inside a number), and the same checks need to be made > > >>>>> (that each field to the right of a # is a field in the left hand > > >>>>> side) as would be made for a ".". > > >>>>> The only > > >>>>> difference is in field visibility - For the "#" any field is > > >>>>> visible, which follows the model currently available in the > > >>>>> Field class with getDeclaredFields(). It also follows the model > > >>>>> that while a field might be private and therefore not directly > > >>>>> accessible from outside, getters and setters can provide access. > > >>>>> > > >>>>> The Property object provides type safe access to the field in > > >>>>> the form of getters and setters. These come in pairs, one for > > >>>>> bound and the other for unbound access. So for bound access no > > >>>>> object is required to fetch the value, for an unbound object the > > >>>>> parent object needs to be specified. > > >>>>> So if > > >>>>> we > > >>>>> have:- > > >>>>> > > >>>>> Propertyprop = foo#bar; > > >>>>> > > >>>>> we can later say:- > > >>>>> > > >>>>> Bar b = prop.get(); > > >>>>> > > >>>>> or for an unbound one from a second Foo object foo2:- > > >>>>> > > >>>>> Bar b = prop.get(foo2); > > >>>>> > > >>>>> The getters and setters in the Property object will defer to > > >>>>> explicitly coded getters and setters if present, otherwise they > > >>>>> will use the Field getter and setter. > > >>>>> > > >>>>> If a setter is not explicitly coded, the implicit setter will > > >>>>> look for a PropertyChangeSupport object in the parent object of > > >>>>> the rightmost field and fire a PropertyChangeEvent to that > > >>>>> object. > > >>>>> > > >>>>> There are also two Annotations provided by the Property class, > > >>>>> ReadOnly and WriteOnly. These stop implicit getters and setters > > >>>>> from trying to read/write the property. > > >>>>> > > >>>>> Talking of Annotations, this notation can also be used to get at > > >>>>> the Annotations for a field. So to test for the presence of an > > >>>>> Annotation Ann on Foo.bar we would use:- > > >>>>> > > >>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > > >>>>> > > >>>>> SIMPLE EXAMPLE: > > >>>>> > > >>>>> To take an example from BeansBinding (taken from Shannon > > >>>>> Hickey's > > >>>>> blog):- > > >>>>> > > >>>>> // create a BeanProperty representing a bean's firstName > > >>>>> Property firstP = BeanProperty.create("firstName"); > > >>>>> // Bind Duke's first name to the text property of a Swing > > >>>>> JTextField > > >>>>> BeanProperty textP = BeanProperty.create("text"); > > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > > >>>>> firstP, textfield, textP); > > >>>>> binding.bind(); > > >>>>> > > >>>>> > > >>>>> would instead be written:- > > >>>>> > > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > > >>>>> duke#firstName, textfield#text); > > >>>>> binding.bind(); > > >>>>> > > >>>>> which of course can be checked by the IDE/compiler, and will not > > >>>>> wait until run time (not even instantiation time) to show up the > > >>>>> error. > > >>>>> > > >>>>> ADVANCED EXAMPLE: > > >>>>> > > >>>>> For a JComboBox (or JList or JTable or JTree) there is a need to > > >>>>> map a list of objects to the value strings (or column contents). > > >>>>> For this we need to have an unbound Property which can be > > >>>>> applied to each element of the list. > > >>>>> > > >>>>> Duke duke; > > >>>>> Listdukes; > > >>>>> BoundComboBox combo = new > > >>>>> BoundComboBox(dukes,Duke#fullname,this#duke); > > >>>>> > > >>>>> and now the combo box will be populated from the list dukes, and > > >>>>> the display values in the list will be taken from the fullname > > >>>>> field of each Duke element, and the initial value will be set > > >>>>> from the local class field duke and any changes to the combo box > > >>>>> selected element will be reflected back to the duke field. > > >>>>> > > >>>>> DETAILS > > >>>>> > > >>>>> SPECIFICATION: > > >>>>> > > >>>>> This proposal adds a new syntactic element, "#", which can be > > >>>>> used in the same way that "." can be used to qualify fields > > >>>>> within a Java object. > > >>>>> > > >>>>> COMPILATION: > > >>>>> > > >>>>> This proposal requires no change to the class files, and is > > >>>>> implemented by a simple generation of the required instance > > >>>>> using the relevant Property constructor. Obviously the compiler > > >>>>> would have to make sure that the use that the property object > > >>>>> was being put to (in the examples above the left hand side of > > >>>>> the assignment) had the correct Generic attributes. > > >>>>> > > >>>>> TESTING: > > >>>>> > > >>>>> How can the feature be tested? > > >>>>> > > >>>>> LIBRARY SUPPORT: > > >>>>> > > >>>>> The new Property class is required (see below). > > >>>>> > > >>>>> REFLECTIVE APIS: > > >>>>> > > >>>>> No changes are required to the reflective APIs although it makes > > >>>>> extensive use of those APIs. > > >>>>> > > >>>>> OTHER CHANGES: > > >>>>> > > >>>>> No other changes are requires. > > >>>>> > > >>>>> MIGRATION: > > >>>>> > > >>>>> Fortunately there is no code that is formally part of J2SE 6 > > >>>>> which uses such Properties. There are however two proposals > > >>>>> which will need it (BeansBinding and JPA Criteria API), but > > >>>>> neither of these seem to be destined to be part of J2SE 7 > > >>>>> (BeansBinding seems to have died the death and the Criteria API > > >>>>> would be part of the next J2EE which will follow J2SE 7), so > > >>>>> this will provide a base for them to use and no existing code > > >>>>> need to be updated. > > >>>>> > > >>>>> There are other extant Beans-Binding libraries, which could be > > >>>>> modified to use this proposal, but as none of the existing > > >>>>> features have been changed there is no need to change them > > >>>>> (other than for type safety and compiler/ IDE checkability). > > >>>>> > > >>>>> COMPATIBILITY > > >>>>> > > >>>>> BREAKING CHANGES: > > >>>>> > > >>>>> None. This change should not make any existing correct code > > >>>>> fail to compile or run or change the way in which it > > >>>>> compiles/runs. > > >>>>> > > >>>>> EXISTING PROGRAMS: > > >>>>> > > >>>>> No change required to any existing programs > > >>>>> > > >>>>> REFERENCES > > >>>>> > > >>>>> EXISTING BUGS: > > >>>>> > > >>>>> None > > >>>>> > > >>>>> URL FOR PROTOTYPE (optional): > > >>>>> > > >>>>> I do not have the knowledge to make changes to the compiler, and > > >>>>> the only documentation making such changes concentrated on > > >>>>> adding operators not changes at this level. So there is no > > >>>>> prototype of the compiler part, but the Property class follows:- > > >>>>> > > >>>>> package java.lang.reflect; > > >>>>> > > >>>>> import java.beans.BeanInfo; > > >>>>> import java.beans.Introspector; > > >>>>> import java.beans.PropertyChangeSupport; import > > >>>>> java.beans.PropertyDescriptor; import java.lang.reflect.Field; > > >>>>> import java.lang.reflect.Method; > > >>>>> > > >>>>> /** > > >>>>> * Property class > > >>>>> * This is the support class for use with the # notation to > > >>>>> provide lightweight > > >>>>> * Property support for Java. > > >>>>> * > > >>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > > >>>>> * @licence LPGL V2 : details of which can be found at http:// > > >>>>> fsf.org. > > >>>>> * @author david.goodenough at linkchoose.co.uk > > >>>>> * > > >>>>> * @param The Parent class for this field > > >>>>> * @param The Type of this field */ public class > > >>>>> Property { private C parent; private Class parentClass; > > >>>>> private Field[] fields; private PropertyDescriptor[] pd = null; > > >>>>> /** > > >>>>> * Constructor used to create Property objects. The Parent > > >>>>> object may be > > >>>>> * null, but should normally be specified as it can be > > >>>>> overridden anyway. > > >>>>> * @param parent C object that contains the field > > >>>>> * @param field Field describing this field */ public > > >>>>> Property(C parent, String ... fieldNames) { > > >>>>> this.parent = parent; > > >>>>> this(parent.getClass(), fieldNames); > > >>>>> } > > >>>>> /** > > >>>>> * Constructor for unbound Properties, but also used internally > > >>>>> after setting > > >>>>> * the parent object by the bound Property objects. > > >>>>> * @param parentClass Class of the parent object > > >>>>> * @param fieldNames String[] of field names > > >>>>> */ > > >>>>> public Property(ClassparentClass, String .. fieldNames) { > > >>>>> this.parentClass = parentClass; > > >>>>> fields = new Field[fieldNames.length]; > > >>>>> pd = new PropertyDescriptor[fieldNames.length]; > > >>>>> outer: for(int index = 0; index < fields.length; index++) { > > >>>>> Field[]dclFields = parentClass.getDeclaredFields(); > > >>>>> for(Field field:dclFields) { > > >>>>> if(field.getName().equals(fieldNames[index])) { > > >>>>> fields[index] = field; > > >>>>> field.setAccessible(true); > > >>>>> try { > > >>>>> BeanInfo beanInfo = > > >>>>> Introspector.getBeanInfo(parent.getClass()); > > >>>>> PropertyDescriptor[]props = > > >>>>> beanInfo.getPropertyDescriptors(); > > >>>>> for(PropertyDescriptor prop : props) { > > >>>>> if(prop.getName().equals(field.getName())) { > > >>>>> pd[index] = prop; > > >>>>> break; > > >>>>> } > > >>>>> } > > >>>>> } catch(Exception e) { /* assume can not find getter/ > > >>>>> setter */ } > > >>>>> parentClass = field.getType(); > > >>>>> continue outer; > > >>>>> } > > >>>>> } > > >>>>> throw new IllegalArgumentException("Field " + fieldNames[index] + > > >>>>> " not found in class " + > > >>>>> parentClass.getCanonicalName()); > > >>>>> } > > >>>>> } > > >>>>> /** > > >>>>> * Getter from the field in the parent specified when this > > >>>>> Property was created. > > >>>>> * @see Property.get(C otherParent) > > >>>>> * @return F the value of this field */ public F get() { > > >>>>> return get(parent); > > >>>>> } > > >>>>> /** > > >>>>> * Getter with explicit parent. > > >>>>> * This code will check see if this field is WriteOnly, and > > >>>>> complain if it is. > > >>>>> * It will then see if the use has provided am explicit getter, > > >>>>> and call that > > >>>>> * if present, otherwise it will just fetch the value through > > >>>>> the Field provided > > >>>>> * method. > > >>>>> * @param otherParent C parent object > > >>>>> * @return F value of the field > > >>>>> */ > > >>>>> @SuppressWarnings("unchecked") // This should actually not be > > >>>>> needed, > > >>>>> // but the Field.get method is > > >>>>> not typed public F get(C otherParent) { > > >>>>> Object result = otherParent; > > >>>>> try { > > >>>>> for(int index = 0; index < fields.length; index++) { > > >>>>> > > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > > >>>>> throw new IllegalAccessException( > > >>>>> "Can not get from a WriteOnly field - " + > > >>>>> fields[index].getName()); > > >>>>> Method getter = pd[index] == null ? null : > > >>>>> pd[index].getReadMethod(); > > >>>>> if(getter == null) result = fields[index].get(result); > > >>>>> else result = getter.invoke(result); > > >>>>> } > > >>>>> } catch(Exception e) { > > >>>>> throw new RuntimeException("Should not occur exception", e); > > >>>>> } > > >>>>> return (F)result; > > >>>>> } > > >>>>> /** > > >>>>> * Setter to set the value of the field in the parent object > > >>>>> declared with the > > >>>>> * Property object > > >>>>> * @param newValue F new value of this field */ public void > > >>>>> set(F newValue) { > > >>>>> set(parent,newValue); > > >>>>> } > > >>>>> /** > > >>>>> * Setter to set the value of the field to an explicit parent > > >>>>> object. > > >>>>> * If there is a ReadOnly annotation, then we object. If there > > >>>>> is an explicit > > >>>>> * setter then we use that, otherwise we set the field using the > > >>>>> Field provided > > >>>>> * set method and if there is a PropertyChangeSupport field, > > >>>>> fire a property > > >>>>> * change event to it. > > >>>>> * We walk our way down the field chain, until we have the last > > >>>>> object and its > > >>>>> * field, and then we do the set. > > >>>>> * @param parent C explicit parent object > > >>>>> * @param newValue F new value for field in parent */ public > > >>>>> void set(C parent,F newValue) { > > >>>>> try { > > >>>>> Object last = parent; > > >>>>> int index; > > >>>>> for(index = 0; index < fields.length - 1; index++) { > > >>>>> > > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > > >>>>> throw new IllegalAccessException( > > >>>>> "Can not get from a WriteOnly field - " + > > >>>>> fields[index].getName()); > > >>>>> Method getter = pd[index] == null ? null : > > >>>>> pd[index].getReadMethod(); > > >>>>> if(getter == null) last = fields[index].get(last); > > >>>>> else last = getter.invoke(last); > > >>>>> } > > >>>>> > > >>>>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > > >>>>> throw new IllegalAccessException( > > >>>>> "Can not get from a WriteOnly field - " + > > >>>>> fields[index].getName()); > > >>>>> Method setter = pd[index] == null ? null : > > >>>>> pd[index].getWriteMethod(); > > >>>>> if(setter == null) { > > >>>>> PropertyChangeSupport pcs = findPcs(last.getClass()); > > >>>>> fields[index].set(last,newValue); > > >>>>> if(pcs != null) > > >>>>> pcs.firePropertyChange(fields[index].getName(), > > >>>>> newValue, > > >>>>> > > >>>>> fields[index].get(last)); > > >>>>> } else setter.invoke(last,newValue); > > >>>>> } catch(Exception e) { > > >>>>> throw new RuntimeException("Should not occur > > >>>>> exception", e); > > >>>>> } > > >>>>> } > > >>>>> /** > > >>>>> * This is used so that the caller can view the Field name > > >>>>> * @return String field name > > >>>>> */ > > >>>>> public String[] getFieldName() { > > >>>>> String[]names = new String[fields.length]; > > >>>>> for(int index = 0; index < fields.length; index++) { > > >>>>> names[index] = fields[index].getName(); > > >>>>> } > > >>>>> return names; > > >>>>> } > > >>>>> /** > > >>>>> * This method is used to fetch the Field array, which is > > >>>>> useful if you need to > > >>>>> * access the Annotations of a field. > > >>>>> * @return Field[] the array of Fields describing this Property. > > >>>>> */ > > >>>>> public Field[] getFields() { > > >>>>> return fields; > > >>>>> } > > >>>>> /** > > >>>>> * This private method looks for a PropertyChangeSupport object > > >>>>> in the class and > > >>>>> * if one is found it will return it. It looks right the way up > > >>>>> the class tree > > >>>>> * by recurring up the superClasses. > > >>>>> * @param parent Class to check for PropertyChangeSupport fields > > >>>>> * @return PropertyChangeSupport first found object, or null if > > >>>>> not found */ private PropertyChangeSupport findPcs(Class > > >>>>> parent) { > > >>>>> Field fields[] = parent.getDeclaredFields(); > > >>>>> for(Field field:fields) { > > >>>>> field.setAccessible(true); > > >>>>> try { > > >>>>> if(field.getType() == PropertyChangeSupport.class) > > >>>>> return (PropertyChangeSupport)field.get(parent); > > >>>>> } catch(Exception e) { } > > >>>>> } > > >>>>> // If we did not find it then try the superclass > > >>>>> ClasssuperClass = parent.getSuperclass(); > > >>>>> if(superClass == null) return null; > > >>>>> return findPcs(parent.getClass().getSuperclass()); > > >>>>> } > > >>>>> /** > > >>>>> * This annotation is used to mark a field as WriteOnly, i.e. it > > >>>>> can not be read. > > >>>>> * This stops the automatic getter operation. > > >>>>> */ > > >>>>> public @interface WriteOnly { > > >>>>> } > > >>>>> /** > > >>>>> * This annotation is used to mark a field as ReadOnly, i.e. it > > >>>>> can not be written. > > >>>>> * This stops the automatic setter operation. > > >>>>> */ > > >>>>> public @interface ReadOnly { > > >>>>> } > > >>>>> } From david.goodenough at linkchoose.co.uk Wed Mar 4 07:55:43 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 4 Mar 2009 15:55:43 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <49AE977C.8040907@sun.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <200903040941.16335.david.goodenough@linkchoose.co.uk> <49AE977C.8040907@sun.com> Message-ID: <200903041555.46210.david.goodenough@linkchoose.co.uk> On Wednesday 04 March 2009, Joseph D. Darcy wrote: > David Goodenough wrote: > > On Wednesday 04 March 2009, Joseph D. Darcy wrote: > >> Neal Gafter wrote: > >>> Joe Darcy sort of ruled out adding property support in project coin in > >>> http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > >> > >> Correct; properties (and closures and reified generics) are examples of > >> changes out of scope for Project Coin. > > > > OK, if it will make easier I will change its name. > > Changing the proposal's name doesn't change what it is! > > -Joe Yes, well to quote your blog entry:- >Properties: While a detailed judgment would have to be made against a >specific proposal, as a new kind of type properties would most likely be at >least medium-sized. This one is very small (at least compared to some of the others I see in the list). So a detailed judgement needs to made against this specific proposal. This proposal is an attempt to get the core of the problem, to strip away much that has been added to existing proposals, and to solve the problems that any Beans Binding framework and APIs like the JPA Criteria API have and that can currently only be solved by using String field names which can not reasonably be checked by a compiler/IDE. I would suggest that one of Java's greatest strengths is its checkability, and the lack of this simple proposal (or something like it) drives a coach and horses through that strength leaving it not much better than a scripting language. David From develop4lasu at gmail.com Wed Mar 4 09:06:02 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 4 Mar 2009 18:06:02 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903031459.03331.david.goodenough@linkchoose.co.uk> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> Message-ID: <28bca0ff0903040906q15bb6265hd849372ab8b84892@mail.gmail.com> Hi. I do not know if I understand you right. MAJOR DISADVANTAGE: - Property names can be dropped (methods not). - Linking naming with code logics. Other proposal that may make yours one unnecessarily: add @ operator (or ^) method@ would return Method object for given method. field@ would return Field object for given field. - This should allow u to write classes u need and make language almost 100% as it is. - It would be faster. - Independend from names. I might be wrong so tell me if I missed something. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Wed Mar 4 09:31:16 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 4 Mar 2009 17:31:16 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <28bca0ff0903040906q15bb6265hd849372ab8b84892@mail.gmail.com> References: <200903031459.03331.david.goodenough@linkchoose.co.uk> <28bca0ff0903040906q15bb6265hd849372ab8b84892@mail.gmail.com> Message-ID: <200903041731.18231.david.goodenough@linkchoose.co.uk> On Wednesday 04 March 2009, Marek Kozie? wrote: > Hi. > > I do not know if I understand you right. > > MAJOR DISADVANTAGE: > - Property names can be dropped (methods not). > - Linking naming with code logics. > > Other proposal that may make yours one unnecessarily: > > add @ operator (or ^) > method@ would return Method object for given method. > field@ would return Field object for given field. > > - This should allow u to write classes u need and make language almost 100% > as it is. > - It would be faster. > - Independend from names. > > I might be wrong so tell me if I missed something. I have no problem in extending this to Methods. I just do not have a need for extending it to Methods so I have not considered it. I also have no problem with simplifying my proposal to generate Field objects, were it possible which I have my doubts about. The problem with getting Field and Method objects is that you need to be sure that you get the real Field or Method object, and that is difficult as I see it as a result of the way that Field and Method data is stored in class files. They are stored in a binary format and then real Field and Method objects are generated at run time. Correlating that process with the code that the compiler would generate is (I think - please someone prove me wrong) difficult. It is important that we get to the real Field and Method objects for two reasons. Firstly this mechanism can also be used to find Annotations, which is something currently lacking from the PropertyDescriptor support which returns the Class of the return object from the getter not the Class of the field which means you can not find its annotations. The second problem is that we might want to use the Field object to correlate with the parent object. We can scan the Field array from an object very easily, and I am not quite sure I know the checks that a .equals method would have to do to establish equality when reference identity would do. David From Alex.Buckley at Sun.COM Wed Mar 4 09:59:17 2009 From: Alex.Buckley at Sun.COM (Alex Buckley) Date: Wed, 04 Mar 2009 09:59:17 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AE9CA8.5020202@univ-mlv.fr> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <49AE7AFD.7010609@univ-mlv.fr> <15e8b9d20903040647n4efbfdag9c8191194b7f9899@mail.gmail.com> <49AE9CA8.5020202@univ-mlv.fr> Message-ID: <49AEC175.2050804@sun.com> R?mi Forax wrote: > Neal Gafter a ?crit : >> Remi- >> >> Do you have any evidence that this is a sound extension of the type >> system? >> > I don't think the rule about generics interfaces is here to ensure that > the type system is sound or not. > It's about avoiding clash between bridges that as you know contains code. As fully explained at http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ401 What would you do about bridge methods in the example there? In fact, don't tell me. Either file a Request For Enhancement against JLS 8.1.5, or fill in the proposal form and send it to coin-dev. Don't take the ARM proposal discussion off-topic. Alex From jjb at google.com Wed Mar 4 11:09:22 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 11:09:22 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> Message-ID: <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> Mark, Hello again. On Wed, Mar 4, 2009 at 5:36 AM, Mark Mahieu wrote: > > > Now, where I was going with my last email was that a library could include > an interface that extends Disposable, refining the exception types thrown: > > interface SWTDisposable extends Disposable { > void close() throws SWTException; > } > > The afore-mentioned programmer could now hold a Collection > and have much more appropriate exception types to deal with in their cleanup > code. (SWTException is unchecked in real life, but the point's the same). > Seems harmless. This could also be be retrofitted: a class could implement Disposable, and then be retrofitted to implement SWTDisposable in a later release. My natural inclination would be to do this only where there was a clear need, and do it on a case-by-case basis as the need arose. > > OK, well for once the SWT team's aversion to interfaces has an up-side, and > we can easily retrofit this with Disposable, calling dispose() from close(). > Or can we? > > public class Path extends Resource { > > /** > * Closes the current sub path by adding to the receiver a line from the > current point of the path back to the starting point of the sub path. > */ > public void close() { > // ... > } > > // ... > } > > > http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Path.html > Yep. This was bound to happen:( That's why Tim Peierls favored the use of an annotation to mark the "disposal method." But Mark Reinhold has made it clear that this would (still) be unacceptable to Sun: annotations must not change semantics. So be it. This problem is one of those unfortunate things that happen when you retrofit a feature after a platform has been around for over a decade:( I think the solution must necessarily be a bit hackish. Here's one possibility, based loosely on the way for-each works. A resource can implement one of several interfaces. One (currently named Disposable) contains a close method. Another (name tbd) contains a dispose method. A third might contain a destroy method. I can't imagine an existing type to which none of these three interfaces can be retrofitted. The SWT Resource type could be retrofitted to implement the interface with the dispose method, without even adding a new method. This isn't beautiful, but it works. I think it's probably a good idea. Thanks for all the sleuthing, Josh From thorsten at vanellen.de Wed Mar 4 12:09:35 2009 From: thorsten at vanellen.de (Thorsten van Ellen) Date: Wed, 04 Mar 2009 21:09:35 +0100 Subject: Idea for Language Extensions for Interface-Protocols, was Re: Automatic Resource Management and Simple Resource Clean-up In-Reply-To: <49AD9EBE.5010808@vanellen.de> References: <49AD9EBE.5010808@vanellen.de> Message-ID: <49AEDFFF.5080101@vanellen.de> By the way: * allocate - deallocate * open - close * begin - commit/rollback * lock - unlock * push - push - pop - pop and so on, all have somthing in common and that is: a protocol on top of the signature. Expressing protocols for interfaces might be a great language feature and solving many more bugs caused by misused interfaces than only misused resources. But surely it is a complex feature. Protocols itself could be expressed with their own languages, e.g., simple regular expressions or even more complex expressions. Languages that can be evaluated at compile time, e.g., for simple cases like "open - close" and languages that have to trace a state to be evaluated at runtime, e.g., "push - push - pop - pop". Compile time mechanisms can not easily be developed by individuals. Runtime mechanisms could be developed individually without language extensions but need effort for every single case. Language extensions like regular expressions could solve the problem generally with one runtime mechanism. Some of them could also be expressed by design by contract which is also a complex feature probably even more complex, but that only works at runtime and does not find errors at compile time. It is only one idea, no proposal, probably too complex for this project and therefore offtopic. Best regards Thorsten van Ellen From scolebourne at joda.org Wed Mar 4 13:32:51 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 04 Mar 2009 21:32:51 +0000 Subject: PROPOSAL: Static Methods in Interfaces In-Reply-To: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> References: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> Message-ID: <49AEF383.2000607@joda.org> Reinier Zwitserloot wrote: > MAJOR DISADVANTAGE: > > No opportunity to use the static > keyword in interfaces for some sort of factory interface concept (an > interface for constructors and static methods). I think this is a key one, as it limits future Java changes. I'd like to see Java support 'static implements': public class Foo implements Bar, static Baz { ... } where any methods defined by Baz have to be implemented by Foo as static methods. > ALTERNATIVES: > > The usual solution to this problem right now is to offer a separate > utility class (a class that is not instantiable and contains only > static methods) that contain the utility methods, along with a > reference in the javadoc of the interface to this utility class. For > example, java.util.Collections is the utility class that goes with > Map, List, Set and other Java Collections API interfaces. I don't consider the utils class to be a particularly bad alternative. > java.util.List/Map/Set: All methods in java.util.Collections should > also be made available on the appropriate java collections API > interface. > java.io.Closeable: should contain a utility method > 'closeAndIgnoreException' (arguably better suited on InputStream > instead). > java.util.List/Set: Should contain an 'of' method that makes > unmodifiable lists and sets via varargs. > java.io.FileFilter: Should contain an 'ofExtension(String)' method > that creates a FileFilter for the provided extension. Making these changes would appear to be backwards incompatible if the implementing class already defines the method added to the interface. Stephen From markmahieu at googlemail.com Wed Mar 4 13:45:26 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 4 Mar 2009 21:45:26 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <17b2302a0903031747o1c5049d0ncac56a00815ed348@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> Message-ID: <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> Josh, On 4 Mar 2009, at 19:09, Joshua Bloch wrote: > I think the solution must necessarily be a bit hackish. Here's > one possibility, based loosely on the way for-each works. A > resource can implement one of several interfaces. One (currently > named Disposable) contains a close method. Another (name tbd) > contains a dispose method. A third might contain a destroy > method. I can't imagine an existing type to which none of these > three interfaces can be retrofitted. The SWT Resource type could > be retrofitted to implement the interface with the dispose method, > without even adding a new method. This isn't beautiful, but it > works. I think it's probably a good idea. Well, since we probably can't iron out every inconsistency with what's gone before, we could try to be consistently ironic: interface Disposable { void close() throws Exception; } interface Destroyable { void dispose() throws Exception; } interface Kloseable { void destroy() throws Exception; } ;) In all seriousness, what should the behaviour then be if a class implements two or more of these interfaces? Should all of the 'disposal' methods be invoked? Putting interfaces aside for a moment, instead of an annotation my instinct would have been to reach for a modifier here, especially given that this proposal is for dedicated language support rather than a library based solution. There's even one reserved word already that conveys the meaning pretty well: class SomeResourceType { public finally void release() { // ... } } That approach may well raise all sorts of questions as well - I can certainly think of a couple - but compared to using an annotation, what's wrong with it? Mark From forax at univ-mlv.fr Wed Mar 4 13:48:27 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 04 Mar 2009 22:48:27 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AEC175.2050804@sun.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20902272320g795546a6ya8acfe85b53dedad@mail.gmail.com> <17b2302a0902280434l4c402408ga05f8a5c1bfe0c2a@mail.gmail.com> <15e8b9d20902280741q17b33d86lf323f62d2759df3@mail.gmail.com> <17b2302a0902281108l64f2a7t3bd109a9941c6751@mail.gmail.com> <57AC202F-57F8-464F-B7AA-2992025C038D@twistedbanana.demon.co.uk> <17b2302a0903031722h627831baj5913653729949592@mail.gmail.com> <49AE7AFD.7010609@univ-mlv.fr> <15e8b9d20903040647n4efbfdag9c8191194b7f9899@mail.gmail.com> <49AE9CA8.5020202@univ-mlv.fr> <49AEC175.2050804@sun.com> Message-ID: <49AEF72B.8070807@univ-mlv.fr> Alex Buckley a ?crit : > R?mi Forax wrote: >> Neal Gafter a ?crit : >>> Remi- >>> >>> Do you have any evidence that this is a sound extension of the type >>> system? >>> >> I don't think the rule about generics interfaces is here to ensure >> that the type system is sound or not. >> It's about avoiding clash between bridges that as you know contains >> code. > > As fully explained at > http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ401 > > > What would you do about bridge methods in the example there? > > In fact, don't tell me. Either file a Request For Enhancement against > JLS 8.1.5, or fill in the proposal form and send it to coin-dev. Don't > take the ARM proposal discussion off-topic. > > Alex Hi Alex, I was not trying to hijack the ARM proposal discussion but just saying that interface Disposable can be a generics. R?mi From jjb at google.com Wed Mar 4 14:17:33 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 14:17:33 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> Message-ID: <17b2302a0903041417t15b0c8bck5a3d5c27e4b51103@mail.gmail.com> Mark, On Wed, Mar 4, 2009 at 1:45 PM, Mark Mahieu wrote: > > > In all seriousness, what should the behaviour then be if a class implements > two or more of these interfaces? Should all of the 'disposal' methods be > invoked? > I'd make it a compile-time error to use an automatic resource management statement if the static type is a subtype of more than one of these interfaces. > > Putting interfaces aside for a moment, instead of an annotation my instinct > would have been to reach for a modifier here, > That's a possibility too. Josh From reinier at zwitserloot.com Wed Mar 4 14:35:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 4 Mar 2009 23:35:46 +0100 Subject: PROPOSAL: Static Methods in Interfaces In-Reply-To: <49AEF383.2000607@joda.org> References: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> <49AEF383.2000607@joda.org> Message-ID: <02EC68D8-E2D4-4250-9139-14D50F5E3E75@zwitserloot.com> Hey Stephen, Answers inline. Summary: 1. This proposal does not preclude future 'static implements' concepts. Because of similar terminology there might be more confusion, is all. 2. No, you're mistaken, there is no backwards incompatibility. --Reinier Zwitserloot On Mar 4, 2009, at 22:32, Stephen Colebourne wrote: > Reinier Zwitserloot wrote: >> MAJOR DISADVANTAGE: >> >> No opportunity to use the static >> keyword in interfaces for some sort of factory interface concept (an >> interface for constructors and static methods). > > I think this is a key one, as it limits future Java changes. I'd > like to > see Java support 'static implements': I'd like that as well, but it's not a key disadvantage. There are plenty of ways to make that happen even if static methods are allowed in interfaces. The only disadvantage here is that the existence of this feature, as well as a static implements feature, can be slightly more confusing that either one on its own. Two rough sketches of static implements features that don't conflict with the Static Methods in Interfaces proposal: //separate interfaces from static-implements type interfaces entirely. public factory interface Foo { public static void someMethod(); } or: //use the 'abstract' keyword. public interface Foo { public abstract static void someMethod(); } Either of those approaches would be fine. > > I don't consider the utils class to be a particularly bad alternative. I do. If there is a method that does useful things to Lists, provided by the author(s) of the List interface, then it should be in List, or at the very least, it should be possible to link the ListUtils class to the List interface via something that IDEs will universally recognize. If you'd like to propose a way to do that instead, for example with an annotation, I could live with that as well, though such a proposal would not cater as nicely to the 'other languages on the JVM' crowd, and would not result in code that is as elegant. (I consider List.of(foo, bar); a lot cleaner than ListUtils.of(foo, bar);, but perhaps one can't argue taste). > > Making these changes would appear to be backwards incompatible if the > implementing class already defines the method added to the interface. I don't think it would be, because, as the proposal mentions, static methods in interfaces do NOT inherit. So, If List.java did have a static of method, then trying: ArrayList.of(foo, bar); would not be legal (method not found). So, if someone has rolled their own List implementation that so happens to have a static of method, then there's no problem at all: List.of(); //finds List's of. MyOwnListImpl.of(); //finds your own of(). If of() isn't a static method, there is still no problem. The proposal outlines that static calls via an instance aren't allowed either, so: List x = new MyOwnListImpl(); x.of(); //wouldn't find EITHER method. It won't find List.of() because you can't invoke static methods on interfaces via an instance, and it won't find your own home-grown of for the same reason you won't be allowed to call intValue() on a variable of type Object that just so happens to hold an Integer instance). If I'm mistaken, please outline an example of a collision so I can add a relevant paragraph in the 'compatibilities' section, but I don't think there is one. It's one of the reasons why the proposal contains the caveat that static methods in interfaces do not inherit at all. > From tim at peierls.net Wed Mar 4 14:40:16 2009 From: tim at peierls.net (Tim Peierls) Date: Wed, 4 Mar 2009 17:40:16 -0500 Subject: Proposal: Automatic Resource Management In-Reply-To: <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903031808n1e75986ch4e58d9ed51dfc25c@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> Message-ID: <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> I've never understood the fervor with which Java is defended from annotations that can change program semantics; the defenders' arguments always sound suspiciously circular. But never mind that ... I confess that even though I would have been happy with @Finally public void release() { ... } I'd much prefer public finally void release() { ... } If, as I fear, neither of these are ultimately found palatable, then Disposable.close() may have to do -- it might be restricted to solving a smaller problem than I'd hoped, but that's still an important problem to solve. --tim On Wed, Mar 4, 2009 at 4:45 PM, Mark Mahieu wrote: > Putting interfaces aside for a moment, instead of an annotation my > instinct would have been to reach for a modifier here, especially > given that this proposal is for dedicated language support rather > than a library based solution. There's even one reserved word > already that conveys the meaning pretty well: > > class SomeResourceType { > > public finally void release() { > // ... > } > } > > > That approach may well raise all sorts of questions as well - I can > certainly think of a couple - but compared to using an annotation, > what's wrong with it? From Joe.Darcy at Sun.COM Wed Mar 4 15:08:03 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 15:08:03 -0800 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> Message-ID: <49AF09D3.7050506@sun.com> Neal Gafter wrote: > On Mon, Mar 2, 2009 at 10:29 PM, Joseph D. Darcy wrote: > >>> MAJOR DISADVANTAGE: >>> >>> One-time implementation cost for adding the features to the compiler. >>> Longer language specification in describing the behavior. >>> >>> >> What sort of poor programming practices could this feature encourage or >> enable? >> > > I don't see any, but perhaps I'm shortsighted. > > >>> The type system is affected as follows: For the purpose of type >>> checking, a catch parameter declared with a disjunction has type >>> lub(t1, t2, ...) [JLS3 15.12.2.5]. >>> >> In terms of finding the members of the type, it is good existing concepts in >> the JLS can be used. >> >> What happens if someone writes >> >> catch(final IOException | SomeSubclassOfIOException e) {...} >> >> In other words, is it legal to have subclasses of a caught exception listed >> too? >> > > I don't really care one way or the other. As written, yes, it is > allowed and means the same thing as the supertype alone. > Okay. >>> To avoid the need to add support for general disjunctive types, but >>> leaving open the possibility of a future extension along these lines, >>> a catch parameter whose type has more than one disjunct is required to >>> be declared final. >>> >>> >> I think that is a fine compromise that keep the current feature smaller >> while allowing room for a broader feature later. >> >> Some worked examples of the sets of thrown exceptions types under various >> tricky code samples would help clarify the data flow algorithm for me. >> > > Sure, I can do that. Do you think that should go in the specification? > Yes; effectively sets of exception types are being computed and operated on; it would help clarify some of hter interactions for me to see some worked examples. >>> A catch clause is currently compiled (before this change) to an entry >>> in an exception table that specifies the type of the exception and the >>> address of the code for the catch body. To generate code for this new >>> construct, the compiler would generate an entry in the exception table >>> for each type in the exception parameter's list of types. >>> >>> >> Interesting; so there would be no code duplication even in the class files. >> > > Correct. That's what the current prototype (in the BGGA compiler) > does for this construct. > > >> How could the increased exception precision be maintained will still allow >> programs such as the one above to compile? >> > > I don't think it can without making rather complex rules, but I'll > think about it more. > > However, one could take only the multicatch part of this proposal and > not the final/rethrow part, and then I believe one could specify it > without there being a breaking change. > Without the final rethrow, do actual disjunctive types need to be added to support multi-catch? Thanks, -Joe From Joe.Darcy at Sun.COM Wed Mar 4 15:11:55 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 15:11:55 -0800 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <15e8b9d20903030704j4fbf2f31if64f59b381c8864f@mail.gmail.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> <08E77F6F-6D7F-4A0F-B389-4851039220F0@zwitserloot.com> <15e8b9d20903030704j4fbf2f31if64f59b381c8864f@mail.gmail.com> Message-ID: <49AF0ABB.20104@sun.com> Hello. I'd prefer to see this listed as an alternative in the next iteration of the Improved Exception Handling draft to the problem of source incompatibility, an incompatibility we might be able to live with anyway. I think a general foreign interoperability proposal while interesting, would be outside the focus of Project Coin. -Joe Neal Gafter wrote: > I think relaxing the rules for interoperability is a great idea. I > know a few places where Java's language rules interfere with > interoperability, but I wasn't aware of this one before. I suggest > you write it as a separate proposal, please. > > On Tue, Mar 3, 2009 at 2:06 AM, Reinier Zwitserloot > wrote: > >> Maybe I'm making this too simple, but what if javac will treat all >> catch blocks of a type that isn't thrown by the try block as warnings >> instead of errors? That fixes Neal's Improved Exception Handling issue >> of not being 100% source compatible with java 6, no? >> >> I assume source compatibility where code that is clearly broken >> results in a warning in java 7 (but is still compiled with exactly the >> same semantics) whereas it was silently compiled by java 6 is only >> good news. >> >> Also, because in just about every other language on the JVM, checked >> exceptions can be thrown without being declared, I think this is a >> good idea in general, considering that java wants to be more >> interoperable with non-java JVM languages. To work around this issue >> now, you have to either wrap the call in a wrapper method that adds >> the exception to the throws list, or you have to create a dummy method >> that declares the throwable in the throws list but doesn't throw it, >> just so javac will stop refusing to compile your code. That's clearly >> a hack solution, and the elimination of it should be a good thing, >> even if you need to use a @SuppressWarnings instead, no? >> >> Should I write up a proposal for this? Should Neal add it to his >> proposal? Or is it just a horribly stupid idea? :) >> >> --Reinier Zwitserloot >> >> >> >> On Mar 3, 2009, at 08:33, Neal Gafter wrote: >> >> >>> On Mon, Mar 2, 2009 at 10:29 PM, Joseph D. Darcy >>> wrote: >>> >>>>> MAJOR DISADVANTAGE: >>>>> >>>>> One-time implementation cost for adding the features to the >>>>> compiler. >>>>> Longer language specification in describing the behavior. >>>>> >>>>> >>>> What sort of poor programming practices could this feature >>>> encourage or >>>> enable? >>>> >>> I don't see any, but perhaps I'm shortsighted. >>> >>> >>>>> The type system is affected as follows: For the purpose of type >>>>> checking, a catch parameter declared with a disjunction has type >>>>> lub(t1, t2, ...) [JLS3 15.12.2.5]. >>>>> >>>> In terms of finding the members of the type, it is good existing >>>> concepts in >>>> the JLS can be used. >>>> >>>> What happens if someone writes >>>> >>>> catch(final IOException | SomeSubclassOfIOException e) {...} >>>> >>>> In other words, is it legal to have subclasses of a caught >>>> exception listed >>>> too? >>>> >>> I don't really care one way or the other. As written, yes, it is >>> allowed and means the same thing as the supertype alone. >>> >>> >>>>> To avoid the need to add support for general disjunctive types, but >>>>> leaving open the possibility of a future extension along these >>>>> lines, >>>>> a catch parameter whose type has more than one disjunct is >>>>> required to >>>>> be declared final. >>>>> >>>>> >>>> I think that is a fine compromise that keep the current feature >>>> smaller >>>> while allowing room for a broader feature later. >>>> >>>> Some worked examples of the sets of thrown exceptions types under >>>> various >>>> tricky code samples would help clarify the data flow algorithm for >>>> me. >>>> >>> Sure, I can do that. Do you think that should go in the >>> specification? >>> >>> >>>>> A catch clause is currently compiled (before this change) to an >>>>> entry >>>>> in an exception table that specifies the type of the exception and >>>>> the >>>>> address of the code for the catch body. To generate code for this >>>>> new >>>>> construct, the compiler would generate an entry in the exception >>>>> table >>>>> for each type in the exception parameter's list of types. >>>>> >>>>> >>>> Interesting; so there would be no code duplication even in the >>>> class files. >>>> >>> Correct. That's what the current prototype (in the BGGA compiler) >>> does for this construct. >>> >>> >>>> How could the increased exception precision be maintained will >>>> still allow >>>> programs such as the one above to compile? >>>> >>> I don't think it can without making rather complex rules, but I'll >>> think about it more. >>> >>> However, one could take only the multicatch part of this proposal and >>> not the final/rethrow part, and then I believe one could specify it >>> without there being a breaking change. >>> >>> >> >> > > From jjb at google.com Wed Mar 4 15:17:28 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 15:17:28 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> Message-ID: <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Tim, Hi! On Wed, Mar 4, 2009 at 2:40 PM, Tim Peierls wrote: > I've never understood the fervor with which Java is defended from > annotations that can change program semantics; the defenders' arguments > always sound suspiciously circular. But never mind that ... I confess that > even though I would have been happy with > > @Finally public void release() { ... } > > I'd much prefer > > public finally void release() { ... } > I think it's worth adding this to the proposal as a design alternative. The finally modifier could appear on one and only one method. It would have to be a public, parameterless instance method. This would require a (small) class file format change, and a change to the JavaDoc tool, which would document that the class was a "resource," and which method was its disposal method. It would make the automatic resource management statement a bit more broadly applicable at the expense of a bit of added complexity. Josh > From Joe.Darcy at Sun.COM Wed Mar 4 15:28:20 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 15:28:20 -0800 Subject: (update) Use "default" keyword for default visibility In-Reply-To: <43577BD5-8BD8-45F0-B190-EB04FBB283C3@iam.unibe.ch> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <49AD1C0B.3070907@joda.org> <43577BD5-8BD8-45F0-B190-EB04FBB283C3@iam.unibe.ch> Message-ID: <49AF0E94.6000206@sun.com> Hello. While the lack of an explicit name for the default accessibility in Java has slightly annoyed me at times over the years, I don't think it in isolation is such a troublesome issue that a language change is warranted. A few comments inline... Adrian Kuhn wrote: > Updated the default visibility proposal > > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Adrian Kuhn > > OVERVIEW: > Allow the "package" keyword to be used as modifier for default > visibility. > > FEATURE SUMMARY: > Use "package" keyword for default visibility. > > MAJOR ADVANTAGE: > This change is a "5 cent coin" at best, there are not many advantages > beyond improved readability and a more beautiful language definition. > However, the benefit of improved readability is not to be > underestimated. The missing keyword for default visibility breaks the > symmetry of visibility modifiers. The use of package visibility is > less obvious than other visibility since an explicit modifier is > missing. This decreases readability of source code. For example, > omitting any of the three explicit modifiers by mistake (or vice verse > mistakingly adding any of the tree) may introduce unexpected behavior > which is hard to spot due to the bad readability. > > MAJOR BENEFIT: > Improved readability. > > MAJOR DISADVANTAGE: > Two ways to express the same thing (in compatibility mode). > > ALTERNATIVES: > - Using /*default*/ comments (as often seen) is not an alternative > since such comments are not processed by the compiler. > - Using a custom-made @Package annotation is feasible (it is what I > use now) and can be processed by the compiler using an annotation > processor. > > EXAMPLES > > SIMPLE EXAMPLE: > public class Point { > package int x; > package int y; > } > > ADVANCED EXAMPLE: > package ch.akuhn.util; > package class Foo { > } > > DETAILS > > SPECIFICATION: > "package" is already a keyword, introducing it as a new visibility > modifier is thus save. To distinguish package visible top-level > classes and package declarations, the grammar will need a lookahead of > two tokens (I dont know if this is a problem). > Not all modifiers are applicable in all places. For example, "private" cannot appear on the methods of an interface. A more convincing specification would list explicitly the grammar changes and updated JLS sections. > COMPILATION: > Same as now with implicit default visibility. > > TESTING: > Same as now with implicit default visibility. > > LIBRARY SUPPORT: > None. > > REFLECTIVE APIS: > None. > > OTHER CHANGES: > None. > > MIGRATION: > See below, strict vs compatibility mode. > > COMPATIBILITY: > A compiler switch is offered to set either strict or compatibility > mode. In strict mode, an error is issued if a member has not > visibility modifier. That would be a non-starter if mandatory; it would mean gratuitous source incompatibilities between JDK 7 and earlier source levels. An annotation processor can be written to do this to enforce local coding conventions. -Joe > In compatibility mode, members without visibility > modifier as treated as default visibile (which is the current > semantics of Java). > > BREAKING CHANGES: > None. > > EXISTING PROGRAMS: > Work fine in compatibility mode. > > REFERENCES > > EXISTING BUGS: To my best knowledge, none. > > URL FOR PROTOTYPE (optional): > > On Mar 3, 2009, at 13:01 , Stephen Colebourne wrote: > > >>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >>> AUTHOR(S): Adrian Kuhn >>> OVERVIEW >>> Allow the "default" keyword to be used as modifier for default >>> visibility. In strict mode, missing use of default is a warning / >>> error, in compatibility mode both the current (ie no default >>> keyword) and the new syntax are accepted. >>> FEATURE SUMMARY: Use "default" keyword for default visibility. >>> MAJOR ADVANTAGE: The missing keyword for default visibility breaks >>> the symmetry of visibility modifiers. Since it is the only >>> implicit modifier, omitting any of the three explicit modifiers by >>> mistake may be the source of unexpected behavior and thus hard to >>> track down bugs. (There was an example on a blog post recently, >>> but I cannot find it know). >>> MAJOR BENEFIT: Symmetry of visibility modifiers is restored. >>> MAJOR DISADVANTAGE: Two ways to express the same thing (in >>> compatibility mode). >>> ALTERNATIVES: Using a comment such as /* default */ is not an >>> alternative since such comments are not processed by the compiler. >>> EXAMPLES >>> public class C { >>> default Field f; >>> } >>> SIMPLE EXAMPLE: See above. >>> ADVANCED EXAMPLE: None. >>> DETAILS >>> SPECIFICATION: "default" is already a keyword and introducing it as >>> a new visibility modifier is save, it does not lead to ambiguous >>> grammar. >>> COMPILATION: Same as now for implicit default visibility. >>> TESTING: Same as now for implicit default visibility. >>> LIBRARY SUPPORT: None. >>> REFLECTIVE APIS: None. >>> OTHER CHANGES: None. >>> MIGRATION: Compatibility mode allows both, implicit and explicit >>> default visibility, to be used at the same time. >>> COMPATIBILITY >>> BREAKING CHANGES: None. >>> EXISTING PROGRAMS: Work fine in compatibility mode. >>> REFERENCES >>> EXISTING BUGS: To my best knowledge, none. >>> URL FOR PROTOTYPE (optional): >>> > > > From Joe.Darcy at Sun.COM Wed Mar 4 15:39:00 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 15:39:00 -0800 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: References: Message-ID: <49AF1114.3080205@sun.com> Greetings. Static import was surprising complicated in JDK 5. While these aliases could alleviate some problems, I think they would be easily abused and even when not being abused render code less readable. Phil Varner wrote: > Import Aliases for Classes and Static Methods > > http://docs.google.com/Doc?id=dgx74dt7_19dxnspbhj > > AUTHOR: Phil Varner > > OVERVIEW > > FEATURE SUMMARY: The import aliases feature allows a user to provide > an alias underwhich an imported class or statically imported method > must be referred to in the containing source file. An example of the > use of this feature is "import java.sql.Date as SqlDate;" > > MAJOR ADVANTAGE: This feature would allow easier use of multiple > classes which have the same name but different packages to be used in > the same source file. > > MAJOR BENEFIT: This will prevent the necessity of fully-qualifiying > all class references when there is a name collision, leading to more > readable code. > IMO, having alternate names for potentially common classes would be less readable. > MAJOR DISADVANTAGE: This will introduce an extra level of indirection > when determing the source of a given class or method, introduce a new > keyword 'as', and will require changes to IDE code completion > functionality. > > ALTERNATIVES: In some cases, a nested class can be created which > trivially derives a class involved in the name collision. For a > method, a wrapper method can be created in the source file. > > EXAMPLES > > SIMPLE EXAMPLE: > > Example #1, duplicate class name > > Current code: > > new java.sql.Date(new java.util.Date()); > > New code: > > import java.sql.Date as SqlDate; > import java.util.Date as UtilDate; > > new SqlDate(new UtilDate()); > > Example #2, statically imported method alias > > Current code: > > import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName; > > public static int mrlacsmn(final int arg1, final String arg2){ > return myReallyLongAndComplicatedStaticMethodName(arg1, arg2); > } > > mrlacsmn(1, a); > > New code: > > import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName > as mrlacsmn; > > mrlacsmn(1, a); > > ADVANCED EXAMPLE: > > Example #3 > > Translation of persistent formats between similar APIs. > > In many domains, it is not uncommon to have two different APIs with > classes with the same name. For example, in a production rules API, > one may have classes "RuleSet" and "Rule". When attempting to use the > API to translate between these these APIs, it must be decided that one > is fully-qualified and one is not. This can lead to code like: > > com.example.foo.bar.sdk.RuleSet srcRuleSet = ...; > com.example.foo.bar.sdk2.RuleSet dstRuleSet = new > com.example.foo.bar.sdk2.RuleSet(); > migrate(srcRuleSet, dstRuleSet); > ... > > private static void migrate(com.example.foo.bar.sdk.RuleSet srcRuleSet, > com.example.foo.bar.sdk2.RuleSet dstRuleSet){ > ... > } > > Note that it is good practice here not to import either class because > it is too easy to accidentally misuse constants and static methods. > > With the 'as' syntax, one could instead write the far less verbose and > more readible: > > import com.example.foo.bar.sdk.RuleSet as SrcRuleSet; > import com.example.foo.bar.sdk2.RuleSet as DstRuleSet; > > ... > > SrcRuleSet srcRuleSet = ...; > DstRuleSet destRuleSet = new DstRuleSet(); > migrate(srcRuleSet, dstRuleSet); > > ... > > private static void migrate(SrcRuleSet srcRuleSet, > DstRuleSet dstRuleSet){ > ... > } > > Example #4 > > Ensuring correct method selection when static importing overloaded methods. > > Current code: > import static org.testng.Assert.assertEquals; > > public static int aeo(Object arg1, Object arg2){ > assertEquals(arg1, arg2); > } > > public static int aec(Collection arg1, Collection arg2){ > assertEquals(arg1, arg2); > } > > aeo(obj1, obj2); > aec(list1, list2); > > New code: > > import static org.testng.Assert.assertEquals(Object, Object) as aeo; > import static org.testng.Assert.assertEquals(Collection, Collection) as aec; > > aeo(obj1, obj2); > aec(list1, list2); > > Note: it is possible that this sort of method selection is beyond the > scope of a COIN proposal > > DETAILS > > SPECIFICATION: > > Grammar > > modification (JLS 3.9): > Keyword: > as > ... > > modification (JLS 7.5): > ImportDeclaration: > SingleTypeImportDeclarationWithAlias > SingleStaticImportDeclarationWithAlias > ... > > addition: > SingleTypeImportDeclarationWithAlias: > import TypeName as Identifier; > > addition: > SingleStaticImportDeclarationWithAlias: > import static TypeName . Identifier as Identifier; > > > Note that this would explicitly forbid wildcard imports from being aliased. > > There are no known effects on the type system or meaning of > expressions and statements in the Java Programming Language. > While grammar changes are part of the picture, the substantive changes would be to JLSv3 section 6.5 "Determining the Meaning of a Name": http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.5 -Joe > COMPILATION: This feature would be a compile-time transform. It would > only affect the way in which a non-fully qualified class or method > name was resolved to a fully-qualified class or method name. > > TESTING: This change would be tested in a manner similar how how the > existing code which resolves the fully-qualified names of classes and > methods is tested. > > LIBRARY SUPPORT: No change > > REFLECTIVE APIS: No change > > OTHER CHANGES: No change > > MIGRATION: This change is backwards-compatible with existing code. > > COMPATIBILITY > > BREAKING CHANGES: No change > > EXISTING PROGRAMS: No change > > REFERENCES > > EXISTING BUGS: None at present > > URL FOR PROTOTYPE (optional): None at present > > From scolebourne at joda.org Wed Mar 4 15:54:49 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 04 Mar 2009 23:54:49 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: <49AF14C9.3050309@joda.org> > interface Disposable { > void close() throws Exception; > } > interface Destroyable { > void dispose() throws Exception; > } > interface Kloseable { > void destroy() throws Exception; > } Er, no. If its to be an interface it needs to be just one. A single interface - Disposable defining close() covers most use cases, and API writers would adapt in the future. > public finally void release() { ... } I think this works well, and opens up more options. Are there any specific grammer objections? It would be possible to add a marker interface Finally which enforces the presence of the finally modifier, but that seems to have little obvious benefit, and be a bit magical. Stephen From jjb at google.com Wed Mar 4 16:37:41 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 16:37:41 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AF14C9.3050309@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <49AF14C9.3050309@joda.org> Message-ID: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> It is perhaps worth reiterating that the "finally" (or other keyword) solution really does make things more complex. We'd need to add rules like this: A class is a resource iff it has a method that is labeled finally. The superclass of a resource must not be a resource. The finally modifier must not be used on an interface method. We'd need to decide which bit is to be set in the class file to indicate that a method has the finally modifier (luckily there are 6 available). We'd need to decide whether a bit should be set on the resource class, and if so, which bit. It would be redundant to set such a bit, but it would allow the compiler and the VM to quickly determine whether a class was a resource. We'd have to modify JavaDoc. And so on. In the absence of this addition, the proposal really is a simple AST transformation. I'm not arguing that we shouldn't do the "finally" (or other keyword) thing, but that we should only do it if we decide that the added breadth of applicability is worth the added complexity. Remember that Coin means "small change";) Josh On Wed, Mar 4, 2009 at 3:54 PM, Stephen Colebourne wrote: > > interface Disposable { > > void close() throws Exception; > > } > > interface Destroyable { > > void dispose() throws Exception; > > } > > interface Kloseable { > > void destroy() throws Exception; > > } > > Er, no. If its to be an interface it needs to be just one. > > A single interface - Disposable defining close() covers most use cases, > and API writers would adapt in the future. > > > public finally void release() { ... } > > I think this works well, and opens up more options. Are there any > specific grammer objections? > > It would be possible to add a marker interface Finally which enforces > the presence of the finally modifier, but that seems to have little > obvious benefit, and be a bit magical. > > Stephen > > From jodastephen at gmail.com Wed Mar 4 15:59:24 2009 From: jodastephen at gmail.com (Stephen Colebourne) Date: Wed, 04 Mar 2009 23:59:24 +0000 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: <49AF1114.3080205@sun.com> References: <49AF1114.3080205@sun.com> Message-ID: <49AF15DC.20408@gmail.com> Joseph D. Darcy wrote: > IMO, having alternate names for potentially common classes would be less > readable. > The Javapolis discussions of 2007 ended with the majority of participants choosing against aliasing of imports (typedefs). http://www.javapolis.com/confluence/plugins/advanced/gallery-slideshow.action?pageId=32793&decorator=popup&imageNumber=9 Stephen From akuhn at iam.unibe.ch Wed Mar 4 16:43:42 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Thu, 5 Mar 2009 01:43:42 +0100 Subject: (update) Use "default" keyword for default visibility In-Reply-To: <49AF0E94.6000206@sun.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <49AD1C0B.3070907@joda.org> <43577BD5-8BD8-45F0-B190-EB04FBB283C3@iam.unibe.ch> <49AF0E94.6000206@sun.com> Message-ID: On Mar 5, 2009, at 00:28 , Joseph D. Darcy wrote: > Not all modifiers are applicable in all places. For example, > "private" cannot appear on the methods of an interface. A more > convincing specification would list explicitly the grammar changes > and updated JLS sections. That's feels like writing up house rules for D&D :) Changes to http://java.sun.com/docs/books/jls/download/langspec-3.0.pdf 6 [..] The default access is that a member can be accessed anywhere within the package that contains its declaration; other possibilities are public, protected, and private. [* Actually, this is not true for interface members and enum constructors! The introduction of the chapters seems to be prose anyway, so I dont fix that for now. ] 6.6.1 second item - [...] If a top level class or interface type is declared "package" or has no access modifier, then it may be accessed only from within the package in which it is declared. 6.6.1 last item - Otherwise, if the member or constructor is declared "package" or has no access modifier, then access is permitted only when it occurs from within the package in which the type is declared. 6.6.4 If a class lacks the public modifier or is declared "package", access to the class declaration is limited to the package in which it is declared (?6.6). [* Example may need to be updated.] 6.6.5 If the "package" modifier is specified or none of the access modifiers are specified, [..] If a public class has a method or constructor with default access or "package" modifier, then this method or constructor is not accessible to or inherited by a subclass declared outside this package. [* Example may need to be updated.] 8 Field, method, member class, member interface, and constructor declarations may include the access modifiers (?6.6) package, public, protected, or private. 8.1.1 /ClassModifier: one of/ /Annotation/ package public protected private abstract static final strictfp [* I could not find a sentence that declares multiple access modifiers to be a compile-time error. Where is this stated for classes if not here?] 8.2.1.1 [* Example may need to be updated.] 8.3.1 /FieldModifier: one of/ /Annotation/ package public protected private static final transient volatile A compile-time error occurs [..] if a field declaration has more than one of the access modifiers package, public, protected, and private. 8.4.3 /MethodModifier: one of/ /Annotation/ package public protected private abstract static final synchronized native strictfp A compile-time error occurs [..] if a method declaration has more than one of the access modifiers package, public, protected, and private. 8.4.8 [..] of the superclass and superinterfaces that are public, protected, "package" or declared with default access in the same package as C and [..] [...] - /m2/ is public, protected, package or declared with default access in the same package as C, or [...] 8.4.8.4 If the overridden or hidden method is "package" or has default access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs. 8.5.1 The access modifiers package, public, protected, and private are discussed in ?6.6. A compile-time error occurs if a member type declaration has more than one of the access modifiers package, public, protected, and private. 8.8.3 /ConstructorModifier: one of/ /Annotation/ package public protected private The access modifiers package, public, protected, and private are discussed in ?6.6. A compile-time error occurs [..] if a constructor declaration has more than one of the access modifiers package, public, protected, and private. It is a compile-time error if the constructor of an enum type (?8.9) is declared package, public or protected. [* BTW, another irregularity here: for enum constructors, no access modifier means private not default access. This may violate the principle of least surprise. ] 8.8.9 5th paragraph [..] otherwise, if the class is declared "package" or has no access modifier, the default constructor is implicitly given the access modifier "package". 9.1.1 /InterfaceModifier: one of/ /Annotation/ package public protected private abstract static strictfp [* Again, I could not find a sentence that declares multiple access modifiers to be a compile-time error. Where is this stated for interfaces if not here?] 9.3 [* Would need a change if we want to allow interfaces members to be package visible. See Alex Buckley's blog posts. Currently, if interface members do have no access modifiers, they are assumed to be public. ] 9.4 [* Same as above.] 12.3.3 first item [..] because the field or method was declared private, protected, "package", or default access (not public), or because the class was not declared public. 13.4.7 [..] Less access is permitted if the access modifier is changed from "package" access to private access; from protected access to "package" or privat access; or from public access to protected, "package", or private access. [..] 14.3 It is a compile-time error if a local class declaration contains any one of the following access modifiers: package, public, protected, private, or static. [* Is this correct? I guess, since no access modifier on local class means local visibility not default visibility. ] 18.1 /Modifier:/ /Annotation/ package public protected ... >> COMPATIBILITY: >> A compiler switch is offered to set either strict or compatibility >> mode. In strict mode, an error is issued if a member has not >> visibility modifier. > > That would be a non-starter if mandatory; it would mean gratuitous > source incompatibilities between JDK 7 and earlier source levels. > An annotation processor can be written to do this to enforce local > coding conventions. Okay, dropped. cheers, AA From neal at gafter.com Wed Mar 4 18:31:26 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 4 Mar 2009 18:31:26 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AF14C9.3050309@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <49AF14C9.3050309@joda.org> Message-ID: <15e8b9d20903041831r2a2eb289pbefd4a3b27edec62@mail.gmail.com> On Wed, Mar 4, 2009 at 3:54 PM, Stephen Colebourne wrote: >> public finally void release() { ... } > > I think this works well, and opens up more options. Are there any > specific grammer objections? Having both final and finally as modifiers will be confusing. From mr at sun.com Wed Mar 4 19:35:41 2009 From: mr at sun.com (Mark Reinhold) Date: Wed, 04 Mar 2009 19:35:41 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: jjb@google.com; Wed, 04 Mar 2009 16:37:41 PST; <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> Message-ID: <20090305033541.B4CF2D06B@callebaut.niobe.net> > Date: Wed, 04 Mar 2009 16:37:41 -0800 > From: Joshua Bloch > It is perhaps worth reiterating that the "finally" (or other keyword) > solution really does make things more complex. Yes, but the complexity might be worthwhile. On the surface, at least, doing this in the language makes a lot more sense to me than doing it with an interface. There are numerous subtleties, no doubt, but this idea seems worth further investigation. > We'd need to add rules like > this: A class is a resource iff it has a method that is labeled finally. That's not so hard. > The superclass of a resource must not be a resource. Not clear. We could, e.g., allow a superclass to be a resource so long as the subclass does not override the disposal method, or if it does override it then it must declare that exact same method "finally". > The finally modifier > must not be used on an interface method. Yes. By analogy with "synchronized" one could say that "finally" just doesn't belong in an interface. This also avoids clashes in the case of a class that implements two interfaces, each of which declares a different disposal method. > We'd need to decide which bit is > to be set in the class file to indicate that a method has the finally > modifier (luckily there are 6 available). We'd need to decide whether a bit > should be set on the resource class, and if so, which bit. It would be > redundant to set such a bit, but it would allow the compiler and the VM to > quickly determine whether a class was a resource. We'd have to modify > JavaDoc. These are all perfectly valid concerns, but I don't think the answers are necessarily all that hard. > And so on. In the absence of this addition, the proposal really is > a simple AST transformation. I'm not arguing that we shouldn't do > the "finally" (or other keyword) thing, but that we should only do it if we > decide that the added breadth of applicability is worth the added > complexity. Remember that Coin means "small change";) Indeed. Joe might disagree, but to my eye a worked-out proposal for keyword-based disposal methods could still meet the threshold of "small change". - Mark From jjb at google.com Wed Mar 4 19:54:47 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 19:54:47 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <20090305033541.B4CF2D06B@callebaut.niobe.net> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> Message-ID: <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> Mark, Hi. On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > > From: Joshua Bloch > > > It is perhaps worth reiterating that the "finally" (or other keyword) > > solution really does make things more complex. > > Yes, but the complexity might be worthwhile. Agreed. I wasn't saying that we shouldn't do it; just that we should only do it with our eyes open. > On the surface, at least, > doing this in the language makes a lot more sense to me than doing it > with an interface. On the one hand, we did for-each with an interface. But on the other that was targeted at a more limited set of types, and it was no real hardship that the method that they had to implement Iterable. > > > The superclass of a resource must not be a resource. > > Not clear. We could, e.g., allow a superclass to be a resource so long > as the subclass does not override the disposal method, Yep. That's what I meant to say, but now what I said. Oops;) > > > Remember that Coin means "small change";) > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > keyword-based disposal methods could still meet the threshold of "small > change". Well, I'm happy to work it out. Then we'll have two alternatives to compare. Regards, Josh From xmirog at gmail.com Wed Mar 4 21:49:29 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Thu, 05 Mar 2009 06:49:29 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AF14C9.3050309@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <49AF14C9.3050309@joda.org> Message-ID: <49AF67E9.6020004@gmail.com> I like the simplicity of Josh' solution, the rule of throwing the most important exception (the first) and silent the others, using an interface whose method close simply throws Exception...For the Java source code I've been writing for the last 10 years it would fit 100%, I can't remember any "corner case" where it wouldn't fit well, but of course if we can apply this solution to more use cases without losing much simplicity, that would be perfect. For me, using a modifier like finally would also be acceptable. I would love to have this ARM proposal in Java 7! Xavi Stephen Colebourne wrote: > > interface Disposable { > > void close() throws Exception; > > } > > interface Destroyable { > > void dispose() throws Exception; > > } > > interface Kloseable { > > void destroy() throws Exception; > > } > > Er, no. If its to be an interface it needs to be just one. > > A single interface - Disposable defining close() covers most use cases, > and API writers would adapt in the future. > > >> public finally void release() { ... } >> > > I think this works well, and opens up more options. Are there any > specific grammer objections? > > It would be possible to add a marker interface Finally which enforces > the presence of the finally modifier, but that seems to have little > obvious benefit, and be a bit magical. > > Stephen > > > From Joe.Darcy at Sun.COM Wed Mar 4 23:05:04 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 23:05:04 -0800 Subject: Project Coin so far, suggestions for refining current proposals and improving new ones Message-ID: <49AF79A0.7040509@sun.com> Greetings. After a few short days, Project Coin has already received over 10 proposal submissions! Thanks for the insightful feedback and analysis that has been occurring on the list. A few general comments on the proposals that have been sent in so far to help refine those proposals and improve future proposals before they are sent in. The proposals submitted to Project Coin should already be well thought-through. The goal is to have in short order specifications approaching JLS quality, preferably with a prototype to help validate the design. The feedback on the list should be much closer to finding and illuminating any remaining dark corners of a proposal rather than fleshing out its basic structure. If a proposal does not cite chapter and verse of the JLS for parts of its specification, that is a good indication the proposal is too vague. All affected sections of the JLS should be listed, including binary compatibility and the flow analysis in definite assignment. It is fine if someone posts to the list to solicit help writing a proposal for a given change. Proposal writers should be aware of the size and scope parameters established for the project; for background see "Criteria for desirable small language changes" http://blogs.sun.com/darcy/entry/criteria_for_desirable_small_language "Guidance on measuring the size of a language change" http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size Also, proposal writers should search Sun's bug database for bugs related to the change. The URL for the database is http://bugs.sun.com; Java specification issues are in category Java SE and subcategory specification. Of course the database is also searchable with your favorite search engine restricted to that site. Besides the evaluation field from the bug database, the external comment can often also have valuable insight into and discussion of alternatives to solving the problem or reasons why the problem shouldn't be solved. As has already been happening on the list, authors and advocates of a proposal are responsible for responding to feedback and incorporating changes into any subsequent iterations of the proposal. For now, I think it is adequate to just send the revised proposals to the list. Only if there turns out to be frequent change would a more formal tracking system be warranted. Keeping such discussions on the list is important both to allow easy, centralized tracking of the proposal drafts and also for future language archaeologists who are curious about why a particular decision was made. After a few iterations of feedback and refinements, the specification and compilation strategy should be sufficiently detailed to provide high-confidence that the proposal is practical and can be reduced to practice. For example, I think the initial proposal, [1], for the admittedly simple strings in switch change provides adequate detail on these fronts. -Joe [1] http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html PS I've reconfigured the list to accept HTML messages. To get an HTML message through, just send HTML, not HTML and text. From jjb at google.com Wed Mar 4 23:15:30 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 4 Mar 2009 23:15:30 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49AF67E9.6020004@gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <49AF14C9.3050309@joda.org> <49AF67E9.6020004@gmail.com> Message-ID: <17b2302a0903042315l26e012f3s68b7bd48b81bcaa7@mail.gmail.com> Xavi, Thanks very much for the feedback! Josh On Wed, Mar 4, 2009 at 9:49 PM, Xavi Mir? wrote: > I like the simplicity of Josh' solution, the rule of throwing the most > important exception (the first) and silent the others, using an > interface whose method close simply throws Exception...For the Java > source code I've been writing for the last 10 years it would fit 100%, I > can't remember any "corner case" where it wouldn't fit well, but of > course if we can apply this solution to more use cases without losing > much simplicity, that would be perfect. > > For me, using a modifier like finally would also be acceptable. > > I would love to have this ARM proposal in Java 7! > > Xavi > > Stephen Colebourne wrote: > > > interface Disposable { > > > void close() throws Exception; > > > } > > > interface Destroyable { > > > void dispose() throws Exception; > > > } > > > interface Kloseable { > > > void destroy() throws Exception; > > > } > > > > Er, no. If its to be an interface it needs to be just one. > > > > A single interface - Disposable defining close() covers most use cases, > > and API writers would adapt in the future. > > > > > >> public finally void release() { ... } > >> > > > > I think this works well, and opens up more options. Are there any > > specific grammer objections? > > > > It would be possible to add a marker interface Finally which enforces > > the presence of the finally modifier, but that seems to have little > > obvious benefit, and be a bit magical. > > > > Stephen > > > > > > > > > From Joe.Darcy at Sun.COM Wed Mar 4 23:28:02 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 04 Mar 2009 23:28:02 -0800 Subject: PROPOSAL: Static Methods in Interfaces In-Reply-To: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> References: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> Message-ID: <49AF7F02.20901@sun.com> A quick note... Reinier Zwitserloot wrote: > Apparently the previous version's attachment didn't come through > properly, so here's an inline HTML version. > > Static Methods in Interfaces > > VERSION > > > [snip] > REFERENCES > > EXISTING BUGS: > > None. > See http://bugs.sun.com/view_bug.do?bug_id=4093687 -Joe From rssh at gradsoft.com.ua Wed Mar 4 23:52:17 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 5 Mar 2009 09:52:17 +0200 (EET) Subject: String literals in Java 7: version 1.2 Message-ID: <78bb9da52f93ca2910ebca9fe346fd8a.squirrel@wmail.gradsoft.ua> Summary of changes: - methods for setting LF type in strings instead suffixes. - add line-termination escape sequence. (as in C and groovy) Proposal itself: AUTHOR(s): Ruslan Shevchenko, Jeremy Manson (if agree), Reinier Zwitserloot (if agree) OVERVIEW: FEATURE SUMMARY: new string literals in java language: * multiline string literals. * string literals without escape processing. MAJOR ADVANTAGE: Possibility more elegant to code strings from other languages, such as sql constructions or inline xml (for multiline strings) or regular expressions (for string literals without escape processing). MAJOR DISADVANTAGE I don't know ALTERNATIVES: For multiline strings use operations and concatenation methods, such as: String,contact("Multiline \n", "string "); or String bigString="First line\n"+ "second line" For unescaped ('row') stings - use escaping of ordinary java string. EXAMPLES SIMPLE EXAMPLE: Multiline string: StringBuilder sb = new StringBuilder(); sb.append("""select a from Area a, CountryCodes cc where cc.isoCode='UA' and a.owner = cc.country """); if (question.getAreaName()!=null) { sb.append("""and a.name like ? """); sqlParams.setString(++i,question.getAreaName()); } instead: StringBuilder sb = new StringBuilder(); sb.append("select a from Area a, CountryCodes cc\n"); sb.append("where cc.isoCode='UA'\n"); sb.append("and a.owner=cc.country'\n"); if (question.getAreaName()!=null) { sb.append("and a.name like ?"); sqlParams.setString(++i,question.getAreaName()); } String platformDepended="""q """.nativeLf(); is 'q\n' if compiled on Unix and 'q\n\r' if compiled on Windows. String platformIndepended="""q """; is always "q\n". String platformIndepended="""q """U.unixLf(); is the same. String platformIndepended=""" """.windowsLf(); is always '\r\n'. Unescaped String: String myParrern=''..*\.*''; instead String myParrern="\..*\\.*"; String fname=''C:\Program Files\My Program\Configuration''; instead String myParrern="C:\\Program Files\\My Program\\Configuration"; ADVANCED EXAMPLE: String empty=""" """; is empty. String foo = """ bar baz bla qux"; is equal to: String foo = "bar\n baz\n bla\nqux"; String foo = """ foo bar"""; is a compile-time error. String manyQuotes="""\"""\"\"\""""; is """"" String s = """I'm long string in groovy stile wi\ th \\ at end of line"""; is: I'm long string in groovy stile with \ at end of line String s = ''I'm long string in groovy stile wi\ th \\ at end of line''; is: I'm long string in groovy stile wi\ th \\ at end of line DETAILS: Multiline strings are part of program text, which begin and ends by three double quotes. I. e. grammar in 3.10.5 of JLS can be extented as:
MultilineStringLiteral:
        """ MultilineStringCharacters/opt """

MultilineStringCharacters:
        MultilineStringCharacter
        MultilineStringCharacters  (MultilineStringCharacter but not ")
        (MultilineStringCharacters but not "") "

MultilineStringCharacter:
        InputCharacter but not \
        EscapeSequence
        LineTermination
        EolEscapeSequence

EolEscapeSequence: \ LineTermination.

Unescaped strings are part of program text, which begin and ends by two single quotes.
 RowStringLiteral:
                   '' RowInputCharacters/opt ''

 RowInputCharacters:
                      ' (InputCharacter but not ')
                     |
                      (InputCharacter but not ') '
                     |
                      LineTermination
Methods for replacing line termination sequences in string to native format of host platform, and to well-known unix/windows formats must be added to standard library. COMPILATION: Handling of multiline strings: Text within """ brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. sequence \LineTermination at the end of line is erased and such line cause line be concatenated with next line in one. (if nextline exists, otherwise - throw compile-trime error) 3. escape sequences in each line are processed exactly as in ordinary Java strings. 4. elimination of leading whitespaces are processed in next way: - at first determinate sequence of whitespace symbols (exclude LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. let's call it 'leading whitespace sequence' - all next lines must start with same leading whitespace sequence, otherwise compile-time error is thrown. - whitespace processing erase such leading sequence from resulting lines 5. set of lines after erasing of leading whitespace sequence is concatenated, with LF (i. e. '\n') line-termination sequences between two neighbour lines, regardless of host system Handling of row strings: Text within '' brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. set of lines after erasing of leading whitespace sequence is concatenated, with '\n' line-termination sequences between two neighbour lines, No escape processing, no leading whitespace elimination are performed for receiving of resulting string value. new strings literals created and used in .class files exactly as ordinary strings. TESTING: add new strings literals to test-cases for all combinations of finished and unfinished escape sequences and quotes. LIBRARY SUPPORT: Add to String next methods: s.platformLf() - returns string which replace all line-termination sequences in s by value of system property 'line.separator' s.unixLf() - returns string which replace all line-termination sequences in s by '\n' s.windowsLf() - returns string which replace all line-termination sequences in s by '\r\n' REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES Sun bug database http://bugs.sun.com/view_bug.do?bug_id=4165111 http://bugs.sun.com/view_bug.do?bug_id=4472509 Multiline strings proposal in project Kijaro by by Jacek Furmankiewicz http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd From schulz at e-Spirit.de Thu Mar 5 00:16:09 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Thu, 5 Mar 2009 09:16:09 +0100 Subject: PROPOSAL: Static Methods in Interfaces In-Reply-To: <49AEF383.2000607@joda.org> References: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> <49AEF383.2000607@joda.org> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC102BE5A8@osiris2.e-spirit.de> Hi, > I'd like to > see Java support 'static implements': > > public class Foo implements Bar, static Baz { > ... > } > > where any methods defined by Baz have to be implemented by > Foo as static > methods. Someone might remember me writing about this topic under the name "Meta-interfaces/Contracts" in early 2008. I don't think the suggested static methods do collide with a feature to have 'static implements', as these don't need to employ static (abstract) methods, but rather set the scope of the whole interface to define contracts a class has to fulfill (in form of implementing static methods corresponding to the interface). While I shortly thought about posting a proposal on Contracts, I think it is far out of scope for Coin. Regarding static methods in interfaces, I feel a bit undecided, though. While it seems desireable to have common utility methods as close to the related interface as possible, interfaces might become polluted by those methods (as a nested class may do, too) and custom utilities still cannot be linked to the targeted interface. Maybe some possibility to establish a kind of link between utility classes and interfaces would be the better choice. In general, I'd rather prefer a solution like extension methods or similar solutions, accepting not to have it in Coin if considered to big a change. Cheers, Stefan From david.goodenough at linkchoose.co.uk Thu Mar 5 02:31:54 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 5 Mar 2009 10:31:54 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903041535.53432.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903041535.53432.david.goodenough@linkchoose.co.uk> Message-ID: <200903051031.55522.david.goodenough@linkchoose.co.uk> Thinking further about this, there is a problem with using Field objects. Field objects predate Generics, and so the getter/setter that it provides is not one that the compiler/IDE can check. This is real problem and undermines one of the important drivers for this proposal. Now one could rewrite Field to require Generics, but that would break so much code that is is not something I would want to contemplate. In addition applying that to Methods would be well neigh impossible. There is a further problem, which is that as I read it the FCM proposal is only for a single Field object, where my Property object actually holds a Field array, so that it can handle Foo#bar#ali. All in all, I think that introducing a new class (my Property class) solves both the problems, not breaking any existing code and building something that is type safe and checkable and that FCM could subsequently build upon. David On Wednesday 04 March 2009, David Goodenough wrote: > On Wednesday 04 March 2009, Roel Spilker wrote: > > In your proposal, foo#bar would be translated by the compiler into: new > > Property(foo,"bar"); > > > > But I think you should split your proposal into two parts. The first part > > is using the Foo#bar syntax to be a field literal for the field "bar" in > > the type "Foo". This is similar to the FCM proposal > > (http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc). So it would be a > > java.lang.reflect.Field literal. > > > > The second part would be a proposal to build properties using field > > literals. > > > > I give the field literal proposal a chance to be included. > > > > Roel > > I would not be unhappy with that, if were it possible. But I think that > due to the way that Field objects are represented in the class file (in an > odd binary format) and then constructed at run time, that this would not be > possible. It is important (for things like accessing Annotations) that we > get the REAL Field object, and not a partial copy or lookalike. > > If someone can come up with a way of doing that I would be delighted. > > David > > > -----Oorspronkelijk bericht----- > > Van: david.goodenough at linkchoose.co.uk > > [mailto:coin-dev-bounces at openjdk.java.net] Namens David Goodenough > > Verzonden: woensdag 4 maart 2009 10:50 > > Aan: coin-dev at openjdk.java.net > > Onderwerp: Re: PROPOSAL: Lightweight Properties > > > > I am not sure that we would loose anything. The important thing is to > > have an IDE/compiler checkable way of generating Property objects, and > > having two ways of generating them is not really a problem. My Property > > object would happily detect either an explicitly generated getter/setter > > or one generated for you by a property keyword. The property keyword > > would resolve other things (like the automatic generation of > > PropertyChangeSupport, and the controlling of visibility) but it is still > > building on the same basic concept. > > > > If you don't want to use # then the work needed for the compiler gets > > more complicated (I think). One could use a sort of compiler function, > > so one would say property(foo.bar) and it would modify the function of . > > inside the function. > > > > I really want to find a way to get something into Java 7, otherwise we > > are looking to Java 8 (which is at least 3 years away if current > > timescales persist), by which time I suspect that everyone will have > > gotten bored and gone to find pastures new. > > > > David > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > > > But it seems that we _would_ lose a thing or two with this proposal. > > > For example, if a complete properties proposal supports full backwards > > > compatibility and generates getters and setters, then we have a bunch > > > of code around that uses the foo#bar notation, which is by then > > > already outdated, and would in fact get in the way of using foo#bar > > > notation as a shorthand for calling the appropriate getter/setter. I > > > don't know if that is a desired syntax sugar, but the point is: Your > > > proposal would effectively make it impossible to add that later, as it > > > would already be shorthand for creating a Property object. > > > > > > The # and the backtick are the only easily typed symbols that have no > > > meaning whatsoever in java right now. Using one up for an simplified > > > properties proposal is another serious disdvantage. I don't think your > > > proposal makes property support light enough to warrant its inclusion > > > in project coin. That's not to say I have something against > > > properties; on the contrary, I love the idea and I'm very impressed > > > with the way properties work in JavaFX. All the more reason to get it > > > right instead of using a bandage. > > > > > > --Reinier Zwitserloot > > > > > > On Mar 3, 2009, at 23:00, David Goodenough wrote: > > > > Well that depends on what you mean by a complete proposal. > > > > > > > > There are two parts to the use of Properties. There is the > > > > framework side, inside BeansBinding or JPA and then there is the > > > > consumer side, the application code. > > > > > > > > My proposal is very simple on the consumer side (the only bit needed > > > > is the # notation). You can use clasical getters and setters (a > > > > nuisance but everyone understands them), or the simple getter/setter > > > > mechanism that my Property provides. So for the consumer my > > > > proposal is real simple. All you need do is add (either explicity > > > > or by byte code > > > > enhancement) > > > > a PropertyChangeSupport object and the relevant methods and you are > > > > home and dry. > > > > > > > > For the Frameworks, well you only write them once. Even so > > > > something nice and simple appeals and my proposal is simple. > > > > > > > > It may not be Beans as we know it, but they never were integrated > > > > properly into Java. But its really not that dissimilar just > > > > slightly different. > > > > > > > > So other than a little sytactic sugar (not having to code the > > > > PropertyChangeSupport object) we have not really lost anything of > > > > the "full" solution. Having a Bound annotation which would add this > > > > under the covers with a byte code enhancer would not be difficult. > > > > The implicit getters and setters come with the package. So the > > > > question to be asked whether a fuller solution is really needed. > > > > > > > > David > > > > > > > > On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > > > >> The language change required for your proposal is indeed lighter, > > > >> but to understand it, it is seems a lot more complicated. > > > >> > > > >> Also, it would be infeasible to introduce a 'lightweight' > > > >> (according to anyone's definition) proposal now that is lacking in > > > >> certain aspects, and then fix it later, unless that fix is > > > >> syntactically very similar and backwards- and migration compatible. > > > >> That's the major beef I have with this proposal: It effectively > > > >> shuts the door on any other property proposal. In my view, a > > > >> proposal solves the problem properly, or shouldn't be added at all; > > > >> no quick hacky fixes that aren't part of a planned evolution path > > > >> to a complete solution. > > > >> > > > >> If you can highlight how a complete properties proposal will > > > >> seamlessly work with your syntax, I'm more inclined to like it. > > > >> > > > >> --Reinier Zwitserloot > > > >> > > > >> On Mar 3, 2009, at 22:04, David Goodenough wrote: > > > >>> Yes I do. What you propose is much more invasive. Look at it > > > >>> again and maybe you will see the Light(ness). > > > >>> > > > >>> David > > > >>> > > > >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > > > >>>> You call that lightweight? > > > >>>> > > > >>>> How about following the beans spec more to the letter and just > > > >>>> generate the addPropertyChangeListener, > > > >>>> removePropertyChangeListener, setX(), and get/isX() method in > > > >>>> response to seeing a keyword or annotation on a given field. > > > >>>> You'll have to work out the details, but that sounds far, far > > > >>>> simpler to understand. > > > >>>> > > > >>>> You'll need to flesh this out, but it would look something like: > > > >>>> > > > >>>> public class Foo { > > > >>>> private property int x; > > > >>>> } > > > >>>> > > > >>>> Which would generate the addPropertyChangeListener, > > > >>>> removePropertyChangeListener, setX, getX methods, all public, > > > >>>> along with the required infrastructure to make it tick. If you > > > >>>> don't like the generation, for example because you want the > > > >>>> setter to be package private, you just add the setter in the > > > >>>> source file; the keyword will only generate the missing stuff. It > > > >>>> doesn't cover every use case, but there's always the alternative > > > >>>> of doing whatever people do now with beans. Something you didn't > > > >>>> mention in your proposal, by the way. > > > >>>> > > > >>>> I think there's also a fully fleshed out property proposal > > > >>>> (including a 'property' keyword) out there somewhere. > > > >>>> > > > >>>> Possibly make a way to opt out of generating the property change > > > >>>> listener support, and just the getters/setters. > > > >>>> --Reinier Zwitserloot > > > >>>> > > > >>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: > > > >>>>> Below is my proposal for Lightweight Properties. I know that > > > >>>>> the syntax change is an abbomination to some people, but I have > > > >>>>> tried to reduce this to its absolute minimum, while still > > > >>>>> getting a significant benefit. > > > >>>>> > > > >>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > > >>>>> > > > >>>>> AUTHOR(S): > > > >>>>> > > > >>>>> David Goodenough, long time Java user. I can be reached at > > > >>>>> david.goodenough at linkchoose.co.uk. > > > >>>>> > > > >>>>> OVERVIEW > > > >>>>> > > > >>>>> FEATURE SUMMARY: > > > >>>>> > > > >>>>> Lightweight Property support > > > >>>>> > > > >>>>> MAJOR ADVANTAGE: > > > >>>>> > > > >>>>> Both BeansBinding (whether JSR-295 or others such an JFace or > > > >>>>> the JGoodies > > > >>>>> binding) and the JPA Criteria API currently require field names > > > >>>>> (as > > > >>>>> Strings) > > > >>>>> as arguments, which an IDE/compiler can not check. With this > > > >>>>> proposal the strings would be abandoned, and the IDE/compiler > > > >>>>> will be able to check the correctness of the code. > > > >>>>> > > > >>>>> MAJOR BENEFIT: > > > >>>>> > > > >>>>> Manual checking no longer required. This proposal introduces a > > > >>>>> simple well defined IDE/compiler checkable solution. > > > >>>>> > > > >>>>> MAJOR DISADVANTAGE: > > > >>>>> > > > >>>>> It is a language change, and this seems to upset some people. > > > >>>>> > > > >>>>> ALTERNATIVES: > > > >>>>> > > > >>>>> None really, apart from using another language or continuing to > > > >>>>> use String names. The existing solutions all require String > > > >>>>> names which are uncheckable. > > > >>>>> > > > >>>>> EXAMPLES > > > >>>>> > > > >>>>> Lets assume we have a POJO called foo, of type Foo with a field > > > >>>>> bar of type Bar, which itself has a field of type Jim called > > > >>>>> jim. > > > >>>>> > > > >>>>> There are two forms of lightweight properties:- > > > >>>>> > > > >>>>> 1) foo#bar would be translated by the compiler into:- > > > >>>>> > > > >>>>> new Property(foo,"bar"); > > > >>>>> > > > >>>>> while foo#bar#jim would be translated into:- > > > >>>>> > > > >>>>> new Property(foo,"bar","jim"); > > > >>>>> > > > >>>>> 2) Foo#bar would be translated into:- > > > >>>>> > > > >>>>> new Property(Foo.class,"bar"); > > > >>>>> > > > >>>>> while Foo#bar#jim would be translated into:- > > > >>>>> > > > >>>>> new Property(Foo.class,"bar","jim"); > > > >>>>> > > > >>>>> These two forms create (1) a bound Property, or (2) an unbound > > > >>>>> one. > > > >>>>> Bound > > > >>>>> Properties are explicitly bound to a particular instance of a > > > >>>>> class (in this case foo), while unbound Properties are templates > > > >>>>> which can be applied to any instance of class Foo. Actually > > > >>>>> bound properties can also be used as unbound properties, but > > > >>>>> that is a harmless and useful side effect not a primary intent. > > > >>>>> > > > >>>>> The Property class would need to be added (it is appended > > > >>>>> below), and should be added either to the java.beans package or > > > >>>>> to the java.lang.reflect package (with which is probably has > > > >>>>> more in common). > > > >>>>> > > > >>>>> Syntactically a "#" can be placed wherever a "." can be placed > > > >>>>> (except inside a number), and the same checks need to be made > > > >>>>> (that each field to the right of a # is a field in the left hand > > > >>>>> side) as would be made for a ".". > > > >>>>> The only > > > >>>>> difference is in field visibility - For the "#" any field is > > > >>>>> visible, which follows the model currently available in the > > > >>>>> Field class with getDeclaredFields(). It also follows the model > > > >>>>> that while a field might be private and therefore not directly > > > >>>>> accessible from outside, getters and setters can provide access. > > > >>>>> > > > >>>>> The Property object provides type safe access to the field in > > > >>>>> the form of getters and setters. These come in pairs, one for > > > >>>>> bound and the other for unbound access. So for bound access no > > > >>>>> object is required to fetch the value, for an unbound object the > > > >>>>> parent object needs to be specified. > > > >>>>> So if > > > >>>>> we > > > >>>>> have:- > > > >>>>> > > > >>>>> Propertyprop = foo#bar; > > > >>>>> > > > >>>>> we can later say:- > > > >>>>> > > > >>>>> Bar b = prop.get(); > > > >>>>> > > > >>>>> or for an unbound one from a second Foo object foo2:- > > > >>>>> > > > >>>>> Bar b = prop.get(foo2); > > > >>>>> > > > >>>>> The getters and setters in the Property object will defer to > > > >>>>> explicitly coded getters and setters if present, otherwise they > > > >>>>> will use the Field getter and setter. > > > >>>>> > > > >>>>> If a setter is not explicitly coded, the implicit setter will > > > >>>>> look for a PropertyChangeSupport object in the parent object of > > > >>>>> the rightmost field and fire a PropertyChangeEvent to that > > > >>>>> object. > > > >>>>> > > > >>>>> There are also two Annotations provided by the Property class, > > > >>>>> ReadOnly and WriteOnly. These stop implicit getters and setters > > > >>>>> from trying to read/write the property. > > > >>>>> > > > >>>>> Talking of Annotations, this notation can also be used to get at > > > >>>>> the Annotations for a field. So to test for the presence of an > > > >>>>> Annotation Ann on Foo.bar we would use:- > > > >>>>> > > > >>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > > > >>>>> > > > >>>>> SIMPLE EXAMPLE: > > > >>>>> > > > >>>>> To take an example from BeansBinding (taken from Shannon > > > >>>>> Hickey's > > > >>>>> blog):- > > > >>>>> > > > >>>>> // create a BeanProperty representing a bean's firstName > > > >>>>> Property firstP = BeanProperty.create("firstName"); > > > >>>>> // Bind Duke's first name to the text property of a Swing > > > >>>>> JTextField > > > >>>>> BeanProperty textP = BeanProperty.create("text"); > > > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, duke, > > > >>>>> firstP, textfield, textP); > > > >>>>> binding.bind(); > > > >>>>> > > > >>>>> > > > >>>>> would instead be written:- > > > >>>>> > > > >>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > > > >>>>> duke#firstName, textfield#text); > > > >>>>> binding.bind(); > > > >>>>> > > > >>>>> which of course can be checked by the IDE/compiler, and will not > > > >>>>> wait until run time (not even instantiation time) to show up the > > > >>>>> error. > > > >>>>> > > > >>>>> ADVANCED EXAMPLE: > > > >>>>> > > > >>>>> For a JComboBox (or JList or JTable or JTree) there is a need to > > > >>>>> map a list of objects to the value strings (or column contents). > > > >>>>> For this we need to have an unbound Property which can be > > > >>>>> applied to each element of the list. > > > >>>>> > > > >>>>> Duke duke; > > > >>>>> Listdukes; > > > >>>>> BoundComboBox combo = new > > > >>>>> BoundComboBox(dukes,Duke#fullname,this#duke); > > > >>>>> > > > >>>>> and now the combo box will be populated from the list dukes, and > > > >>>>> the display values in the list will be taken from the fullname > > > >>>>> field of each Duke element, and the initial value will be set > > > >>>>> from the local class field duke and any changes to the combo box > > > >>>>> selected element will be reflected back to the duke field. > > > >>>>> > > > >>>>> DETAILS > > > >>>>> > > > >>>>> SPECIFICATION: > > > >>>>> > > > >>>>> This proposal adds a new syntactic element, "#", which can be > > > >>>>> used in the same way that "." can be used to qualify fields > > > >>>>> within a Java object. > > > >>>>> > > > >>>>> COMPILATION: > > > >>>>> > > > >>>>> This proposal requires no change to the class files, and is > > > >>>>> implemented by a simple generation of the required instance > > > >>>>> using the relevant Property constructor. Obviously the compiler > > > >>>>> would have to make sure that the use that the property object > > > >>>>> was being put to (in the examples above the left hand side of > > > >>>>> the assignment) had the correct Generic attributes. > > > >>>>> > > > >>>>> TESTING: > > > >>>>> > > > >>>>> How can the feature be tested? > > > >>>>> > > > >>>>> LIBRARY SUPPORT: > > > >>>>> > > > >>>>> The new Property class is required (see below). > > > >>>>> > > > >>>>> REFLECTIVE APIS: > > > >>>>> > > > >>>>> No changes are required to the reflective APIs although it makes > > > >>>>> extensive use of those APIs. > > > >>>>> > > > >>>>> OTHER CHANGES: > > > >>>>> > > > >>>>> No other changes are requires. > > > >>>>> > > > >>>>> MIGRATION: > > > >>>>> > > > >>>>> Fortunately there is no code that is formally part of J2SE 6 > > > >>>>> which uses such Properties. There are however two proposals > > > >>>>> which will need it (BeansBinding and JPA Criteria API), but > > > >>>>> neither of these seem to be destined to be part of J2SE 7 > > > >>>>> (BeansBinding seems to have died the death and the Criteria API > > > >>>>> would be part of the next J2EE which will follow J2SE 7), so > > > >>>>> this will provide a base for them to use and no existing code > > > >>>>> need to be updated. > > > >>>>> > > > >>>>> There are other extant Beans-Binding libraries, which could be > > > >>>>> modified to use this proposal, but as none of the existing > > > >>>>> features have been changed there is no need to change them > > > >>>>> (other than for type safety and compiler/ IDE checkability). > > > >>>>> > > > >>>>> COMPATIBILITY > > > >>>>> > > > >>>>> BREAKING CHANGES: > > > >>>>> > > > >>>>> None. This change should not make any existing correct code > > > >>>>> fail to compile or run or change the way in which it > > > >>>>> compiles/runs. > > > >>>>> > > > >>>>> EXISTING PROGRAMS: > > > >>>>> > > > >>>>> No change required to any existing programs > > > >>>>> > > > >>>>> REFERENCES > > > >>>>> > > > >>>>> EXISTING BUGS: > > > >>>>> > > > >>>>> None > > > >>>>> > > > >>>>> URL FOR PROTOTYPE (optional): > > > >>>>> > > > >>>>> I do not have the knowledge to make changes to the compiler, and > > > >>>>> the only documentation making such changes concentrated on > > > >>>>> adding operators not changes at this level. So there is no > > > >>>>> prototype of the compiler part, but the Property class follows:- > > > >>>>> > > > >>>>> package java.lang.reflect; > > > >>>>> > > > >>>>> import java.beans.BeanInfo; > > > >>>>> import java.beans.Introspector; > > > >>>>> import java.beans.PropertyChangeSupport; import > > > >>>>> java.beans.PropertyDescriptor; import java.lang.reflect.Field; > > > >>>>> import java.lang.reflect.Method; > > > >>>>> > > > >>>>> /** > > > >>>>> * Property class > > > >>>>> * This is the support class for use with the # notation to > > > >>>>> provide lightweight > > > >>>>> * Property support for Java. > > > >>>>> * > > > >>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > > > >>>>> * @licence LPGL V2 : details of which can be found at http:// > > > >>>>> fsf.org. > > > >>>>> * @author david.goodenough at linkchoose.co.uk > > > >>>>> * > > > >>>>> * @param The Parent class for this field > > > >>>>> * @param The Type of this field */ public class > > > >>>>> Property { private C parent; private Class parentClass; > > > >>>>> private Field[] fields; private PropertyDescriptor[] pd = null; > > > >>>>> /** > > > >>>>> * Constructor used to create Property objects. The Parent > > > >>>>> object may be > > > >>>>> * null, but should normally be specified as it can be > > > >>>>> overridden anyway. > > > >>>>> * @param parent C object that contains the field > > > >>>>> * @param field Field describing this field */ public > > > >>>>> Property(C parent, String ... fieldNames) { > > > >>>>> this.parent = parent; > > > >>>>> this(parent.getClass(), fieldNames); > > > >>>>> } > > > >>>>> /** > > > >>>>> * Constructor for unbound Properties, but also used internally > > > >>>>> after setting > > > >>>>> * the parent object by the bound Property objects. > > > >>>>> * @param parentClass Class of the parent object > > > >>>>> * @param fieldNames String[] of field names > > > >>>>> */ > > > >>>>> public Property(ClassparentClass, String .. fieldNames) { > > > >>>>> this.parentClass = parentClass; > > > >>>>> fields = new Field[fieldNames.length]; > > > >>>>> pd = new PropertyDescriptor[fieldNames.length]; > > > >>>>> outer: for(int index = 0; index < fields.length; index++) { > > > >>>>> Field[]dclFields = parentClass.getDeclaredFields(); > > > >>>>> for(Field field:dclFields) { > > > >>>>> if(field.getName().equals(fieldNames[index])) { > > > >>>>> fields[index] = field; > > > >>>>> field.setAccessible(true); > > > >>>>> try { > > > >>>>> BeanInfo beanInfo = > > > >>>>> Introspector.getBeanInfo(parent.getClass()); > > > >>>>> PropertyDescriptor[]props = > > > >>>>> beanInfo.getPropertyDescriptors(); > > > >>>>> for(PropertyDescriptor prop : props) { > > > >>>>> if(prop.getName().equals(field.getName())) { > > > >>>>> pd[index] = prop; > > > >>>>> break; > > > >>>>> } > > > >>>>> } > > > >>>>> } catch(Exception e) { /* assume can not find getter/ > > > >>>>> setter */ } > > > >>>>> parentClass = field.getType(); > > > >>>>> continue outer; > > > >>>>> } > > > >>>>> } > > > >>>>> throw new IllegalArgumentException("Field " + fieldNames[index] > > > >>>>> + " not found in class " + > > > >>>>> parentClass.getCanonicalName()); > > > >>>>> } > > > >>>>> } > > > >>>>> /** > > > >>>>> * Getter from the field in the parent specified when this > > > >>>>> Property was created. > > > >>>>> * @see Property.get(C otherParent) > > > >>>>> * @return F the value of this field */ public F get() { > > > >>>>> return get(parent); > > > >>>>> } > > > >>>>> /** > > > >>>>> * Getter with explicit parent. > > > >>>>> * This code will check see if this field is WriteOnly, and > > > >>>>> complain if it is. > > > >>>>> * It will then see if the use has provided am explicit getter, > > > >>>>> and call that > > > >>>>> * if present, otherwise it will just fetch the value through > > > >>>>> the Field provided > > > >>>>> * method. > > > >>>>> * @param otherParent C parent object > > > >>>>> * @return F value of the field > > > >>>>> */ > > > >>>>> @SuppressWarnings("unchecked") // This should actually not be > > > >>>>> needed, > > > >>>>> // but the Field.get method is > > > >>>>> not typed public F get(C otherParent) { > > > >>>>> Object result = otherParent; > > > >>>>> try { > > > >>>>> for(int index = 0; index < fields.length; index++) { > > > >>>>> > > > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > > > >>>>> throw new IllegalAccessException( > > > >>>>> "Can not get from a WriteOnly field - " + > > > >>>>> fields[index].getName()); > > > >>>>> Method getter = pd[index] == null ? null : > > > >>>>> pd[index].getReadMethod(); > > > >>>>> if(getter == null) result = fields[index].get(result); > > > >>>>> else result = getter.invoke(result); > > > >>>>> } > > > >>>>> } catch(Exception e) { > > > >>>>> throw new RuntimeException("Should not occur exception", e); > > > >>>>> } > > > >>>>> return (F)result; > > > >>>>> } > > > >>>>> /** > > > >>>>> * Setter to set the value of the field in the parent object > > > >>>>> declared with the > > > >>>>> * Property object > > > >>>>> * @param newValue F new value of this field */ public void > > > >>>>> set(F newValue) { > > > >>>>> set(parent,newValue); > > > >>>>> } > > > >>>>> /** > > > >>>>> * Setter to set the value of the field to an explicit parent > > > >>>>> object. > > > >>>>> * If there is a ReadOnly annotation, then we object. If there > > > >>>>> is an explicit > > > >>>>> * setter then we use that, otherwise we set the field using the > > > >>>>> Field provided > > > >>>>> * set method and if there is a PropertyChangeSupport field, > > > >>>>> fire a property > > > >>>>> * change event to it. > > > >>>>> * We walk our way down the field chain, until we have the last > > > >>>>> object and its > > > >>>>> * field, and then we do the set. > > > >>>>> * @param parent C explicit parent object > > > >>>>> * @param newValue F new value for field in parent */ public > > > >>>>> void set(C parent,F newValue) { > > > >>>>> try { > > > >>>>> Object last = parent; > > > >>>>> int index; > > > >>>>> for(index = 0; index < fields.length - 1; index++) { > > > >>>>> > > > >>>>> if(fields[index].getType().isAnnotationPresent(WriteOnly.class)) > > > >>>>> throw new IllegalAccessException( > > > >>>>> "Can not get from a WriteOnly field - " + > > > >>>>> fields[index].getName()); > > > >>>>> Method getter = pd[index] == null ? null : > > > >>>>> pd[index].getReadMethod(); > > > >>>>> if(getter == null) last = fields[index].get(last); > > > >>>>> else last = getter.invoke(last); > > > >>>>> } > > > >>>>> > > > >>>>> if(fields[index].getType().isAnnotationPresent(ReadOnly.class)) > > > >>>>> throw new IllegalAccessException( > > > >>>>> "Can not get from a WriteOnly field - " + > > > >>>>> fields[index].getName()); > > > >>>>> Method setter = pd[index] == null ? null : > > > >>>>> pd[index].getWriteMethod(); > > > >>>>> if(setter == null) { > > > >>>>> PropertyChangeSupport pcs = > > > >>>>> findPcs(last.getClass()); fields[index].set(last,newValue); > > > >>>>> if(pcs != null) > > > >>>>> pcs.firePropertyChange(fields[index].getName(), > > > >>>>> newValue, > > > >>>>> > > > >>>>> fields[index].get(last)); > > > >>>>> } else setter.invoke(last,newValue); > > > >>>>> } catch(Exception e) { > > > >>>>> throw new RuntimeException("Should not occur > > > >>>>> exception", e); > > > >>>>> } > > > >>>>> } > > > >>>>> /** > > > >>>>> * This is used so that the caller can view the Field name > > > >>>>> * @return String field name > > > >>>>> */ > > > >>>>> public String[] getFieldName() { > > > >>>>> String[]names = new String[fields.length]; > > > >>>>> for(int index = 0; index < fields.length; index++) { > > > >>>>> names[index] = fields[index].getName(); > > > >>>>> } > > > >>>>> return names; > > > >>>>> } > > > >>>>> /** > > > >>>>> * This method is used to fetch the Field array, which is > > > >>>>> useful if you need to > > > >>>>> * access the Annotations of a field. > > > >>>>> * @return Field[] the array of Fields describing this Property. > > > >>>>> */ > > > >>>>> public Field[] getFields() { > > > >>>>> return fields; > > > >>>>> } > > > >>>>> /** > > > >>>>> * This private method looks for a PropertyChangeSupport object > > > >>>>> in the class and > > > >>>>> * if one is found it will return it. It looks right the way up > > > >>>>> the class tree > > > >>>>> * by recurring up the superClasses. > > > >>>>> * @param parent Class to check for PropertyChangeSupport fields > > > >>>>> * @return PropertyChangeSupport first found object, or null if > > > >>>>> not found */ private PropertyChangeSupport findPcs(Class > > > >>>>> parent) { > > > >>>>> Field fields[] = parent.getDeclaredFields(); > > > >>>>> for(Field field:fields) { > > > >>>>> field.setAccessible(true); > > > >>>>> try { > > > >>>>> if(field.getType() == PropertyChangeSupport.class) > > > >>>>> return (PropertyChangeSupport)field.get(parent); > > > >>>>> } catch(Exception e) { } > > > >>>>> } > > > >>>>> // If we did not find it then try the superclass > > > >>>>> ClasssuperClass = parent.getSuperclass(); > > > >>>>> if(superClass == null) return null; > > > >>>>> return findPcs(parent.getClass().getSuperclass()); > > > >>>>> } > > > >>>>> /** > > > >>>>> * This annotation is used to mark a field as WriteOnly, i.e. it > > > >>>>> can not be read. > > > >>>>> * This stops the automatic getter operation. > > > >>>>> */ > > > >>>>> public @interface WriteOnly { > > > >>>>> } > > > >>>>> /** > > > >>>>> * This annotation is used to mark a field as ReadOnly, i.e. it > > > >>>>> can not be written. > > > >>>>> * This stops the automatic setter operation. > > > >>>>> */ > > > >>>>> public @interface ReadOnly { > > > >>>>> } > > > >>>>> } From reinier at zwitserloot.com Thu Mar 5 07:18:00 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 5 Mar 2009 16:18:00 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <2B16F0B2-3463-451D-BA28-01A4D5EB4E7C@zwitserloot.com> <15e8b9d20903031847g142dc043je47dafed271f3853@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: I like the 'finally' keyword idea, but I don't think its neccessarily a good idea to call such classes 'Resources'. Is a lock a resource? (Talking about the general concept here, not any particular implementation). Not sure if that's the right term. It is feasibly something that would have a finally method? Absolutely. Micro-benchmarking is bad, but theoretically, if you wanted to, you could use an ARM-style block to do the job. That's definitely not a resource, and not neccessarily a bright idea, but I hope it gets the point across: The notion of being able to create an object, where that object gets notified if the thread exits the block, no matter how it does so, is sufficiently useful that it will be used by things that aren't neccessarily a 'Resource'. Then again, javadoc should definitely explain that you can use an instance of a class in a guarded block like that, and it'll need some sort of convenient term. "Guarded" is all I can come up with, which doesn't really sound right either. There's an established tradition in the programming world of terms taking on their own meaning. (After all, isn't "static" suggestive of 'constant', even though it has nothing to do with that? The term has been internalized as jargon). --Reinier Zwitserloot On Mar 5, 2009, at 00:17, Joshua Bloch wrote: > Tim, > Hi! > > On Wed, Mar 4, 2009 at 2:40 PM, Tim Peierls wrote: > >> I've never understood the fervor with which Java is defended from >> annotations that can change program semantics; the defenders' >> arguments >> always sound suspiciously circular. But never mind that ... I >> confess that >> even though I would have been happy with >> >> @Finally public void release() { ... } >> >> I'd much prefer >> >> public finally void release() { ... } >> > > I think it's worth adding this to the proposal as a design > alternative. The > finally modifier could appear on one and only one method. It would > have to > be a public, parameterless instance method. This would require a > (small) > class file format change, and a change to the JavaDoc tool, which > would > document that the class was a "resource," and which method was its > disposal > method. It would make the automatic resource management statement a > bit > more broadly applicable at the expense of a bit of added complexity. > > Josh > >> > From david.goodenough at linkchoose.co.uk Thu Mar 5 07:27:51 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 5 Mar 2009 15:27:51 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <0DD690C3-C084-4E80-B74A-353B2657D277@zwitserloot.com> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051031.55522.david.goodenough@linkchoose.co.uk> <0DD690C3-C084-4E80-B74A-353B2657D277@zwitserloot.com> Message-ID: <200903051527.53497.david.goodenough@linkchoose.co.uk> Rienier, Yes I know that Fields have Generics information available, but they are not used in the declaration of a Field object, and so the getter and setter to the value of the field are NOT typed, and thus can not be checked by the compiler/IDE. I do not have the knowledge to add this to the compiler, and the only documentation I have found for adding things to the compiler (as I have already mentioned) did not help - it only talked about adding operators to the compiler. The compiler is not exactly well documented or if it is, Google has been unable to furnish the right documents. The reason that it is needed is very simple. One of the big strengths of Java is that compilers and IDEs can do a really good job of detecting errors, and in the case of IDEs making suggestions as to what can come next. Using String field names in places like Bean Binding frameworks and API approaches to SQL and friends (like the JPA Criteria API) drives a coach and horses through that strength. For that reason, and the fact that this is a VERY simple suggestion, this proposal should be given serious consideration. Now if there people out there with the knowledge to help me get started in understanding what needs to be changed in Javac (I tried Remi Forax as he had already worked in this area, but he was too busy to help when I asked) I am more than happy to try to produce a working javac. But simply jumping into the source from scratch is unlikely to produce a good solution. So perhaps rather than spending our time throwing out reasons why this can not be done, lets try to work together to find a way in which is can be done. David On Thursday 05 March 2009, you wrote: > I think you'll need to spend some more time getting familiar with the > JLS. > > For example, Field objects *DO* have generics information. That's what > Field.getGenericType() is for. > > I -really- doubt you'll get anywhere with your proposal unless you do > both of the following: > > - impress everybody with an exceedingly complete proposal along with > a prototype implementation of javac. Which is going to take a lot more > working knowledge of the JLS and how javac parses source files than > you currently have. > > - either a grassroots campaign of many java programmers that > vindicates your insinuation that properties are so important, they > need to be added to java7, even with this bandaid solution, or > alternatively, convince a number of property evangelising people in > the java community to openly speak in favour of this proposal. > > I imagine that's going to cost you a week or 5 at the very least of > your time, including getting more familiar with the JLS. March is > going to be over by then. > > --Reinier Zwitserloot > > On Mar 5, 2009, at 11:31, David Goodenough wrote: > > Thinking further about this, there is a problem with using Field > > objects. > > > > Field objects predate Generics, and so the getter/setter that it > > provides > > is not one that the compiler/IDE can check. This is real problem and > > undermines one of the important drivers for this proposal. > > > > Now one could rewrite Field to require Generics, but that would break > > so much code that is is not something I would want to contemplate. > > In addition applying that to Methods would be well neigh impossible. > > > > There is a further problem, which is that as I read it the FCM > > proposal > > is only for a single Field object, where my Property object actually > > holds a Field array, so that it can handle Foo#bar#ali. > > > > All in all, I think that introducing a new class (my Property class) > > solves > > both the problems, not breaking any existing code and building > > something > > that is type safe and checkable and that FCM could subsequently build > > upon. > > > > David > > > > On Wednesday 04 March 2009, David Goodenough wrote: > >> On Wednesday 04 March 2009, Roel Spilker wrote: > >>> In your proposal, foo#bar would be translated by the compiler > >>> into: new > >>> Property(foo,"bar"); > >>> > >>> But I think you should split your proposal into two parts. The > >>> first part > >>> is using the Foo#bar syntax to be a field literal for the field > >>> "bar" in > >>> the type "Foo". This is similar to the FCM proposal > >>> (http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc). So it would be a > >>> java.lang.reflect.Field literal. > >>> > >>> The second part would be a proposal to build properties using field > >>> literals. > >>> > >>> I give the field literal proposal a chance to be included. > >>> > >>> Roel > >> > >> I would not be unhappy with that, if were it possible. But I think > >> that > >> due to the way that Field objects are represented in the class file > >> (in an > >> odd binary format) and then constructed at run time, that this > >> would not be > >> possible. It is important (for things like accessing Annotations) > >> that we > >> get the REAL Field object, and not a partial copy or lookalike. > >> > >> If someone can come up with a way of doing that I would be delighted. > >> > >> David > >> > >>> -----Oorspronkelijk bericht----- > >>> Van: david.goodenough at linkchoose.co.uk > >>> [mailto:coin-dev-bounces at openjdk.java.net] Namens David Goodenough > >>> Verzonden: woensdag 4 maart 2009 10:50 > >>> Aan: coin-dev at openjdk.java.net > >>> Onderwerp: Re: PROPOSAL: Lightweight Properties > >>> > >>> I am not sure that we would loose anything. The important thing > >>> is to > >>> have an IDE/compiler checkable way of generating Property objects, > >>> and > >>> having two ways of generating them is not really a problem. My > >>> Property > >>> object would happily detect either an explicitly generated getter/ > >>> setter > >>> or one generated for you by a property keyword. The property > >>> keyword > >>> would resolve other things (like the automatic generation of > >>> PropertyChangeSupport, and the controlling of visibility) but it > >>> is still > >>> building on the same basic concept. > >>> > >>> If you don't want to use # then the work needed for the compiler > >>> gets > >>> more complicated (I think). One could use a sort of compiler > >>> function, > >>> so one would say property(foo.bar) and it would modify the > >>> function of . > >>> inside the function. > >>> > >>> I really want to find a way to get something into Java 7, > >>> otherwise we > >>> are looking to Java 8 (which is at least 3 years away if current > >>> timescales persist), by which time I suspect that everyone will have > >>> gotten bored and gone to find pastures new. > >>> > >>> David > >>> > >>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >>>> But it seems that we _would_ lose a thing or two with this > >>>> proposal. > >>>> For example, if a complete properties proposal supports full > >>>> backwards > >>>> compatibility and generates getters and setters, then we have a > >>>> bunch > >>>> of code around that uses the foo#bar notation, which is by then > >>>> already outdated, and would in fact get in the way of using foo#bar > >>>> notation as a shorthand for calling the appropriate getter/ > >>>> setter. I > >>>> don't know if that is a desired syntax sugar, but the point is: > >>>> Your > >>>> proposal would effectively make it impossible to add that later, > >>>> as it > >>>> would already be shorthand for creating a Property object. > >>>> > >>>> The # and the backtick are the only easily typed symbols that > >>>> have no > >>>> meaning whatsoever in java right now. Using one up for an > >>>> simplified > >>>> properties proposal is another serious disdvantage. I don't think > >>>> your > >>>> proposal makes property support light enough to warrant its > >>>> inclusion > >>>> in project coin. That's not to say I have something against > >>>> properties; on the contrary, I love the idea and I'm very impressed > >>>> with the way properties work in JavaFX. All the more reason to > >>>> get it > >>>> right instead of using a bandage. > >>>> > >>>> --Reinier Zwitserloot > >>>> > >>>> On Mar 3, 2009, at 23:00, David Goodenough wrote: > >>>>> Well that depends on what you mean by a complete proposal. > >>>>> > >>>>> There are two parts to the use of Properties. There is the > >>>>> framework side, inside BeansBinding or JPA and then there is the > >>>>> consumer side, the application code. > >>>>> > >>>>> My proposal is very simple on the consumer side (the only bit > >>>>> needed > >>>>> is the # notation). You can use clasical getters and setters (a > >>>>> nuisance but everyone understands them), or the simple getter/ > >>>>> setter > >>>>> mechanism that my Property provides. So for the consumer my > >>>>> proposal is real simple. All you need do is add (either explicity > >>>>> or by byte code > >>>>> enhancement) > >>>>> a PropertyChangeSupport object and the relevant methods and you > >>>>> are > >>>>> home and dry. > >>>>> > >>>>> For the Frameworks, well you only write them once. Even so > >>>>> something nice and simple appeals and my proposal is simple. > >>>>> > >>>>> It may not be Beans as we know it, but they never were integrated > >>>>> properly into Java. But its really not that dissimilar just > >>>>> slightly different. > >>>>> > >>>>> So other than a little sytactic sugar (not having to code the > >>>>> PropertyChangeSupport object) we have not really lost anything of > >>>>> the "full" solution. Having a Bound annotation which would add > >>>>> this > >>>>> under the covers with a byte code enhancer would not be difficult. > >>>>> The implicit getters and setters come with the package. So the > >>>>> question to be asked whether a fuller solution is really needed. > >>>>> > >>>>> David > >>>>> > >>>>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >>>>>> The language change required for your proposal is indeed lighter, > >>>>>> but to understand it, it is seems a lot more complicated. > >>>>>> > >>>>>> Also, it would be infeasible to introduce a 'lightweight' > >>>>>> (according to anyone's definition) proposal now that is lacking > >>>>>> in > >>>>>> certain aspects, and then fix it later, unless that fix is > >>>>>> syntactically very similar and backwards- and migration > >>>>>> compatible. > >>>>>> That's the major beef I have with this proposal: It effectively > >>>>>> shuts the door on any other property proposal. In my view, a > >>>>>> proposal solves the problem properly, or shouldn't be added at > >>>>>> all; > >>>>>> no quick hacky fixes that aren't part of a planned evolution path > >>>>>> to a complete solution. > >>>>>> > >>>>>> If you can highlight how a complete properties proposal will > >>>>>> seamlessly work with your syntax, I'm more inclined to like it. > >>>>>> > >>>>>> --Reinier Zwitserloot > >>>>>> > >>>>>> On Mar 3, 2009, at 22:04, David Goodenough wrote: > >>>>>>> Yes I do. What you propose is much more invasive. Look at it > >>>>>>> again and maybe you will see the Light(ness). > >>>>>>> > >>>>>>> David > >>>>>>> > >>>>>>> On Tuesday 03 March 2009, Reinier Zwitserloot wrote: > >>>>>>>> You call that lightweight? > >>>>>>>> > >>>>>>>> How about following the beans spec more to the letter and just > >>>>>>>> generate the addPropertyChangeListener, > >>>>>>>> removePropertyChangeListener, setX(), and get/isX() method in > >>>>>>>> response to seeing a keyword or annotation on a given field. > >>>>>>>> You'll have to work out the details, but that sounds far, far > >>>>>>>> simpler to understand. > >>>>>>>> > >>>>>>>> You'll need to flesh this out, but it would look something > >>>>>>>> like: > >>>>>>>> > >>>>>>>> public class Foo { > >>>>>>>> private property int x; > >>>>>>>> } > >>>>>>>> > >>>>>>>> Which would generate the addPropertyChangeListener, > >>>>>>>> removePropertyChangeListener, setX, getX methods, all public, > >>>>>>>> along with the required infrastructure to make it tick. If you > >>>>>>>> don't like the generation, for example because you want the > >>>>>>>> setter to be package private, you just add the setter in the > >>>>>>>> source file; the keyword will only generate the missing > >>>>>>>> stuff. It > >>>>>>>> doesn't cover every use case, but there's always the > >>>>>>>> alternative > >>>>>>>> of doing whatever people do now with beans. Something you > >>>>>>>> didn't > >>>>>>>> mention in your proposal, by the way. > >>>>>>>> > >>>>>>>> I think there's also a fully fleshed out property proposal > >>>>>>>> (including a 'property' keyword) out there somewhere. > >>>>>>>> > >>>>>>>> Possibly make a way to opt out of generating the property > >>>>>>>> change > >>>>>>>> listener support, and just the getters/setters. > >>>>>>>> --Reinier Zwitserloot > >>>>>>>> > >>>>>>>> On Mar 3, 2009, at 15:59, David Goodenough wrote: > >>>>>>>>> Below is my proposal for Lightweight Properties. I know that > >>>>>>>>> the syntax change is an abbomination to some people, but I > >>>>>>>>> have > >>>>>>>>> tried to reduce this to its absolute minimum, while still > >>>>>>>>> getting a significant benefit. > >>>>>>>>> > >>>>>>>>> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >>>>>>>>> > >>>>>>>>> AUTHOR(S): > >>>>>>>>> > >>>>>>>>> David Goodenough, long time Java user. I can be reached at > >>>>>>>>> david.goodenough at linkchoose.co.uk. > >>>>>>>>> > >>>>>>>>> OVERVIEW > >>>>>>>>> > >>>>>>>>> FEATURE SUMMARY: > >>>>>>>>> > >>>>>>>>> Lightweight Property support > >>>>>>>>> > >>>>>>>>> MAJOR ADVANTAGE: > >>>>>>>>> > >>>>>>>>> Both BeansBinding (whether JSR-295 or others such an JFace or > >>>>>>>>> the JGoodies > >>>>>>>>> binding) and the JPA Criteria API currently require field > >>>>>>>>> names > >>>>>>>>> (as > >>>>>>>>> Strings) > >>>>>>>>> as arguments, which an IDE/compiler can not check. With this > >>>>>>>>> proposal the strings would be abandoned, and the IDE/compiler > >>>>>>>>> will be able to check the correctness of the code. > >>>>>>>>> > >>>>>>>>> MAJOR BENEFIT: > >>>>>>>>> > >>>>>>>>> Manual checking no longer required. This proposal introduces a > >>>>>>>>> simple well defined IDE/compiler checkable solution. > >>>>>>>>> > >>>>>>>>> MAJOR DISADVANTAGE: > >>>>>>>>> > >>>>>>>>> It is a language change, and this seems to upset some people. > >>>>>>>>> > >>>>>>>>> ALTERNATIVES: > >>>>>>>>> > >>>>>>>>> None really, apart from using another language or continuing > >>>>>>>>> to > >>>>>>>>> use String names. The existing solutions all require String > >>>>>>>>> names which are uncheckable. > >>>>>>>>> > >>>>>>>>> EXAMPLES > >>>>>>>>> > >>>>>>>>> Lets assume we have a POJO called foo, of type Foo with a > >>>>>>>>> field > >>>>>>>>> bar of type Bar, which itself has a field of type Jim called > >>>>>>>>> jim. > >>>>>>>>> > >>>>>>>>> There are two forms of lightweight properties:- > >>>>>>>>> > >>>>>>>>> 1) foo#bar would be translated by the compiler into:- > >>>>>>>>> > >>>>>>>>> new Property(foo,"bar"); > >>>>>>>>> > >>>>>>>>> while foo#bar#jim would be translated into:- > >>>>>>>>> > >>>>>>>>> new Property(foo,"bar","jim"); > >>>>>>>>> > >>>>>>>>> 2) Foo#bar would be translated into:- > >>>>>>>>> > >>>>>>>>> new Property(Foo.class,"bar"); > >>>>>>>>> > >>>>>>>>> while Foo#bar#jim would be translated into:- > >>>>>>>>> > >>>>>>>>> new Property(Foo.class,"bar","jim"); > >>>>>>>>> > >>>>>>>>> These two forms create (1) a bound Property, or (2) an unbound > >>>>>>>>> one. > >>>>>>>>> Bound > >>>>>>>>> Properties are explicitly bound to a particular instance of a > >>>>>>>>> class (in this case foo), while unbound Properties are > >>>>>>>>> templates > >>>>>>>>> which can be applied to any instance of class Foo. Actually > >>>>>>>>> bound properties can also be used as unbound properties, but > >>>>>>>>> that is a harmless and useful side effect not a primary > >>>>>>>>> intent. > >>>>>>>>> > >>>>>>>>> The Property class would need to be added (it is appended > >>>>>>>>> below), and should be added either to the java.beans package > >>>>>>>>> or > >>>>>>>>> to the java.lang.reflect package (with which is probably has > >>>>>>>>> more in common). > >>>>>>>>> > >>>>>>>>> Syntactically a "#" can be placed wherever a "." can be placed > >>>>>>>>> (except inside a number), and the same checks need to be made > >>>>>>>>> (that each field to the right of a # is a field in the left > >>>>>>>>> hand > >>>>>>>>> side) as would be made for a ".". > >>>>>>>>> The only > >>>>>>>>> difference is in field visibility - For the "#" any field is > >>>>>>>>> visible, which follows the model currently available in the > >>>>>>>>> Field class with getDeclaredFields(). It also follows the > >>>>>>>>> model > >>>>>>>>> that while a field might be private and therefore not directly > >>>>>>>>> accessible from outside, getters and setters can provide > >>>>>>>>> access. > >>>>>>>>> > >>>>>>>>> The Property object provides type safe access to the field in > >>>>>>>>> the form of getters and setters. These come in pairs, one for > >>>>>>>>> bound and the other for unbound access. So for bound access no > >>>>>>>>> object is required to fetch the value, for an unbound object > >>>>>>>>> the > >>>>>>>>> parent object needs to be specified. > >>>>>>>>> So if > >>>>>>>>> we > >>>>>>>>> have:- > >>>>>>>>> > >>>>>>>>> Propertyprop = foo#bar; > >>>>>>>>> > >>>>>>>>> we can later say:- > >>>>>>>>> > >>>>>>>>> Bar b = prop.get(); > >>>>>>>>> > >>>>>>>>> or for an unbound one from a second Foo object foo2:- > >>>>>>>>> > >>>>>>>>> Bar b = prop.get(foo2); > >>>>>>>>> > >>>>>>>>> The getters and setters in the Property object will defer to > >>>>>>>>> explicitly coded getters and setters if present, otherwise > >>>>>>>>> they > >>>>>>>>> will use the Field getter and setter. > >>>>>>>>> > >>>>>>>>> If a setter is not explicitly coded, the implicit setter will > >>>>>>>>> look for a PropertyChangeSupport object in the parent object > >>>>>>>>> of > >>>>>>>>> the rightmost field and fire a PropertyChangeEvent to that > >>>>>>>>> object. > >>>>>>>>> > >>>>>>>>> There are also two Annotations provided by the Property class, > >>>>>>>>> ReadOnly and WriteOnly. These stop implicit getters and > >>>>>>>>> setters > >>>>>>>>> from trying to read/write the property. > >>>>>>>>> > >>>>>>>>> Talking of Annotations, this notation can also be used to > >>>>>>>>> get at > >>>>>>>>> the Annotations for a field. So to test for the presence of an > >>>>>>>>> Annotation Ann on Foo.bar we would use:- > >>>>>>>>> > >>>>>>>>> if(Foo#bar.getFields()[0].isAnnotationPresent(Ann.class)) ... > >>>>>>>>> > >>>>>>>>> SIMPLE EXAMPLE: > >>>>>>>>> > >>>>>>>>> To take an example from BeansBinding (taken from Shannon > >>>>>>>>> Hickey's > >>>>>>>>> blog):- > >>>>>>>>> > >>>>>>>>> // create a BeanProperty representing a bean's firstName > >>>>>>>>> Property firstP = BeanProperty.create("firstName"); > >>>>>>>>> // Bind Duke's first name to the text property of a Swing > >>>>>>>>> JTextField > >>>>>>>>> BeanProperty textP = BeanProperty.create("text"); > >>>>>>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>>>>>>>> duke, > >>>>>>>>> firstP, textfield, textP); > >>>>>>>>> binding.bind(); > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> would instead be written:- > >>>>>>>>> > >>>>>>>>> Binding binding = Bindings.createAutoBinding(READ_WRITE, > >>>>>>>>> duke#firstName, textfield#text); > >>>>>>>>> binding.bind(); > >>>>>>>>> > >>>>>>>>> which of course can be checked by the IDE/compiler, and will > >>>>>>>>> not > >>>>>>>>> wait until run time (not even instantiation time) to show up > >>>>>>>>> the > >>>>>>>>> error. > >>>>>>>>> > >>>>>>>>> ADVANCED EXAMPLE: > >>>>>>>>> > >>>>>>>>> For a JComboBox (or JList or JTable or JTree) there is a > >>>>>>>>> need to > >>>>>>>>> map a list of objects to the value strings (or column > >>>>>>>>> contents). > >>>>>>>>> For this we need to have an unbound Property which can be > >>>>>>>>> applied to each element of the list. > >>>>>>>>> > >>>>>>>>> Duke duke; > >>>>>>>>> Listdukes; > >>>>>>>>> BoundComboBox combo = new > >>>>>>>>> BoundComboBox(dukes,Duke#fullname,this#duke); > >>>>>>>>> > >>>>>>>>> and now the combo box will be populated from the list dukes, > >>>>>>>>> and > >>>>>>>>> the display values in the list will be taken from the fullname > >>>>>>>>> field of each Duke element, and the initial value will be set > >>>>>>>>> from the local class field duke and any changes to the combo > >>>>>>>>> box > >>>>>>>>> selected element will be reflected back to the duke field. > >>>>>>>>> > >>>>>>>>> DETAILS > >>>>>>>>> > >>>>>>>>> SPECIFICATION: > >>>>>>>>> > >>>>>>>>> This proposal adds a new syntactic element, "#", which can be > >>>>>>>>> used in the same way that "." can be used to qualify fields > >>>>>>>>> within a Java object. > >>>>>>>>> > >>>>>>>>> COMPILATION: > >>>>>>>>> > >>>>>>>>> This proposal requires no change to the class files, and is > >>>>>>>>> implemented by a simple generation of the required instance > >>>>>>>>> using the relevant Property constructor. Obviously the > >>>>>>>>> compiler > >>>>>>>>> would have to make sure that the use that the property object > >>>>>>>>> was being put to (in the examples above the left hand side of > >>>>>>>>> the assignment) had the correct Generic attributes. > >>>>>>>>> > >>>>>>>>> TESTING: > >>>>>>>>> > >>>>>>>>> How can the feature be tested? > >>>>>>>>> > >>>>>>>>> LIBRARY SUPPORT: > >>>>>>>>> > >>>>>>>>> The new Property class is required (see below). > >>>>>>>>> > >>>>>>>>> REFLECTIVE APIS: > >>>>>>>>> > >>>>>>>>> No changes are required to the reflective APIs although it > >>>>>>>>> makes > >>>>>>>>> extensive use of those APIs. > >>>>>>>>> > >>>>>>>>> OTHER CHANGES: > >>>>>>>>> > >>>>>>>>> No other changes are requires. > >>>>>>>>> > >>>>>>>>> MIGRATION: > >>>>>>>>> > >>>>>>>>> Fortunately there is no code that is formally part of J2SE 6 > >>>>>>>>> which uses such Properties. There are however two proposals > >>>>>>>>> which will need it (BeansBinding and JPA Criteria API), but > >>>>>>>>> neither of these seem to be destined to be part of J2SE 7 > >>>>>>>>> (BeansBinding seems to have died the death and the Criteria > >>>>>>>>> API > >>>>>>>>> would be part of the next J2EE which will follow J2SE 7), so > >>>>>>>>> this will provide a base for them to use and no existing code > >>>>>>>>> need to be updated. > >>>>>>>>> > >>>>>>>>> There are other extant Beans-Binding libraries, which could be > >>>>>>>>> modified to use this proposal, but as none of the existing > >>>>>>>>> features have been changed there is no need to change them > >>>>>>>>> (other than for type safety and compiler/ IDE checkability). > >>>>>>>>> > >>>>>>>>> COMPATIBILITY > >>>>>>>>> > >>>>>>>>> BREAKING CHANGES: > >>>>>>>>> > >>>>>>>>> None. This change should not make any existing correct code > >>>>>>>>> fail to compile or run or change the way in which it > >>>>>>>>> compiles/runs. > >>>>>>>>> > >>>>>>>>> EXISTING PROGRAMS: > >>>>>>>>> > >>>>>>>>> No change required to any existing programs > >>>>>>>>> > >>>>>>>>> REFERENCES > >>>>>>>>> > >>>>>>>>> EXISTING BUGS: > >>>>>>>>> > >>>>>>>>> None > >>>>>>>>> > >>>>>>>>> URL FOR PROTOTYPE (optional): > >>>>>>>>> > >>>>>>>>> I do not have the knowledge to make changes to the compiler, > >>>>>>>>> and > >>>>>>>>> the only documentation making such changes concentrated on > >>>>>>>>> adding operators not changes at this level. So there is no > >>>>>>>>> prototype of the compiler part, but the Property class > >>>>>>>>> follows:- > >>>>>>>>> > >>>>>>>>> package java.lang.reflect; > >>>>>>>>> > >>>>>>>>> import java.beans.BeanInfo; > >>>>>>>>> import java.beans.Introspector; > >>>>>>>>> import java.beans.PropertyChangeSupport; import > >>>>>>>>> java.beans.PropertyDescriptor; import java.lang.reflect.Field; > >>>>>>>>> import java.lang.reflect.Method; > >>>>>>>>> > >>>>>>>>> /** > >>>>>>>>> * Property class > >>>>>>>>> * This is the support class for use with the # notation to > >>>>>>>>> provide lightweight > >>>>>>>>> * Property support for Java. > >>>>>>>>> * > >>>>>>>>> * @copyright Copyright(C) 2009 David Goodenough Linkchoose Ltd > >>>>>>>>> * @licence LPGL V2 : details of which can be found at http:// > >>>>>>>>> fsf.org. > >>>>>>>>> * @author david.goodenough at linkchoose.co.uk > >>>>>>>>> * > >>>>>>>>> * @param The Parent class for this field > >>>>>>>>> * @param The Type of this field */ public class > >>>>>>>>> Property { private C parent; private Class > >>>>>>>>> parentClass; > >>>>>>>>> private Field[] fields; private PropertyDescriptor[] pd = > >>>>>>>>> null; > >>>>>>>>> /** > >>>>>>>>> * Constructor used to create Property objects. The Parent > >>>>>>>>> object may be > >>>>>>>>> * null, but should normally be specified as it can be > >>>>>>>>> overridden anyway. > >>>>>>>>> * @param parent C object that contains the field > >>>>>>>>> * @param field Field describing this field */ public > >>>>>>>>> Property(C parent, String ... fieldNames) { > >>>>>>>>> this.parent = parent; > >>>>>>>>> this(parent.getClass(), fieldNames); > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * Constructor for unbound Properties, but also used > >>>>>>>>> internally > >>>>>>>>> after setting > >>>>>>>>> * the parent object by the bound Property objects. > >>>>>>>>> * @param parentClass Class of the parent object > >>>>>>>>> * @param fieldNames String[] of field names > >>>>>>>>> */ > >>>>>>>>> public Property(ClassparentClass, String .. fieldNames) { > >>>>>>>>> this.parentClass = parentClass; > >>>>>>>>> fields = new Field[fieldNames.length]; > >>>>>>>>> pd = new PropertyDescriptor[fieldNames.length]; > >>>>>>>>> outer: for(int index = 0; index < fields.length; index++) { > >>>>>>>>> Field[]dclFields = parentClass.getDeclaredFields(); > >>>>>>>>> for(Field field:dclFields) { > >>>>>>>>> if(field.getName().equals(fieldNames[index])) { > >>>>>>>>> fields[index] = field; > >>>>>>>>> field.setAccessible(true); > >>>>>>>>> try { > >>>>>>>>> BeanInfo beanInfo = > >>>>>>>>> Introspector.getBeanInfo(parent.getClass()); > >>>>>>>>> PropertyDescriptor[]props = > >>>>>>>>> beanInfo.getPropertyDescriptors(); > >>>>>>>>> for(PropertyDescriptor prop : props) { > >>>>>>>>> if(prop.getName().equals(field.getName())) { > >>>>>>>>> pd[index] = prop; > >>>>>>>>> break; > >>>>>>>>> } > >>>>>>>>> } > >>>>>>>>> } catch(Exception e) { /* assume can not find > >>>>>>>>> getter/ > >>>>>>>>> setter */ } > >>>>>>>>> parentClass = field.getType(); > >>>>>>>>> continue outer; > >>>>>>>>> } > >>>>>>>>> } > >>>>>>>>> throw new IllegalArgumentException("Field " + > >>>>>>>>> fieldNames[index] > >>>>>>>>> + " not found in class " + > >>>>>>>>> parentClass.getCanonicalName()); > >>>>>>>>> } > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * Getter from the field in the parent specified when this > >>>>>>>>> Property was created. > >>>>>>>>> * @see Property.get(C otherParent) > >>>>>>>>> * @return F the value of this field */ public F get() { > >>>>>>>>> return get(parent); > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * Getter with explicit parent. > >>>>>>>>> * This code will check see if this field is WriteOnly, and > >>>>>>>>> complain if it is. > >>>>>>>>> * It will then see if the use has provided am explicit getter, > >>>>>>>>> and call that > >>>>>>>>> * if present, otherwise it will just fetch the value through > >>>>>>>>> the Field provided > >>>>>>>>> * method. > >>>>>>>>> * @param otherParent C parent object > >>>>>>>>> * @return F value of the field > >>>>>>>>> */ > >>>>>>>>> @SuppressWarnings("unchecked") // This should actually not be > >>>>>>>>> needed, > >>>>>>>>> // but the Field.get method is > >>>>>>>>> not typed public F get(C otherParent) { > >>>>>>>>> Object result = otherParent; > >>>>>>>>> try { > >>>>>>>>> for(int index = 0; index < fields.length; index++) { > >>>>>>>>> > >>>>>>>>> if > >>>>>>>>> (fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>>>>>> throw new IllegalAccessException( > >>>>>>>>> "Can not get from a WriteOnly field - " + > >>>>>>>>> fields[index].getName()); > >>>>>>>>> Method getter = pd[index] == null ? null : > >>>>>>>>> pd[index].getReadMethod(); > >>>>>>>>> if(getter == null) result = fields[index].get(result); > >>>>>>>>> else result = getter.invoke(result); > >>>>>>>>> } > >>>>>>>>> } catch(Exception e) { > >>>>>>>>> throw new RuntimeException("Should not occur exception", e); > >>>>>>>>> } > >>>>>>>>> return (F)result; > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * Setter to set the value of the field in the parent object > >>>>>>>>> declared with the > >>>>>>>>> * Property object > >>>>>>>>> * @param newValue F new value of this field */ public void > >>>>>>>>> set(F newValue) { > >>>>>>>>> set(parent,newValue); > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * Setter to set the value of the field to an explicit parent > >>>>>>>>> object. > >>>>>>>>> * If there is a ReadOnly annotation, then we object. If there > >>>>>>>>> is an explicit > >>>>>>>>> * setter then we use that, otherwise we set the field using > >>>>>>>>> the > >>>>>>>>> Field provided > >>>>>>>>> * set method and if there is a PropertyChangeSupport field, > >>>>>>>>> fire a property > >>>>>>>>> * change event to it. > >>>>>>>>> * We walk our way down the field chain, until we have the last > >>>>>>>>> object and its > >>>>>>>>> * field, and then we do the set. > >>>>>>>>> * @param parent C explicit parent object > >>>>>>>>> * @param newValue F new value for field in parent */ public > >>>>>>>>> void set(C parent,F newValue) { > >>>>>>>>> try { > >>>>>>>>> Object last = parent; > >>>>>>>>> int index; > >>>>>>>>> for(index = 0; index < fields.length - 1; index++) { > >>>>>>>>> > >>>>>>>>> if > >>>>>>>>> (fields[index].getType().isAnnotationPresent(WriteOnly.class)) > >>>>>>>>> throw new IllegalAccessException( > >>>>>>>>> "Can not get from a WriteOnly field - " + > >>>>>>>>> fields[index].getName()); > >>>>>>>>> Method getter = pd[index] == null ? null : > >>>>>>>>> pd[index].getReadMethod(); > >>>>>>>>> if(getter == null) last = fields[index].get(last); > >>>>>>>>> else last = getter.invoke(last); > >>>>>>>>> } > >>>>>>>>> > >>>>>>>>> if > >>>>>>>>> (fields[index].getType().isAnnotationPresent(ReadOnly.class)) > >>>>>>>>> throw new IllegalAccessException( > >>>>>>>>> "Can not get from a WriteOnly field - " + > >>>>>>>>> fields[index].getName()); > >>>>>>>>> Method setter = pd[index] == null ? null : > >>>>>>>>> pd[index].getWriteMethod(); > >>>>>>>>> if(setter == null) { > >>>>>>>>> PropertyChangeSupport pcs = > >>>>>>>>> findPcs(last.getClass()); fields[index].set(last,newValue); > >>>>>>>>> if(pcs != null) > >>>>>>>>> pcs.firePropertyChange(fields[index].getName(), > >>>>>>>>> newValue, > >>>>>>>>> > >>>>>>>>> fields[index].get(last)); > >>>>>>>>> } else setter.invoke(last,newValue); > >>>>>>>>> } catch(Exception e) { > >>>>>>>>> throw new RuntimeException("Should not occur > >>>>>>>>> exception", e); > >>>>>>>>> } > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * This is used so that the caller can view the Field name > >>>>>>>>> * @return String field name > >>>>>>>>> */ > >>>>>>>>> public String[] getFieldName() { > >>>>>>>>> String[]names = new String[fields.length]; > >>>>>>>>> for(int index = 0; index < fields.length; index++) { > >>>>>>>>> names[index] = fields[index].getName(); > >>>>>>>>> } > >>>>>>>>> return names; > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * This method is used to fetch the Field array, which is > >>>>>>>>> useful if you need to > >>>>>>>>> * access the Annotations of a field. > >>>>>>>>> * @return Field[] the array of Fields describing this > >>>>>>>>> Property. > >>>>>>>>> */ > >>>>>>>>> public Field[] getFields() { > >>>>>>>>> return fields; > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * This private method looks for a PropertyChangeSupport object > >>>>>>>>> in the class and > >>>>>>>>> * if one is found it will return it. It looks right the way > >>>>>>>>> up > >>>>>>>>> the class tree > >>>>>>>>> * by recurring up the superClasses. > >>>>>>>>> * @param parent Class to check for PropertyChangeSupport > >>>>>>>>> fields > >>>>>>>>> * @return PropertyChangeSupport first found object, or null if > >>>>>>>>> not found */ private PropertyChangeSupport findPcs(Class > >>>>>>>>> parent) { > >>>>>>>>> Field fields[] = parent.getDeclaredFields(); > >>>>>>>>> for(Field field:fields) { > >>>>>>>>> field.setAccessible(true); > >>>>>>>>> try { > >>>>>>>>> if(field.getType() == PropertyChangeSupport.class) > >>>>>>>>> return (PropertyChangeSupport)field.get(parent); > >>>>>>>>> } catch(Exception e) { } > >>>>>>>>> } > >>>>>>>>> // If we did not find it then try the superclass > >>>>>>>>> ClasssuperClass = parent.getSuperclass(); > >>>>>>>>> if(superClass == null) return null; > >>>>>>>>> return findPcs(parent.getClass().getSuperclass()); > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * This annotation is used to mark a field as WriteOnly, i.e. > >>>>>>>>> it > >>>>>>>>> can not be read. > >>>>>>>>> * This stops the automatic getter operation. > >>>>>>>>> */ > >>>>>>>>> public @interface WriteOnly { > >>>>>>>>> } > >>>>>>>>> /** > >>>>>>>>> * This annotation is used to mark a field as ReadOnly, i.e. it > >>>>>>>>> can not be written. > >>>>>>>>> * This stops the automatic setter operation. > >>>>>>>>> */ > >>>>>>>>> public @interface ReadOnly { > >>>>>>>>> } > >>>>>>>>> } From develop4lasu at gmail.com Thu Mar 5 08:41:02 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 5 Mar 2009 17:41:02 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903051527.53497.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051031.55522.david.goodenough@linkchoose.co.uk> <0DD690C3-C084-4E80-B74A-353B2657D277@zwitserloot.com> <200903051527.53497.david.goodenough@linkchoose.co.uk> Message-ID: <28bca0ff0903050841n7751a3d0yfc268b408b071475@mail.gmail.com> 2009/3/5 David Goodenough > Rienier, > > Yes I know that Fields have Generics information available, but they are > not used in the declaration of a Field object, and so the getter and > setter to the value of the field are NOT typed, and thus can not be > checked by the compiler/IDE. > > I do not have the knowledge to add this to the compiler, and the only > documentation I have found for adding things to the compiler (as I > have already mentioned) did not help - it only talked about adding > operators to the compiler. The compiler is not exactly well documented > or if it is, Google has been unable to furnish the right documents. > > The reason that it is needed is very simple. One of the big strengths > of Java is that compilers and IDEs can do a really good job of detecting > errors, and in the case of IDEs making suggestions as to what can come > next. Using String field names in places like Bean Binding frameworks > and API approaches to SQL and friends (like the JPA Criteria API) drives > a coach and horses through that strength. For that reason, and the fact > that this is a VERY simple suggestion, this proposal should be given > serious consideration. > > Now if there people out there with the knowledge to help me get started > in understanding what needs to be changed in Javac (I tried Remi Forax > as he had already worked in this area, but he was too busy to help when > I asked) I am more than happy to try to produce a working javac. But > simply jumping into the source from scratch is unlikely to produce a good > solution. > > So perhaps rather than spending our time throwing out reasons why this > can not be done, lets try to work together to find a way in which is can > be done. > > David > > On Thursday 05 March 2009, you wrote: > > I think you'll need to spend some more time getting familiar with the > > JLS. > > > > For example, Field objects *DO* have generics information. That's what > > Field.getGenericType() is for. > > > > I -really- doubt you'll get anywhere with your proposal unless you do > > both of the following: > > > > - impress everybody with an exceedingly complete proposal along with > > a prototype implementation of javac. Which is going to take a lot more > > working knowledge of the JLS and how javac parses source files than > > you currently have. > > > > - either a grassroots campaign of many java programmers that > > vindicates your insinuation that properties are so important, they > > need to be added to java7, even with this bandaid solution, or > > alternatively, convince a number of property evangelising people in > > the java community to openly speak in favour of this proposal. > > > > I imagine that's going to cost you a week or 5 at the very least of > > your time, including getting more familiar with the JLS. March is > > going to be over by then. > > > > --Reinier Zwitserloot > > > I do not see the problem you have. If you have 'static' name of field (only then compiler can check it) then you can simply use field. If u do not have that information (it's dynamic) then also compiler is unable to determine it's type before execution. That why I do not see why we need any other solution than linking 'Fields' with fields to make it refactor friendly and easy to use. Am I wrong? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Thu Mar 5 09:09:44 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 5 Mar 2009 17:09:44 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <28bca0ff0903050841n7751a3d0yfc268b408b071475@mail.gmail.com> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051527.53497.david.goodenough@linkchoose.co.uk> <28bca0ff0903050841n7751a3d0yfc268b408b071475@mail.gmail.com> Message-ID: <200903051709.46250.david.goodenough@linkchoose.co.uk> On Thursday 05 March 2009, Marek Kozie? wrote: > 2009/3/5 David Goodenough > > > Rienier, > > > > Yes I know that Fields have Generics information available, but they are > > not used in the declaration of a Field object, and so the getter and > > setter to the value of the field are NOT typed, and thus can not be > > checked by the compiler/IDE. > > > > I do not have the knowledge to add this to the compiler, and the only > > documentation I have found for adding things to the compiler (as I > > have already mentioned) did not help - it only talked about adding > > operators to the compiler. The compiler is not exactly well documented > > or if it is, Google has been unable to furnish the right documents. > > > > The reason that it is needed is very simple. One of the big strengths > > of Java is that compilers and IDEs can do a really good job of detecting > > errors, and in the case of IDEs making suggestions as to what can come > > next. Using String field names in places like Bean Binding frameworks > > and API approaches to SQL and friends (like the JPA Criteria API) drives > > a coach and horses through that strength. For that reason, and the fact > > that this is a VERY simple suggestion, this proposal should be given > > serious consideration. > > > > Now if there people out there with the knowledge to help me get started > > in understanding what needs to be changed in Javac (I tried Remi Forax > > as he had already worked in this area, but he was too busy to help when > > I asked) I am more than happy to try to produce a working javac. But > > simply jumping into the source from scratch is unlikely to produce a good > > solution. > > > > So perhaps rather than spending our time throwing out reasons why this > > can not be done, lets try to work together to find a way in which is can > > be done. > > > > David > > > > On Thursday 05 March 2009, you wrote: > > > I think you'll need to spend some more time getting familiar with the > > > JLS. > > > > > > For example, Field objects *DO* have generics information. That's what > > > Field.getGenericType() is for. > > > > > > I -really- doubt you'll get anywhere with your proposal unless you do > > > both of the following: > > > > > > - impress everybody with an exceedingly complete proposal along with > > > a prototype implementation of javac. Which is going to take a lot more > > > working knowledge of the JLS and how javac parses source files than > > > you currently have. > > > > > > - either a grassroots campaign of many java programmers that > > > vindicates your insinuation that properties are so important, they > > > need to be added to java7, even with this bandaid solution, or > > > alternatively, convince a number of property evangelising people in > > > the java community to openly speak in favour of this proposal. > > > > > > I imagine that's going to cost you a week or 5 at the very least of > > > your time, including getting more familiar with the JLS. March is > > > going to be over by then. > > > > > > --Reinier Zwitserloot > > I do not see the problem you have. > > If you have 'static' name of field (only then compiler can check it) then > you can simply use field. Well no, because if you need to use an explicit getter or setter to do some extra processing or in the setter you want to fire a PropertyChangeEvent then the Field on its own is not enough. The Field setter could be extended, but as it does not know the parent object (the think of which this is a Field) it can not look for a PropertyChangeSupport object. The Field set method does not try to fire PropertyChangeEvents, and does not provide to use an explicitly coded setter. That could be got around by passing the Field object into a Property constructor, rather than the field names, but again we do not have access to the parent object which makes searching for getters and setters and PropertyChangeSupport objects rather difficult. > > If u do not have that information (it's dynamic) then also compiler is > unable to determine it's type before execution. true > > That why I do not see why we need any other solution than linking 'Fields' > with fields to make it refactor friendly and easy to use. I do not see (maybe I did not understand FCM) how I could handle foo#bar#ali. In this case you need a Field array, not just a field. Additionally the FCM case only seems to handle the Foo#bar case, not the foo#bar case. That is not the end of the world - it would work in the examples I need, but it is less than my proposal covers. > > Am I wrong? Either I have missunderstood the FCM (which is quite possible) or it does not match what my proposal offers. David From develop4lasu at gmail.com Thu Mar 5 09:25:07 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 5 Mar 2009 18:25:07 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903051709.46250.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051527.53497.david.goodenough@linkchoose.co.uk> <28bca0ff0903050841n7751a3d0yfc268b408b071475@mail.gmail.com> <200903051709.46250.david.goodenough@linkchoose.co.uk> Message-ID: <28bca0ff0903050925u21245b22lb750469e64174c05@mail.gmail.com> 2009/3/5 David Goodenough > On Thursday 05 March 2009, Marek Kozie? wrote: > > 2009/3/5 David Goodenough > > > > > Rienier, > > > > > > Yes I know that Fields have Generics information available, but they > are > > > not used in the declaration of a Field object, and so the getter and > > > setter to the value of the field are NOT typed, and thus can not be > > > checked by the compiler/IDE. > > > > > > I do not have the knowledge to add this to the compiler, and the only > > > documentation I have found for adding things to the compiler (as I > > > have already mentioned) did not help - it only talked about adding > > > operators to the compiler. The compiler is not exactly well documented > > > or if it is, Google has been unable to furnish the right documents. > > > > > > The reason that it is needed is very simple. One of the big strengths > > > of Java is that compilers and IDEs can do a really good job of > detecting > > > errors, and in the case of IDEs making suggestions as to what can come > > > next. Using String field names in places like Bean Binding frameworks > > > and API approaches to SQL and friends (like the JPA Criteria API) > drives > > > a coach and horses through that strength. For that reason, and the > fact > > > that this is a VERY simple suggestion, this proposal should be given > > > serious consideration. > > > > > > Now if there people out there with the knowledge to help me get started > > > in understanding what needs to be changed in Javac (I tried Remi Forax > > > as he had already worked in this area, but he was too busy to help when > > > I asked) I am more than happy to try to produce a working javac. But > > > simply jumping into the source from scratch is unlikely to produce a > good > > > solution. > > > > > > So perhaps rather than spending our time throwing out reasons why this > > > can not be done, lets try to work together to find a way in which is > can > > > be done. > > > > > > David > > > > > > On Thursday 05 March 2009, you wrote: > > > > I think you'll need to spend some more time getting familiar with the > > > > JLS. > > > > > > > > For example, Field objects *DO* have generics information. That's > what > > > > Field.getGenericType() is for. > > > > > > > > I -really- doubt you'll get anywhere with your proposal unless you do > > > > both of the following: > > > > > > > > - impress everybody with an exceedingly complete proposal along > with > > > > a prototype implementation of javac. Which is going to take a lot > more > > > > working knowledge of the JLS and how javac parses source files than > > > > you currently have. > > > > > > > > - either a grassroots campaign of many java programmers that > > > > vindicates your insinuation that properties are so important, they > > > > need to be added to java7, even with this bandaid solution, or > > > > alternatively, convince a number of property evangelising people in > > > > the java community to openly speak in favour of this proposal. > > > > > > > > I imagine that's going to cost you a week or 5 at the very least of > > > > your time, including getting more familiar with the JLS. March is > > > > going to be over by then. > > > > > > > > --Reinier Zwitserloot > > > > I do not see the problem you have. > > > > If you have 'static' name of field (only then compiler can check it) then > > you can simply use field. > Well no, because if you need to use an explicit getter or setter to do some > extra processing or in the setter you want to fire a PropertyChangeEvent > then the Field on its own is not enough. > > The Field setter could be extended, but as it does not know the parent > object (the think of which this is a Field) it can not look for a > PropertyChangeSupport object. The Field set method does not try > to fire PropertyChangeEvents, and does not provide to use an > explicitly coded setter. That could be got around by passing the > Field object into a Property constructor, rather than the field names, > but again we do not have access to the parent object which makes > searching for getters and setters and PropertyChangeSupport objects > rather difficult. > > > > If u do not have that information (it's dynamic) then also compiler is > > unable to determine it's type before execution. > true > > > > That why I do not see why we need any other solution than linking > 'Fields' > > with fields to make it refactor friendly and easy to use. > I do not see (maybe I did not understand FCM) how I could handle > foo#bar#ali. In this case you need a Field array, not just a field. > Additionally the FCM case only seems to handle the Foo#bar case, > not the foo#bar case. That is not the end of the world - it would work > in the examples I need, but it is less than my proposal covers. > > > > Am I wrong? > Either I have missunderstood the FCM (which is quite possible) or it does > not > match what my proposal offers. > > David > > > So why not use Fields when it's needed. And mix it with: class YoursClass{ private final Container field = new Container(); } where Container: class final Container{ private Type element; public Type get(){ return element;} public void set(Type element){ /* validate */ /* evens before */ this.element=element; /* evens after */ } } Pesonaly I use Container mixed with validators. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Thu Mar 5 09:36:07 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 5 Mar 2009 17:36:07 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <28bca0ff0903050925u21245b22lb750469e64174c05@mail.gmail.com> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051709.46250.david.goodenough@linkchoose.co.uk> <28bca0ff0903050925u21245b22lb750469e64174c05@mail.gmail.com> Message-ID: <200903051736.09311.david.goodenough@linkchoose.co.uk> On Thursday 05 March 2009, Marek Kozie? wrote: > 2009/3/5 David Goodenough > > > On Thursday 05 March 2009, Marek Kozie? wrote: > > > 2009/3/5 David Goodenough > > > > > > > Rienier, > > > > > > > > Yes I know that Fields have Generics information available, but they > > > > are > > > > > > not used in the declaration of a Field object, and so the getter and > > > > setter to the value of the field are NOT typed, and thus can not be > > > > checked by the compiler/IDE. > > > > > > > > I do not have the knowledge to add this to the compiler, and the only > > > > documentation I have found for adding things to the compiler (as I > > > > have already mentioned) did not help - it only talked about adding > > > > operators to the compiler. The compiler is not exactly well > > > > documented or if it is, Google has been unable to furnish the right > > > > documents. > > > > > > > > The reason that it is needed is very simple. One of the big > > > > strengths of Java is that compilers and IDEs can do a really good job > > > > of > > > > detecting > > > > > > errors, and in the case of IDEs making suggestions as to what can > > > > come next. Using String field names in places like Bean Binding > > > > frameworks and API approaches to SQL and friends (like the JPA > > > > Criteria API) > > > > drives > > > > > > a coach and horses through that strength. For that reason, and the > > > > fact > > > > > > that this is a VERY simple suggestion, this proposal should be given > > > > serious consideration. > > > > > > > > Now if there people out there with the knowledge to help me get > > > > started in understanding what needs to be changed in Javac (I tried > > > > Remi Forax as he had already worked in this area, but he was too busy > > > > to help when I asked) I am more than happy to try to produce a > > > > working javac. But simply jumping into the source from scratch is > > > > unlikely to produce a > > > > good > > > > > > solution. > > > > > > > > So perhaps rather than spending our time throwing out reasons why > > > > this can not be done, lets try to work together to find a way in > > > > which is > > > > can > > > > > > be done. > > > > > > > > David > > > > > > > > On Thursday 05 March 2009, you wrote: > > > > > I think you'll need to spend some more time getting familiar with > > > > > the JLS. > > > > > > > > > > For example, Field objects *DO* have generics information. That's > > > > what > > > > > > > Field.getGenericType() is for. > > > > > > > > > > I -really- doubt you'll get anywhere with your proposal unless you > > > > > do both of the following: > > > > > > > > > > - impress everybody with an exceedingly complete proposal along > > > > with > > > > > > > a prototype implementation of javac. Which is going to take a lot > > > > more > > > > > > > working knowledge of the JLS and how javac parses source files than > > > > > you currently have. > > > > > > > > > > - either a grassroots campaign of many java programmers that > > > > > vindicates your insinuation that properties are so important, they > > > > > need to be added to java7, even with this bandaid solution, or > > > > > alternatively, convince a number of property evangelising people in > > > > > the java community to openly speak in favour of this proposal. > > > > > > > > > > I imagine that's going to cost you a week or 5 at the very least of > > > > > your time, including getting more familiar with the JLS. March is > > > > > going to be over by then. > > > > > > > > > > --Reinier Zwitserloot > > > > > > I do not see the problem you have. > > > > > > If you have 'static' name of field (only then compiler can check it) > > > then you can simply use field. > > > > Well no, because if you need to use an explicit getter or setter to do > > some extra processing or in the setter you want to fire a > > PropertyChangeEvent then the Field on its own is not enough. > > > > The Field setter could be extended, but as it does not know the parent > > object (the think of which this is a Field) it can not look for a > > PropertyChangeSupport object. The Field set method does not try > > to fire PropertyChangeEvents, and does not provide to use an > > explicitly coded setter. That could be got around by passing the > > Field object into a Property constructor, rather than the field names, > > but again we do not have access to the parent object which makes > > searching for getters and setters and PropertyChangeSupport objects > > rather difficult. > > > > > If u do not have that information (it's dynamic) then also compiler is > > > unable to determine it's type before execution. > > > > true > > > > > That why I do not see why we need any other solution than linking > > > > 'Fields' > > > > > with fields to make it refactor friendly and easy to use. > > > > I do not see (maybe I did not understand FCM) how I could handle > > foo#bar#ali. In this case you need a Field array, not just a field. > > Additionally the FCM case only seems to handle the Foo#bar case, > > not the foo#bar case. That is not the end of the world - it would work > > in the examples I need, but it is less than my proposal covers. > > > > > Am I wrong? > > > > Either I have missunderstood the FCM (which is quite possible) or it does > > not > > match what my proposal offers. > > > > David > > > > > > So why not use Fields when it's needed. > > And mix it with: > > class YoursClass{ > > private final Container field = new Container(); > > } > > where Container: > > class final Container{ > > private Type element; > > public Type get(){ return element;} > > public void set(Type element){ /* validate */ /* evens before */ > this.element=element; /* evens after */ } > > } > > Pesonaly I use Container mixed with validators. Now you have lost me. I do not understand this or how it would help. David From develop4lasu at gmail.com Thu Mar 5 09:40:53 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 5 Mar 2009 18:40:53 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903051736.09311.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051709.46250.david.goodenough@linkchoose.co.uk> <28bca0ff0903050925u21245b22lb750469e64174c05@mail.gmail.com> <200903051736.09311.david.goodenough@linkchoose.co.uk> Message-ID: <28bca0ff0903050940v60551aefp37a36cdefb0f7673@mail.gmail.com> 2009/3/5 David Goodenough > > Now you have lost me. I do not understand this or how it would help. > > David > > You can use container to store element: Container field instead of: Field field And you can add listeners / validators to it, delegate it, ..... -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Thu Mar 5 09:56:49 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 5 Mar 2009 17:56:49 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <28bca0ff0903050940v60551aefp37a36cdefb0f7673@mail.gmail.com> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051736.09311.david.goodenough@linkchoose.co.uk> <28bca0ff0903050940v60551aefp37a36cdefb0f7673@mail.gmail.com> Message-ID: <200903051756.51085.david.goodenough@linkchoose.co.uk> On Thursday 05 March 2009, Marek Kozie? wrote: > 2009/3/5 David Goodenough > > > Now you have lost me. I do not understand this or how it would help. > > > > David > > You can use container to store element: > > Container field > > instead of: > > Field field > > And you can add listeners / validators to it, delegate it, ..... How does adding a Generics qualifier of Field help? Or is this an FCM thing? David From develop4lasu at gmail.com Thu Mar 5 11:40:54 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 5 Mar 2009 20:40:54 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903051756.51085.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051736.09311.david.goodenough@linkchoose.co.uk> <28bca0ff0903050940v60551aefp37a36cdefb0f7673@mail.gmail.com> <200903051756.51085.david.goodenough@linkchoose.co.uk> Message-ID: <28bca0ff0903051140s6204bacg204e7ccbc4ea7cfb@mail.gmail.com> 2009/3/5 David Goodenough > On Thursday 05 March 2009, Marek Kozie? wrote: > > 2009/3/5 David Goodenough > > > > > Now you have lost me. I do not understand this or how it would help. > > > > > > David > > > > You can use container to store element: > > > > Container field > > > > instead of: > > > > Field field > > > > And you can add listeners / validators to it, delegate it, ..... > > How does adding a Generics qualifier of Field help? Or is this an FCM > thing? > > David > > It's more like workaround. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From belingueres at gmail.com Thu Mar 5 13:05:28 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Thu, 5 Mar 2009 19:05:28 -0200 Subject: PROPOSAL: fold keyword In-Reply-To: References: Message-ID: Hi, This is a proposal for adding a simple "fold" operation on Collections. It is in a very draft state IMO, and perhaps it was already discussed in the process of adding closures to the language. Here I send it to you, nevertheless. Regards, Gabriel PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Gabriel Belingueres OVERVIEW Provide a "fold" sentence to Java for non trivial iterations over Collections. See http://en.wikipedia.org/wiki/Fold_(higher-order_function) FEATURE SUMMARY: Add the ability to support a form of "advanced for statement", to capture typical collection iteration patterns involving tests on some condition to break the iteration, or calculating a single value from the collection elements, assigning a default value when the collection is empty. The new "fold" keyword acts like a sugared, moderately complex enhanced for keyword that abstract this typical processing on collections. MAJOR ADVANTAGE: Makes the coding of not so trivial operations on collections more readable. MAJOR BENEFIT: Readability: Makes clearer the intention of the programmer when iterating over a collection to perform those typical but non trivial iterations. MAJOR DISADVANTAGE: Some increased implementation and testing complexity for the compiler. Add a new keyword for the language "fold". ALTERNATIVES: There are some free libraries like Apache's common-collection that helps in abstracting some aspects of complex collection iteration, however this library in particular is targeted for older java versions with no support for generics (others may do though). Libraries would need to pass the body of the for loop as an object, requiring to create an anonymous class, or making use of reflection to call the appropriate statements as if it where the body of the loop, making the implementation either less readable or less efficient, respectively. The full fledged alternative would be to add closures to Java (but closures seems to be not targeted for Java 7 AFAIK.) EXAMPLES SIMPLE EXAMPLE: ?List list = ArrayList(); ?l.add(...); ?// sum all numbers in the list ?Integer sum = ? ?fold(Integer n : list; ? ? // iterating collection element n ? ? ? ? Integer result = 0) { // Where to accumulate the result, and the initial value ? ? ?result += n; ? ?}; ?System.out.println(sum); ADVANCED EXAMPLES: ?// returns true if all salaries of the employee collection are lower than 1000 or the collection is empty. ?List emps = ....; ?Boolean allLower = ? ?fold(Employee emp : emps; ? ? ? ? Boolean result = Boolean.TRUE; ? ? ? ? !result) { ?// break condition: must be a boolean expression ? ? ?result = (emp.getSalary().compareTo(new BigDecimal(1000) < 0); ? ?} ?// returns a new collection with the salaries of the employees not on vacation ?List emps = ...; ?List salaries = ? ?fold(Employee e : emps; ? ? ? ? List newList = new ArrayList()) { ? ? ?if (!e.onVacation()) { ? ? ? ?newList.add(e.getSalary()); ? ? ?} ? ?} ?// returns the first N employees whose sum of salaries are lower than 1000000 ?List emps = ...; ?BigDecimal sum = BigDecimal.ZERO; // sum the salaries ?List selectedEmps = ? ?fold(Employee e : emps; ? ? ? ? List result = new ArrayList(); ? ? ? ? sum.add(e.getSalary()).compareTo(new BigDecimal(1000000)) < 0) { ? ? ? ? result.add(e); ? ? ? ? sum = sum.add(e.getSalary()); ? ?}; DETAILS SPECIFICATION: The following is somewhat informal, making emphasis in this draft document on the main idea instead of in formal grammar and JLS issues. SYNTAX: foldStatement: ? ?fold(VariableModifiers_opt Type Identifier: Expression; LocalVariableDeclaration; Expression_opt) Statement The first part is similar to what is required for the enhanced "for" keyword. The second part is a variable declaration that MUST be initialized with the value returned when the collection is empty. (It seems to me that it doesn't make any sense if the variable is declared "final".) Should be limited in scope to the fold body (to align the behavior with the for keyword). The third part is an optional boolean expression which acts as a break condition. The fold returns an object that is to be assignable from the same static type declared in the second part, which can be assigned to a variable or used as an expression. The behavior when the collection is null, or in the presence of exceptions should follow the same criteria than the enhanced for loop. COMPILATION: Here are desugarings to currently legal Java source for the two examples above: ? ?// simple example ? ?Integer sum; ? ?{ // new scope for synthetic variables ? ? ?Integer $result = 0; ? ? ?if (!list.isEmpty()) { // NPE if collection is null ? ? ? ?for(Integer n : list) { ? ? ? ? ?$result += n; ? ? ? ?} ? ? ?} ? ? ?sum = $result; ? ?} ? ?// first advanced example (with break condition) ? ?Boolean allLower; ? ?{ // new scope for synthetic variables ? ? ?Boolean $result = Boolean.TRUE; ? ? ?if (!emps.isEmpty()) { // NPE if collection is null ? ? ? ?for(Employee e : emps) { ? ? ? ? ?if (!$result) ? ? ? ? ? ?break; ? ? ? ? ?$result = (emp.getSalary().compareTo(new BigDecimal(1000)); ? ? ? ?} ? ? ?} ? ? ?allLower = $result; ? ?} TESTING: Generating various simple and complex uses of the new structure and verifying the proper execution results; combinations to test include fold statements with and without break conditions, tests with specific collection types such as Lists, Sets, Maps. Can expand on the enhanced for tests for further testing. LIBRARY SUPPORT: The same libraries that needs to be supported by the enhanced for loop. REFLECTIVE APIS: None of core reflection, javax.lang.model.*, the doclet API, and JDPA model statements; therefore, they are unaffected (AFAIK). The tree API in javac, does model statements, but maybe we can adapt the existing API for enhanced for statements. OTHER CHANGES: No. MIGRATION: Look for collection iterations with nested break conditions or element processing returning a single value. 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 (doing a quick search on the bug database.) URL FOR PROTOTYPE (optional): No prototype at this time. From jjb at google.com Thu Mar 5 13:28:11 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 5 Mar 2009 13:28:11 -0800 Subject: PROPOSAL: fold keyword In-Reply-To: References: Message-ID: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> Gabriel, This doesn't seem compelling. Here's your simple example: // sum all numbers in the list Integer sum = fold(Integer n : list; // iterating collection element n Integer result = 0) { // Where to accumulate the result, and the initial value result += n; }; } And here's how it looks today (with no change to the language or libraries): Integer sum = 0; for (Integer n : list) sum += n; Here's one of your complex examples: // returns a new collection with the salaries of the employees not on vacation List salaries = fold(Employee e : emps; List newList = new ArrayList()) { if (!e.onVacation()) { newList.add(e.getSalary()); } } And here's how it looks today: List salaries = new ArrayList(); for (Employee e : emps) if (!e.onVacation()) salaries.add(e.getSalary()); To my eyes, the current version is clearer as well as shorter. Josh From suranap at gmail.com Thu Mar 5 14:16:02 2009 From: suranap at gmail.com (Pinku Surana) Date: Thu, 5 Mar 2009 17:16:02 -0500 Subject: PROPOSAL: Multiple switch expressions and case ranges Message-ID: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> Has the switch statement in C languages evolved much since the '80s? I'm envious of the case/match expression in functional languages and looking for simple ways to make 'switch' more powerful. AUTHOR(S): Pinku Surana OVERVIEW FEATURE SUMMARY: Extend the switch statement to support multiple switch expressions and case ranges. MAJOR ADVANTAGE: It is syntactic sugar that makes it easier to write/read complex logic. This is one small aspect of the vastly more powerful match or case expression in functional languages. MAJOR BENEFIT: Better readability for complex cases, and potentially better performance relative to if statements. MAJOR DISADVANTAGE: Requires changes to compiler. ALTERNATIVES: It can currently be implemented with if statements. EXAMPLES Show us the code! SIMPLE EXAMPLE: Show the simplest possible program utilizing the new feature. switch (c) { case ['a'..'z']: return "lower case" ; case ['A'..'Z']: return "upper case" ; default: return "something else" ; } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. switch (suit, value) { case [SPADE..CLUB], [2..10] : return "black low-value card" ; case [HEART..DIAMOND], [2..10] : return "red low-value card" ; case _, [11..14]: return "face card" ; } 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. * The lexer will need to support underscore ('_') and ".." * The parser rules for switch statements must be changed. SwitchStatement: switch (Expression [, Expression]*) SwitchBlock SwitchLabel: case CaseExpressions : default : CaseExpressions: CaseExpression CaseExpressions , CaseExpression CaseExpression: _ ConstantExpression [ ConstantExpression .. ConstantExpression ] EnumConstantName [ EnumConstantName .. EnumConstantName ] * Semantic rules: - The number of CaseExpressions must equal the number of expressions in the SwitchStatement - The underscore ('_') means "don't care" - In [ c1 .. c2], c1 should be less than c2 - The types of the constants/enums must match the type of the expression in the same position - If the range of constants/enums overlap between case arms, then raise an error. COMPILATION: Simple desugaring transformations: ---------------------------------- switch (e1, e2) { case C1, C2: stmt1 ; case C3, _: stmt2 ; default: stmt3 ; } ==> x = e1 ; y = e2 ; switch (x) { case C1: switch (y) { case C2: stmt1 ; case C4: stmt2 ; default: stmt3 ; } break ; case C3: stmt2 ; break ; default: stmt3 ; } ----------------------------------- case [V1 .. Vn] : stmts ; ==> case V1: case V2: ... case Vn: stmts ; ----------------------------------- Both of these could blow up in code size. Therefore, a better implementation of the switch would compile down to gotos to the correct statement block. This is why proper compiler support would be nice. For case ranges, if the range is too big then turn into an if statement: "if (x >= V1 && x <= V2)". TESTING: How can the feature be tested? Normal compiler testing. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? None 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. The reflection APIs will need to return a list of switch expressions and case constants. Also, new expression nodes must be added for ranges and for the "don't care" underscore. 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. Don't think so. MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. I think this would be difficult because the logic would be obscured in if statements. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. None. 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? Should be backwards compatible. REFERENCES EXISTING BUGS: Please include a list of any existing Sun bug ids related to this proposal. URL FOR PROTOTYPE (optional): If there's interest, I can cook up a prototype with Polyglot. From schulz at e-Spirit.de Thu Mar 5 14:19:53 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Thu, 5 Mar 2009 23:19:53 +0100 Subject: PROPOSAL: Lightweight Properties References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com><200903051527.53497.david.goodenough@linkchoose.co.uk><28bca0ff0903050841n7751a3d0yfc268b408b071475@mail.gmail.com> <200903051709.46250.david.goodenough@linkchoose.co.uk> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC01FED3@osiris2.e-spirit.de> > I do not see (maybe I did not understand FCM) how I could handle > foo#bar#ali. In this case you need a Field array, not just a field. > Additionally the FCM case only seems to handle the Foo#bar case, > not the foo#bar case. That is not the end of the world - it would work > in the examples I need, but it is less than my proposal covers. Field literals as defined by FCM are meant to ease access for reflection. There was no further intent, AFAIR, as to have an analogue to Method literals. As the result is a Field instance, chaining does not make sense. Literals are only defined on types not instances. I'm not sure about autoconverting foo#bar to some Property instance. The main goal, as far as I understood, is to have compile time checks on accessing properties instead of using Strings. Not sure, if this helps, but just to note down the thought: As a prerequisite, we might need a generified Field class (not necessarily has to be the java.reflect.Field class). Now assuming Foo having a field bar of type Bar, and Bar having a field baz of type Baz. Using (generified) Field literals, one could create a property builder taking Fields instead of Strings as parameters, e.g.: Property p1 = PropertyBuilder.on(Foo.class).at(Foo#bar); Property p2 = PropertyBuilder.on(Foo.class).via(Foo#bar).at(Bar#baz); Property p3 = PropertyBuilder.on(foo).at(Foo#bar); Property p4 = PropertyBuilder.on(foo).via(Foo#bar).at(Bar#baz); I admit, this does not look as neat, but would serve the purpose. Or am I missing the target? Cheers, Stefan From tim at peierls.net Thu Mar 5 14:24:13 2009 From: tim at peierls.net (Tim Peierls) Date: Thu, 5 Mar 2009 17:24:13 -0500 Subject: PROPOSAL: fold keyword In-Reply-To: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> References: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> Message-ID: <63b4e4050903051424k5806158as698cfbf580bf6043@mail.gmail.com> Also check out ParallelArray, which is built on top of the ForkJoin framework proposed for Java 7: http://gee.cs.oswego.edu/dl/jsr166/dist/extra166ydocs/extra166y/ParallelArray.html The simple example becomes trivial: long sum = parallelLongArray.sum(); The more complex example that Josh mentioned would look like this: ParallelArray emps = ... // Salaries of employees not on vacation: return emps .withFilter(notPredicate(isOnVacation)) .withMapping(salaryField) .all(); where notPredicate is a static import from CommonOps, and isOnVacation and salaryField could be defined as: static final Predicate isOnVacation = new Predicate { public boolean op(Employee e) { return e.onVacation(); } }; static final Op salaryField = new Op { public BigDecimal op(Employee e) { return e.getSalary(); } }; These examples are likely to outperform the sequential versions on a multiprocessor for moderately large inputs. --tim On Thu, Mar 5, 2009 at 4:28 PM, Joshua Bloch wrote: > Gabriel, > > This doesn't seem compelling. > > Here's your simple example: > > // sum all numbers in the list > Integer sum = > fold(Integer n : list; // iterating collection element n > Integer result = 0) { // Where to accumulate the result, and > the initial value > result += n; > }; > } > > And here's how it looks today (with no change to the language or > libraries): > > Integer sum = 0; > for (Integer n : list) > sum += n; > > > Here's one of your complex examples: > > // returns a new collection with the salaries of the employees not on > vacation > List salaries = > fold(Employee e : emps; > List newList = new ArrayList()) { > if (!e.onVacation()) { > newList.add(e.getSalary()); > } > } > > And here's how it looks today: > > List salaries = new ArrayList(); > for (Employee e : emps) > if (!e.onVacation()) > salaries.add(e.getSalary()); > > To my eyes, the current version is clearer as well as shorter. > > Josh > > From reinier at zwitserloot.com Thu Mar 5 17:15:28 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 6 Mar 2009 02:15:28 +0100 Subject: PROPOSAL: Multiple switch expressions and case ranges In-Reply-To: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> References: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> Message-ID: This proposal does not appear to be complete. As you yourself mention, attempting to switch on [0 .. 1000000000] would generate an enormous class file. Also, your first desugaring example, which rewrites a multi-switch statement to nested switch statements, is certainly not a trivial operation. Where's the specification (and preferably some example code) on how the compiler is supposed to get from the sugar to the desugar? Perhaps this is an error in the Project Coin form, but all proposals should list chapter and verse of the JLS entries that need to be updated, which neccessarily includes a complete and detailed treatment on how the compiler is supposed to do the job. A single example desugaring isn't good enough. Any proposal that includes words like 'If XYZ is too big', is neccessarily not ready for this mailing list (as a proposal. It's fine as a request for comments and help). When does a range become too big? Could you explain the impact on size vs. lookup speed and make a solid recommendation for the right size to switch over? There's no need to update reflection APIs; you can't get at method code with them. You have to update the internal AST API, which you could list for completeness sake, but I don't think that's the intent of the Project Coin form (though, most proposals so far do mention it. I feel its not neccessary because 99% of all project coin proposals I can even think of require it. It's kind of implied when you say "Language Change Proposal"). JNI, the javadoc tool. I sort of like where this proposal is going, but as you yourself mentioned, the power of match/case in languages like Scala and Haskell is scary, and thus this proposal needs to be well aware of how java might some day get there, and be sure that we don't close future avenues early by screwing up now. I think this idea is probably out of scope, but I'll let Joe Darcy and friends be the judge of that. At the very least I would expect this system to work with Comparables, assuming the input and both range ends are all Comparable-compatible with each other (as provided by generics). Matching on type is also a relevant usecase in my opinion, so even if your proposal doesn't add it, you may want to include a rough sketch just to show that your syntax won't get in the way of a future expansion. --Reinier Zwitserloot On Mar 5, 2009, at 23:16, Pinku Surana wrote: > Has the switch statement in C languages evolved much since the '80s? > I'm > envious of the case/match expression in functional languages and > looking for > simple ways to make 'switch' more powerful. > > > > AUTHOR(S): Pinku Surana > > OVERVIEW > > FEATURE SUMMARY: > > Extend the switch statement to support multiple switch expressions > and case > ranges. > > MAJOR ADVANTAGE: > > It is syntactic sugar that makes it easier to write/read complex > logic. This is one small aspect of the vastly more powerful match or > case expression in functional languages. > > MAJOR BENEFIT: > > Better readability for complex cases, and potentially better > performance relative to if statements. > > MAJOR DISADVANTAGE: > > Requires changes to compiler. > > ALTERNATIVES: > > It can currently be implemented with if statements. > > EXAMPLES > > Show us the code! > > SIMPLE EXAMPLE: Show the simplest possible program utilizing the new > feature. > > switch (c) { > case ['a'..'z']: return "lower case" ; > case ['A'..'Z']: return "upper case" ; > default: return "something else" ; > } > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > switch (suit, value) { > case [SPADE..CLUB], [2..10] : return "black low-value card" ; > case [HEART..DIAMOND], [2..10] : return "red low-value card" ; > case _, [11..14]: return "face card" ; > } > > 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. > > * The lexer will need to support underscore ('_') and ".." > * The parser rules for switch statements must be changed. > > SwitchStatement: > switch (Expression [, Expression]*) SwitchBlock > > SwitchLabel: > case CaseExpressions : > default : > > CaseExpressions: > CaseExpression > CaseExpressions , CaseExpression > > CaseExpression: > _ > ConstantExpression > [ ConstantExpression .. ConstantExpression ] > EnumConstantName > [ EnumConstantName .. EnumConstantName ] > > * Semantic rules: > - The number of CaseExpressions must equal the number of > expressions in > the SwitchStatement > - The underscore ('_') means "don't care" > - In [ c1 .. c2], c1 should be less than c2 > - The types of the constants/enums must match the type of the > expression > in the same position > - If the range of constants/enums overlap between case arms, then > raise an > error. > > COMPILATION: > > Simple desugaring transformations: > > ---------------------------------- > switch (e1, e2) { > case C1, C2: stmt1 ; > case C3, _: stmt2 ; > default: stmt3 ; > } > ==> > x = e1 ; > y = e2 ; > switch (x) { > case C1: switch (y) { > case C2: stmt1 ; > case C4: stmt2 ; > default: stmt3 ; > } > break ; > case C3: stmt2 ; > break ; > default: stmt3 ; > } > ----------------------------------- > case [V1 .. Vn] : stmts ; > ==> > case V1: > case V2: > ... > case Vn: stmts ; > ----------------------------------- > > > Both of these could blow up in code size. Therefore, a better > implementation of the switch would compile down to gotos to the > correct statement block. This is why proper compiler support would > be nice. > > For case ranges, if the range is too big then turn into an if > statement: > "if (x >= V1 && x <= V2)". > > > TESTING: How can the feature be tested? > > Normal compiler testing. > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > > None > > 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. > > The reflection APIs will need to return a list of switch expressions > and case constants. Also, new expression nodes must be added for > ranges and for the "don't care" underscore. > > 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. > > Don't think so. > > MIGRATION: Sketch how a code base could be converted, manually or > automatically, to use the new feature. > > I think this would be difficult because the logic would be obscured > in if > statements. > > COMPATIBILITY > > BREAKING CHANGES: Are any previously valid programs now invalid? If > so, list > one. > > None. > > 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? > > Should be backwards compatible. > > REFERENCES > > EXISTING BUGS: Please include a list of any existing Sun bug ids > related to > this proposal. > > URL FOR PROTOTYPE (optional): > > If there's interest, I can cook up a prototype with Polyglot. > From crazybob at crazybob.org Thu Mar 5 17:30:00 2009 From: crazybob at crazybob.org (Bob Lee) Date: Thu, 5 Mar 2009 17:30:00 -0800 Subject: PROPOSAL: Simplified Varargs Method Invocation Message-ID: Simplified Varargs Method Invocation AUTHOR: Bob Lee *OVERVIEW * FEATURE SUMMARY: When a programmer tries to invoke a *varargs* (variable arity) method with a non-reifiable varargs type, the compiler currently generates an "unsafe operation" warning. This proposal moves the warning from the call site to the method declaration. MAJOR ADVANTAGE: Safely and significantly reduces the total number of warnings reported to and suppressed by programmers. Reduces programmer confusion. Enables API designers to use varargs. MAJOR BENEFIT: Plugs a leaky abstraction. Creating an array when you call a varargs method is an implementation detail that we needn't expose to users. Addresses a well known "gotcha" encountered when you mix varargs and generics. Most programmers are surprised to find out you can only clear this warning by suppressing it (especially considering we introduced varargs and generics in the same language update); they waste time looking for alternatives that don't exist. Google Code Search finds almost 90k callers of Arrays.asList() (http://tinyurl.com/dept4d). We could safely suppress the warning once and for all on asList()'s declaration instead of unnecessarily warning every caller that uses a non-reifiable type. MAJOR DISADVANTAGE: The compiler will generate a warning for a method declaration whether or not someone actually calls the method with a non-reifiable type. Allows loss of type safety if the varargs method suppresses the warning and uses the varargs array unsafely. ALTERNATIVES: a) Don't mix varargs with generics. Use the more verbose and less straightforward but warning-free builder pattern. Most API designers choose this route. b) Improve the warning message. Current message: "uses unchecked or unsafe operations" c) Reify generics. d) Introduce a second varargs syntax (perhaps using "...." instead of "...") that uses List instead of T[]. e) Defile the type system. Note: This proposal doesn't preclude any of these other approaches. *EXAMPLES * Before this change: static List asList(T... elements) { ... } static List> stringFactories() { Callable a, b, c; ... *// Warning: **"uses unchecked or unsafe operations"* return asList(a, b, c); } After this change: *// Warning: **"enables unsafe generic array creation"* static List asList(T... elements) { ... } static List> stringFactories() { Callable a, b, c; ... return asList(a, b, c); } If asList() prohibits storing elements that aren't of type T in the elements array, we can safely suppress the warning: *@SuppressWarnings("generic-varargs") // Ensures only values of type T can be stored in elements. * static List asList(T... elements) { ... } *DETAILS * SPECIFICATION: When compiling code that calls a varargs method with a non-reifiable varargs element type, if the target method was compiled targeting Java 7 or later, the compiler needn't generate a warning for the caller. When compiling a varargs method that could accept a non-reifiable varargs type, the compiler should generate a warning on the varargs method declaration. A varargs type is non-reifiable if it contains a type variable anywhere in its signature. For a varargs argument of type T, the programmer can safely suppress the warning using @SuppressWarnings("generic-varargs") so long as the varargs method ensures that only elements of type T can be stored in the varargs array. COMPILATION: Tools should no longer generate a warning for varargs method callers. Instead, they should generate a warning for varargs method declarations that support non-reifiable types. TESTING: Compile test programs and ensure that the compiler generates the expected warnings. LIBRARY SUPPORT: Suppress warnings on the following varargs methods in the JDK: - Arrays.asList(T... a) - Collections.addAll(Collection c, T... elements) - EnumSet.of(E first, E... rest) REFLECTIVE APIS: n/a OTHER CHANGES: n/a MIGRATION: Existing callers may be able to remove @SuppressWarnings("unchecked") from their code. Existing libraries should add @SuppressWarnings("generic-varargs") to methods with signatures containing non-reifiable varargs types. *COMPATIBILITY * BREAKING CHANGES: None EXISTING PROGRAMS: If you recompile an existing program with "-target 7", the compiler will generate warnings for method declarations containing non-reifiable varargs types. *REFERENCES * EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971 JLS Section 15.12.4.2 "Evaluate Arguments" ( http://java.sun.com/docs/books/jls/third_edition/html/expressions.html) "If the method being invoked is a variable arity method (?8.4.1)m, it necessarily has n>0 formal parameters. The final formal parameter of m necessarily has type T[] for some T, and m is necessarily being invoked with k0 actual argument expressions. If m is being invoked with kn actual argument expressions, or, if m is being invoked with k=n actual argument expressions and the type of the kth argument expression is not assignment compatible with T[], then the argument list (e1, ... , en-1, en, ...ek) is evaluated as if it were written as (e1, ..., en-1, new T[]{en, ..., ek}). The argument expressions (possibly rewritten as described above) are now evaluated to yield argument values. Each argument value corresponds to exactly one of the method's n formal parameters." Angelika Langer's Java Generics FAQ, "Why does the compiler sometimes issue an unchecked warning when I invoke a 'varargs' method?" ( http://tinyurl.com/8w2dk) Josh Bloch's "Effective Java" 2nd Edition, page 120 ( http://tinyurl.com/chtgbd) Alex Miller's blog, "Generics puzzler - array construction" ( http://tech.puredanger.com/2007/02/27/generics-array-construction/) "Java Generic and Collections", page 95 (http://tinyurl.com/c53pnu) From Joe.Darcy at Sun.COM Thu Mar 5 18:03:34 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Thu, 05 Mar 2009 18:03:34 -0800 Subject: PROPOSAL: Multiple switch expressions and case ranges In-Reply-To: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> References: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> Message-ID: <49B08476.8090706@sun.com> Pinku Surana wrote: > Has the switch statement in C languages evolved much since the '80s? I'm > envious of the case/match expression in functional languages and looking for > simple ways to make 'switch' more powerful. > > > > AUTHOR(S): Pinku Surana > > OVERVIEW > > FEATURE SUMMARY: > > Extend the switch statement to support multiple switch expressions and case > ranges. > [snip] > EXISTING BUGS: Please include a list of any existing Sun bug ids related to > this proposal. > > The Sun bug database has bugs in this area. -Joe From philvarner at gmail.com Thu Mar 5 20:50:26 2009 From: philvarner at gmail.com (Phil Varner) Date: Thu, 5 Mar 2009 20:50:26 -0800 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: <49AF15DC.20408@gmail.com> References: <49AF1114.3080205@sun.com> <49AF15DC.20408@gmail.com> Message-ID: > Static import was surprising complicated in JDK 5. While these aliases could alleviate some problems, I think they would be easily abused > and even when not being abused render code less readable. > IMO, having alternate names for potentially common classes would be less readable. I agree for common classes this could be a problem, but I don't think it would be any less of a problem than the existing support for wildcards. I see this more as a solution targeted mostly for long package names with overlapping class names. I'm going to need to think some about what "readable" really means, and would be interested in any thoughts on this topic. > While grammar changes are part of the picture, the substantive changes would be to JLSv3 section 6.5 "Determining the Meaning of a Name": Thanks for pointing this out, it's definitely a huge hole in the proposal. > The Javapolis discussions of 2007 ended with the majority of > participants choosing against aliasing of imports (typedefs). > > http://www.javapolis.com/confluence/plugins/advanced/gallery-slideshow.action?pageId=32793&decorator=popup&imageNumber=9 Thanks for the pointer. I, too, would probably vote against a the proposal of import Map as CodeValueMap; Several of the related bugs mention this syntax, but I think this combines two issues together. It seems to me that the simple mapping of a fully-qualified class name to a "short" name is separate from the typedefing of a specifically-parameterized generified type to a short name. --Phil -- Machines might be interesting, but people are fascinating. -- K.P. From reinier at zwitserloot.com Thu Mar 5 21:39:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 6 Mar 2009 06:39:06 +0100 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: References: Message-ID: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> Heh, that was the next proposal I was going to write. (Apologies for a long and technically complicated post. I've rewritten it several times in an attempt to get to the point faster, but this is the best I can do). It really pains me to rain on your parade. I was doing some experimenting and found an admittedly very unlikely scenario that isn't backwards compatible. Then I realized, that this is actually (arguably) a bug, or at least a severe misfeature in javac right now! Therefore, this proposal should fix this problem as well. Of all proposals so far, I rate this one the highest, because it causes so much confusion and is closer to a bug in javac than a language feature, so I would be very happy if this proposal can be fully ironed out. Complete code showing the problem - copy and paste into Main.java, compile, and run: ------ import java.util.*; class Foo { public void foo(T... t) {} } class Bar extends Foo { //de-varargsing? Why is this legal? public void foo(String[] t) { System.out.println(t.getClass().getComponentType()); } } public class Main { public static void main(String[] args) { Foo f = new Bar(); List l = Arrays.asList("a", "b", "c"); bar(f, l); } public static void bar(Foo f, List l) { f.foo(l.get(0), l.get(1), l.get(2)); } } ----- The result is an error: Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; Right now, you get the usual varargs warning, but nothing else at compile time. At runtime, you get the above error. The real bug here is the ability for any subclass to de-varargs a parameter. This bit has nothing to do with the proposal, other than that it so happens to deal with varargs. De-varargsing a parameter is somewhat similar to a subclass tightening the type of an overriden parameter, which isn't legal / gives you a different method altogether instead of overriding. If you really want to pass varargs into such a method, then the only solution is to cast the object to a less specific type, and then all of a sudden it works. In other words, this can happen, right now, in java 1.5/1.6: SubType s = new SubType(); s.foo(a, b, c); //method not found. SuperType st = s; st.foo(a, b, c); //no problem. I say that's a bug. The more serious problem, and one directly related to the proposal, is trying to reify a superclass's array type. (the subclass in the example above turning Foo's T into a reified 'String'). This action is fundamentally broken, and yet there's no way to avoid it. You can't effectively override a method of a superclass containing a generics type as an array's component type if you reified that generics parameter. You can try, but many callers simply can't call your method anymore. Right now, in java 1.5/1.6, you do get that generics warning Bob Lee's proposal is trying to move to the callee site, though it's not very informative and there's absolutely nothing a caller can do whatsoever. If Bob Lee's proposal is implemented, the warning just as useless, and arguably skipped even faster than it is now. Specifically, you can't: A: widen the type of the parameter in the overriding method's signature to Object[] or Object..., as javac will refuse to compile it due to two different signatures erasing to the same signature. B: add a bogus type and use that T. Javac will compile it, but the signature of that method is then foo(String[]), and thus its a completely separate method, that doesn't override parent's foo method. Therefore, addendum #1 to this proposal: Generate more warnings. A. If you are overriding a method where in your signature an array is not varargsed, but in any of your supertypes' signatures, it is varargsed. This warning should be very severe as well and suggest in no uncertain terms that you NEED to replace your [] with "..."; optimally this is a compile time error, but fixing this now wouldn't be migration compatible. This warning should not show up if using - source 1.4 or lower, for obvious reasons. B. If you are overriding a method where in your signature an array type's component type has been reified compared to any of your supertypes' signatures for this method. The warning should explain that there's no work-around, but that anybody treating your instance as a type of (X) will likely get a runtime error if they tried to call this method. The only fix I can think of is to rejigger the signatures somehow: The method should signature as an Object[] same as parent, but javac should NOT consider this a separate method that erases to the same signature - it IS intended as the same method. If this is done, the warning on the method should be translated to something along the lines of Bob Lee's proposed warning (the actual component type of the array, if asked for at reification, isn't neccessarily correct, and your string array might all of a sudden give you integers if the caller handed you a generics-tainted array). A second addendum I would strongly urge is to use escape detection to eliminate the warning on the var-args-using methods. The following operations are all entirely safe, and they are also the only ones used by every single varargs method I've ever laid my eyes on, except Arrays.asList: Safe #1: Ask for the vararg array's length. Obviously safe - length has no relation to the array's type. Safe #2: Member lookup (array[index]). The type of a member lookup is entirely dependent on the compile-time type. The caller needs to worry about that compile-time type too, so can't stuff mistyped things in that varargs array without triggering a generics warning of their own. Once somebody somewhere gets a generics warning, any resulting ClassCastExceptions are acceptable (that's the status quo now, after all). Non-generified lookups such as the example above can't even run, because the method invocation itself will already blow up. This is bad, but it happens now too. Safe #3: foreaching through a varargs parameter. foreaching a combination of .length and member lookups, so by induction is obviously as safe as #1 and #2. Anything else, -anything- at all, including using it in any expression (other than the safe forms above), storing it into another variable or field, using it as a parameter to another method, or calling any other property on it, including toString() (there's no point in calling toString() on an array anyway, so why bother declaring that safe?) - is unsafe, and would generate the warning. The warning is then not generated on the var-args-accepting-method's signature, but instead on the first node in that method's AST that does something that isn't safe to the varargs parameter. The only borderline cases where the above preconditions are broken is Arrays.asList, which is a unique exception, and varargs methods that pass the entire varargs parameter to a helper method. It might be possible to declare passing varargs parameters to another method that also takes varargs as safe, but I'm not 100% certain that's always safe (as safe as generics are going to be in a non-reified world, that is). Note that for most of these cases, there are mixed-version problems. New code that calls into old code means nobody gets any warnings. I'm not sure if Bob's proposal includes this, but the compiler should continue to generate warnings on the site of the caller if the class file format of the targeted method goes with javac v1.6 or below. If a code-base starts mixing generated class files, things get even worse; methods that, during compile-time, weren't overriding anything, are suddenly supposed to override a generics or varargs based superclass because just the superclass has been recompiled with changes, for example. The only argument I can give in favour of this proposal is that doing that sort of thing already breaks a number of apparent invariants and can give you NoSuchMethodErrors and the like. --Reinier Zwitserloot On Mar 6, 2009, at 02:30, Bob Lee wrote: > Simplified Varargs Method Invocation > AUTHOR: Bob Lee > > *OVERVIEW > * > FEATURE SUMMARY: When a programmer tries to invoke a *varargs* > (variable > arity) method with a non-reifiable varargs type, the compiler > currently > generates an "unsafe operation" warning. This proposal moves the > warning > from the call site to the method declaration. > > MAJOR ADVANTAGE: Safely and significantly reduces the total number of > warnings reported to and suppressed by programmers. Reduces programmer > confusion. Enables API designers to use varargs. > > MAJOR BENEFIT: Plugs a leaky abstraction. Creating an array when you > call a > varargs method is an implementation detail that we needn't expose to > users. > Addresses a well known "gotcha" encountered when you mix varargs and > generics. Most programmers are surprised to find out you can only > clear this > warning by suppressing it (especially considering we introduced > varargs and > generics in the same language update); they waste time looking for > alternatives that don't exist. Google Code Search finds almost 90k > callers > of Arrays.asList() (http://tinyurl.com/dept4d). We could safely > suppress the > warning once and for all on asList()'s declaration instead of > unnecessarily > warning every caller that uses a non-reifiable type. > > MAJOR DISADVANTAGE: The compiler will generate a warning for a method > declaration whether or not someone actually calls the method with a > non-reifiable type. Allows loss of type safety if the varargs method > suppresses the warning and uses the varargs array unsafely. > > ALTERNATIVES: > a) Don't mix varargs with generics. Use the more verbose and less > straightforward but warning-free builder pattern. Most API designers > choose > this route. > b) Improve the warning message. Current message: "uses unchecked or > unsafe > operations" > c) Reify generics. > d) Introduce a second varargs syntax (perhaps using "...." instead of > "...") that uses List instead of T[]. > e) Defile the type system. > > Note: This proposal doesn't preclude any of these other approaches. > > *EXAMPLES > * > Before this change: > > static List asList(T... elements) { ... } > > static List> stringFactories() { > Callable a, b, c; > ... > *// Warning: **"uses unchecked or unsafe operations"* > return asList(a, b, c); > } > > After this change: > > *// Warning: **"enables unsafe generic array creation"* > static List asList(T... elements) { ... } > > static List> stringFactories() { > Callable a, b, c; > ... > return asList(a, b, c); > } > > If asList() prohibits storing elements that aren't of type T in the > elements > array, we can safely suppress the warning: > > *@SuppressWarnings("generic-varargs") > // Ensures only values of type T can be stored in elements. > * static List asList(T... elements) { ... } > > *DETAILS > * > SPECIFICATION: When compiling code that calls a varargs method with a > non-reifiable varargs element type, if the target method was compiled > targeting Java 7 or later, the compiler needn't generate a warning > for the > caller. When compiling a varargs method that could accept a non- > reifiable > varargs type, the compiler should generate a warning on the varargs > method > declaration. A varargs type is non-reifiable if it contains a type > variable > anywhere in its signature. For a varargs argument of type T, the > programmer > can safely suppress the warning using @SuppressWarnings("generic- > varargs") > so long as the varargs method ensures that only elements of type T > can be > stored in the varargs array. > > COMPILATION: Tools should no longer generate a warning for varargs > method > callers. Instead, they should generate a warning for varargs method > declarations that support non-reifiable types. > > TESTING: Compile test programs and ensure that the compiler > generates the > expected warnings. > > LIBRARY SUPPORT: Suppress warnings on the following varargs methods > in the > JDK: > - Arrays.asList(T... a) > - Collections.addAll(Collection c, T... elements) > - EnumSet.of(E first, E... rest) > > REFLECTIVE APIS: n/a > > OTHER CHANGES: n/a > > MIGRATION: Existing callers may be able to remove > @SuppressWarnings("unchecked") from their code. Existing libraries > should > add @SuppressWarnings("generic-varargs") to methods with signatures > containing non-reifiable varargs types. > > *COMPATIBILITY > * > BREAKING CHANGES: None > > EXISTING PROGRAMS: If you recompile an existing program with "- > target 7", > the compiler will generate warnings for method declarations containing > non-reifiable varargs types. > > *REFERENCES > * > EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971 > > JLS Section 15.12.4.2 "Evaluate Arguments" ( > http://java.sun.com/docs/books/jls/third_edition/html/ > expressions.html) > > "If the method being invoked is a variable arity method > (?8.4.1) >m, > it necessarily has n>0 formal parameters. The final formal parameter > of m > necessarily has type T[] for some T, and m is necessarily being > invoked with > k0 actual argument expressions. > > If m is being invoked with kn actual argument expressions, or, if m > is being > invoked with k=n actual argument expressions and the type of the kth > argument expression is not assignment compatible with T[], then the > argument > list (e1, ... , en-1, en, ...ek) is evaluated as if it were written > as (e1, > ..., en-1, new T[]{en, ..., ek}). > > The argument expressions (possibly rewritten as described above) are > now > evaluated to yield argument values. Each argument value corresponds to > exactly one of the method's n formal parameters." > > Angelika Langer's Java Generics FAQ, "Why does the compiler > sometimes issue > an unchecked warning when I invoke a 'varargs' method?" ( > http://tinyurl.com/8w2dk) > > Josh Bloch's "Effective Java" 2nd Edition, page 120 ( > http://tinyurl.com/chtgbd) > > Alex Miller's blog, "Generics puzzler - array construction" ( > http://tech.puredanger.com/2007/02/27/generics-array-construction/) > > "Java Generic and Collections", page 95 (http://tinyurl.com/c53pnu) > From develop4lasu at gmail.com Thu Mar 5 22:40:33 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 6 Mar 2009 07:40:33 +0100 Subject: PROPOSAL: Multiple switch expressions and case ranges In-Reply-To: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> References: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> Message-ID: <28bca0ff0903052240v754328ceief2f2ff6ac738500@mail.gmail.com> Hi. I hoped that no one will be interested in this solution (but I was wrong). Extending switch is no problem for me, but why so partially? Let's see some switch construction that would allow to handle any object (inluding null-s) and keep encapsulation as well: >Base Interfaces: public interface Equally { /** * @return true if objects are equal */ boolean equal(Type object, Type other); } public interface EquallyAsymmetric { /** * @return true if objects are equal */ boolean equal(Source source, Target target); } // Same as Comparator but allow encapsulation public interface ComparatorAsymmetric { int compare(Source source, Target target); } Switch: switch ( Expression : Equally) SwitchBlock switch ( Expression : EquallyAsymmetric) SwitchBlock switch ( Expression : Comparator) SwitchBlock switch ( Expression : ComparatorAsymmetric) SwitchBlock switch ( Expression : null) SwitchBlock // for natural order >How would that work? public class SomeData { public SomeData(String key, Data data) { super(); this.key = key; this.data = data; // validation } private Data data; public final String key; public final static Equally equally = new EquallySomeData(); public final static EquallyAsymmetric equallyAsymmetric = new EquallyAsymmetricSomeData(); ; public final static Comparator comparator = new ComparatorSomeData(); private static class ComparatorSomeData implements Comparator { @Override public int compare(SomeData o1, SomeData o2) { return o1.key.compareTo(o2.key); } }; private static class EquallyAsymmetricSomeData implements EquallyAsymmetric { @Override public boolean equal(SomeData source, String target) { return source.key.equals(target); } }; private static class EquallySomeData implements Equally { @Override public boolean equal(SomeData object, SomeData other) { return object.key.equals(other.key); } } } Equally sample: SomeData getMatch(String key) { switch (new SomeData(key,null):SomeData.equally) { case someData: break; default: break; } } Equally asymmetric sample: SomeData getMatch(String key) { switch (new SomeData(key,null):SomeData.equallyAsymmetric ) { case ?some?: break; default: break; } } Comparator sample: SomeData getMatch(String key) { switch (new SomeData(key,null):SomeData.equallyAsymmetric ) { case lower <= ... < upper, special: break; default: break; } } Notice that if you want ranges in case soon or later o will need relations: <=, >=, <, >, because there is no (""-1), I know there is workaround but as I think there is no need to put solution which require new workarounds. >WORKAROUND: enum Switch { ONE("asd") { @Override public void action() { System.out.println(this.text); } },// TWO("bad");// protected String text; public void action() { throw new NotImplementedException(); } Switch(String text) { if (text == null) { throw new NullPointerException("text"); } this.text = text; } public static Switch getByText(String text) { if (text == null) return null; for (Switch casee : Switch.values()) { if (casee.text.equals(text)) return casee; } return null; } public static Switch getByTextForStartWith(String prefix) { if (prefix == null) return null; for (Switch casee : Switch.values()) { if (casee.text.startsWith(prefix)) return casee; } return null; } } REFERENCES: http://bugs.sun.com/view_bug.do?bug_id=5012262 http://lasu2string.blogspot.com/2008/12/string-switch-small-language-changes-on.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From crazybob at crazybob.org Fri Mar 6 00:02:25 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 00:02:25 -0800 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> References: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> Message-ID: On Thu, Mar 5, 2009 at 9:39 PM, Reinier Zwitserloot wrote: > (Apologies for a long and technically complicated post. I've rewritten > it several times in an attempt to get to the point faster, but this is > the best I can do). > Not at all. This is great. Thanks for the feedback, Reinier! Right now, you get the usual varargs warning, but nothing else at > compile time. At runtime, you get the above error. > I get this warning on Bar.foo(String[]): "cannot override foo(T...) in Foo; overriding method is missing '...'" I get a similar warning when I try to override an array method with a varargs method. > The more serious problem, and one directly related to the proposal, is > trying to reify a superclass's array type. (the subclass in the > example above turning Foo's T into a reified 'String'). This action is > fundamentally broken, and yet there's no way to avoid it. You can't > effectively override a method of a superclass containing a generics > type as an array's component type if you reified that generics > parameter. You can try, but many callers simply can't call your method > anymore. Right now, in java 1.5/1.6, you do get that generics warning > Bob Lee's proposal is trying to move to the callee site, though it's > not very informative and there's absolutely nothing a caller can do > whatsoever. If Bob Lee's proposal is implemented, the warning just as > useless, and arguably skipped even faster than it is now. > > Specifically, you can't: > > A: widen the type of the parameter in the overriding method's > signature to Object[] or Object..., as javac will refuse to compile it > due to two different signatures erasing to the same signature. > > B: add a bogus type and use that T. Javac will > compile it, but the signature of that method is then foo(String[]), > and thus its a completely separate method, that doesn't override > parent's foo method. > Good catch. I hadn't thought about this. It would be nice if javac could just erase to Object[] in the overridding method, but I can't say whether or not that's a viable option. Looks like I have some investigation ahead of me. A second addendum I would strongly urge is to use escape detection to > eliminate the warning on the var-args-using methods. The following > operations are all entirely safe, and they are also the only ones used > by every single varargs method I've ever laid my eyes on, except > Arrays.asList: > This is what I meant by alternative e) defile the type system. :-) Basically, you can always just store the varargs value in an Object variable. When I discussed this with Alex Buckley, he found generating a warning in this case too distastful. On the bright side, this warning only turns up 3 times in the entire JDK, so it's probably best to keep the proposal simple. Note that for most of these cases, there are mixed-version problems. > New code that calls into old code means nobody gets any warnings. I'm > not sure if Bob's proposal includes this, but the compiler should > continue to generate warnings on the site of the caller if the class > file format of the targeted method goes with javac v1.6 or below. > The proposal covers this in the spec: "if the target method was compiled targeting Java 7 or later" Bob From forax at univ-mlv.fr Fri Mar 6 00:28:38 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 06 Mar 2009 09:28:38 +0100 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> References: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> Message-ID: <49B0DEB6.4010308@univ-mlv.fr> Reinier Zwitserloot a ?crit : > Heh, that was the next proposal I was going to write. > > (Apologies for a long and technically complicated post. I've rewritten > it several times in an attempt to get to the point faster, but this is > the best I can do). > > It really pains me to rain on your parade. I was doing some > experimenting and found an admittedly very unlikely scenario that > isn't backwards compatible. Then I realized, that this is actually > (arguably) a bug, or at least a severe misfeature in javac right now! > Therefore, this proposal should fix this problem as well. Of all > proposals so far, I rate this one the highest, because it causes so > much confusion and is closer to a bug in javac than a language > feature, so I would be very happy if this proposal can be fully ironed > out. > > Complete code showing the problem - copy and paste into Main.java, > compile, and run: > > ------ > > import java.util.*; > > class Foo { > public void foo(T... t) {} > } > > class Bar extends Foo { > //de-varargsing? Why is this legal? > Because you want to be able to replace an array with a varargs in library without creating errors in code that use that library. > public void foo(String[] t) { > System.out.println(t.getClass().getComponentType()); > } > } > > public class Main { > public static void main(String[] args) { > Foo f = new Bar(); > List l = Arrays.asList("a", "b", "c"); > bar(f, l); > } > > public static void bar(Foo f, List l) { > f.foo(l.get(0), l.get(1), l.get(2)); > } > } > > ----- > > The result is an error: > > Exception in thread "main" java.lang.ClassCastException: > [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; > > Right now, you get the usual varargs warning, but nothing else at > compile time. At runtime, you get the above error. > Warnings in Java are not like in C, it means something will go wrong :) the call: f.foo(l.get(0), l.get(1), l.get(2)); generate a warning because you are creating an arry of parameterized type (a Foo[]) which are "inherently unsafe" to quote gilad bracha. > The real bug here is the ability for any subclass to de-varargs a > parameter. No [...] See: >> Angelika Langer's Java Generics FAQ, "Why does the compiler >> sometimes issue >> an unchecked warning when I invoke a 'varargs' method?" ( >> http://tinyurl.com/8w2dk) >> R?mi From david.goodenough at linkchoose.co.uk Fri Mar 6 01:47:22 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Fri, 6 Mar 2009 09:47:22 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <7D2077BFF677D2429DDDEE095D9A48AC01FED3@osiris2.e-spirit.de> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051709.46250.david.goodenough@linkchoose.co.uk> <7D2077BFF677D2429DDDEE095D9A48AC01FED3@osiris2.e-spirit.de> Message-ID: <200903060947.24239.david.goodenough@linkchoose.co.uk> On Thursday 05 March 2009, Schulz, Stefan wrote: > > I do not see (maybe I did not understand FCM) how I could handle > > foo#bar#ali. In this case you need a Field array, not just a field. > > Additionally the FCM case only seems to handle the Foo#bar case, > > not the foo#bar case. That is not the end of the world - it would work > > in the examples I need, but it is less than my proposal covers. > > Field literals as defined by FCM are meant to ease access for reflection. > There was no further intent, AFAIR, as to have an analogue to Method > literals. As the result is a Field instance, chaining does not make sense. > Literals are only defined on types not instances. > > I'm not sure about autoconverting foo#bar to some Property instance. The > main goal, as far as I understood, is to have compile time checks on > accessing properties instead of using Strings. Not sure, if this helps, but > just to note down the thought: > > As a prerequisite, we might need a generified Field class (not necessarily > has to be the java.reflect.Field class). Now assuming Foo having a field > bar of type Bar, and Bar having a field baz of type Baz. Using (generified) > Field literals, one could create a property builder taking Fields instead > of Strings as parameters, e.g.: > > Property p1 = PropertyBuilder.on(Foo.class).at(Foo#bar); > Property p2 = > PropertyBuilder.on(Foo.class).via(Foo#bar).at(Bar#baz); Property > p3 = PropertyBuilder.on(foo).at(Foo#bar); > Property p4 = PropertyBuilder.on(foo).via(Foo#bar).at(Bar#baz); > > I admit, this does not look as neat, but would serve the purpose. Or am I > missing the target? > > Cheers, > Stefan Yes it would server the purpose, and frankly ease of use is trumped by desparate need so I am happy to take any compiler checkable solution that works. In effect the Property class becomes the generified Field object, so that problem is circumvented. The only thing it can not do is to check that the chain is correct (i.e in the example above that Foo#bar is a Bar( at compile time. When the PropertyBuilding is building the Property it can, but that is a little later than I would like - but still a great improvement on evalutation time, added to which the chained case is a minority case. My only question concerns annotations. It is important that the Field object is the real one, and not a synthetic partial copy. The reason for this is so that I can access Annotations. If this will work then I am happy. So if FCM is going to be in -7 then my proposal is unnecessary. But of course that makes an assumption and unless I have missed something it seemed to be as far off as Property support. David From schulz at e-Spirit.de Fri Mar 6 02:07:14 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Fri, 6 Mar 2009 11:07:14 +0100 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903060947.24239.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com><200903051709.46250.david.goodenough@linkchoose.co.uk><7D2077BFF677D2429DDDEE095D9A48AC01FED3@osiris2.e-spirit.de> <200903060947.24239.david.goodenough@linkchoose.co.uk> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC105DEECA@osiris2.e-spirit.de> > In effect the Property class becomes the generified Field > object, so that > problem is circumvented. Well, the generified Field object should be returned by the reference, so that the generic type can be retrieved at compile-time, otherwise it would not make much sense. That's why the example uses the factory method at(), otherwise it will be difficult to have compile time type safety. > The only thing it can not do is to check that the chain is > correct (i.e in the > example above that Foo#bar is a Bar( at compile time. When the > PropertyBuilding is building the Property it can, but that > is a little later > than I would like - but still a great improvement on > evalutation time, added > to which the chained case is a minority case. You are right. I forgot about the correctness of the chain. And this will only be possible by a new notation. > My only question concerns annotations. It is important that > the Field object > is the real one, and not a synthetic partial copy. The > reason for this is > so that I can access Annotations. If this will work then I am happy. I don't understand this one. You won't annotate the Field class but the field, so the object returned will have to support Annotation retrieval, I guess. > So if FCM is going to be in -7 then my proposal is > unnecessary. But of course > that makes an assumption and unless I have missed something it seemed > to be as far off as Property support. FCM won't. But maybe a proposal for Field-Literals might have a chance, as it seems a coin to me. Not much magic about it, I think. But then again, I might miss the hard parts as I have no real insight into javac etc. @Joe: Would it make sense to file a proposal on Field-Literals or would it be doomed right away? And I am not sure, whether completing such a proposal by Method- and Constructor-Literals would become too big for Coin. Any hint? Further, I am not sure, how elaborate I could do it by myself, too, so any coop is welcome. Sorry, for getting off topic. Cheers, Stefan From david.goodenough at linkchoose.co.uk Fri Mar 6 02:10:38 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Fri, 6 Mar 2009 10:10:38 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <200903060947.24239.david.goodenough@linkchoose.co.uk> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <7D2077BFF677D2429DDDEE095D9A48AC01FED3@osiris2.e-spirit.de> <200903060947.24239.david.goodenough@linkchoose.co.uk> Message-ID: <200903061010.40646.david.goodenough@linkchoose.co.uk> On Friday 06 March 2009, David Goodenough wrote: > On Thursday 05 March 2009, Schulz, Stefan wrote: > > > I do not see (maybe I did not understand FCM) how I could handle > > > foo#bar#ali. In this case you need a Field array, not just a field. > > > Additionally the FCM case only seems to handle the Foo#bar case, > > > not the foo#bar case. That is not the end of the world - it would work > > > in the examples I need, but it is less than my proposal covers. > > > > Field literals as defined by FCM are meant to ease access for reflection. > > There was no further intent, AFAIR, as to have an analogue to Method > > literals. As the result is a Field instance, chaining does not make > > sense. Literals are only defined on types not instances. > > > > I'm not sure about autoconverting foo#bar to some Property instance. The > > main goal, as far as I understood, is to have compile time checks on > > accessing properties instead of using Strings. Not sure, if this helps, > > but just to note down the thought: > > > > As a prerequisite, we might need a generified Field class (not > > necessarily has to be the java.reflect.Field class). Now assuming Foo > > having a field bar of type Bar, and Bar having a field baz of type Baz. > > Using (generified) Field literals, one could create a property builder > > taking Fields instead of Strings as parameters, e.g.: > > > > Property p1 = PropertyBuilder.on(Foo.class).at(Foo#bar); > > Property p2 = > > PropertyBuilder.on(Foo.class).via(Foo#bar).at(Bar#baz); Property > Bar> p3 = PropertyBuilder.on(foo).at(Foo#bar); > > Property p4 = PropertyBuilder.on(foo).via(Foo#bar).at(Bar#baz); > > > > I admit, this does not look as neat, but would serve the purpose. Or am I > > missing the target? > > > > Cheers, > > Stefan > > Yes it would server the purpose, and frankly ease of use is trumped by > desparate need so I am happy to take any compiler checkable solution > that works. > > In effect the Property class becomes the generified Field object, so that > problem is circumvented. > > The only thing it can not do is to check that the chain is correct (i.e in > the example above that Foo#bar is a Bar( at compile time. When the > PropertyBuilding is building the Property it can, but that is a little > later than I would like - but still a great improvement on evalutation > time, added to which the chained case is a minority case. > > My only question concerns annotations. It is important that the Field > object is the real one, and not a synthetic partial copy. The reason for > this is so that I can access Annotations. If this will work then I am > happy. > > So if FCM is going to be in -7 then my proposal is unnecessary. But of > course that makes an assumption and unless I have missed something it > seemed to be as far off as Property support. > > David As a further thought, I don't suppose there is any chance of changing FCM slightly to have Foo#bar#ali produce a Field array? The simple case can continue to produce a single Field and the PropertyBuilder can have overloaded methods. That would get around the checkability problem. David From david.goodenough at linkchoose.co.uk Fri Mar 6 02:24:10 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Fri, 6 Mar 2009 10:24:10 +0000 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <7D2077BFF677D2429DDDEE095D9A48AC105DEECA@osiris2.e-spirit.de> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903060947.24239.david.goodenough@linkchoose.co.uk> <7D2077BFF677D2429DDDEE095D9A48AC105DEECA@osiris2.e-spirit.de> Message-ID: <200903061024.11476.david.goodenough@linkchoose.co.uk> On Friday 06 March 2009, Schulz, Stefan wrote: > > In effect the Property class becomes the generified Field > > object, so that > > problem is circumvented. > > Well, the generified Field object should be returned by the reference, so > that the generic type can be retrieved at compile-time, otherwise it would > not make much sense. That's why the example uses the factory method > at(), otherwise it will be difficult to have > compile time type safety. > > > The only thing it can not do is to check that the chain is > > correct (i.e in the > > example above that Foo#bar is a Bar( at compile time. When the > > PropertyBuilding is building the Property it can, but that > > is a little later > > than I would like - but still a great improvement on > > evalutation time, added > > to which the chained case is a minority case. > > You are right. I forgot about the correctness of the chain. And this will > only be possible by a new notation. If the FCM could be extended to produce a Field array if there was a chain that would be a good solution to this problem (see my other response). > > > My only question concerns annotations. It is important that > > the Field object > > is the real one, and not a synthetic partial copy. The > > reason for this is > > so that I can access Annotations. If this will work then I am happy. > > I don't understand this one. You won't annotate the Field class but the > field, so the object returned will have to support Annotation retrieval, I > guess. This concern arised from a problem with PropertyDescriptors. If you get a PropertyDescriptor for a field, and ask for its Type, the Class that is returned is the Class of the return object from the getter rather than the Class of the actual field. This means that you can not get access to any annotations that have been declared on the field. What I was worried about was that this mechanism might construct a Field object, rather than returning the real Field object held in the containing class, and thus be subject to the same problem. Sorry if I was unclear (I may still be unclear). > > > So if FCM is going to be in -7 then my proposal is > > unnecessary. But of course > > that makes an assumption and unless I have missed something it seemed > > to be as far off as Property support. > > FCM won't. But maybe a proposal for Field-Literals might have a chance, as > it seems a coin to me. Not much magic about it, I think. But then again, I > might miss the hard parts as I have no real insight into javac etc. Well I have started to work on that. I hope to have at least a first cut next week although it is making my head ache a bit. On second (or it is third) reading, the documentation I have found is making more sense than it did the previous times. > > @Joe: Would it make sense to file a proposal on Field-Literals or would it > be doomed right away? And I am not sure, whether completing such a proposal > by Method- and Constructor-Literals would become too big for Coin. Any > hint? I would be quite happy to reduce my proposal to just Field Literals. > > Further, I am not sure, how elaborate I could do it by myself, too, so any > coop is welcome. Sorry, for getting off topic. > > Cheers, Stefan David From reinier at zwitserloot.com Fri Mar 6 06:58:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 6 Mar 2009 15:58:06 +0100 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: <49B0DEB6.4010308@univ-mlv.fr> References: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> <49B0DEB6.4010308@univ-mlv.fr> Message-ID: The plot thickens. Javac v1.5 WILL warn you when you de-varargs a superclass. However, any javac v1.6 will NOT. Evidently one of the javac engineers had a reason to remove the warning. That reason would probably be very pertinent to this discussion. Anyone familiar enough with mercurial to dig the comment on this changeset out of the javac's repository? Remi - I covered the need to update superclasses without breaking implementers, but if you (re)compile a subclass that de-varargses when source compatibility mode is 1.5 or up, I can see absolutely no reason for javac to be silent about it. It should generate this warning. That change to javac 1.6 needs to be undone. If, as Remi suggests, we treat warnings as effective errors, and thus we treat generics-based arrays as something you really shouldn't ever use, then we have an entirely different bug: The varargs mechanism is then broken. Something as simple as this should then not be something you ever ought to do (eventhough in practice it can't go wrong and the warning generated by the following code snippet is a 'bug' in that there's no way it'll ever break): listOfLists = Arrays.asList(listA, listB); If there is no (acceptible) way to let the compiler figure out what is and isn't safe, then the only solution I can see is to introduce java.lang.VarArgs, and new syntax (4 dots?), or just re-use java.util.List. Either way, I'm still convinced that this is effectively a javac bug, or at the very least a severe 'feature' that has caused many tens of thousands of manhours of solution-hunting and frustration. For what it's worth, its my opinion that we can and should figure out when varargs methods are perfectly safe, generate no warnings anywhere if that happens and all involved code is compiled by javac7 or higher, and accept that Bad Things will happen if you varargs a non-reified type into a method where a subclass has reified the type (but that warning should be restored). After all, Bad Things happen now too, and in either situation you get at least 1 warning. However, in the proposed solution, the warning is at least moved to the place where it is more relevant: The programmer who is reifying that array type. Granted, without an additional proposal to rewrite a signature to Object[], there's nothing this programmer can do about it, but at least he knows what's happening. The current warning on the call site does absolutely nothing useful other than suggesting you can't really use varargs at all, eventhough (quite literally) in 99%+ of all cases, there's absolutely no danger whatsoever. --Reinier Zwitserloot On Mar 6, 2009, at 09:28, R?mi Forax wrote: > Reinier Zwitserloot a ?crit : >> Heh, that was the next proposal I was going to write. >> >> (Apologies for a long and technically complicated post. I've >> rewritten it several times in an attempt to get to the point >> faster, but this is the best I can do). >> >> It really pains me to rain on your parade. I was doing some >> experimenting and found an admittedly very unlikely scenario that >> isn't backwards compatible. Then I realized, that this is actually >> (arguably) a bug, or at least a severe misfeature in javac right >> now! Therefore, this proposal should fix this problem as well. Of >> all proposals so far, I rate this one the highest, because it >> causes so much confusion and is closer to a bug in javac than a >> language feature, so I would be very happy if this proposal can be >> fully ironed out. >> >> Complete code showing the problem - copy and paste into Main.java, >> compile, and run: >> >> ------ >> >> import java.util.*; >> >> class Foo { >> public void foo(T... t) {} >> } >> >> class Bar extends Foo { >> //de-varargsing? Why is this legal? >> > Because you want to be able to replace an array with a varargs in > library without > creating errors in code that use that library. >> public void foo(String[] t) { >> System.out.println(t.getClass().getComponentType()); >> } >> } >> >> public class Main { >> public static void main(String[] args) { >> Foo f = new Bar(); >> List l = Arrays.asList("a", "b", "c"); >> bar(f, l); >> } >> >> public static void bar(Foo f, List l) { >> f.foo(l.get(0), l.get(1), l.get(2)); >> } >> } >> > >> ----- >> >> The result is an error: >> >> Exception in thread "main" java.lang.ClassCastException: >> [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; >> >> Right now, you get the usual varargs warning, but nothing else at >> compile time. At runtime, you get the above error. >> > Warnings in Java are not like in C, it means something will go > wrong :) > > the call: > > f.foo(l.get(0), l.get(1), l.get(2)); > > generate a warning because you are creating an arry of parameterized > type > (a Foo[]) which are "inherently unsafe" to quote gilad bracha. > >> The real bug here is the ability for any subclass to de-varargs a >> parameter. > No > > [...] > > See: >>> Angelika Langer's Java Generics FAQ, "Why does the compiler >>> sometimes issue >>> an unchecked warning when I invoke a 'varargs' method?" ( >>> http://tinyurl.com/8w2dk) >>> > R?mi From reinier at zwitserloot.com Fri Mar 6 07:09:57 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 6 Mar 2009 16:09:57 +0100 Subject: Proposal: Import Aliases for Classes and Static Methods In-Reply-To: References: <49AF1114.3080205@sun.com> <49AF15DC.20408@gmail.com> Message-ID: <76EF2101-0CF8-4CDF-912F-9A36EE2A40C3@zwitserloot.com> package imports would solve all these problems no, and be simpler to boot? My major concern with type aliases is code snippets: When people post a snippet, they almost never include import statements. Many IDEs ship out-of-the-box as collapsing import statements but nothing else. They aren't generally considered important to grok any code snippet. But with type aliases, that changes. Note that anybody casually perusing a complete source file is effectively still 'reading a snippet', so to speak, though at least an IDE can help and e.g. jump to the proper class when ctrl+clicking the type, or showing the complete type in a tooltip. You don't have that problem with package imports. "sql.List" is about as easy to type as "SQLList", and it does not create the inherent confusion in the name that "SQLList" has; I would interpret any type named "SQLList" as "A List contain SQLs, whatever those are". Someone else will need to adapt or rewrite a proposal (my plate is full). Package imports don't help if the only difference in the FQN is near the front, but I don't know of any two commonly used classes together that differ only near the front. (e.g. sunw.io.Serializable vs. java.io.Serializable can't be simplified with package imports, but, nobody uses sunw.*, so not a relevant use case). --Reinier Zwitserloot On Mar 6, 2009, at 05:50, Phil Varner wrote: >> Static import was surprising complicated in JDK 5. While these >> aliases could alleviate some problems, I think they would be easily >> abused >> and even when not being abused render code less readable. >> IMO, having alternate names for potentially common classes would be >> less readable. > > I agree for common classes this could be a problem, but I don't think > it would be any less of a problem than the existing support for > wildcards. I see this more as a solution targeted mostly for long > package names with overlapping class names. I'm going to need to > think some about what "readable" really means, and would be interested > in any thoughts on this topic. > >> While grammar changes are part of the picture, the substantive >> changes would be to JLSv3 section 6.5 "Determining the Meaning of a >> Name": > > Thanks for pointing this out, it's definitely a huge hole in the > proposal. > >> The Javapolis discussions of 2007 ended with the majority of >> participants choosing against aliasing of imports (typedefs). >> >> http://www.javapolis.com/confluence/plugins/advanced/gallery-slideshow.action?pageId=32793&decorator=popup&imageNumber=9 > > Thanks for the pointer. I, too, would probably vote against a the > proposal of > import Map as CodeValueMap; > > Several of the related bugs mention this syntax, but I think this > combines two issues together. It seems to me that the simple mapping > of a fully-qualified class name to a "short" name is separate from the > typedefing of a specifically-parameterized generified type to a short > name. > > --Phil > > -- > > Machines might be interesting, but people are fascinating. -- K.P. > From markmahieu at googlemail.com Fri Mar 6 08:55:49 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 6 Mar 2009 16:55:49 +0000 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: References: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> <49B0DEB6.4010308@univ-mlv.fr> Message-ID: <3B6B416F-B1F8-4D65-810C-B1F8C0032C4A@googlemail.com> Reinier, On 6 Mar 2009, at 14:58, Reinier Zwitserloot wrote: > The plot thickens. Javac v1.5 WILL warn you when you de-varargs a > superclass. However, any javac v1.6 will NOT. Evidently one of the > javac engineers had a reason to remove the warning. That reason would > probably be very pertinent to this discussion. Anyone familiar enough > with mercurial to dig the comment on this changeset out of the javac's > repository? > is this what you're looking for? http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5048776 Regards, Mark From reinier at zwitserloot.com Fri Mar 6 11:20:02 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 6 Mar 2009 20:20:02 +0100 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: <3B6B416F-B1F8-4D65-810C-B1F8C0032C4A@googlemail.com> References: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> <49B0DEB6.4010308@univ-mlv.fr> <3B6B416F-B1F8-4D65-810C-B1F8C0032C4A@googlemail.com> Message-ID: <8A06B6EA-DC3B-46D8-AE6E-4321E7055AAD@zwitserloot.com> Mark, good find. It turns out that you can use varargs to invoke a method with signature: public void methodName(Foobar[] x) {} *IF* any supertype of the type containing this method has the same method with varargs. I assume that's why the warning was removed. This magic varargs behaviour is present in both javac 1.5 and javac 1.6. --Reinier Zwitserloot On Mar 6, 2009, at 17:55, Mark Mahieu wrote: > Reinier, > > On 6 Mar 2009, at 14:58, Reinier Zwitserloot wrote: > >> The plot thickens. Javac v1.5 WILL warn you when you de-varargs a >> superclass. However, any javac v1.6 will NOT. Evidently one of the >> javac engineers had a reason to remove the warning. That reason would >> probably be very pertinent to this discussion. Anyone familiar enough >> with mercurial to dig the comment on this changeset out of the >> javac's >> repository? >> > > is this what you're looking for? > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5048776 > > > Regards, > > Mark From crazybob at crazybob.org Fri Mar 6 11:46:50 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 11:46:50 -0800 Subject: PROPOSAL: Simplified Varargs Method Invocation In-Reply-To: <3B6B416F-B1F8-4D65-810C-B1F8C0032C4A@googlemail.com> References: <1782F7B0-2747-4D28-998B-929D0733291D@zwitserloot.com> <49B0DEB6.4010308@univ-mlv.fr> <3B6B416F-B1F8-4D65-810C-B1F8C0032C4A@googlemail.com> Message-ID: Thanks, Mark. I'll add bug #5048776 to the reference section. It sounds like we have three issues I'll address in the next rev: 1) Overriding vararg methods with array methods and vice versa: This generated a warning in Java 5, but it doesn't appear to do so in Java 6. I can't find anything about it in the JLS. I'm going to update the proposal to recommend that we bring the warning back in Java 7 (being sure to specify it in the JLS this time around). 2) Overriding a non-refiable varargs method with a reifiable varargs method (for example, T... with String...): If a client doesn't know the type of T and they call the reifiable version of the method through the non-reifiable API, the client will create an Object[], but the reifiable method only takes a ReifiableType[], so the client gets a CCE at run time. I don't think that modifying the reifiable method to use Object[] under the covers is a viable option. Doing so would break compatibility. For example, if I run against a library compiled with an older compiler, I'll get the CCE at run time but no warnings at compile time. It's interesting that not one of the references I cited mention this situation (it certainly doesn't spring to mind when I see an "unchecked or unsafe operation" warning). As an API designer, it's already the case today that I can't use varargs in this situation, so I'm going to update the proposal to suggest that we generate a warning when you try to override a non-reifiable varargs with a reifiable varargs. This has the added benefit of failing faster. If I do make this mistake in my API, I'll find out right away instead of waiting until someone tries to compile code that uses a non-reifiable type against my API. Addressing this issue makes the proposal even more compelling than before. On the bright side, there are no examples of this in the JDK. All of the varargs methods with non-reifiable types are static. 3) There is a small window where you'll get no warning. For example, I compile the API and client in Java 7 but run against a library compiled in Java 6. This is nothing new. For example, I could compile against a generified API, but run against an older implementation of the API compiled targeting Java 4 and get no warnings. I'll note this in the disadvantages section. Can you think of anything else I should address in the next rev? Thanks, Bob From tim at peierls.net Fri Mar 6 12:50:23 2009 From: tim at peierls.net (Tim Peierls) Date: Fri, 6 Mar 2009 15:50:23 -0500 Subject: Proposal: Block Expressions for Java Message-ID: <63b4e4050903061250r24df3e5braf5cd490c1753f80@mail.gmail.com> I kind of like Neal's block expression proposal, but I am struggling to find more compelling examples for it. Instead of *super((double pi = Math.PI ; pi*pi)**);* it would be clearer to write *super(Math.PI * Math.PI**);* Instead of public static final Map primes = ( Map t = new HashMap(); t.put(1, 2); t.put(2, 3); t.put(3, 5); t.put(4, 7); Collections.unmodifiableMap(t)); it would be better to use a Builder like the one in Google Collections' ImmutableMap: public static final ImmutableMap PRIMES = new ImmutableMap.Builder() .put(1, 2).put(2, 3).put(3, 5).put(4, 7) .build(); That particular example could in turn be rewritten more simply as public static final ImmutableMap PRIMES = ImmutableMap.of(1, 2, 2, 3, 3, 5, 4, 7); So while I understand the intention behind these examples, I think they could be improved. Any ideas? What I like about the proposal is the ability to add side-effects in places I currently can't without distorting the existing logic. For example, let's say I want to add logging of the value computed in the while-loop test of this fragment: while (jobsRemaining() > 0) { processSomeJobs(); } I could write: int j = jobsRemaining(); log.info("jobs remaining = %d", j); while (j > 0) { processSomeJobs(); j = jobsRemaining(); log.info("jobs remaining = %d", j); } but that means repeating the logging statement and introducing a variable j with scope greater than the while loop. If I don't introduce a variable I have to repeat the call to jobsRemaining(), which might not be appropriate if it's an expensive call (and I'd still have to repeat the logging call). I could write a helper method instead: int computeAndLogJobsRemaining() { int j = jobsRemaining(); log.info("jobs remaining = %d", j); return j; } ... while (computeAndLogJobsRemaining() > 0) { processSomeJobs(); } but that's adding a lot of machinery for something as conceptually simple as this. Similarly for solutions involving method interception. The proposed enhancement would (I think) let me write something like this: while (( int j = jobsRemaining(); log.info("jobs remaining = %d", j); j > 0 )) { // are two levels of parens necessary? processSomeJobs(); } which is exactly what I wanted to say, without having to change the structure of the original code. Could I get along without this? Absolutely. Would I find it useful? Yes, occasionally it would be quite handy. --tim From neal at gafter.com Fri Mar 6 12:58:40 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Mar 2009 12:58:40 -0800 Subject: Proposal: Block Expressions for Java In-Reply-To: <63b4e4050903061250r24df3e5braf5cd490c1753f80@mail.gmail.com> References: <63b4e4050903061250r24df3e5braf5cd490c1753f80@mail.gmail.com> Message-ID: <15e8b9d20903061258k128c1864i417bbb8444d8189e@mail.gmail.com> The places I would have found this most useful are in a super() invocation, where you simply can't write a local variable before, and in a control-flow expression of one sort or another, like ?:, &&, ||, or on the right-hand-side of an assert statement. This kind of thing is particularly useful in automatically-generated code. On Fri, Mar 6, 2009 at 12:50 PM, Tim Peierls wrote: > I kind of like Neal's block expression proposal, but I am struggling to find > more compelling examples for it. Instead of > > *super((double pi = Math.PI ; pi*pi)**);* > > it would be clearer to write > > *super(Math.PI * Math.PI**);* > > Instead of > > public static final Map primes = ( > ? ?Map t = new HashMap(); > ? ?t.put(1, 2); t.put(2, 3); t.put(3, 5); t.put(4, 7); > ? ?Collections.unmodifiableMap(t)); > > it would be better to use a Builder like the one in Google Collections' > ImmutableMap: > > public static final ImmutableMap PRIMES = ? ? new > ImmutableMap.Builder() > ? ? ? ?.put(1, 2).put(2, 3).put(3, 5).put(4, 7) > ? ? ? ?.build(); > > That particular example could in turn be rewritten more simply as > > public static final ImmutableMap PRIMES = > ? ?ImmutableMap.of(1, 2, 2, 3, 3, 5, 4, 7); > > So while I understand the intention behind these examples, I think they > could be improved. ?Any ideas? > > What I like about the proposal is the ability to add side-effects in places > I currently can't without distorting the existing logic. For example, let's > say I want to add logging of the value computed in the while-loop test > of this fragment: > > while (jobsRemaining() > 0) { > ? ?processSomeJobs(); > } > > I could write: > > int j = jobsRemaining(); > log.info("jobs remaining = %d", j); > while (j > 0) { > ? ?processSomeJobs(); > ? ?j = jobsRemaining(); > ? ?log.info("jobs remaining = %d", j); > } > > but that means repeating the logging statement and introducing a variable j > with scope greater than the while loop. If I don't introduce a variable I > have to repeat the call to jobsRemaining(), which might not be appropriate > if it's an expensive call (and I'd still have to repeat the logging call). > > I could write a helper method instead: > > int computeAndLogJobsRemaining() { > ? ?int j = jobsRemaining(); > ? ?log.info("jobs remaining = %d", j); > ? ?return j; > } > ... > while (computeAndLogJobsRemaining() > 0) { > ? ?processSomeJobs(); > } > > but that's adding a lot of machinery for something as conceptually simple as > this. Similarly for solutions involving method interception. > > The proposed enhancement would (I think) let me write something like this: > > while (( > ? ?int j = jobsRemaining(); > ? ?log.info("jobs remaining = %d", j); > ? ?j > 0 > )) { ? ? ? ? ? ? ? ? ? ?// are two levels of parens necessary? > ? ?processSomeJobs(); > } > > which is exactly what I wanted to say, without having to change the > structure of the original code. > > Could I get along without this? Absolutely. ?Would I find it useful? ?Yes, > occasionally it would be quite handy. > > --tim > > From crazybob at crazybob.org Fri Mar 6 13:11:06 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 13:11:06 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: The "finally" modifier is very clever, but I think we're underestimating its complexity and overestimating its benefits. All of the use cases I've seen can be supported by pure syntax sugar based on two interfaces: Disposable.dispose() and Resource.close(). I've come across one exception: Apache HttpClient. It just so happens I'm a contributer to that project, and I'd rather make HttpResponse implement Closeable than add the complexity of supporting "finally" to the language. In other words, I'd much rather us adapt our APIs to support a very simple language feature than add a complex feature like the finally modifier, modify the bytecode format, etc. The examples where the interface-based approach works well are too numerous to count. Does anyone have real world examples where adapting an API to work with Disposable or Resource would be so egregious as to justify the complexity inherent in the finally modifier? Please limit examples to only those that you would actually want to use with this language construct. For example, Lock.unlock() and Process.destroy() don't count, but this construct would certainly come in handy for Process.getInputStream/OutputStream/ErrorStream(). Bob From crazybob at crazybob.org Fri Mar 6 13:14:50 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 13:14:50 -0800 Subject: Proposal: Block Expressions for Java In-Reply-To: <15e8b9d20903061258k128c1864i417bbb8444d8189e@mail.gmail.com> References: <63b4e4050903061250r24df3e5braf5cd490c1753f80@mail.gmail.com> <15e8b9d20903061258k128c1864i417bbb8444d8189e@mail.gmail.com> Message-ID: On Fri, Mar 6, 2009 at 12:58 PM, Neal Gafter wrote: > The places I would have found this most useful are in a super() > invocation, where you simply can't write a local variable before Can we just lighten the restrictions on what you can do before calling super()? I know the VM already supports it. Bob From Joe.Darcy at Sun.COM Fri Mar 6 13:33:04 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 06 Mar 2009 13:33:04 -0800 Subject: PROPOSAL: Lightweight Properties In-Reply-To: <7D2077BFF677D2429DDDEE095D9A48AC105DEECA@osiris2.e-spirit.de> References: <96DF7D6A-C683-4989-955C-D4A90BBC4B54@zwitserloot.com> <200903051709.46250.david.goodenough@linkchoose.co.uk> <7D2077BFF677D2429DDDEE095D9A48AC01FED3@osiris2.e-spirit.de> <200903060947.24239.david.goodenough@linkchoose.co.uk> <7D2077BFF677D2429DDDEE095D9A48AC105DEECA@osiris2.e-spirit.de> Message-ID: <49B19690.4070701@sun.com> Schulz, Stefan wrote: >> In effect the Property class becomes the generified Field >> object, so that >> problem is circumvented. >> > > Well, the generified Field object should be returned by the reference, so that the generic type can be retrieved at compile-time, otherwise it would not make much sense. That's why the example uses the factory method at(), otherwise it will be difficult to have compile time type safety. > > >> The only thing it can not do is to check that the chain is >> correct (i.e in the >> example above that Foo#bar is a Bar( at compile time. When the >> PropertyBuilding is building the Property it can, but that >> is a little later >> than I would like - but still a great improvement on >> evalutation time, added >> to which the chained case is a minority case. >> > > You are right. I forgot about the correctness of the chain. And this will only be possible by a new notation. > > >> My only question concerns annotations. It is important that >> the Field object >> is the real one, and not a synthetic partial copy. The >> reason for this is >> so that I can access Annotations. If this will work then I am happy. >> > > I don't understand this one. You won't annotate the Field class but the field, so the object returned will have to support Annotation retrieval, I guess. > > >> So if FCM is going to be in -7 then my proposal is >> unnecessary. But of course >> that makes an assumption and unless I have missed something it seemed >> to be as far off as Property support. >> > > FCM won't. But maybe a proposal for Field-Literals might have a chance, as it seems a coin to me. Not much magic about it, I think. But then again, I might miss the hard parts as I have no real insight into javac etc. > > @Joe: Would it make sense to file a proposal on Field-Literals or would it be doomed right away? And I am not sure, whether completing such a proposal by Method- and Constructor-Literals would become too big for Coin. Any hint? > I would judge field, method, and constructor literals to be too large for Project Coin. Cheers, -Joe From markmahieu at googlemail.com Fri Mar 6 13:40:16 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 6 Mar 2009 21:40:16 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: Hi, Bob. On 6 Mar 2009, at 21:11, Bob Lee wrote: > Does anyone have real world > examples where adapting an API to work with Disposable or Resource > would be > so egregious as to justify the complexity inherent in the finally > modifier? > Please limit examples to only those that you would actually want to > use with > this language construct. Well, that is what I've been doing. Josh suggested an interface in the proposal and asked for people to look for real APIs that it wouldn't work with. I pointed one out, Josh suggested another variation, I found another API. Now you're suggesting yet another variation, which is fine but personally I'm not going to keep this little loop going ad infinitum, and that is why I suggested an alternative approach that may be worth investigating. I suppose what I should really do is try to find the notes I made just over a year ago when I built my prototype of the earlier version of ARM, but off the top of my head I don't recall there being anything that would help here. However, I do know that the 'finally' modifier definitely wasn't something I investigated. > > Bob > Regards, Mark From suranap at gmail.com Fri Mar 6 13:44:20 2009 From: suranap at gmail.com (Pinku Surana) Date: Fri, 6 Mar 2009 16:44:20 -0500 Subject: PROPOSAL: Multiple switch expressions and case ranges In-Reply-To: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> References: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> Message-ID: <30992e5d0903061344w1cbf4285i143291cae930bdeb@mail.gmail.com> Updated: Added relevant bug id. Added support for sequences within ranges. More info on how to compile this feature. Maybe this should be split into two proposals? (1) case ranges and (2) multiple switch expressions. AUTHOR(S): Pinku Surana OVERVIEW FEATURE SUMMARY: Extend the switch statement to support multiple switch expressions and case ranges. MAJOR ADVANTAGE: It is syntactic sugar that makes it easier to write/read complex logic. This is one small aspect of the vastly more powerful match or case expression in functional languages. MAJOR BENEFIT: Better readability for complex cases, and potentially better performance relative to if statements. MAJOR DISADVANTAGE: Requires changes to compiler. ALTERNATIVES: It can currently be implemented with if statements. EXAMPLES Show us the code! SIMPLE EXAMPLE: Show the simplest possible program utilizing the new feature. switch (c) { case ['a'..'z']: return "lower case" ; case ['A'..'Z']: return "upper case" ; default: return "something else" ; } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. switch (suit, value) { case [SPADE,CLUB], [2..10] : return "black low-value card" ; case [HEART,DIAMOND], [2..10] : return "red low-value card" ; case _, [11..14] : return "face card" ; } 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. * The lexer will need to support underscore ('_') and ".." * The parser rules for switch statements must be changed. SwitchStatement: switch (Expression [, Expression]*) SwitchBlock SwitchLabel: case CaseExpression [, CaseExpression]* : default : CaseExpression: _ ConstantExpression EnumConstantName [ CaseRanges ] CaseRanges CaseRange CaseRanges , CaseRange CaseRange ConstantExpression EnumConstantName ConstantExpression .. ConstantExpression EnumConstantName .. EnumConstantName * Semantic rules: - The number of CaseExpressions must equal the number of expressions in the SwitchStatement - The underscore ('_') means "don't care" - In [ c1 .. c2], c1 should be less than c2 - The types of the constants/enums must match the type of the expression in the same position - If the range of constants/enums overlap between case arms, then raise an error. COMPILATION: The implementation for these two features is similar to that of switch in any optimizing compiler. There are two popular implementations for switch: jump tables (JT) and branching search (BS). This high-level switch statement must be "lowered" to a combination of JT and BS, either implementing them manually and/or using the switch bytecode where appropriate. First, case ranges are a simple extension because it gives the compiler an easily recognizable dense region of constants. If that range is small enough (ask the JIT guys), then use the switch bytecode so the JIT will generate an efficient JT. If the range is large and the JIT would have done BS anyway, implement the range checks using standard BS techniques. These techniques have been around for over 30 years. Second, multiple switch expressions are a bit more complicated, but the implementation has existed in pattern matcher compilers for functional languages for over 20 years. In fact, this will be much simpler because it only supports constants. Basically, the compiler builds a decision tree where the case constant/ranges are at the leaves. Then it merges redundant checks and generates BS code and/or uses the switch bytecode to get the JIT to implement a JT. TESTING: How can the feature be tested? Normal compiler testing. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? None 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. The package com.sun.source.tree will need to return a list of switch expressions and case constants. Also, new expression nodes must be added for ranges and for the "don't care" underscore. 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. Don't think so. MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. I think this would be difficult because the logic would be obscured in if statements. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. None. 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? Should be backwards compatible. REFERENCES EXISTING BUGS: Please include a list of any existing Sun bug ids related to this proposal. 4269827 I couldn't find any RFEs for multiple switch expressions. URL FOR PROTOTYPE (optional): If there's interest, I can cook up a prototype with Polyglot. From suranap at gmail.com Fri Mar 6 14:17:49 2009 From: suranap at gmail.com (Pinku Surana) Date: Fri, 6 Mar 2009 17:17:49 -0500 Subject: PROPOSAL: Multiple switch expressions and case ranges In-Reply-To: References: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> Message-ID: <30992e5d0903061417r14c7b0f1k7b84cc48f218db@mail.gmail.com> Let me try to answer some questions: 1) How do you compile the switch statement? I've updated my proposal to include more info, though the techniques are well known for switch statements and pattern matchers. The main thing I do not know is when will the JIT create a jump table for a small, dense range of numbers. The switch is compiled into bytecodes to implement search by branching, but when a subset fits the JIT's idea of "small" then the compiler should use the switch bytecode. It's not rocket surgery. ;-) 2) Why doesn't this proposal have more fancy stuff in it? Project Coin is for "small" changes, and I think these changes are small from the programmer's perspective. More importantly, the many dozens of attempts to add pattern matching to Java-like languages have been extremely complex. Take a look at active patterns in F# or JMatch's modes. For example, adding a type check to this proposal suddenly introduces multiple dispatch problems: TypeB is-a TypeA; TypeB obj1, obj2 ; switch (obj1, obj2) { case TypeA x, TypeB y: f(x,y) ; case TypeB y, TypeA x: g(x,y) ; } Without multiple switch expressions, adding type checks is much simpler and could generate vastly better code than a sequence of instanceof calls. But that's another proposal. - Pinku On Thu, Mar 5, 2009 at 8:15 PM, Reinier Zwitserloot wrote: > This proposal does not appear to be complete. As you yourself mention, > attempting to switch on [0 .. 1000000000] would generate an enormous > class file. Also, your first desugaring example, which rewrites a > multi-switch statement to nested switch statements, is certainly not a > trivial operation. Where's the specification (and preferably some > example code) on how the compiler is supposed to get from the sugar to > the desugar? Perhaps this is an error in the Project Coin form, but > all proposals should list chapter and verse of the JLS entries that > need to be updated, which neccessarily includes a complete and > detailed treatment on how the compiler is supposed to do the job. A > single example desugaring isn't good enough. > > Any proposal that includes words like 'If XYZ is too big', is > neccessarily not ready for this mailing list (as a proposal. It's fine > as a request for comments and help). When does a range become too big? > Could you explain the impact on size vs. lookup speed and make a solid > recommendation for the right size to switch over? > > There's no need to update reflection APIs; you can't get at method > code with them. You have to update the internal AST API, which you > could list for completeness sake, but I don't think that's the intent > of the Project Coin form (though, most proposals so far do mention it. > I feel its not neccessary because 99% of all project coin proposals I > can even think of require it. It's kind of implied when you say > "Language Change Proposal"). JNI, the javadoc tool. > > I sort of like where this proposal is going, but as you yourself > mentioned, the power of match/case in languages like Scala and Haskell > is scary, and thus this proposal needs to be well aware of how java > might some day get there, and be sure that we don't close future > avenues early by screwing up now. I think this idea is probably out of > scope, but I'll let Joe Darcy and friends be the judge of that. At the > very least I would expect this system to work with Comparables, > assuming the input and both range ends are all Comparable-compatible > with each other (as provided by generics). Matching on type is also a > relevant usecase in my opinion, so even if your proposal doesn't add > it, you may want to include a rough sketch just to show that your > syntax won't get in the way of a future expansion. > > > > --Reinier Zwitserloot > > > > On Mar 5, 2009, at 23:16, Pinku Surana wrote: > > > Has the switch statement in C languages evolved much since the '80s? > > I'm > > envious of the case/match expression in functional languages and > > looking for > > simple ways to make 'switch' more powerful. > > > > > > > > AUTHOR(S): Pinku Surana > > > > OVERVIEW > > > > FEATURE SUMMARY: > > > > Extend the switch statement to support multiple switch expressions > > and case > > ranges. > > > > MAJOR ADVANTAGE: > > > > It is syntactic sugar that makes it easier to write/read complex > > logic. This is one small aspect of the vastly more powerful match or > > case expression in functional languages. > > > > MAJOR BENEFIT: > > > > Better readability for complex cases, and potentially better > > performance relative to if statements. > > > > MAJOR DISADVANTAGE: > > > > Requires changes to compiler. > > > > ALTERNATIVES: > > > > It can currently be implemented with if statements. > > > > EXAMPLES > > > > Show us the code! > > > > SIMPLE EXAMPLE: Show the simplest possible program utilizing the new > > feature. > > > > switch (c) { > > case ['a'..'z']: return "lower case" ; > > case ['A'..'Z']: return "upper case" ; > > default: return "something else" ; > > } > > > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > > > switch (suit, value) { > > case [SPADE..CLUB], [2..10] : return "black low-value card" ; > > case [HEART..DIAMOND], [2..10] : return "red low-value card" ; > > case _, [11..14]: return "face card" ; > > } > > > > 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. > > > > * The lexer will need to support underscore ('_') and ".." > > * The parser rules for switch statements must be changed. > > > > SwitchStatement: > > switch (Expression [, Expression]*) SwitchBlock > > > > SwitchLabel: > > case CaseExpressions : > > default : > > > > CaseExpressions: > > CaseExpression > > CaseExpressions , CaseExpression > > > > CaseExpression: > > _ > > ConstantExpression > > [ ConstantExpression .. ConstantExpression ] > > EnumConstantName > > [ EnumConstantName .. EnumConstantName ] > > > > * Semantic rules: > > - The number of CaseExpressions must equal the number of > > expressions in > > the SwitchStatement > > - The underscore ('_') means "don't care" > > - In [ c1 .. c2], c1 should be less than c2 > > - The types of the constants/enums must match the type of the > > expression > > in the same position > > - If the range of constants/enums overlap between case arms, then > > raise an > > error. > > > > COMPILATION: > > > > Simple desugaring transformations: > > > > ---------------------------------- > > switch (e1, e2) { > > case C1, C2: stmt1 ; > > case C3, _: stmt2 ; > > default: stmt3 ; > > } > > ==> > > x = e1 ; > > y = e2 ; > > switch (x) { > > case C1: switch (y) { > > case C2: stmt1 ; > > case C4: stmt2 ; > > default: stmt3 ; > > } > > break ; > > case C3: stmt2 ; > > break ; > > default: stmt3 ; > > } > > ----------------------------------- > > case [V1 .. Vn] : stmts ; > > ==> > > case V1: > > case V2: > > ... > > case Vn: stmts ; > > ----------------------------------- > > > > > > Both of these could blow up in code size. Therefore, a better > > implementation of the switch would compile down to gotos to the > > correct statement block. This is why proper compiler support would > > be nice. > > > > For case ranges, if the range is too big then turn into an if > > statement: > > "if (x >= V1 && x <= V2)". > > > > > > TESTING: How can the feature be tested? > > > > Normal compiler testing. > > > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > > > > None > > > > 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. > > > > The reflection APIs will need to return a list of switch expressions > > and case constants. Also, new expression nodes must be added for > > ranges and for the "don't care" underscore. > > > > 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. > > > > Don't think so. > > > > MIGRATION: Sketch how a code base could be converted, manually or > > automatically, to use the new feature. > > > > I think this would be difficult because the logic would be obscured > > in if > > statements. > > > > COMPATIBILITY > > > > BREAKING CHANGES: Are any previously valid programs now invalid? If > > so, list > > one. > > > > None. > > > > 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? > > > > Should be backwards compatible. > > > > REFERENCES > > > > EXISTING BUGS: Please include a list of any existing Sun bug ids > > related to > > this proposal. > > > > URL FOR PROTOTYPE (optional): > > > > If there's interest, I can cook up a prototype with Polyglot. > > > > > From crazybob at crazybob.org Fri Mar 6 14:54:59 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 14:54:59 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: Mark, On Fri, Mar 6, 2009 at 1:40 PM, Mark Mahieu wrote: > On 6 Mar 2009, at 21:11, Bob Lee wrote: > >> Does anyone have real world >> examples where adapting an API to work with Disposable or Resource would >> be >> so egregious as to justify the complexity inherent in the finally >> modifier? >> Please limit examples to only those that you would actually want to use >> with >> this language construct. >> > > Well, that is what I've been doing. Let me rephrase. I'm suggesting that we shouldn't try to cater to each and every existing use case--it's not worth it. I didn't recommend supporting "Disposable.dispose()" because it works seamlessly for some existing use cases. It's just a coincidence that its signature matches. I suggested "dispose()" because it sounds more general than "close()" and has wider applicability for future APIs. We could just as easily use "release", but we should just pick one (in addition to close()). We have to draw the line somewhere, and less is more. Heck, maybe we should just support close()! As someone who is partially responsible for the API of the most ill-fitting use case (HttpResponse), I'm saying I'd rather keep the language simple and adapt the API. For other existing APIs, we can add close() or dispose() or introduce adapter classes. It appears the cases where this is necessary are relatively rare though. This reminds me a bit of foreach and java.util.Enumeration. Does it bother you much that foreach foreach doesn't support Enumeration? It doesn't me. I'm glad that foreach is simpler and easier to learn. I think it's a good thing that foreach has encouraged API designers to converge on supporting Iterable (as opposed to Enumeration and Iterator directly). In that same vein, if we take the interface-based approach, "try resource" would encourage API designer's to converge on one or two interfaces, something that would enable further APIs that deal with Disposables (like Neal suggested). As an aside, if I were writing a library that deals with Disposables, it would not bother me that dispose() throws Exception. In general, I'm either going to wrap the exception and rethrow it or log it somehow. Bob From neal at gafter.com Fri Mar 6 15:19:26 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Mar 2009 15:19:26 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> On Fri, Mar 6, 2009 at 1:11 PM, Bob Lee wrote: > The "finally" modifier is very clever, but I think we're underestimating its > Does anyone have real world > examples where adapting an API to work with Disposable or Resource would be > so egregious as to justify the complexity inherent in the finally modifier? > Please limit examples to only those that you would actually want to use with > this language construct. For example, Lock.unlock() and Process.destroy() > don't count If you've already decided which resource-like APIs "count", then you don't need to ask us. Personally, I'd like java.util.locks.Lock to be easier to use, though I understand this proposal doesn't solve that. We've already discussed sql transactions too. From markmahieu at googlemail.com Fri Mar 6 15:27:05 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 6 Mar 2009 23:27:05 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> Message-ID: Right - I do agree with your points in general, and there are certainly aspects of the interface approach that I like very much. All I'm suggesting is that using a modifier instead is a possible alternative that I personally think is worth investigating. I certainly don't think it's clearly better or anything like that; I don't see enough evidence either way at this point, and as I said when I suggested it, I can think of a number of questions that would need answering. Please don't take the fact that I've been looking for problematic APIs, or suggesting alternatives, as a negative; my intention is to provide constructive points (critical or otherwise) which are of value to the discussion and the proposal. In particular, I think that documenting specific examples of problematic APIs adds to the proposal rather than detracts from it. Best regards, Mark On 6 Mar 2009, at 22:54, Bob Lee wrote: > > Let me rephrase. I'm suggesting that we shouldn't try to cater to > each and every existing use case--it's not worth it. I didn't > recommend supporting "Disposable.dispose()" because it works > seamlessly for some existing use cases. It's just a coincidence > that its signature matches. I suggested "dispose()" because it > sounds more general than "close()" and has wider applicability for > future APIs. We could just as easily use "release", but we should > just pick one (in addition to close()). We have to draw the line > somewhere, and less is more. Heck, maybe we should just support > close()! > > As someone who is partially responsible for the API of the most ill- > fitting use case (HttpResponse), I'm saying I'd rather keep the > language simple and adapt the API. For other existing APIs, we can > add close() or dispose() or introduce adapter classes. It appears > the cases where this is necessary are relatively rare though. > > This reminds me a bit of foreach and java.util.Enumeration. Does it > bother you much that foreach foreach doesn't support Enumeration? > It doesn't me. I'm glad that foreach is simpler and easier to > learn. I think it's a good thing that foreach has encouraged API > designers to converge on supporting Iterable (as opposed to > Enumeration and Iterator directly). In that same vein, if we take > the interface-based approach, "try resource" would encourage API > designer's to converge on one or two interfaces, something that > would enable further APIs that deal with Disposables (like Neal > suggested). > > As an aside, if I were writing a library that deals with > Disposables, it would not bother me that dispose() throws > Exception. In general, I'm either going to wrap the exception and > rethrow it or log it somehow. > > Bob From crazybob at crazybob.org Fri Mar 6 16:02:12 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 16:02:12 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903031947g75dc9a6n908b959bfb57c0d2@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> Message-ID: On Fri, Mar 6, 2009 at 3:19 PM, Neal Gafter wrote: > If you've already decided which resource-like APIs "count", then you > don't need to ask us. Did I unfairly discount some APIs? If so, please speak up. > Personally, I'd like java.util.locks.Lock to be > easier to use, though I understand this proposal doesn't solve that. While hugely beneficial for I/O operations, this language feature would be overkill for locks--locks don't throw exceptions, don't need to be nested, aren't interacted with in the statement block, etc. A synchronized (Lock) syntax wouldn't have been bad if introduced in Java 5 though. > We've already discussed sql transactions too. > I thought it was clear that this language construct works fine w/ SQL transactions. I guess not. It is unfortunate that Connection.close() doesn't specify commit/rollback behavior (when auto-commit is disabled). .Net's SqlConnection does the right thing (Go, M$! :-)). Most people would expect that if you close a connection without explicitly committing the tx, the tx should roll back. Unfortunately, Oracle's impl does just the opposite; it commits the tx! Most people don't use the raw JDBC API to manage their txs, but if you do, you have a couple options. a) Maybe your connection pool does the right thing already--that is roll back uncommitted txs when returning a connection to the pool. If you're not sure whether or not your impl does the right thing, play it safe and b) wrap the connection. try (Connection c = safe(...)) { ... } I should reiterate, most people use more modern, higher-level APIs like @Transactional or even javax.transaction, not Connection. If you use Connection to manage a tx, you have to pass the same Connection all over the place--not recommended. Bob From crazybob at crazybob.org Fri Mar 6 16:13:59 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 6 Mar 2009 16:13:59 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> Message-ID: On Fri, Mar 6, 2009 at 4:02 PM, Bob Lee wrote: > If you're not sure whether or not your impl does the right thing, play it > safe and b) wrap the connection. > I should further point out that this language feature does not create the need for a wrapper. You should have the wrapper already, unless of course you enjoy writing the same rollback/close logic over and over. Connection wrappers are also already necessary for other reasons: http://weblogs.java.net/blog/crazybob/archive/2004/03/patch_leaky_con.html Bob From markmahieu at googlemail.com Fri Mar 6 16:26:54 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 7 Mar 2009 00:26:54 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> Message-ID: <8924C8BC-FDBD-46EC-BEC8-A45A32CC5B47@googlemail.com> On 7 Mar 2009, at 00:13, Bob Lee wrote: > > I should further point out that this language feature does not > create the > need for a wrapper. You should have the wrapper already, unless of > course > you enjoy writing the same rollback/close logic over and over. > Connection > wrappers are also already necessary for other reasons: > http://weblogs.java.net/blog/crazybob/archive/2004/03/ > patch_leaky_con.html > > Bob > They certainly are. After putting a system live a couple of years ago we found that the VM was mysteriously switching timezone part way through the day. Turned out to be the JDBC driver changing the timezone to do a calculation, then changing it back. Apart from being an incredible hack, it was also completely unsynchronized, so when the system was under load one thread would change it, then another would store the changed value as the one it should restore it to, after which the VM was permanently in the other timezone. Mark From neal at gafter.com Fri Mar 6 17:08:51 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Mar 2009 17:08:51 -0800 Subject: Proposal: Block Expressions for Java In-Reply-To: References: <63b4e4050903061250r24df3e5braf5cd490c1753f80@mail.gmail.com> <15e8b9d20903061258k128c1864i417bbb8444d8189e@mail.gmail.com> Message-ID: <15e8b9d20903061708p8fd3d7eh4e6cf3df29c258ad@mail.gmail.com> On Fri, Mar 6, 2009 at 1:14 PM, Bob Lee wrote: > On Fri, Mar 6, 2009 at 12:58 PM, Neal Gafter wrote: >> >> The places I would have found this most useful are in a super() >> invocation, where you simply can't write a local variable before > > Can we just lighten the restrictions on what you can do before calling > super()? I know the VM already supports it. Not easily. It would require adding a whole new set of definite-assignment-like rules to ensure that super() gets called exactly once. Currently, the rule is that if the first statement isn't a super call, then super() is implicitly inserted. From neal at gafter.com Fri Mar 6 17:36:56 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 6 Mar 2009 17:36:56 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> Message-ID: <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> On Fri, Mar 6, 2009 at 4:02 PM, Bob Lee wrote: > On Fri, Mar 6, 2009 at 3:19 PM, Neal Gafter wrote: >> >> If you've already decided which resource-like APIs "count", then you >> don't need to ask us. > > Did I unfairly discount some APIs? If so, please speak up. I did, and you quoted me just after asking the question (see below, for example). Apparently, because some other use cases are more problematic, you feel that the ones I brought up are unimportant. I've certainly run into situations where automatic pairing of resource acquisition and release for java.util.concurrent locks would have avoided errors. I know that supporting resource acquisition and release for all the different resource APIs that exist (or will exist) in Java is difficult to do apriori in a language change (which is why I prefer an API-based solution), but pretending the use cases don't exist seems dishonest. >> Personally, I'd like java.util.locks.Lock to be >> easier to use, though I understand this proposal doesn't solve that. From reinier at zwitserloot.com Fri Mar 6 22:03:25 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 7 Mar 2009 07:03:25 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword Message-ID: We have written up a proposal for adding a 'source' and 'encoding' keyword (alternatives to the -source and -encoding keywords on the command line; they work pretty much just as you expect). The keywords are context sensitive and must both appear before anything else other than comments to be parsed. In case the benefit isn't obvious: It is a great help when you are trying to port a big project to a new source language compatibility. Leaving half your sourcebase in v1.6 and the other half in v1.7 is pretty much impossible today, it's all-or- nothing. It should also be a much nicer solution to the 'assert in v1.4' dilemma, which I guess is going to happen to v1.7 as well, given that 'module' is most likely going to become a keyword. Finally, it makes java files a lot more portable; you no longer run into your strings looking weird when you move your Windows-1252 codefile java source to a mac, for example. Before we finish it though, some open questions we'd like some feedback on: A) Technically, starting a file with "source 1.4" is obviously silly; javac v1.4 doesn't know about the source keyword and would thus fail immediately. However, practically, its still useful. Example: if you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 syntax), but have a few files remaining on GWT v1.4 (which uses java 1.4 syntax), then tossing a "source 1.4;" in those older files eliminates all the generics warnings and serves as a reminder that you should still convert those at some point. However, it isn't -actually- compatible with a real javac 1.4. We're leaning to making "source 1.6;" (and below) legal even when using a javac v1.7 or above, but perhaps that's a bridge too far? We could go with magic comments but that seems like a very bad solution. also: Encoding is rather a hairy issue; javac will need to read the file to find the encoding, but to read a file, it needs to know about encoding! Fortunately, *every single* popular encoding on wikipedia's popular encoding list at: http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings will encode "encoding own-name-in-that-encoding;" the same as ASCII would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt anyone ever uses to program java). Therefore, the proposal includes the following strategy to find the encoding statement in a java source file without knowing the encoding beforehand: An entirely separate parser (the encoding parser) is run repeatedly until the right encoding is found. First it'll decode the input with ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per the java standard), then as UTF-32 (BE if no BOM), then the current behaviour (-encoding parameter's value if any, otherwise platform default encoding). This separate parser works as follows: 1. Ignore any comments and whitespace. 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if that pattern matches partially but is not correctly completed, that parser run exits without finding an encoding, immediately. 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches partially but is not correctly completed, that parser run exists without finding an encoding, immediately. If it does complete, the parser also exists immediately and returns the captured value. 5. If it finds anything else, stop immediately, returning no encoding found. Once it's found something, the 'real' java parser will run using the found encoding (this overrides any -encoding on the command line). Note that the encoding parser stops quickly; For example, if it finds a stray \0 or e.g. the letter 'i' (perhaps the first letter of an import statement), it'll stop immediately. If an encoding is encountered that was not found during the standard decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to a platform default/command line encoding param, (e.g. a platform that defaults to UTF-16LE without a byte order mark) a warning explaining that the encoding statement isn't doing anything is generated. Of course, if the encoding doesn't match itself, you get an error (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If there is no encoding statement, the 'real' java parser does what it does now: Use the -encoding parameter of javac, and if that wasn't present, the platform default. However, there is 1 major and 1 minor problem with this approach: B) This means javac will need to read every source file many times to compile it. Worst case (no encoding keyword): 5 times. Standard case if an encoding keyword: 2 times (3 times if UTF-16). Fortunately all runs should stop quickly, due to the encoding parser's penchant to quit very early. Javacs out there will either stuff the entire source file into memory, or if not, disk cache should take care of it, but we can't prove beyond a doubt that this repeated parsing will have no significant impact on compile time. Is this a showstopper? Is the need to include a new (but small) parser into javac a showstopper? C) Certain character sets, such as ISO-2022, can make the encoding statement unreadable with the standard strategy if a comment including non-ASCII characters precedes the encoding statement. These situations are very rare (in fact, I haven't managed to find an example), so is it okay to just ignore this issue? If you add the encoding statement after a bunch of comments that make it invisible, and then compile it with the right -encoding parameter, you WILL get a warning that the encoding statement isn't going to help a javac on another platform / without that encoding parameter to figure it out, so you just get the current status quo: your source file won't compile without an explicit -encoding parameter (or if that happens to be the platform default). Should this be mentioned in the proposal? Should the compiler (and the proposal) put effort into generating a useful warning message, such as figuring out if it WOULD parse correctly if the encoding statement is at the very top of the source file, vs. suggesting to recode in UTF-8? and a final dilemma: D) Should we separate the proposals for source and encoding keywords? The source keyword is more useful and a lot simpler overall than the encoding keyword, but they do sort of go together. --Reinier Zwitserloot and Roel Spilker From igor.v.karp at gmail.com Fri Mar 6 23:18:13 2009 From: igor.v.karp at gmail.com (Igor Karp) Date: Fri, 6 Mar 2009 23:18:13 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: Message-ID: On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot wrote: > We have written up a proposal for adding a 'source' and 'encoding' > keyword (alternatives to the -source and -encoding keywords on the > command line; they work pretty much just as you expect). The keywords > are context sensitive and must both appear before anything else other > than comments to be parsed. In case the benefit isn't obvious: It is a > great help when you are trying to port a big project to a new source > language compatibility. Leaving half your sourcebase in v1.6 and the > other half in v1.7 is pretty much impossible today, it's all-or- > nothing. It should also be a much nicer solution to the 'assert in > v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > that 'module' is most likely going to become a keyword. Finally, it > makes java files a lot more portable; you no longer run into your > strings looking weird when you move your Windows-1252 codefile java > source to a mac, for example. > > Before we finish it though, some open questions we'd like some > feedback on: > > A) Technically, starting a file with "source 1.4" is obviously silly; > javac v1.4 doesn't know about the source keyword and would thus fail > immediately. However, practically, its still useful. Example: if > you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > syntax), but have a few files remaining on GWT v1.4 (which uses java > 1.4 syntax), then tossing a "source 1.4;" in those older files > eliminates all the generics warnings and serves as a reminder that you > should still convert those at some point. However, it isn't -actually- > compatible with a real javac 1.4. We're leaning to making "source > 1.6;" ?(and below) legal even when using a javac v1.7 or above, but > perhaps that's a bridge too far? We could go with magic comments but > that seems like a very bad solution. > > also: > > Encoding is rather a hairy issue; javac will need to read the file to > find the encoding, but to read a file, it needs to know about > encoding! Fortunately, *every single* popular encoding on wikipedia's > popular encoding list at: > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > will encode "encoding own-name-in-that-encoding;" the same as ASCII > would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > anyone ever uses to program java). > > Therefore, the proposal includes the following strategy to find the > encoding statement in a java source file without knowing the encoding > beforehand: > > An entirely separate parser (the encoding parser) is run repeatedly > until the right encoding is found. First it'll decode the input with > ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > the java standard), then as UTF-32 (BE if no BOM), then the current > behaviour (-encoding parameter's value if any, otherwise platform > default encoding). This separate parser works as follows: > > 1. Ignore any comments and whitespace. > 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > that pattern matches partially but is not correctly completed, that > parser run exits without finding an encoding, immediately. > 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > partially but is not correctly completed, that parser run exists > without finding an encoding, immediately. If it does complete, the > parser also exists immediately and returns the captured value. > 5. If it finds anything else, stop immediately, returning no encoding > found. > > Once it's found something, the 'real' java parser will run using the > found encoding (this overrides any -encoding on the command line). > Note that the encoding parser stops quickly; For example, if it finds > a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > import statement), it'll stop immediately. > > If an encoding is encountered that was not found during the standard > decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > a platform default/command line encoding param, (e.g. a platform that > defaults to UTF-16LE without a byte order mark) a warning explaining > that the encoding statement isn't doing anything is generated. Of > course, if the encoding doesn't match itself, you get an error > (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > there is no encoding statement, the 'real' java parser does what it > does now: Use the -encoding parameter of javac, and if that wasn't > present, the platform default. > > However, there is 1 major and 1 minor problem with this approach: > > B) This means javac will need to read every source file many times to > compile it. > > Worst case (no encoding keyword): 5 times. > Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > Fortunately all runs should stop quickly, due to the encoding parser's > penchant to quit very early. Javacs out there will either stuff the > entire source file into memory, or if not, disk cache should take care > of it, but we can't prove beyond a doubt that this repeated parsing > will have no significant impact on compile time. Is this a > showstopper? Is the need to include a new (but small) parser into > javac a showstopper? > > C) Certain character sets, such as ISO-2022, can make the encoding > statement unreadable with the standard strategy if a comment including > non-ASCII characters precedes the encoding statement. These situations > are very rare (in fact, I haven't managed to find an example), so is > it okay to just ignore this issue? If you add the encoding statement > after a bunch of comments that make it invisible, and then compile it > with the right -encoding parameter, you WILL get a warning that the > encoding statement isn't going to help a javac on another platform / > without that encoding parameter to figure it out, so you just get the > current status quo: your source file won't compile without an explicit > -encoding parameter (or if that happens to be the platform default). > Should this be mentioned in the proposal? Should the compiler (and the > proposal) put effort into generating a useful warning message, such as > figuring out if it WOULD parse correctly if the encoding statement is > at the very top of the source file, vs. suggesting to recode in UTF-8? > > and a final dilemma: > > D) Should we separate the proposals for source and encoding keywords? > The source keyword is more useful and a lot simpler overall than the > encoding keyword, but they do sort of go together. Separate. Another reason is: the argument of applying different settings to different parts of the project is much less valid with encoding than with source. > > --Reinier Zwitserloot and Roel Spilker > > Overall: I would prefer command line options enhanced to handle the situation rather than language change. Igor Karp From reinier at zwitserloot.com Fri Mar 6 23:39:57 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 7 Mar 2009 08:39:57 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: Message-ID: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Igor, how could the command line options be expanded? Allow -encoding to specify a separate encoding for each file? I don't see how that can work. There's no way I or anyone else is going to edit a build script (be it just javac, a home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully enumerate every file's source compatibility level. Changing the command line options also incurs the neccessary wrath of all those build tool developers as they'd have to update their software to handle the new option (adding an option is a change too!) Could you also elaborate on why you don't like it? For example, how can the benefits of having (more) portable source files, easier migration, and a much cleaner solution to e.g. the assert-in-javac1.4 be achieved with e.g. command line options, or do you not consider any of those worthwhile? As an aside, how do people approach project coin submissions? I tend to look at a proposal's value, which is its benefit divided by the disadvantages (end-programmer complexity to learn, amount of changes needed to javac and/or JVM, and restrictions on potential future expansions). One of the reasons I'm writing this up with Roel is because the disadvantages seemed to be almost nonexistent on the outset (the encoding stuff made it more complicated, but at least the complication is entirely hidden from java developer's eyes, so it value proposal is still aces in my book). If there's a goal to keep the total language changes, no matter how simple they are, down to a small set, then benefit regardless of disadvantages is the better yardstick. --Reinier Zwitserloot On Mar 7, 2009, at 08:15, Igor Karp wrote: > On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > wrote: >> We have written up a proposal for adding a 'source' and 'encoding' >> keyword (alternatives to the -source and -encoding keywords on the >> command line; they work pretty much just as you expect). The keywords >> are context sensitive and must both appear before anything else other >> than comments to be parsed. In case the benefit isn't obvious: It >> is a >> great help when you are trying to port a big project to a new source >> language compatibility. Leaving half your sourcebase in v1.6 and the >> other half in v1.7 is pretty much impossible today, it's all-or- >> nothing. It should also be a much nicer solution to the 'assert in >> v1.4' dilemma, which I guess is going to happen to v1.7 as well, >> given >> that 'module' is most likely going to become a keyword. Finally, it >> makes java files a lot more portable; you no longer run into your >> strings looking weird when you move your Windows-1252 codefile java >> source to a mac, for example. >> >> Before we finish it though, some open questions we'd like some >> feedback on: >> >> A) Technically, starting a file with "source 1.4" is obviously silly; >> javac v1.4 doesn't know about the source keyword and would thus fail >> immediately. However, practically, its still useful. Example: if >> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 >> syntax), but have a few files remaining on GWT v1.4 (which uses java >> 1.4 syntax), then tossing a "source 1.4;" in those older files >> eliminates all the generics warnings and serves as a reminder that >> you >> should still convert those at some point. However, it isn't - >> actually- >> compatible with a real javac 1.4. We're leaning to making "source >> 1.6;" (and below) legal even when using a javac v1.7 or above, but >> perhaps that's a bridge too far? We could go with magic comments but >> that seems like a very bad solution. >> >> also: >> >> Encoding is rather a hairy issue; javac will need to read the file to >> find the encoding, but to read a file, it needs to know about >> encoding! Fortunately, *every single* popular encoding on wikipedia's >> popular encoding list at: >> >> http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings >> >> will encode "encoding own-name-in-that-encoding;" the same as ASCII >> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt >> anyone ever uses to program java). >> >> Therefore, the proposal includes the following strategy to find the >> encoding statement in a java source file without knowing the encoding >> beforehand: >> >> An entirely separate parser (the encoding parser) is run repeatedly >> until the right encoding is found. First it'll decode the input with >> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per >> the java standard), then as UTF-32 (BE if no BOM), then the current >> behaviour (-encoding parameter's value if any, otherwise platform >> default encoding). This separate parser works as follows: >> >> 1. Ignore any comments and whitespace. >> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - >> if >> that pattern matches partially but is not correctly completed, that >> parser run exits without finding an encoding, immediately. >> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern >> matches >> partially but is not correctly completed, that parser run exists >> without finding an encoding, immediately. If it does complete, the >> parser also exists immediately and returns the captured value. >> 5. If it finds anything else, stop immediately, returning no encoding >> found. >> >> Once it's found something, the 'real' java parser will run using the >> found encoding (this overrides any -encoding on the command line). >> Note that the encoding parser stops quickly; For example, if it finds >> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an >> import statement), it'll stop immediately. >> >> If an encoding is encountered that was not found during the standard >> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due >> to >> a platform default/command line encoding param, (e.g. a platform that >> defaults to UTF-16LE without a byte order mark) a warning explaining >> that the encoding statement isn't doing anything is generated. Of >> course, if the encoding doesn't match itself, you get an error >> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). >> If >> there is no encoding statement, the 'real' java parser does what it >> does now: Use the -encoding parameter of javac, and if that wasn't >> present, the platform default. >> >> However, there is 1 major and 1 minor problem with this approach: >> >> B) This means javac will need to read every source file many times to >> compile it. >> >> Worst case (no encoding keyword): 5 times. >> Standard case if an encoding keyword: 2 times (3 times if UTF-16). >> >> Fortunately all runs should stop quickly, due to the encoding >> parser's >> penchant to quit very early. Javacs out there will either stuff the >> entire source file into memory, or if not, disk cache should take >> care >> of it, but we can't prove beyond a doubt that this repeated parsing >> will have no significant impact on compile time. Is this a >> showstopper? Is the need to include a new (but small) parser into >> javac a showstopper? >> >> C) Certain character sets, such as ISO-2022, can make the encoding >> statement unreadable with the standard strategy if a comment >> including >> non-ASCII characters precedes the encoding statement. These >> situations >> are very rare (in fact, I haven't managed to find an example), so is >> it okay to just ignore this issue? If you add the encoding statement >> after a bunch of comments that make it invisible, and then compile it >> with the right -encoding parameter, you WILL get a warning that the >> encoding statement isn't going to help a javac on another platform / >> without that encoding parameter to figure it out, so you just get the >> current status quo: your source file won't compile without an >> explicit >> -encoding parameter (or if that happens to be the platform default). >> Should this be mentioned in the proposal? Should the compiler (and >> the >> proposal) put effort into generating a useful warning message, such >> as >> figuring out if it WOULD parse correctly if the encoding statement is >> at the very top of the source file, vs. suggesting to recode in >> UTF-8? >> >> and a final dilemma: >> >> D) Should we separate the proposals for source and encoding keywords? >> The source keyword is more useful and a lot simpler overall than the >> encoding keyword, but they do sort of go together. > Separate. Another reason is: the argument of applying different > settings to > different parts of the project is much less valid with encoding than > with source. > >> >> --Reinier Zwitserloot and Roel Spilker >> >> > Overall: I would prefer command line options enhanced to handle the > situation > rather than language change. > > Igor Karp From xmirog at gmail.com Sat Mar 7 02:02:12 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Sat, 07 Mar 2009 11:02:12 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> Message-ID: <49B24624.7080708@gmail.com> Neal, this proposal tries to achieve big benefits with small changes. In my opinion, Streams, Readers, Writers, Formatters, Channels, Sockets, Connections, Statements, ResultSets, or java.awt.Graphics are much more used than Locks. This does not mean that Locks are not important. If the proposal can be applied to the formers it will be a huge benefit, although Locks can't be used directly with it. I agree with Bob, adapters can be used for many use cases where "close" methods are incompatible with the Disposable or Resource interface. And although the proposal is not designed to manage Locks, perhaps a kind of "safe unlocker" can be easily made, so this original code: myLock.lock(); try { // access the resource protected by myLock } finally { myLock.unlock(); } could be written this way: try (SafeUnlocker = new SafeUnlocker(myLock)) { // access the resource protected by myLock } where SafeUnlocker would be more or less like this: public class SafeUnlocker implements Disposable { private final Lock lock; public SafeUnlocker(Lock lock){ this.lock = lock; lock.lock(); } public void close throws Exception { lock.unlock(); } } The name SafeUnlocker maybe it's not appropriate, but I haven't found a better one. There can be problems in this source code that I haven't seen...this is only an idea. Regards, Xavi Neal Gafter escribi?: > On Fri, Mar 6, 2009 at 4:02 PM, Bob Lee wrote: > >> On Fri, Mar 6, 2009 at 3:19 PM, Neal Gafter wrote: >> >>> If you've already decided which resource-like APIs "count", then you >>> don't need to ask us. >>> >> Did I unfairly discount some APIs? If so, please speak up. >> > > I did, and you quoted me just after asking the question (see below, > for example). Apparently, because some other use cases are more > problematic, you feel that the ones I brought up are unimportant. > I've certainly run into situations where automatic pairing of resource > acquisition and release for java.util.concurrent locks would have > avoided errors. I know that supporting resource acquisition and > release for all the different resource APIs that exist (or will exist) > in Java is difficult to do apriori in a language change (which is why > I prefer an API-based solution), but pretending the use cases don't > exist seems dishonest. > > >>> Personally, I'd like java.util.locks.Lock to be >>> easier to use, though I understand this proposal doesn't solve that From xmirog at gmail.com Sat Mar 7 02:20:53 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Sat, 07 Mar 2009 11:20:53 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B24624.7080708@gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903041109rd051b7eh60a72830e86fa970@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> Message-ID: <49B24A85.8010402@gmail.com> There is an error in my code: this part is incorrect, the Lock object to unlock is this.lock: public void close throws Exception { lock.unlock(); } ...so: public void close throws Exception { this.lock.unlock(); } Sorry! Xavi Xavi Mir? escribi?: > Neal, > > this proposal tries to achieve big benefits with small changes. In > my opinion, Streams, Readers, Writers, Formatters, Channels, Sockets, > Connections, Statements, ResultSets, or java.awt.Graphics are much > more used than Locks. This does not mean that Locks are not important. > If the proposal can be applied to the formers it will be a huge > benefit, although Locks can't be used directly with it. > > I agree with Bob, adapters can be used for many use cases where > "close" methods are incompatible with the Disposable or Resource > interface. And although the proposal is not designed to manage Locks, > perhaps a kind of "safe unlocker" can be easily made, so this original > code: > > myLock.lock(); > try { > // access the resource protected by myLock > } finally { > myLock.unlock(); > } > > could be written this way: > > try (SafeUnlocker = new SafeUnlocker(myLock)) { > // access the resource protected by myLock > } > > where SafeUnlocker would be more or less like this: > > public class SafeUnlocker implements Disposable { > > private final Lock lock; > > public SafeUnlocker(Lock lock){ > this.lock = lock; > lock.lock(); > } > > public void close throws Exception { > lock.unlock(); > } > } > > The name SafeUnlocker maybe it's not appropriate, but I haven't found > a better one. There can be problems in this source code that I haven't > seen...this is only an idea. > > Regards, > > Xavi > > Neal Gafter escribi?: >> On Fri, Mar 6, 2009 at 4:02 PM, Bob Lee wrote: >> >>> On Fri, Mar 6, 2009 at 3:19 PM, Neal Gafter wrote: >>> >>>> If you've already decided which resource-like APIs "count", then you >>>> don't need to ask us. >>>> >>> Did I unfairly discount some APIs? If so, please speak up. >>> >> >> I did, and you quoted me just after asking the question (see below, >> for example). Apparently, because some other use cases are more >> problematic, you feel that the ones I brought up are unimportant. >> I've certainly run into situations where automatic pairing of resource >> acquisition and release for java.util.concurrent locks would have >> avoided errors. I know that supporting resource acquisition and >> release for all the different resource APIs that exist (or will exist) >> in Java is difficult to do apriori in a language change (which is why >> I prefer an API-based solution), but pretending the use cases don't >> exist seems dishonest. >> >> >>>> Personally, I'd like java.util.locks.Lock to be >>>> easier to use, though I understand this proposal doesn't solve that > From schulz at e-spirit.de Sat Mar 7 02:53:42 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 07 Mar 2009 11:53:42 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: Message-ID: <49B25236.3010205@e-spirit.de> My first reaction on both issues was to have these information in an external file. But then again you'd either have to ship additional files or will lose the information. I know, magic comments usually are somehow not desired, but in this case, I'd see the advantage for it (backward compatibility). Especially, as it IMO is no change in the Java language, but rather enables inline, file-scoped compiler options. For example: //%encoding ISO 8859-1%// //%source 1.4%// Requiring such statements to be placed before ANY other statement in the file would also speed up their detection. Stefan Reinier Zwitserloot schrieb: > We have written up a proposal for adding a 'source' and 'encoding' > keyword (alternatives to the -source and -encoding keywords on the > command line; they work pretty much just as you expect). The keywords > are context sensitive and must both appear before anything else other > than comments to be parsed. In case the benefit isn't obvious: It is a > great help when you are trying to port a big project to a new source > language compatibility. Leaving half your sourcebase in v1.6 and the > other half in v1.7 is pretty much impossible today, it's all-or- > nothing. It should also be a much nicer solution to the 'assert in > v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > that 'module' is most likely going to become a keyword. Finally, it > makes java files a lot more portable; you no longer run into your > strings looking weird when you move your Windows-1252 codefile java > source to a mac, for example. > > Before we finish it though, some open questions we'd like some > feedback on: > > A) Technically, starting a file with "source 1.4" is obviously silly; > javac v1.4 doesn't know about the source keyword and would thus fail > immediately. However, practically, its still useful. Example: if > you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > syntax), but have a few files remaining on GWT v1.4 (which uses java > 1.4 syntax), then tossing a "source 1.4;" in those older files > eliminates all the generics warnings and serves as a reminder that you > should still convert those at some point. However, it isn't -actually- > compatible with a real javac 1.4. We're leaning to making "source > 1.6;" (and below) legal even when using a javac v1.7 or above, but > perhaps that's a bridge too far? We could go with magic comments but > that seems like a very bad solution. > > also: > > Encoding is rather a hairy issue; javac will need to read the file to > find the encoding, but to read a file, it needs to know about > encoding! Fortunately, *every single* popular encoding on wikipedia's > popular encoding list at: > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > will encode "encoding own-name-in-that-encoding;" the same as ASCII > would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > anyone ever uses to program java). > > Therefore, the proposal includes the following strategy to find the > encoding statement in a java source file without knowing the encoding > beforehand: > > An entirely separate parser (the encoding parser) is run repeatedly > until the right encoding is found. First it'll decode the input with > ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > the java standard), then as UTF-32 (BE if no BOM), then the current > behaviour (-encoding parameter's value if any, otherwise platform > default encoding). This separate parser works as follows: > > 1. Ignore any comments and whitespace. > 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > that pattern matches partially but is not correctly completed, that > parser run exits without finding an encoding, immediately. > 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > partially but is not correctly completed, that parser run exists > without finding an encoding, immediately. If it does complete, the > parser also exists immediately and returns the captured value. > 5. If it finds anything else, stop immediately, returning no encoding > found. > > Once it's found something, the 'real' java parser will run using the > found encoding (this overrides any -encoding on the command line). > Note that the encoding parser stops quickly; For example, if it finds > a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > import statement), it'll stop immediately. > > If an encoding is encountered that was not found during the standard > decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > a platform default/command line encoding param, (e.g. a platform that > defaults to UTF-16LE without a byte order mark) a warning explaining > that the encoding statement isn't doing anything is generated. Of > course, if the encoding doesn't match itself, you get an error > (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > there is no encoding statement, the 'real' java parser does what it > does now: Use the -encoding parameter of javac, and if that wasn't > present, the platform default. > > However, there is 1 major and 1 minor problem with this approach: > > B) This means javac will need to read every source file many times to > compile it. > > Worst case (no encoding keyword): 5 times. > Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > Fortunately all runs should stop quickly, due to the encoding parser's > penchant to quit very early. Javacs out there will either stuff the > entire source file into memory, or if not, disk cache should take care > of it, but we can't prove beyond a doubt that this repeated parsing > will have no significant impact on compile time. Is this a > showstopper? Is the need to include a new (but small) parser into > javac a showstopper? > > C) Certain character sets, such as ISO-2022, can make the encoding > statement unreadable with the standard strategy if a comment including > non-ASCII characters precedes the encoding statement. These situations > are very rare (in fact, I haven't managed to find an example), so is > it okay to just ignore this issue? If you add the encoding statement > after a bunch of comments that make it invisible, and then compile it > with the right -encoding parameter, you WILL get a warning that the > encoding statement isn't going to help a javac on another platform / > without that encoding parameter to figure it out, so you just get the > current status quo: your source file won't compile without an explicit > -encoding parameter (or if that happens to be the platform default). > Should this be mentioned in the proposal? Should the compiler (and the > proposal) put effort into generating a useful warning message, such as > figuring out if it WOULD parse correctly if the encoding statement is > at the very top of the source file, vs. suggesting to recode in UTF-8? > > and a final dilemma: > > D) Should we separate the proposals for source and encoding keywords? > The source keyword is more useful and a lot simpler overall than the > encoding keyword, but they do sort of go together. > > --Reinier Zwitserloot and Roel Spilker > > From peter at retep.org.uk Sat Mar 7 03:11:54 2009 From: peter at retep.org.uk (Peter Mount) Date: Sat, 7 Mar 2009 11:11:54 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B24624.7080708@gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> Message-ID: <85bf933e0903070311y322884f2xdef845aacec5b2f6@mail.gmail.com> On Sat, Mar 7, 2009 at 10:02 AM, Xavi Mir? wrote: > Neal, > > this proposal tries to achieve big benefits with small changes. In my > opinion, Streams, Readers, Writers, Formatters, Channels, Sockets, > Connections, Statements, ResultSets, or java.awt.Graphics are much more > used than Locks. This does not mean that Locks are not important. If the > proposal can be applied to the formers it will be a huge benefit, > although Locks can't be used directly with it. > > I agree with Bob, adapters can be used for many use cases where > "close" methods are incompatible with the Disposable or Resource > interface. And although the proposal is not designed to manage Locks, > perhaps a kind of "safe unlocker" can be easily made, so this original > code: > > myLock.lock(); > try { > // access the resource protected by myLock > } finally { > myLock.unlock(); > } > > could be written this way: > > try (SafeUnlocker = new SafeUnlocker(myLock)) { > // access the resource protected by myLock > } > > where SafeUnlocker would be more or less like this: > > public class SafeUnlocker implements Disposable { > > private final Lock lock; > > public SafeUnlocker(Lock lock){ > this.lock = lock; > lock.lock(); > } > > public void close throws Exception { > lock.unlock(); > } > } > > The name SafeUnlocker maybe it's not appropriate, but I haven't found a > better one. There can be problems in this source code that I haven't > seen...this is only an idea. > > Regards, > > Xavi > > I use the concurrency package extensively, mainly within a high load online gaming environment and I would be concerned about the overhead of the large number of SafeUnlocker instances generated, their effects with the Garbage Collector and the increase in the memory footprint when the locks are used recursively (ReentrantLock and ReadWriteReentrantLock) - please correct me if I'm wrong here. The only way I can see my concerns satisfied would be to use something like: public class DisposableLock implements Disposable { private final Lock lock; public DisposableLock(Lock lock){ this.lock = lock; lock.lock(); } public void close throws Exception { lock.unlock(); } } Then in my useage: final DisposableLock lock = new DisposableLock( new ReentrantLock() ); public void method() { try ( lock ) { // access the resource protected by lock } } That would account for a simple ReentrantLock, but for ReentrantReadWriteLock we could then use something like: final ReadWriteLock lock = new ReentrantReadWriteLock(); final DisposableLock readLock = new DisposableLock( lock.readLock() ); final DisposableLock writeLock = new DisposableLock( lock.writeLock() ); public void method() { try ( readLock ) { // access the resource protected by the read lock } } public void setSomething() { try ( writeLock ) { // access the resource protected by the write lock } } It does make the code a lot easier to read, and is cleaner than how I currently do something similar in 1.6 - naughtily using an annotation processor to inject a try {} finally {} around the locked methods. Peter -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From vilya.harvey at gmail.com Sat Mar 7 03:22:27 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Sat, 7 Mar 2009 11:22:27 +0000 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <49B25236.3010205@e-spirit.de> References: <49B25236.3010205@e-spirit.de> Message-ID: <6aef848f0903070322p13abf697v144ce47ced54de06@mail.gmail.com> Instead of magic comments, how about defining these as javadoc tags? That would provide a way to specify the info for whole packages, as well as individual classes; it wouldn't require any syntax changes either, so would be backwards compatible. The downside is that it would require adding support for javadoc comments at the file level. Vil. 2009/3/7 Stefan Schulz > My first reaction on both issues was to have these information in an > external file. But then again you'd either have to ship additional files > or will lose the information. > I know, magic comments usually are somehow not desired, but in this > case, I'd see the advantage for it (backward compatibility). Especially, > as it IMO is no change in the Java language, but rather enables inline, > file-scoped compiler options. For example: > > //%encoding ISO 8859-1%// > //%source 1.4%// > > Requiring such statements to be placed before ANY other statement in the > file would also speed up their detection. > > Stefan > > Reinier Zwitserloot schrieb: > > We have written up a proposal for adding a 'source' and 'encoding' > > keyword (alternatives to the -source and -encoding keywords on the > > command line; they work pretty much just as you expect). The keywords > > are context sensitive and must both appear before anything else other > > than comments to be parsed. In case the benefit isn't obvious: It is a > > great help when you are trying to port a big project to a new source > > language compatibility. Leaving half your sourcebase in v1.6 and the > > other half in v1.7 is pretty much impossible today, it's all-or- > > nothing. It should also be a much nicer solution to the 'assert in > > v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > > that 'module' is most likely going to become a keyword. Finally, it > > makes java files a lot more portable; you no longer run into your > > strings looking weird when you move your Windows-1252 codefile java > > source to a mac, for example. > > > > Before we finish it though, some open questions we'd like some > > feedback on: > > > > A) Technically, starting a file with "source 1.4" is obviously silly; > > javac v1.4 doesn't know about the source keyword and would thus fail > > immediately. However, practically, its still useful. Example: if > > you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > > syntax), but have a few files remaining on GWT v1.4 (which uses java > > 1.4 syntax), then tossing a "source 1.4;" in those older files > > eliminates all the generics warnings and serves as a reminder that you > > should still convert those at some point. However, it isn't -actually- > > compatible with a real javac 1.4. We're leaning to making "source > > 1.6;" (and below) legal even when using a javac v1.7 or above, but > > perhaps that's a bridge too far? We could go with magic comments but > > that seems like a very bad solution. > > > > also: > > > > Encoding is rather a hairy issue; javac will need to read the file to > > find the encoding, but to read a file, it needs to know about > > encoding! Fortunately, *every single* popular encoding on wikipedia's > > popular encoding list at: > > > > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > > > will encode "encoding own-name-in-that-encoding;" the same as ASCII > > would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > > anyone ever uses to program java). > > > > Therefore, the proposal includes the following strategy to find the > > encoding statement in a java source file without knowing the encoding > > beforehand: > > > > An entirely separate parser (the encoding parser) is run repeatedly > > until the right encoding is found. First it'll decode the input with > > ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > > the java standard), then as UTF-32 (BE if no BOM), then the current > > behaviour (-encoding parameter's value if any, otherwise platform > > default encoding). This separate parser works as follows: > > > > 1. Ignore any comments and whitespace. > > 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > > that pattern matches partially but is not correctly completed, that > > parser run exits without finding an encoding, immediately. > > 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > > partially but is not correctly completed, that parser run exists > > without finding an encoding, immediately. If it does complete, the > > parser also exists immediately and returns the captured value. > > 5. If it finds anything else, stop immediately, returning no encoding > > found. > > > > Once it's found something, the 'real' java parser will run using the > > found encoding (this overrides any -encoding on the command line). > > Note that the encoding parser stops quickly; For example, if it finds > > a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > > import statement), it'll stop immediately. > > > > If an encoding is encountered that was not found during the standard > > decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > > a platform default/command line encoding param, (e.g. a platform that > > defaults to UTF-16LE without a byte order mark) a warning explaining > > that the encoding statement isn't doing anything is generated. Of > > course, if the encoding doesn't match itself, you get an error > > (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > > there is no encoding statement, the 'real' java parser does what it > > does now: Use the -encoding parameter of javac, and if that wasn't > > present, the platform default. > > > > However, there is 1 major and 1 minor problem with this approach: > > > > B) This means javac will need to read every source file many times to > > compile it. > > > > Worst case (no encoding keyword): 5 times. > > Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > > > Fortunately all runs should stop quickly, due to the encoding parser's > > penchant to quit very early. Javacs out there will either stuff the > > entire source file into memory, or if not, disk cache should take care > > of it, but we can't prove beyond a doubt that this repeated parsing > > will have no significant impact on compile time. Is this a > > showstopper? Is the need to include a new (but small) parser into > > javac a showstopper? > > > > C) Certain character sets, such as ISO-2022, can make the encoding > > statement unreadable with the standard strategy if a comment including > > non-ASCII characters precedes the encoding statement. These situations > > are very rare (in fact, I haven't managed to find an example), so is > > it okay to just ignore this issue? If you add the encoding statement > > after a bunch of comments that make it invisible, and then compile it > > with the right -encoding parameter, you WILL get a warning that the > > encoding statement isn't going to help a javac on another platform / > > without that encoding parameter to figure it out, so you just get the > > current status quo: your source file won't compile without an explicit > > -encoding parameter (or if that happens to be the platform default). > > Should this be mentioned in the proposal? Should the compiler (and the > > proposal) put effort into generating a useful warning message, such as > > figuring out if it WOULD parse correctly if the encoding statement is > > at the very top of the source file, vs. suggesting to recode in UTF-8? > > > > and a final dilemma: > > > > D) Should we separate the proposals for source and encoding keywords? > > The source keyword is more useful and a lot simpler overall than the > > encoding keyword, but they do sort of go together. > > > > --Reinier Zwitserloot and Roel Spilker > > > > > > From xmirog at gmail.com Sat Mar 7 07:09:20 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Sat, 07 Mar 2009 16:09:20 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <85bf933e0903070311y322884f2xdef845aacec5b2f6@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <85bf933e0903070311y322884f2xdef845aacec5b2f6@mail.gmail.com> Message-ID: <49B28E20.7040809@gmail.com> Peter, good point, there would be a lot of objects. Maybe a better adapter would be one similar to your example, but that doesn't lock in the constructor and which returns its instance when locks: public class SafeUnlocker implements Disposable { private final Lock lock; public SafeUnlocker(Lock lock){ this.lock = lock; } public SafeUnlocker lock(){ this.lock.lock(); return this; } public void close throws Exception { this.lock.unlock(); } } ...so it could be used this way: // -- This could be used as a private field or as a variable // -- It doesn't lock when it's built, only when its lock method is invoked SafeUnlocker myUnlocker = new SafeUnlocker(myLock); ... ... try (myUnlocker.lock()) { // access the resource protected by myLock } But I would like to emphasize that the benefits of using this proposal are huge without direct support for Locks. Josh has made very clear it is not intended to be used with Locks. Regards, Xavi Peter Mount escribi?: > > > On Sat, Mar 7, 2009 at 10:02 AM, Xavi Mir? > wrote: > > Neal, > > this proposal tries to achieve big benefits with small changes. > In my > opinion, Streams, Readers, Writers, Formatters, Channels, Sockets, > Connections, Statements, ResultSets, or java.awt.Graphics are much > more > used than Locks. This does not mean that Locks are not important. > If the > proposal can be applied to the formers it will be a huge benefit, > although Locks can't be used directly with it. > > I agree with Bob, adapters can be used for many use cases where > "close" methods are incompatible with the Disposable or Resource > interface. And although the proposal is not designed to manage Locks, > perhaps a kind of "safe unlocker" can be easily made, so this > original code: > > myLock.lock(); > try { > // access the resource protected by myLock > } finally { > myLock.unlock(); > } > > could be written this way: > > try (SafeUnlocker = new SafeUnlocker(myLock)) { > // access the resource protected by myLock > } > > where SafeUnlocker would be more or less like this: > > public class SafeUnlocker implements Disposable { > > private final Lock lock; > > public SafeUnlocker(Lock lock){ > this.lock = lock; > lock.lock(); > } > > public void close throws Exception { > lock.unlock(); > } > } > > The name SafeUnlocker maybe it's not appropriate, but I haven't > found a > better one. There can be problems in this source code that I haven't > seen...this is only an idea. > > Regards, > > Xavi > > > I use the concurrency package extensively, mainly within a high load > online gaming environment and I would be concerned about the overhead > of the large number of SafeUnlocker instances generated, their effects > with the Garbage Collector and the increase in the memory footprint > when the locks are used recursively (ReentrantLock and > ReadWriteReentrantLock) - please correct me if I'm wrong here. > > The only way I can see my concerns satisfied would be to use something > like: > > public class DisposableLock implements Disposable { > > private final Lock lock; > > public DisposableLock(Lock lock){ > this.lock = lock; > lock.lock(); > } > > public void close throws Exception { > lock.unlock(); > } > } > > Then in my useage: > > final DisposableLock lock = new DisposableLock( new ReentrantLock() ); > > public void method() > { > try ( lock ) { > // access the resource protected by lock > } > } > > That would account for a simple ReentrantLock, but for > ReentrantReadWriteLock we could then use something like: > > final ReadWriteLock lock = new ReentrantReadWriteLock(); > final DisposableLock readLock = new DisposableLock( lock.readLock() ); > final DisposableLock writeLock = new DisposableLock( lock.writeLock() ); > > public void method() > { > try ( readLock ) { > // access the resource protected by the read lock > } > } > > public void setSomething() > { > try ( writeLock ) { > // access the resource protected by the write lock > } > } > > It does make the code a lot easier to read, and is cleaner than how I > currently do something similar in 1.6 - naughtily using an annotation > processor to inject a try {} finally {} around the locked methods. > > Peter > > -- > Peter Mount > e: peter at retep.org.uk > w: http://retep.org > Jabber/GTalk: peter at retep.org MSN: > retep207 at hotmail.com From scolebourne at joda.org Sat Mar 7 07:45:13 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 07 Mar 2009 15:45:13 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B28E20.7040809@gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <85bf933e0903070311y322884f2xdef845aacec5b2f6@mail.gmail.com> <49B28E20.7040809@gmail.com> Message-ID: <49B29689.5090302@joda.org> Xavi Mir? wrote: > But I would like to emphasize that the benefits of using this proposal > are huge without direct support for Locks. Josh has made very clear it > is not intended to be used with Locks. I think this is understood, however the reality is that it will be. As soon as the ARM code is in the compiler, an open source project will appear with code to wrap other classes to make them work with the ARM block. Of course that doesn't mean ARM is good or bad, just that we should be realistic about how widely used it will be. There are other cases that I don't think ARM will handle perfectly (and BGGA/JCA do). For example, looping around the lines in a file, which might ideally look like: for (String str : file.readLines()) { // process lines } <-- close file here The closest ARM is this: try (BufferedReader in = file.openBufferedReader()) { for (String str : in.lines()) { <-- new method returning an Iterable // process lines } } Of course, that is still a lot better than today. And really, thats the point. My personal take is that I would welcome ARM in Java 7, either interface-based or keyword-based. I think the benefits are sufficiently great that we shouldn't make developers to wait any longer. I am of course fully aware of the reduction in value that BGGA/JCA style control invocation then faces as a language change (and hence the passion in the debate, notably from Neal). However, with closures officially defined as 'out' I have to choose between solving real issues now (in the 80% case) or waiting another 3 years+. I choose pragmatism - solve the 80% now with ARM, and reconsider BGGA/JCA later. Stephen From scolebourne at joda.org Sat Mar 7 07:57:19 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 07 Mar 2009 15:57:19 +0000 Subject: Proposal: Block Expressions for Java In-Reply-To: <15e8b9d20903061258k128c1864i417bbb8444d8189e@mail.gmail.com> References: <63b4e4050903061250r24df3e5braf5cd490c1753f80@mail.gmail.com> <15e8b9d20903061258k128c1864i417bbb8444d8189e@mail.gmail.com> Message-ID: <49B2995F.40300@joda.org> > On Fri, Mar 6, 2009 at 12:50 PM, Tim Peierls wrote: >> I kind of like Neal's block expression proposal, but I am struggling to find >> more compelling examples for it. Neal Gafter wrote: > The places I would have found this most useful are in a super() > invocation, where you simply can't write a local variable before, The correct solution to this is to allow code before super(). That might be out of scope for Coin, but it is a better solution. > in a control-flow expression of one sort or another, like ?:, &&, ||, > or on the right-hand-side of an assert statement. This kind of thing > is particularly useful in automatically-generated code. Again, there is a use case here, but manly for auto-generated code. (The cases where this comes up otherwise are very rare, and handled by a static method). Adding this feature isn't overly harmful, but I don't think its especially in the Java-style (ie. it fits expression only languages like Scala). Personally I'm opposed. Stephen From scolebourne at joda.org Sat Mar 7 08:03:52 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 07 Mar 2009 16:03:52 +0000 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49AABBA2.3040009@joda.org> References: <49AABBA2.3040009@joda.org> Message-ID: <49B29AE8.3090308@joda.org> Stephen Colebourne wrote: > Elvis and Other Null-Safe Operators for Java @Joe, do I need to formally separate the two parts of this proposal to get them considered separately? (The ?: 'elvis' default in null operator has received no comments and is very useful alone, whereas the ?. / ?[] has received more criticism - even though I still think it would be very useful) Stephen From markmahieu at googlemail.com Sat Mar 7 08:19:33 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 7 Mar 2009 16:19:33 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B29689.5090302@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <85bf933e0903070311y322884f2xdef845aacec5b2f6@mail.gmail.com> <49B28E20.7040809@gmail.com> <49B29689.5090302@joda.org> Message-ID: <1331AB4F-D3DF-4A09-9CCA-F451F4555B6B@googlemail.com> Yes, well a key advantage of the kind of library based approach that Neal advocates is that it is much easier to improve or evolve after the core language change has been made. But I'm not convinced that the introduction of ARM now would have such a reduction in value of a control invocation feature added in a later release. Firstly, the uses of such a feature are far more wide- ranging, and secondly, there's the possibility that it could actually *replace* the dedicated language feature without requiring any user code changes. If that sounds far-fetched, look at the 'for each' support Neal has built into BGGA. He almost has it at the point that it could silently replace the dedicated language support for the for-each loop added in Java 5, so although adding BGGA would add complexity to the language spec, it could conceivably take some away as well, and give us the flexibility of a library-base solution. The same could conceivably happen with ARM, but it's extremely unlikely while the various parties involved are apparently only interested in discussing either/or scenarios (yes, I'm guilty of that too). Regards, Mark On 7 Mar 2009, at 15:45, Stephen Colebourne wrote: > > My personal take is that I would welcome ARM in Java 7, either > interface-based or keyword-based. I think the benefits are > sufficiently > great that we shouldn't make developers to wait any longer. > > I am of course fully aware of the reduction in value that BGGA/JCA > style > control invocation then faces as a language change (and hence the > passion in the debate, notably from Neal). > > However, with closures officially defined as 'out' I have to choose > between solving real issues now (in the 80% case) or waiting another 3 > years+. I choose pragmatism - solve the 80% now with ARM, and > reconsider > BGGA/JCA later. > > Stephen > > > From igor.v.karp at gmail.com Sat Mar 7 09:27:42 2009 From: igor.v.karp at gmail.com (Igor Karp) Date: Sat, 7 Mar 2009 09:27:42 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: Reiner, please see the comments inline. On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot wrote: > Igor, > > how could the command line options be expanded? Allow -encoding to specify a > separate encoding for each file? I don't see how that can work. For example: allow multiple -encoding options and add optional path to encoding -encoding [,] Where path can be either a package (settings applied to the package and every package under it) or a single file for maximum precision. So one can have: -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding X,a.b.c.d.IAmSpecial IAMSpecial.java will get encoding X, everything else under a.b.c will get encoding Z, everything else under a.b will get encoding Y and the rest will get encoding X. Same approach can be applied to -source. > There's no > way I or anyone else is going to edit a build script (be it just javac, a > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully > enumerate every file's source compatibility level. Sure, thats what argfiles are for: store the settings in a file and use javac @argfile. And doing it as proposed above on a package level would make it more manageable. Remember in your proposal the only option is to specify it on a file level (this is fixable i guess). > Changing the command line > options also incurs the neccessary wrath of all those build tool developers > as they'd have to update their software to handle the new option (adding an > option is a change too!) Not more than changing the language itself. > > Could you also elaborate on why you don't like it? For example, how can the > benefits of having (more) portable source files, easier migration, and a > much cleaner solution to e.g. the assert-in-javac1.4 be achieved with e.g. > command line options, or do you not consider any of those worthwhile? I fully support the goal. I even see it as is a bit too narrow (see below). But I do not see a need to change the language to achieve that goal. On a conceptual level I see these options as a metadata of the source files and I don't like the idea of coupling it with the file. One can avoid all this complexity of extra parsing by specifying the encoding in an external file. This external file does not have itself to be in that encoding. In fact it can be restricted to be always in ASCII. I think the addition of an optional path and allowing multiple use of the same option approach is much more scalable: it could be extended to the other existing options (like -deprecation, -Xlint, etc.) and to the options that might appear in the future. I wish I could concentrate on deprecations in a certain package and ignore them everywhere else for now: javac -deprecation,really.rusty.one ... Finished with (or gave up on ;) that one and want to switch to the next one: javac -deprecation,another.old.one Igor Karp > > As an aside, how do people approach project coin submissions? I tend to look > at a proposal's value, which is its benefit divided by the disadvantages > (end-programmer complexity to learn, amount of changes needed to javac > and/or JVM, and restrictions on potential future expansions). One of the > reasons I'm writing this up with Roel is because the disadvantages seemed to > be almost nonexistent on the outset (the encoding stuff made it more > complicated, but at least the complication is entirely hidden from java > developer's eyes, so it value proposal is still aces in my book). If there's > a goal to keep the total language changes, no matter how simple they are, > down to a small set, then benefit regardless of disadvantages is the better > yardstick. > > ?--Reinier Zwitserloot > > > > On Mar 7, 2009, at 08:15, Igor Karp wrote: > >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot >> wrote: >>> >>> We have written up a proposal for adding a 'source' and 'encoding' >>> keyword (alternatives to the -source and -encoding keywords on the >>> command line; they work pretty much just as you expect). The keywords >>> are context sensitive and must both appear before anything else other >>> than comments to be parsed. In case the benefit isn't obvious: It is a >>> great help when you are trying to port a big project to a new source >>> language compatibility. Leaving half your sourcebase in v1.6 and the >>> other half in v1.7 is pretty much impossible today, it's all-or- >>> nothing. It should also be a much nicer solution to the 'assert in >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, given >>> that 'module' is most likely going to become a keyword. Finally, it >>> makes java files a lot more portable; you no longer run into your >>> strings looking weird when you move your Windows-1252 codefile java >>> source to a mac, for example. >>> >>> Before we finish it though, some open questions we'd like some >>> feedback on: >>> >>> A) Technically, starting a file with "source 1.4" is obviously silly; >>> javac v1.4 doesn't know about the source keyword and would thus fail >>> immediately. However, practically, its still useful. Example: if >>> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 >>> syntax), but have a few files remaining on GWT v1.4 (which uses java >>> 1.4 syntax), then tossing a "source 1.4;" in those older files >>> eliminates all the generics warnings and serves as a reminder that you >>> should still convert those at some point. However, it isn't -actually- >>> compatible with a real javac 1.4. We're leaning to making "source >>> 1.6;" ?(and below) legal even when using a javac v1.7 or above, but >>> perhaps that's a bridge too far? We could go with magic comments but >>> that seems like a very bad solution. >>> >>> also: >>> >>> Encoding is rather a hairy issue; javac will need to read the file to >>> find the encoding, but to read a file, it needs to know about >>> encoding! Fortunately, *every single* popular encoding on wikipedia's >>> popular encoding list at: >>> >>> >>> http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings >>> >>> will encode "encoding own-name-in-that-encoding;" the same as ASCII >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt >>> anyone ever uses to program java). >>> >>> Therefore, the proposal includes the following strategy to find the >>> encoding statement in a java source file without knowing the encoding >>> beforehand: >>> >>> An entirely separate parser (the encoding parser) is run repeatedly >>> until the right encoding is found. First it'll decode the input with >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per >>> the java standard), then as UTF-32 (BE if no BOM), then the current >>> behaviour (-encoding parameter's value if any, otherwise platform >>> default encoding). This separate parser works as follows: >>> >>> 1. Ignore any comments and whitespace. >>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if >>> that pattern matches partially but is not correctly completed, that >>> parser run exits without finding an encoding, immediately. >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches >>> partially but is not correctly completed, that parser run exists >>> without finding an encoding, immediately. If it does complete, the >>> parser also exists immediately and returns the captured value. >>> 5. If it finds anything else, stop immediately, returning no encoding >>> found. >>> >>> Once it's found something, the 'real' java parser will run using the >>> found encoding (this overrides any -encoding on the command line). >>> Note that the encoding parser stops quickly; For example, if it finds >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an >>> import statement), it'll stop immediately. >>> >>> If an encoding is encountered that was not found during the standard >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to >>> a platform default/command line encoding param, (e.g. a platform that >>> defaults to UTF-16LE without a byte order mark) a warning explaining >>> that the encoding statement isn't doing anything is generated. Of >>> course, if the encoding doesn't match itself, you get an error >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If >>> there is no encoding statement, the 'real' java parser does what it >>> does now: Use the -encoding parameter of javac, and if that wasn't >>> present, the platform default. >>> >>> However, there is 1 major and 1 minor problem with this approach: >>> >>> B) This means javac will need to read every source file many times to >>> compile it. >>> >>> Worst case (no encoding keyword): 5 times. >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). >>> >>> Fortunately all runs should stop quickly, due to the encoding parser's >>> penchant to quit very early. Javacs out there will either stuff the >>> entire source file into memory, or if not, disk cache should take care >>> of it, but we can't prove beyond a doubt that this repeated parsing >>> will have no significant impact on compile time. Is this a >>> showstopper? Is the need to include a new (but small) parser into >>> javac a showstopper? >>> >>> C) Certain character sets, such as ISO-2022, can make the encoding >>> statement unreadable with the standard strategy if a comment including >>> non-ASCII characters precedes the encoding statement. These situations >>> are very rare (in fact, I haven't managed to find an example), so is >>> it okay to just ignore this issue? If you add the encoding statement >>> after a bunch of comments that make it invisible, and then compile it >>> with the right -encoding parameter, you WILL get a warning that the >>> encoding statement isn't going to help a javac on another platform / >>> without that encoding parameter to figure it out, so you just get the >>> current status quo: your source file won't compile without an explicit >>> -encoding parameter (or if that happens to be the platform default). >>> Should this be mentioned in the proposal? Should the compiler (and the >>> proposal) put effort into generating a useful warning message, such as >>> figuring out if it WOULD parse correctly if the encoding statement is >>> at the very top of the source file, vs. suggesting to recode in UTF-8? >>> >>> and a final dilemma: >>> >>> D) Should we separate the proposals for source and encoding keywords? >>> The source keyword is more useful and a lot simpler overall than the >>> encoding keyword, but they do sort of go together. >> >> Separate. Another reason is: the argument of applying different settings >> to >> different parts of the project is much less valid with encoding than >> with source. >> >>> >>> --Reinier Zwitserloot and Roel Spilker >>> >>> >> Overall: I would prefer command line options enhanced to handle the >> situation >> rather than language change. >> >> Igor Karp > > From neal at gafter.com Sat Mar 7 09:28:40 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 09:28:40 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> Message-ID: <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> On Fri, Feb 27, 2009 at 10:29 PM, Joshua Bloch wrote: > ? ? ? ? ? ?try { localVar.close(); } catch(Exception #ignore) { } Simply discarding exceptions seems wrong. As a practical matter, if I were to use a construct like this I would want the "ignored" exceptions to be logged so that we don't sweep programming errors under the rug. From neal at gafter.com Sat Mar 7 09:42:45 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 09:42:45 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: Message-ID: <15e8b9d20903070942x3a91b67ejf3de9b0980e2aa97@mail.gmail.com> I think you'll find that the devil is in the details. First, you'll have to incorporate all the language rules from all the versions of the JLS into a new edition of the JLS (depending on the "source" setting). Second, you'll have to describe in precise detail the interaction of code written in different source settings when combined into a single program. How are Java 5 bridge methods seen in a Java 4 program? What happens in a Java 4 program if you attempt to override a method that had a Java 5 covariant return in its superclass? You'll have to spell out these interactions in the language specification in gory detail. That might be useful to do, but it's hard to imagine that you'd have time to even scratch the surface, much less complete such a specification, in the timeframe of project coin. On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot wrote: > We have written up a proposal for adding a 'source' and 'encoding' > keyword (alternatives to the -source and -encoding keywords on the > command line; they work pretty much just as you expect). The keywords > are context sensitive and must both appear before anything else other > than comments to be parsed. In case the benefit isn't obvious: It is a > great help when you are trying to port a big project to a new source > language compatibility. Leaving half your sourcebase in v1.6 and the > other half in v1.7 is pretty much impossible today, it's all-or- > nothing. It should also be a much nicer solution to the 'assert in > v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > that 'module' is most likely going to become a keyword. Finally, it > makes java files a lot more portable; you no longer run into your > strings looking weird when you move your Windows-1252 codefile java > source to a mac, for example. > > Before we finish it though, some open questions we'd like some > feedback on: > > A) Technically, starting a file with "source 1.4" is obviously silly; > javac v1.4 doesn't know about the source keyword and would thus fail > immediately. However, practically, its still useful. Example: if > you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > syntax), but have a few files remaining on GWT v1.4 (which uses java > 1.4 syntax), then tossing a "source 1.4;" in those older files > eliminates all the generics warnings and serves as a reminder that you > should still convert those at some point. However, it isn't -actually- > compatible with a real javac 1.4. We're leaning to making "source > 1.6;" ?(and below) legal even when using a javac v1.7 or above, but > perhaps that's a bridge too far? We could go with magic comments but > that seems like a very bad solution. > > also: > > Encoding is rather a hairy issue; javac will need to read the file to > find the encoding, but to read a file, it needs to know about > encoding! Fortunately, *every single* popular encoding on wikipedia's > popular encoding list at: > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > will encode "encoding own-name-in-that-encoding;" the same as ASCII > would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > anyone ever uses to program java). > > Therefore, the proposal includes the following strategy to find the > encoding statement in a java source file without knowing the encoding > beforehand: > > An entirely separate parser (the encoding parser) is run repeatedly > until the right encoding is found. First it'll decode the input with > ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > the java standard), then as UTF-32 (BE if no BOM), then the current > behaviour (-encoding parameter's value if any, otherwise platform > default encoding). This separate parser works as follows: > > 1. Ignore any comments and whitespace. > 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > that pattern matches partially but is not correctly completed, that > parser run exits without finding an encoding, immediately. > 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > partially but is not correctly completed, that parser run exists > without finding an encoding, immediately. If it does complete, the > parser also exists immediately and returns the captured value. > 5. If it finds anything else, stop immediately, returning no encoding > found. > > Once it's found something, the 'real' java parser will run using the > found encoding (this overrides any -encoding on the command line). > Note that the encoding parser stops quickly; For example, if it finds > a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > import statement), it'll stop immediately. > > If an encoding is encountered that was not found during the standard > decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > a platform default/command line encoding param, (e.g. a platform that > defaults to UTF-16LE without a byte order mark) a warning explaining > that the encoding statement isn't doing anything is generated. Of > course, if the encoding doesn't match itself, you get an error > (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > there is no encoding statement, the 'real' java parser does what it > does now: Use the -encoding parameter of javac, and if that wasn't > present, the platform default. > > However, there is 1 major and 1 minor problem with this approach: > > B) This means javac will need to read every source file many times to > compile it. > > Worst case (no encoding keyword): 5 times. > Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > Fortunately all runs should stop quickly, due to the encoding parser's > penchant to quit very early. Javacs out there will either stuff the > entire source file into memory, or if not, disk cache should take care > of it, but we can't prove beyond a doubt that this repeated parsing > will have no significant impact on compile time. Is this a > showstopper? Is the need to include a new (but small) parser into > javac a showstopper? > > C) Certain character sets, such as ISO-2022, can make the encoding > statement unreadable with the standard strategy if a comment including > non-ASCII characters precedes the encoding statement. These situations > are very rare (in fact, I haven't managed to find an example), so is > it okay to just ignore this issue? If you add the encoding statement > after a bunch of comments that make it invisible, and then compile it > with the right -encoding parameter, you WILL get a warning that the > encoding statement isn't going to help a javac on another platform / > without that encoding parameter to figure it out, so you just get the > current status quo: your source file won't compile without an explicit > -encoding parameter (or if that happens to be the platform default). > Should this be mentioned in the proposal? Should the compiler (and the > proposal) put effort into generating a useful warning message, such as > figuring out if it WOULD parse correctly if the encoding statement is > at the very top of the source file, vs. suggesting to recode in UTF-8? > > and a final dilemma: > > D) Should we separate the proposals for source and encoding keywords? > The source keyword is more useful and a lot simpler overall than the > encoding keyword, but they do sort of go together. > > --Reinier Zwitserloot and Roel Spilker > > From jjb at google.com Sat Mar 7 09:48:56 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 7 Mar 2009 09:48:56 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> Message-ID: <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> Neal, Agreed. I like the solution in the "Additional Features" section of the proposal entitled "Retaining suppressed exceptions." If there are no compelling objections, I'll promote this to the body of the proposal in the next revision (and fill in the details). Josh On Sat, Mar 7, 2009 at 9:28 AM, Neal Gafter wrote: > On Fri, Feb 27, 2009 at 10:29 PM, Joshua Bloch wrote: > > try { localVar.close(); } catch(Exception #ignore) { } > > Simply discarding exceptions seems wrong. As a practical matter, if I > were to use a construct like this I would want the "ignored" > exceptions to be logged so that we don't sweep programming errors > under the rug. > From schulz at e-spirit.de Sat Mar 7 09:51:21 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 07 Mar 2009 18:51:21 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B29689.5090302@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <85bf933e0903070311y322884f2xdef845aacec5b2f6@mail.gmail.com><49B28E20.7040809@gmail.com> <49B29689.5090302@joda.org> Message-ID: <49B2B419.9080801@e-spirit.de> Stephen Colebourne wrote: > I think this is understood, however the reality is that it will be. As > soon as the ARM code is in the compiler, an open source project will > appear with code to wrap other classes to make them work with the ARM block. > > Of course that doesn't mean ARM is good or bad, just that we should be > realistic about how widely used it will be. I completely agree. Whatever tool a programmer is given, he or she will apply it for good and bad. > However, with closures officially defined as 'out' I have to choose > between solving real issues now (in the 80% case) or waiting another 3 > years+. I choose pragmatism - solve the 80% now with ARM, and reconsider > BGGA/JCA later. To me, ARM does not come even near 80% of the cases I would like to see being solved and what BGGA/JCA could provide. It's a somewhat the least common denominator of the desired solution. Together with for-each, it will introduce yet another language level control for solving a niche of problems. (That does not mean, it's a bad idea.) In the discussion about whether to use a language level (finally) or API level (interface) solution, the siginficant problem I see is the reuse of an existing interface/signature. As some pointed out, existing classes that have or comply to such an interface may not be ready for this kind of usage within a try() statement, although they can be applied. My first reaction was to prefer the language level solution, as no existing class can be used without re-considering its use in that new statement. But a newly introduced interface having a method most likely not matching existing ones for resources would nearly have the same effect. I would also oppose to allow multiple interfaces because of the above reasons. Stefan From jeremy.manson at gmail.com Sat Mar 7 09:51:39 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 7 Mar 2009 09:51:39 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B24624.7080708@gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> Message-ID: <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> Neal said he thought the cure was worse than the disease with that approach when I pointed it out earlier in the thread (I called the class LockDisposer, FWIW). I believe he was probably referring to the verbosity and the extra objects. The "right" fix, if we want to support this pattern, is to allow the try resource statement to accept expressions that return Disposables, and to retrofit the relevant lock APIs with disposables and lock methods that return this: class Lock implements Disposable { public Lock dlock() { return this; } @Override public void dispose() { unlock(); } } Then, for Lock lock, you can just say: try (lock.lock()) { // ... } Which is much cleaner. Jeremy On Sat, Mar 7, 2009 at 2:02 AM, Xavi Mir? wrote: > Neal, > > ? this proposal tries to achieve big benefits with small changes. In my > opinion, Streams, Readers, Writers, Formatters, Channels, Sockets, > Connections, Statements, ResultSets, or java.awt.Graphics are much more > used than Locks. This does not mean that Locks are not important. If the > proposal can be applied to the formers it will be a huge benefit, > although Locks can't be used directly with it. > > ? I agree with Bob, adapters can be used for many use cases where > "close" methods are incompatible with the Disposable or Resource > interface. And although the proposal is not designed to manage Locks, > perhaps a kind of "safe unlocker" can be easily made, so this original code: > > ? ? myLock.lock(); > ? ? try { > ? ? ? ? // access the resource protected by myLock > ? ? } finally { > ? ? ? ? myLock.unlock(); > ? ? } > > could be written this way: > > ? ? try (SafeUnlocker = new SafeUnlocker(myLock)) { > ? ? ? ? // access the resource protected by myLock > ? ? } > > where SafeUnlocker would be more or less like this: > > public class SafeUnlocker implements Disposable { > > ?private final Lock lock; > > ?public SafeUnlocker(Lock lock){ > ? ?this.lock = lock; > ? ?lock.lock(); > ?} > > ?public void close throws Exception { > ? ?lock.unlock(); > ?} > } > > The name SafeUnlocker maybe it's not appropriate, but I haven't found a > better one. There can be problems in this source code that I haven't > seen...this is only an idea. > > ?Regards, > > ? ? ?Xavi > > Neal Gafter escribi?: >> On Fri, Mar 6, 2009 at 4:02 PM, Bob Lee wrote: >> >>> On Fri, Mar 6, 2009 at 3:19 PM, Neal Gafter wrote: >>> >>>> If you've already decided which resource-like APIs "count", then you >>>> don't need to ask us. >>>> >>> Did I unfairly discount some APIs? If so, please speak up. >>> >> >> I did, and you quoted me just after asking the question (see below, >> for example). ?Apparently, because some other use cases are more >> problematic, you feel that the ones I brought up are unimportant. >> I've certainly run into situations where automatic pairing of resource >> acquisition and release for java.util.concurrent locks would have >> avoided errors. ?I know that supporting resource acquisition and >> release for all the different resource APIs that exist (or will exist) >> in Java is difficult to do apriori in a language change (which is why >> I prefer an API-based solution), but pretending the use cases don't >> exist seems dishonest. >> >> >>>> Personally, I'd like java.util.locks.Lock to be >>>> easier to use, though I understand this proposal doesn't solve that > > > From jeremy.manson at gmail.com Sat Mar 7 09:52:28 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 7 Mar 2009 09:52:28 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> Message-ID: <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> On Sat, Mar 7, 2009 at 9:51 AM, Jeremy Manson wrote: > Then, for Lock lock, you can just say: > > try (lock.lock()) { > ?// ... > } > > Which is much cleaner. Sorry, that should be: try (lock.dlock()) { // ... } Jeremy From r.spilker at gmail.com Sat Mar 7 09:54:26 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Sat, 7 Mar 2009 18:54:26 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <15e8b9d20903070942x3a91b67ejf3de9b0980e2aa97@mail.gmail.com> References: <15e8b9d20903070942x3a91b67ejf3de9b0980e2aa97@mail.gmail.com> Message-ID: Thanks for your feedback. However, we'd rather first get answers to the questions asked, then submit the PROPOSAL and get the discussion going. That said, the main idea for now was to have the file know the version instead of having to specify it on the command line. That way you can just compile your whole project, when previously you had to compile the java5 files and the java6 files in separate steps. And things got more complicated when there were dependencies. Can you please explain how in the current situation the "interaction of code written in different source settings when combined into a single program" was handled just fine, but would fail if we do it using a single javac invocation using the source keyword? On Sat, Mar 7, 2009 at 6:42 PM, Neal Gafter wrote: > I think you'll find that the devil is in the details. First, you'll > have to incorporate all the language rules from all the versions of > the JLS into a new edition of the JLS (depending on the "source" > setting). Second, you'll have to describe in precise detail the > interaction of code written in different source settings when combined > into a single program. How are Java 5 bridge methods seen in a Java 4 > program? What happens in a Java 4 program if you attempt to override > a method that had a Java 5 covariant return in its superclass? You'll > have to spell out these interactions in the language specification in > gory detail. That might be useful to do, but it's hard to imagine > that you'd have time to even scratch the surface, much less complete > such a specification, in the timeframe of project coin. > > On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > wrote: > > We have written up a proposal for adding a 'source' and 'encoding' > > keyword (alternatives to the -source and -encoding keywords on the > > command line; they work pretty much just as you expect). The keywords > > are context sensitive and must both appear before anything else other > > than comments to be parsed. In case the benefit isn't obvious: It is a > > great help when you are trying to port a big project to a new source > > language compatibility. Leaving half your sourcebase in v1.6 and the > > other half in v1.7 is pretty much impossible today, it's all-or- > > nothing. It should also be a much nicer solution to the 'assert in > > v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > > that 'module' is most likely going to become a keyword. Finally, it > > makes java files a lot more portable; you no longer run into your > > strings looking weird when you move your Windows-1252 codefile java > > source to a mac, for example. > > > > Before we finish it though, some open questions we'd like some > > feedback on: > > > > A) Technically, starting a file with "source 1.4" is obviously silly; > > javac v1.4 doesn't know about the source keyword and would thus fail > > immediately. However, practically, its still useful. Example: if > > you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > > syntax), but have a few files remaining on GWT v1.4 (which uses java > > 1.4 syntax), then tossing a "source 1.4;" in those older files > > eliminates all the generics warnings and serves as a reminder that you > > should still convert those at some point. However, it isn't -actually- > > compatible with a real javac 1.4. We're leaning to making "source > > 1.6;" (and below) legal even when using a javac v1.7 or above, but > > perhaps that's a bridge too far? We could go with magic comments but > > that seems like a very bad solution. > > > > also: > > > > Encoding is rather a hairy issue; javac will need to read the file to > > find the encoding, but to read a file, it needs to know about > > encoding! Fortunately, *every single* popular encoding on wikipedia's > > popular encoding list at: > > > > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > > > will encode "encoding own-name-in-that-encoding;" the same as ASCII > > would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > > anyone ever uses to program java). > > > > Therefore, the proposal includes the following strategy to find the > > encoding statement in a java source file without knowing the encoding > > beforehand: > > > > An entirely separate parser (the encoding parser) is run repeatedly > > until the right encoding is found. First it'll decode the input with > > ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > > the java standard), then as UTF-32 (BE if no BOM), then the current > > behaviour (-encoding parameter's value if any, otherwise platform > > default encoding). This separate parser works as follows: > > > > 1. Ignore any comments and whitespace. > > 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > > that pattern matches partially but is not correctly completed, that > > parser run exits without finding an encoding, immediately. > > 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > > partially but is not correctly completed, that parser run exists > > without finding an encoding, immediately. If it does complete, the > > parser also exists immediately and returns the captured value. > > 5. If it finds anything else, stop immediately, returning no encoding > > found. > > > > Once it's found something, the 'real' java parser will run using the > > found encoding (this overrides any -encoding on the command line). > > Note that the encoding parser stops quickly; For example, if it finds > > a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > > import statement), it'll stop immediately. > > > > If an encoding is encountered that was not found during the standard > > decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > > a platform default/command line encoding param, (e.g. a platform that > > defaults to UTF-16LE without a byte order mark) a warning explaining > > that the encoding statement isn't doing anything is generated. Of > > course, if the encoding doesn't match itself, you get an error > > (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > > there is no encoding statement, the 'real' java parser does what it > > does now: Use the -encoding parameter of javac, and if that wasn't > > present, the platform default. > > > > However, there is 1 major and 1 minor problem with this approach: > > > > B) This means javac will need to read every source file many times to > > compile it. > > > > Worst case (no encoding keyword): 5 times. > > Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > > > Fortunately all runs should stop quickly, due to the encoding parser's > > penchant to quit very early. Javacs out there will either stuff the > > entire source file into memory, or if not, disk cache should take care > > of it, but we can't prove beyond a doubt that this repeated parsing > > will have no significant impact on compile time. Is this a > > showstopper? Is the need to include a new (but small) parser into > > javac a showstopper? > > > > C) Certain character sets, such as ISO-2022, can make the encoding > > statement unreadable with the standard strategy if a comment including > > non-ASCII characters precedes the encoding statement. These situations > > are very rare (in fact, I haven't managed to find an example), so is > > it okay to just ignore this issue? If you add the encoding statement > > after a bunch of comments that make it invisible, and then compile it > > with the right -encoding parameter, you WILL get a warning that the > > encoding statement isn't going to help a javac on another platform / > > without that encoding parameter to figure it out, so you just get the > > current status quo: your source file won't compile without an explicit > > -encoding parameter (or if that happens to be the platform default). > > Should this be mentioned in the proposal? Should the compiler (and the > > proposal) put effort into generating a useful warning message, such as > > figuring out if it WOULD parse correctly if the encoding statement is > > at the very top of the source file, vs. suggesting to recode in UTF-8? > > > > and a final dilemma: > > > > D) Should we separate the proposals for source and encoding keywords? > > The source keyword is more useful and a lot simpler overall than the > > encoding keyword, but they do sort of go together. > > > > --Reinier Zwitserloot and Roel Spilker > > > > > > From r.spilker at gmail.com Sat Mar 7 09:55:22 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Sat, 7 Mar 2009 18:55:22 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: I'd say javadoc, as well as annotation, should never influence the result of the compiler. That's just not the right vehicle. Roel On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp wrote: > Reiner, > > please see the comments inline. > > On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot > wrote: > > Igor, > > > > how could the command line options be expanded? Allow -encoding to > specify a > > separate encoding for each file? I don't see how that can work. > For example: allow multiple -encoding options and add optional path to > encoding -encoding [,] > Where path can be either a package (settings applied to the package > and every package under it) or a single file for maximum precision. > So one can have: > -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding > X,a.b.c.d.IAmSpecial > IAMSpecial.java will get encoding X, > everything else under a.b.c will get encoding Z, > everything else under a.b will get encoding Y > and the rest will get encoding X. > Same approach can be applied to -source. > > > There's no > > way I or anyone else is going to edit a build script (be it just javac, a > > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully > > enumerate every file's source compatibility level. > Sure, thats what argfiles are for: store the settings in a file and > use javac @argfile. > > And doing it as proposed above on a package level would make it more > manageable. > Remember in your proposal the only option is to specify it on a file > level (this is fixable i guess). > > > Changing the command line > > options also incurs the neccessary wrath of all those build tool > developers > > as they'd have to update their software to handle the new option (adding > an > > option is a change too!) > Not more than changing the language itself. > > > > > Could you also elaborate on why you don't like it? For example, how can > the > > benefits of having (more) portable source files, easier migration, and a > > much cleaner solution to e.g. the assert-in-javac1.4 be achieved with > e.g. > > command line options, or do you not consider any of those worthwhile? > I fully support the goal. I even see it as is a bit too narrow (see > below). But I do not see a need to change the language to achieve that > goal. > > On a conceptual level I see these options as a metadata of the source > files and I don't like the idea of coupling it with the file. > One can avoid all this complexity of extra parsing by specifying the > encoding in an external file. This external file does not have > itself to be in that encoding. In fact it can be restricted to be > always in ASCII. > > I think the addition of an optional path and allowing multiple use of > the same option approach is much more scalable: it could be extended > to the other existing options (like -deprecation, -Xlint, etc.) and to > the options that might appear in the future. > > I wish I could concentrate on deprecations in a certain package and > ignore them everywhere else for now: > javac -deprecation,really.rusty.one ... > Finished with (or gave up on ;) that one and want to switch to the next > one: > javac -deprecation,another.old.one > > Igor Karp > > > > > As an aside, how do people approach project coin submissions? I tend to > look > > at a proposal's value, which is its benefit divided by the disadvantages > > (end-programmer complexity to learn, amount of changes needed to javac > > and/or JVM, and restrictions on potential future expansions). One of the > > reasons I'm writing this up with Roel is because the disadvantages seemed > to > > be almost nonexistent on the outset (the encoding stuff made it more > > complicated, but at least the complication is entirely hidden from java > > developer's eyes, so it value proposal is still aces in my book). If > there's > > a goal to keep the total language changes, no matter how simple they are, > > down to a small set, then benefit regardless of disadvantages is the > better > > yardstick. > > > > --Reinier Zwitserloot > > > > > > > > On Mar 7, 2009, at 08:15, Igor Karp wrote: > > > >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > >> wrote: > >>> > >>> We have written up a proposal for adding a 'source' and 'encoding' > >>> keyword (alternatives to the -source and -encoding keywords on the > >>> command line; they work pretty much just as you expect). The keywords > >>> are context sensitive and must both appear before anything else other > >>> than comments to be parsed. In case the benefit isn't obvious: It is a > >>> great help when you are trying to port a big project to a new source > >>> language compatibility. Leaving half your sourcebase in v1.6 and the > >>> other half in v1.7 is pretty much impossible today, it's all-or- > >>> nothing. It should also be a much nicer solution to the 'assert in > >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > >>> that 'module' is most likely going to become a keyword. Finally, it > >>> makes java files a lot more portable; you no longer run into your > >>> strings looking weird when you move your Windows-1252 codefile java > >>> source to a mac, for example. > >>> > >>> Before we finish it though, some open questions we'd like some > >>> feedback on: > >>> > >>> A) Technically, starting a file with "source 1.4" is obviously silly; > >>> javac v1.4 doesn't know about the source keyword and would thus fail > >>> immediately. However, practically, its still useful. Example: if > >>> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > >>> syntax), but have a few files remaining on GWT v1.4 (which uses java > >>> 1.4 syntax), then tossing a "source 1.4;" in those older files > >>> eliminates all the generics warnings and serves as a reminder that you > >>> should still convert those at some point. However, it isn't -actually- > >>> compatible with a real javac 1.4. We're leaning to making "source > >>> 1.6;" (and below) legal even when using a javac v1.7 or above, but > >>> perhaps that's a bridge too far? We could go with magic comments but > >>> that seems like a very bad solution. > >>> > >>> also: > >>> > >>> Encoding is rather a hairy issue; javac will need to read the file to > >>> find the encoding, but to read a file, it needs to know about > >>> encoding! Fortunately, *every single* popular encoding on wikipedia's > >>> popular encoding list at: > >>> > >>> > >>> > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > >>> > >>> will encode "encoding own-name-in-that-encoding;" the same as ASCII > >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > >>> anyone ever uses to program java). > >>> > >>> Therefore, the proposal includes the following strategy to find the > >>> encoding statement in a java source file without knowing the encoding > >>> beforehand: > >>> > >>> An entirely separate parser (the encoding parser) is run repeatedly > >>> until the right encoding is found. First it'll decode the input with > >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > >>> the java standard), then as UTF-32 (BE if no BOM), then the current > >>> behaviour (-encoding parameter's value if any, otherwise platform > >>> default encoding). This separate parser works as follows: > >>> > >>> 1. Ignore any comments and whitespace. > >>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > >>> that pattern matches partially but is not correctly completed, that > >>> parser run exits without finding an encoding, immediately. > >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > >>> partially but is not correctly completed, that parser run exists > >>> without finding an encoding, immediately. If it does complete, the > >>> parser also exists immediately and returns the captured value. > >>> 5. If it finds anything else, stop immediately, returning no encoding > >>> found. > >>> > >>> Once it's found something, the 'real' java parser will run using the > >>> found encoding (this overrides any -encoding on the command line). > >>> Note that the encoding parser stops quickly; For example, if it finds > >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > >>> import statement), it'll stop immediately. > >>> > >>> If an encoding is encountered that was not found during the standard > >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > >>> a platform default/command line encoding param, (e.g. a platform that > >>> defaults to UTF-16LE without a byte order mark) a warning explaining > >>> that the encoding statement isn't doing anything is generated. Of > >>> course, if the encoding doesn't match itself, you get an error > >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > >>> there is no encoding statement, the 'real' java parser does what it > >>> does now: Use the -encoding parameter of javac, and if that wasn't > >>> present, the platform default. > >>> > >>> However, there is 1 major and 1 minor problem with this approach: > >>> > >>> B) This means javac will need to read every source file many times to > >>> compile it. > >>> > >>> Worst case (no encoding keyword): 5 times. > >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). > >>> > >>> Fortunately all runs should stop quickly, due to the encoding parser's > >>> penchant to quit very early. Javacs out there will either stuff the > >>> entire source file into memory, or if not, disk cache should take care > >>> of it, but we can't prove beyond a doubt that this repeated parsing > >>> will have no significant impact on compile time. Is this a > >>> showstopper? Is the need to include a new (but small) parser into > >>> javac a showstopper? > >>> > >>> C) Certain character sets, such as ISO-2022, can make the encoding > >>> statement unreadable with the standard strategy if a comment including > >>> non-ASCII characters precedes the encoding statement. These situations > >>> are very rare (in fact, I haven't managed to find an example), so is > >>> it okay to just ignore this issue? If you add the encoding statement > >>> after a bunch of comments that make it invisible, and then compile it > >>> with the right -encoding parameter, you WILL get a warning that the > >>> encoding statement isn't going to help a javac on another platform / > >>> without that encoding parameter to figure it out, so you just get the > >>> current status quo: your source file won't compile without an explicit > >>> -encoding parameter (or if that happens to be the platform default). > >>> Should this be mentioned in the proposal? Should the compiler (and the > >>> proposal) put effort into generating a useful warning message, such as > >>> figuring out if it WOULD parse correctly if the encoding statement is > >>> at the very top of the source file, vs. suggesting to recode in UTF-8? > >>> > >>> and a final dilemma: > >>> > >>> D) Should we separate the proposals for source and encoding keywords? > >>> The source keyword is more useful and a lot simpler overall than the > >>> encoding keyword, but they do sort of go together. > >> > >> Separate. Another reason is: the argument of applying different settings > >> to > >> different parts of the project is much less valid with encoding than > >> with source. > >> > >>> > >>> --Reinier Zwitserloot and Roel Spilker > >>> > >>> > >> Overall: I would prefer command line options enhanced to handle the > >> situation > >> rather than language change. > >> > >> Igor Karp > > > > > > From r.spilker at gmail.com Sat Mar 7 09:55:57 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Sat, 7 Mar 2009 18:55:57 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: In the proposal, there is a paragraph about having these keywords in the package-info.java (and in the module-info.java) as well to allow for a more coarse-grained declaration. We didn? put this in the PRE-PROPOSAL email since it was already so long. Please keep to the questions asked in the PRE-PROPOSAL, and wait for a discussion until the PROPOSAL is sent. Roel On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp wrote: > Reiner, > > please see the comments inline. > > On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot > wrote: > > Igor, > > > > how could the command line options be expanded? Allow -encoding to > specify a > > separate encoding for each file? I don't see how that can work. > For example: allow multiple -encoding options and add optional path to > encoding -encoding [,] > Where path can be either a package (settings applied to the package > and every package under it) or a single file for maximum precision. > So one can have: > -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding > X,a.b.c.d.IAmSpecial > IAMSpecial.java will get encoding X, > everything else under a.b.c will get encoding Z, > everything else under a.b will get encoding Y > and the rest will get encoding X. > Same approach can be applied to -source. > > > There's no > > way I or anyone else is going to edit a build script (be it just javac, a > > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully > > enumerate every file's source compatibility level. > Sure, thats what argfiles are for: store the settings in a file and > use javac @argfile. > > And doing it as proposed above on a package level would make it more > manageable. > Remember in your proposal the only option is to specify it on a file > level (this is fixable i guess). > > > Changing the command line > > options also incurs the neccessary wrath of all those build tool > developers > > as they'd have to update their software to handle the new option (adding > an > > option is a change too!) > Not more than changing the language itself. > > > > > Could you also elaborate on why you don't like it? For example, how can > the > > benefits of having (more) portable source files, easier migration, and a > > much cleaner solution to e.g. the assert-in-javac1.4 be achieved with > e.g. > > command line options, or do you not consider any of those worthwhile? > I fully support the goal. I even see it as is a bit too narrow (see > below). But I do not see a need to change the language to achieve that > goal. > > On a conceptual level I see these options as a metadata of the source > files and I don't like the idea of coupling it with the file. > One can avoid all this complexity of extra parsing by specifying the > encoding in an external file. This external file does not have > itself to be in that encoding. In fact it can be restricted to be > always in ASCII. > > I think the addition of an optional path and allowing multiple use of > the same option approach is much more scalable: it could be extended > to the other existing options (like -deprecation, -Xlint, etc.) and to > the options that might appear in the future. > > I wish I could concentrate on deprecations in a certain package and > ignore them everywhere else for now: > javac -deprecation,really.rusty.one ... > Finished with (or gave up on ;) that one and want to switch to the next > one: > javac -deprecation,another.old.one > > Igor Karp > > > > > As an aside, how do people approach project coin submissions? I tend to > look > > at a proposal's value, which is its benefit divided by the disadvantages > > (end-programmer complexity to learn, amount of changes needed to javac > > and/or JVM, and restrictions on potential future expansions). One of the > > reasons I'm writing this up with Roel is because the disadvantages seemed > to > > be almost nonexistent on the outset (the encoding stuff made it more > > complicated, but at least the complication is entirely hidden from java > > developer's eyes, so it value proposal is still aces in my book). If > there's > > a goal to keep the total language changes, no matter how simple they are, > > down to a small set, then benefit regardless of disadvantages is the > better > > yardstick. > > > > --Reinier Zwitserloot > > > > > > > > On Mar 7, 2009, at 08:15, Igor Karp wrote: > > > >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > >> wrote: > >>> > >>> We have written up a proposal for adding a 'source' and 'encoding' > >>> keyword (alternatives to the -source and -encoding keywords on the > >>> command line; they work pretty much just as you expect). The keywords > >>> are context sensitive and must both appear before anything else other > >>> than comments to be parsed. In case the benefit isn't obvious: It is a > >>> great help when you are trying to port a big project to a new source > >>> language compatibility. Leaving half your sourcebase in v1.6 and the > >>> other half in v1.7 is pretty much impossible today, it's all-or- > >>> nothing. It should also be a much nicer solution to the 'assert in > >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > >>> that 'module' is most likely going to become a keyword. Finally, it > >>> makes java files a lot more portable; you no longer run into your > >>> strings looking weird when you move your Windows-1252 codefile java > >>> source to a mac, for example. > >>> > >>> Before we finish it though, some open questions we'd like some > >>> feedback on: > >>> > >>> A) Technically, starting a file with "source 1.4" is obviously silly; > >>> javac v1.4 doesn't know about the source keyword and would thus fail > >>> immediately. However, practically, its still useful. Example: if > >>> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > >>> syntax), but have a few files remaining on GWT v1.4 (which uses java > >>> 1.4 syntax), then tossing a "source 1.4;" in those older files > >>> eliminates all the generics warnings and serves as a reminder that you > >>> should still convert those at some point. However, it isn't -actually- > >>> compatible with a real javac 1.4. We're leaning to making "source > >>> 1.6;" (and below) legal even when using a javac v1.7 or above, but > >>> perhaps that's a bridge too far? We could go with magic comments but > >>> that seems like a very bad solution. > >>> > >>> also: > >>> > >>> Encoding is rather a hairy issue; javac will need to read the file to > >>> find the encoding, but to read a file, it needs to know about > >>> encoding! Fortunately, *every single* popular encoding on wikipedia's > >>> popular encoding list at: > >>> > >>> > >>> > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > >>> > >>> will encode "encoding own-name-in-that-encoding;" the same as ASCII > >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > >>> anyone ever uses to program java). > >>> > >>> Therefore, the proposal includes the following strategy to find the > >>> encoding statement in a java source file without knowing the encoding > >>> beforehand: > >>> > >>> An entirely separate parser (the encoding parser) is run repeatedly > >>> until the right encoding is found. First it'll decode the input with > >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > >>> the java standard), then as UTF-32 (BE if no BOM), then the current > >>> behaviour (-encoding parameter's value if any, otherwise platform > >>> default encoding). This separate parser works as follows: > >>> > >>> 1. Ignore any comments and whitespace. > >>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > >>> that pattern matches partially but is not correctly completed, that > >>> parser run exits without finding an encoding, immediately. > >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > >>> partially but is not correctly completed, that parser run exists > >>> without finding an encoding, immediately. If it does complete, the > >>> parser also exists immediately and returns the captured value. > >>> 5. If it finds anything else, stop immediately, returning no encoding > >>> found. > >>> > >>> Once it's found something, the 'real' java parser will run using the > >>> found encoding (this overrides any -encoding on the command line). > >>> Note that the encoding parser stops quickly; For example, if it finds > >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > >>> import statement), it'll stop immediately. > >>> > >>> If an encoding is encountered that was not found during the standard > >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > >>> a platform default/command line encoding param, (e.g. a platform that > >>> defaults to UTF-16LE without a byte order mark) a warning explaining > >>> that the encoding statement isn't doing anything is generated. Of > >>> course, if the encoding doesn't match itself, you get an error > >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > >>> there is no encoding statement, the 'real' java parser does what it > >>> does now: Use the -encoding parameter of javac, and if that wasn't > >>> present, the platform default. > >>> > >>> However, there is 1 major and 1 minor problem with this approach: > >>> > >>> B) This means javac will need to read every source file many times to > >>> compile it. > >>> > >>> Worst case (no encoding keyword): 5 times. > >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). > >>> > >>> Fortunately all runs should stop quickly, due to the encoding parser's > >>> penchant to quit very early. Javacs out there will either stuff the > >>> entire source file into memory, or if not, disk cache should take care > >>> of it, but we can't prove beyond a doubt that this repeated parsing > >>> will have no significant impact on compile time. Is this a > >>> showstopper? Is the need to include a new (but small) parser into > >>> javac a showstopper? > >>> > >>> C) Certain character sets, such as ISO-2022, can make the encoding > >>> statement unreadable with the standard strategy if a comment including > >>> non-ASCII characters precedes the encoding statement. These situations > >>> are very rare (in fact, I haven't managed to find an example), so is > >>> it okay to just ignore this issue? If you add the encoding statement > >>> after a bunch of comments that make it invisible, and then compile it > >>> with the right -encoding parameter, you WILL get a warning that the > >>> encoding statement isn't going to help a javac on another platform / > >>> without that encoding parameter to figure it out, so you just get the > >>> current status quo: your source file won't compile without an explicit > >>> -encoding parameter (or if that happens to be the platform default). > >>> Should this be mentioned in the proposal? Should the compiler (and the > >>> proposal) put effort into generating a useful warning message, such as > >>> figuring out if it WOULD parse correctly if the encoding statement is > >>> at the very top of the source file, vs. suggesting to recode in UTF-8? > >>> > >>> and a final dilemma: > >>> > >>> D) Should we separate the proposals for source and encoding keywords? > >>> The source keyword is more useful and a lot simpler overall than the > >>> encoding keyword, but they do sort of go together. > >> > >> Separate. Another reason is: the argument of applying different settings > >> to > >> different parts of the project is much less valid with encoding than > >> with source. > >> > >>> > >>> --Reinier Zwitserloot and Roel Spilker > >>> > >>> > >> Overall: I would prefer command line options enhanced to handle the > >> situation > >> rather than language change. > >> > >> Igor Karp > > > > > > From jeremy.manson at gmail.com Sat Mar 7 10:07:25 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 7 Mar 2009 10:07:25 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <15e8b9d20903070942x3a91b67ejf3de9b0980e2aa97@mail.gmail.com> References: <15e8b9d20903070942x3a91b67ejf3de9b0980e2aa97@mail.gmail.com> Message-ID: <1631da7d0903071007v42704a1ma3c7861022e98da6@mail.gmail.com> I completely agree with Neal. Also, you are only discussing the language, and not the APIs. An historical problem with javac -source is that it doesn't actually prevent you from calling APIs that only exist in later versions, it only restricts you to the earlier version of the language. If you use javac -source 5 nowadays, that doesn't actually prevent you from putting calls to Deques and ConcurrentSkipListMaps in your code. The easiest way to fix this would be aggressive use of the @since tags, but they are only consistently used in java.lang / java.util, and that's only because Martin Buchholz made it a priority to go back and fix all of the non-existent / incorrect ones. Jeremy On Sat, Mar 7, 2009 at 9:42 AM, Neal Gafter wrote: > I think you'll find that the devil is in the details. ?First, you'll > have to incorporate all the language rules from all the versions of > the JLS into a new edition of the JLS (depending on the "source" > setting). ?Second, you'll have to describe in precise detail the > interaction of code written in different source settings when combined > into a single program. ?How are Java 5 bridge methods seen in a Java 4 > program? ?What happens in a Java 4 program if you attempt to override > a method that had a Java 5 covariant return in its superclass? ?You'll > have to spell out these interactions in the language specification in > gory detail. ?That might be useful to do, but it's hard to imagine > that you'd have time to even scratch the surface, much less complete > such a specification, in the timeframe of project coin. > > On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > wrote: >> We have written up a proposal for adding a 'source' and 'encoding' >> keyword (alternatives to the -source and -encoding keywords on the >> command line; they work pretty much just as you expect). The keywords >> are context sensitive and must both appear before anything else other >> than comments to be parsed. In case the benefit isn't obvious: It is a >> great help when you are trying to port a big project to a new source >> language compatibility. Leaving half your sourcebase in v1.6 and the >> other half in v1.7 is pretty much impossible today, it's all-or- >> nothing. It should also be a much nicer solution to the 'assert in >> v1.4' dilemma, which I guess is going to happen to v1.7 as well, given >> that 'module' is most likely going to become a keyword. Finally, it >> makes java files a lot more portable; you no longer run into your >> strings looking weird when you move your Windows-1252 codefile java >> source to a mac, for example. >> >> Before we finish it though, some open questions we'd like some >> feedback on: >> >> A) Technically, starting a file with "source 1.4" is obviously silly; >> javac v1.4 doesn't know about the source keyword and would thus fail >> immediately. However, practically, its still useful. Example: if >> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 >> syntax), but have a few files remaining on GWT v1.4 (which uses java >> 1.4 syntax), then tossing a "source 1.4;" in those older files >> eliminates all the generics warnings and serves as a reminder that you >> should still convert those at some point. However, it isn't -actually- >> compatible with a real javac 1.4. We're leaning to making "source >> 1.6;" ?(and below) legal even when using a javac v1.7 or above, but >> perhaps that's a bridge too far? We could go with magic comments but >> that seems like a very bad solution. >> >> also: >> >> Encoding is rather a hairy issue; javac will need to read the file to >> find the encoding, but to read a file, it needs to know about >> encoding! Fortunately, *every single* popular encoding on wikipedia's >> popular encoding list at: >> >> http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings >> >> will encode "encoding own-name-in-that-encoding;" the same as ASCII >> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt >> anyone ever uses to program java). >> >> Therefore, the proposal includes the following strategy to find the >> encoding statement in a java source file without knowing the encoding >> beforehand: >> >> An entirely separate parser (the encoding parser) is run repeatedly >> until the right encoding is found. First it'll decode the input with >> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per >> the java standard), then as UTF-32 (BE if no BOM), then the current >> behaviour (-encoding parameter's value if any, otherwise platform >> default encoding). This separate parser works as follows: >> >> 1. Ignore any comments and whitespace. >> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if >> that pattern matches partially but is not correctly completed, that >> parser run exits without finding an encoding, immediately. >> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches >> partially but is not correctly completed, that parser run exists >> without finding an encoding, immediately. If it does complete, the >> parser also exists immediately and returns the captured value. >> 5. If it finds anything else, stop immediately, returning no encoding >> found. >> >> Once it's found something, the 'real' java parser will run using the >> found encoding (this overrides any -encoding on the command line). >> Note that the encoding parser stops quickly; For example, if it finds >> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an >> import statement), it'll stop immediately. >> >> If an encoding is encountered that was not found during the standard >> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to >> a platform default/command line encoding param, (e.g. a platform that >> defaults to UTF-16LE without a byte order mark) a warning explaining >> that the encoding statement isn't doing anything is generated. Of >> course, if the encoding doesn't match itself, you get an error >> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If >> there is no encoding statement, the 'real' java parser does what it >> does now: Use the -encoding parameter of javac, and if that wasn't >> present, the platform default. >> >> However, there is 1 major and 1 minor problem with this approach: >> >> B) This means javac will need to read every source file many times to >> compile it. >> >> Worst case (no encoding keyword): 5 times. >> Standard case if an encoding keyword: 2 times (3 times if UTF-16). >> >> Fortunately all runs should stop quickly, due to the encoding parser's >> penchant to quit very early. Javacs out there will either stuff the >> entire source file into memory, or if not, disk cache should take care >> of it, but we can't prove beyond a doubt that this repeated parsing >> will have no significant impact on compile time. Is this a >> showstopper? Is the need to include a new (but small) parser into >> javac a showstopper? >> >> C) Certain character sets, such as ISO-2022, can make the encoding >> statement unreadable with the standard strategy if a comment including >> non-ASCII characters precedes the encoding statement. These situations >> are very rare (in fact, I haven't managed to find an example), so is >> it okay to just ignore this issue? If you add the encoding statement >> after a bunch of comments that make it invisible, and then compile it >> with the right -encoding parameter, you WILL get a warning that the >> encoding statement isn't going to help a javac on another platform / >> without that encoding parameter to figure it out, so you just get the >> current status quo: your source file won't compile without an explicit >> -encoding parameter (or if that happens to be the platform default). >> Should this be mentioned in the proposal? Should the compiler (and the >> proposal) put effort into generating a useful warning message, such as >> figuring out if it WOULD parse correctly if the encoding statement is >> at the very top of the source file, vs. suggesting to recode in UTF-8? >> >> and a final dilemma: >> >> D) Should we separate the proposals for source and encoding keywords? >> The source keyword is more useful and a lot simpler overall than the >> encoding keyword, but they do sort of go together. >> >> --Reinier Zwitserloot and Roel Spilker >> >> > > From neal at gafter.com Sat Mar 7 10:11:10 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 10:11:10 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <15e8b9d20903070942x3a91b67ejf3de9b0980e2aa97@mail.gmail.com> Message-ID: <15e8b9d20903071011o782a8069h95aca84369b10191@mail.gmail.com> On Sat, Mar 7, 2009 at 9:54 AM, Roel Spilker wrote: > Can you please explain how in the current situation the "interaction of code > written in different source settings when combined > into a single program" was handled just fine, but would fail if we do it > using a single javac invocation using the source keyword? I think you missed my point. Project coin is for small language changes. Small, as in requiring only modest changes to the language specification. This proposal would require a large change to the language specification. The language specification today does NOT talk about mixed version programs, as the specification describes only a single version of the language. You may think it's a bad thing that there is no central specification we can consult to understand how mixed version code should work, and I might even agree. But the spec including the proposed change would be required to describe all versions of the language and their interactions, and much of this specification work would have to be done from scratch. I don't mean to say that is necessarily a bad thing, I just can't imagine how it could be done in the scope of project coin. From schulz at e-spirit.de Sat Mar 7 10:15:08 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 07 Mar 2009 19:15:08 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com><63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com><17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com><15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com><15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com><49B24624.7080708@gmail.com><1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> Message-ID: <49B2B9AC.1040703@e-spirit.de> Jeremy Manson wrote: > try (lock.dlock()) { > // ... > } The problem with this solution is that lock implements Disposable and may be used in the try statement directly, without any error being visible at compile time (and maybe non-deterministically failing at runtime). The "dlock()" might return a Disposable, but it should at least be some wrapper on the lock instance. Btw., allowing for expressions instead of assignments only is some additional syntactic sugar adding a temporary variable for the assignment. Stefan From neal at gafter.com Sat Mar 7 10:18:54 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 10:18:54 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> Message-ID: <15e8b9d20903071018h135a09a8m6d4b7fa9bd741e51@mail.gmail.com> On Sat, Mar 7, 2009 at 9:51 AM, Jeremy Manson wrote: > The "right" fix, if we want to support this pattern, is to allow the > try resource statement to accept expressions that return Disposables, > and to retrofit the relevant lock APIs with disposables and lock > methods that return this: > > class Lock implements Disposable { > ?public Lock dlock() { > ? ?return this; > ?} > ?@Override public void dispose() { > ? ?unlock(); > ?} > } Lock is an interface. Adding methods to an existing interface breaks compatibility. From jjb at google.com Sat Mar 7 10:19:56 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 7 Mar 2009 10:19:56 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B2B9AC.1040703@e-spirit.de> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> <49B2B9AC.1040703@e-spirit.de> Message-ID: <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> If people feel that the locking case is important, I encourage them to pursue it with another proposal. I suspect that it won't be difficult to write. But I am less certain that it will pay for itself. I believe that the cost-benefit ratio for "true resources" is much higher than for locks. When Doug was working on JSR 166 we discussed linguistic support, but he never really felt the need. Josh On Sat, Mar 7, 2009 at 10:15 AM, Stefan Schulz wrote: > Jeremy Manson wrote: > > try (lock.dlock()) { > > // ... > > } > > The problem with this solution is that lock implements Disposable and > may be used in the try statement directly, without any error being > visible at compile time (and maybe non-deterministically failing at > runtime). The "dlock()" might return a Disposable, but it should at > least be some wrapper on the lock instance. > > Btw., allowing for expressions instead of assignments only is some > additional syntactic sugar adding a temporary variable for the assignment. > > Stefan > > From neal at gafter.com Sat Mar 7 10:21:27 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 10:21:27 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> Message-ID: <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> On Sat, Mar 7, 2009 at 9:48 AM, Joshua Bloch wrote: > Agreed. ?I like the solution in the "Additional Features" section of the > proposal entitled "Retaining suppressed exceptions." ?If there are no > compelling objections, I'll promote this to the body of the proposal in the > next revision (and fill in the details). I don't see how that solves the problem. Are you suggesting that everywhere someone handles an exception they should also check for a chain of ignored exceptions and log them? That doesn't seem very DRY. From igor.v.karp at gmail.com Sat Mar 7 10:22:42 2009 From: igor.v.karp at gmail.com (Igor Karp) Date: Sat, 7 Mar 2009 10:22:42 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: Roel, well, these were not my ideas anyway ;-). I would be equally unhappy using javadoc appoach. And as a side note: @Override does influence the result of the compiler already. Igor On Sat, Mar 7, 2009 at 9:55 AM, Roel Spilker wrote: > I'd say javadoc, as well as annotation, should never influence the result of > the compiler. That's just not the right vehicle. > > Roel > > On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp wrote: >> >> Reiner, >> >> please see the comments inline. >> >> On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot >> wrote: >> > Igor, >> > >> > how could the command line options be expanded? Allow -encoding to >> > specify a >> > separate encoding for each file? I don't see how that can work. >> For example: allow multiple -encoding options and add optional path to >> encoding -encoding [,] >> Where path can be either a package (settings applied to the package >> and every package under it) or a single file for maximum precision. >> So one can have: >> -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding >> X,a.b.c.d.IAmSpecial >> IAMSpecial.java will get encoding X, >> everything else under a.b.c will get encoding Z, >> everything else under a.b will get encoding Y >> and the rest will get encoding X. >> Same approach can be applied to -source. >> >> > There's no >> > way I or anyone else is going to edit a build script (be it just javac, >> > a >> > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully >> > enumerate every file's source compatibility level. >> Sure, thats what argfiles are for: store the settings in a file and >> use javac @argfile. >> >> And doing it as proposed above on a package level would make it more >> manageable. >> Remember in your proposal the only option is to specify it on a file >> level (this is fixable i guess). >> >> > Changing the command line >> > options also incurs the neccessary wrath of all those build tool >> > developers >> > as they'd have to update their software to handle the new option (adding >> > an >> > option is a change too!) >> Not more than changing the language itself. >> >> > >> > Could you also elaborate on why you don't like it? For example, how can >> > the >> > benefits of having (more) portable source files, easier migration, and a >> > much cleaner solution to e.g. the assert-in-javac1.4 be achieved with >> > e.g. >> > command line options, or do you not consider any of those worthwhile? >> I fully support the goal. I even see it as is a bit too narrow (see >> below). But I do not see a need to change the language to achieve that >> goal. >> >> On a conceptual level I see these options as a metadata of the source >> files and I don't like the idea of coupling it with the file. >> One can avoid all this complexity of extra parsing by specifying the >> encoding in an external file. This external file does not have >> itself to be in that encoding. In fact it can be restricted to be >> always in ASCII. >> >> I think the addition of an optional path and allowing multiple use of >> the same option approach is much more scalable: it could be extended >> to the other existing options (like -deprecation, -Xlint, etc.) and to >> the options that might appear in the future. >> >> I wish I could concentrate on deprecations in a certain package and >> ignore them everywhere else for now: >> javac -deprecation,really.rusty.one ... >> Finished with (or gave up on ;) that one and want to switch to the next >> one: >> javac -deprecation,another.old.one >> >> Igor Karp >> >> > >> > As an aside, how do people approach project coin submissions? I tend to >> > look >> > at a proposal's value, which is its benefit divided by the disadvantages >> > (end-programmer complexity to learn, amount of changes needed to javac >> > and/or JVM, and restrictions on potential future expansions). One of the >> > reasons I'm writing this up with Roel is because the disadvantages >> > seemed to >> > be almost nonexistent on the outset (the encoding stuff made it more >> > complicated, but at least the complication is entirely hidden from java >> > developer's eyes, so it value proposal is still aces in my book). If >> > there's >> > a goal to keep the total language changes, no matter how simple they >> > are, >> > down to a small set, then benefit regardless of disadvantages is the >> > better >> > yardstick. >> > >> > ?--Reinier Zwitserloot >> > >> > >> > >> > On Mar 7, 2009, at 08:15, Igor Karp wrote: >> > >> >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot >> >> wrote: >> >>> >> >>> We have written up a proposal for adding a 'source' and 'encoding' >> >>> keyword (alternatives to the -source and -encoding keywords on the >> >>> command line; they work pretty much just as you expect). The keywords >> >>> are context sensitive and must both appear before anything else other >> >>> than comments to be parsed. In case the benefit isn't obvious: It is a >> >>> great help when you are trying to port a big project to a new source >> >>> language compatibility. Leaving half your sourcebase in v1.6 and the >> >>> other half in v1.7 is pretty much impossible today, it's all-or- >> >>> nothing. It should also be a much nicer solution to the 'assert in >> >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, given >> >>> that 'module' is most likely going to become a keyword. Finally, it >> >>> makes java files a lot more portable; you no longer run into your >> >>> strings looking weird when you move your Windows-1252 codefile java >> >>> source to a mac, for example. >> >>> >> >>> Before we finish it though, some open questions we'd like some >> >>> feedback on: >> >>> >> >>> A) Technically, starting a file with "source 1.4" is obviously silly; >> >>> javac v1.4 doesn't know about the source keyword and would thus fail >> >>> immediately. However, practically, its still useful. Example: if >> >>> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 >> >>> syntax), but have a few files remaining on GWT v1.4 (which uses java >> >>> 1.4 syntax), then tossing a "source 1.4;" in those older files >> >>> eliminates all the generics warnings and serves as a reminder that you >> >>> should still convert those at some point. However, it isn't -actually- >> >>> compatible with a real javac 1.4. We're leaning to making "source >> >>> 1.6;" ?(and below) legal even when using a javac v1.7 or above, but >> >>> perhaps that's a bridge too far? We could go with magic comments but >> >>> that seems like a very bad solution. >> >>> >> >>> also: >> >>> >> >>> Encoding is rather a hairy issue; javac will need to read the file to >> >>> find the encoding, but to read a file, it needs to know about >> >>> encoding! Fortunately, *every single* popular encoding on wikipedia's >> >>> popular encoding list at: >> >>> >> >>> >> >>> >> >>> http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings >> >>> >> >>> will encode "encoding own-name-in-that-encoding;" the same as ASCII >> >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt >> >>> anyone ever uses to program java). >> >>> >> >>> Therefore, the proposal includes the following strategy to find the >> >>> encoding statement in a java source file without knowing the encoding >> >>> beforehand: >> >>> >> >>> An entirely separate parser (the encoding parser) is run repeatedly >> >>> until the right encoding is found. First it'll decode the input with >> >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per >> >>> the java standard), then as UTF-32 (BE if no BOM), then the current >> >>> behaviour (-encoding parameter's value if any, otherwise platform >> >>> default encoding). This separate parser works as follows: >> >>> >> >>> 1. Ignore any comments and whitespace. >> >>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if >> >>> that pattern matches partially but is not correctly completed, that >> >>> parser run exits without finding an encoding, immediately. >> >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches >> >>> partially but is not correctly completed, that parser run exists >> >>> without finding an encoding, immediately. If it does complete, the >> >>> parser also exists immediately and returns the captured value. >> >>> 5. If it finds anything else, stop immediately, returning no encoding >> >>> found. >> >>> >> >>> Once it's found something, the 'real' java parser will run using the >> >>> found encoding (this overrides any -encoding on the command line). >> >>> Note that the encoding parser stops quickly; For example, if it finds >> >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an >> >>> import statement), it'll stop immediately. >> >>> >> >>> If an encoding is encountered that was not found during the standard >> >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to >> >>> a platform default/command line encoding param, (e.g. a platform that >> >>> defaults to UTF-16LE without a byte order mark) a warning explaining >> >>> that the encoding statement isn't doing anything is generated. Of >> >>> course, if the encoding doesn't match itself, you get an error >> >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If >> >>> there is no encoding statement, the 'real' java parser does what it >> >>> does now: Use the -encoding parameter of javac, and if that wasn't >> >>> present, the platform default. >> >>> >> >>> However, there is 1 major and 1 minor problem with this approach: >> >>> >> >>> B) This means javac will need to read every source file many times to >> >>> compile it. >> >>> >> >>> Worst case (no encoding keyword): 5 times. >> >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). >> >>> >> >>> Fortunately all runs should stop quickly, due to the encoding parser's >> >>> penchant to quit very early. Javacs out there will either stuff the >> >>> entire source file into memory, or if not, disk cache should take care >> >>> of it, but we can't prove beyond a doubt that this repeated parsing >> >>> will have no significant impact on compile time. Is this a >> >>> showstopper? Is the need to include a new (but small) parser into >> >>> javac a showstopper? >> >>> >> >>> C) Certain character sets, such as ISO-2022, can make the encoding >> >>> statement unreadable with the standard strategy if a comment including >> >>> non-ASCII characters precedes the encoding statement. These situations >> >>> are very rare (in fact, I haven't managed to find an example), so is >> >>> it okay to just ignore this issue? If you add the encoding statement >> >>> after a bunch of comments that make it invisible, and then compile it >> >>> with the right -encoding parameter, you WILL get a warning that the >> >>> encoding statement isn't going to help a javac on another platform / >> >>> without that encoding parameter to figure it out, so you just get the >> >>> current status quo: your source file won't compile without an explicit >> >>> -encoding parameter (or if that happens to be the platform default). >> >>> Should this be mentioned in the proposal? Should the compiler (and the >> >>> proposal) put effort into generating a useful warning message, such as >> >>> figuring out if it WOULD parse correctly if the encoding statement is >> >>> at the very top of the source file, vs. suggesting to recode in UTF-8? >> >>> >> >>> and a final dilemma: >> >>> >> >>> D) Should we separate the proposals for source and encoding keywords? >> >>> The source keyword is more useful and a lot simpler overall than the >> >>> encoding keyword, but they do sort of go together. >> >> >> >> Separate. Another reason is: the argument of applying different >> >> settings >> >> to >> >> different parts of the project is much less valid with encoding than >> >> with source. >> >> >> >>> >> >>> --Reinier Zwitserloot and Roel Spilker >> >>> >> >>> >> >> Overall: I would prefer command line options enhanced to handle the >> >> situation >> >> rather than language change. >> >> >> >> Igor Karp >> > >> > >> > > From neal at gafter.com Sat Mar 7 10:28:33 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 10:28:33 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> <49B2B9AC.1040703@e-spirit.de> <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> Message-ID: <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> Although I understand this proposal does not address locks (among others), holding a lock is most definitely holding a "true resource". On Sat, Mar 7, 2009 at 10:19 AM, Joshua Bloch wrote: > If people feel that the locking case is important, I encourage them to > pursue it with another proposal. ?I suspect that it won't be difficult to > write. ?But I am less certain that it will pay for itself. ?I believe that > the cost-benefit ratio for "true resources" is much higher than for locks. > ?When Doug was working on JSR 166 we discussed linguistic support, but he > never really felt the need. From jjb at google.com Sat Mar 7 10:31:23 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 7 Mar 2009 10:31:23 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> Message-ID: <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> Neal, On Sat, Mar 7, 2009 at 10:21 AM, Neal Gafter wrote: > On Sat, Mar 7, 2009 at 9:48 AM, Joshua Bloch wrote: > > Agreed. I like the solution in the "Additional Features" section of the > > proposal entitled "Retaining suppressed exceptions." If there are no > > compelling objections, I'll promote this to the body of the proposal in > the > > next revision (and fill in the details). > > I don't see how that solves the problem. Are you suggesting that > everywhere someone handles an exception they should also check for a > chain of ignored exceptions and log them? I am not suggesting this. Most people have no need to look at these exceptions. Those who do can read them by calling the getSuppressedExceptions()method. If people think it's worth it, the stack trace printing code could be modified to include suppressed exceptions. In many cases, that would cause suppressed exceptions to be logged automatically. But I have some misgivings about this approach: I suspect there are programs that parse stack traces. While I frown on this behavior, and the spec does not guarantee that it works, I'd hate to be responsible for breaking these programs. What do others think of the "Retaining suppressed exceptions" feature? Should it be promoted to the body of the proposal? Should the suppressed exceptions be included in the stack trace? Thanks, Josh From scolebourne at joda.org Sat Mar 7 10:31:31 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 07 Mar 2009 18:31:31 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> Message-ID: <49B2BD83.1070508@joda.org> Neal Gafter wrote: > On Sat, Mar 7, 2009 at 9:48 AM, Joshua Bloch wrote: >> Agreed. I like the solution in the "Additional Features" section of the >> proposal entitled "Retaining suppressed exceptions." If there are no >> compelling objections, I'll promote this to the body of the proposal in the >> next revision (and fill in the details). > > I don't see how that solves the problem. Are you suggesting that > everywhere someone handles an exception they should also check for a > chain of ignored exceptions and log them? That doesn't seem very DRY. The problem is complicated in a different way in BGGA/JCA control invocation. While BGGA/JCA can have a 'manage resource and log exceptions' API as well as a 'manage resource and ignore exceptions' API, the problem is which is the default? Developers now have to choose one API over another. And with the logging case they might well have to write their own version that writes to their particular logger. More work. So, while its a Good Thing that you /can/ write your own version of the API with your own exception handling, it could make the users life harder. Pros and Cons. Stephen From neal at gafter.com Sat Mar 7 10:39:19 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 10:39:19 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B2BD83.1070508@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <49B2BD83.1070508@joda.org> Message-ID: <15e8b9d20903071039x12328875wa1aa52bbf8d7c354@mail.gmail.com> On Sat, Mar 7, 2009 at 10:31 AM, Stephen Colebourne wrote: > The problem is complicated in a different way in BGGA/JCA control > invocation. > > While BGGA/JCA can have a 'manage resource and log exceptions' API as > well as a 'manage resource and ignore exceptions' API, the problem is > which is the default? Developers now have to choose one API over > another. And with the logging case they might well have to write their > own version that writes to their particular logger. More work. That's not a very good API design for this class of problems. I would rather expect that a resource management API written using BGGA would allow the developer to register a handler for these ignored exceptions. From peter at retep.org.uk Sat Mar 7 10:39:31 2009 From: peter at retep.org.uk (Peter Mount) Date: Sat, 7 Mar 2009 18:39:31 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> <49B2B9AC.1040703@e-spirit.de> <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> Message-ID: <85bf933e0903071039k12296eacg1627fe37adb7429e@mail.gmail.com> On Sat, Mar 7, 2009 at 6:28 PM, Neal Gafter wrote: > Although I understand this proposal does not address locks (among > others), holding a lock is most definitely holding a "true resource". > > On Sat, Mar 7, 2009 at 10:19 AM, Joshua Bloch wrote: > > If people feel that the locking case is important, I encourage them to > > pursue it with another proposal. I suspect that it won't be difficult to > > write. But I am less certain that it will pay for itself. I believe > that > > the cost-benefit ratio for "true resources" is much higher than for > locks. > > When Doug was working on JSR 166 we discussed linguistic support, but he > > never really felt the need. > > Perhaps we are looking at this in the wrong way? The current proposal is for Disposable resources by modifying try so it takes a Disposable expression so for Locks, although they are resources perhaps this should be an additional proposal done in a similar way but with try also accepting Lock as the expression? i.e. private final Lock lock; public void doSomething() { try( lock ) { // do something within the lock } } where the try actually calls lock() before the body and unlock() at the end. If you think this should be a separate but related proposal I'll be happy to write one. Peter -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From jjb at google.com Sat Mar 7 10:40:29 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 7 Mar 2009 10:40:29 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> <49B2B9AC.1040703@e-spirit.de> <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> Message-ID: <17b2302a0903071040y40fe7a02oe72f93f59569bb8f@mail.gmail.com> Neal, Sorry, I should have defined my terms. I define a "true resource" as an object that can only used once, and then must be disposed of, never to be used again. Josh On Sat, Mar 7, 2009 at 10:28 AM, Neal Gafter wrote: > Although I understand this proposal does not address locks (among > others), holding a lock is most definitely holding a "true resource". > > On Sat, Mar 7, 2009 at 10:19 AM, Joshua Bloch wrote: > > If people feel that the locking case is important, I encourage them to > > pursue it with another proposal. I suspect that it won't be difficult to > > write. But I am less certain that it will pay for itself. I believe > that > > the cost-benefit ratio for "true resources" is much higher than for > locks. > > When Doug was working on JSR 166 we discussed linguistic support, but he > > never really felt the need. > From igor.v.karp at gmail.com Sat Mar 7 11:01:07 2009 From: igor.v.karp at gmail.com (Igor Karp) Date: Sat, 7 Mar 2009 11:01:07 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: Roel, On Sat, Mar 7, 2009 at 9:55 AM, Roel Spilker wrote: > In the proposal, there is a paragraph about having these keywords in the > package-info.java (and in the module-info.java) as well to allow for a more > coarse-grained declaration. We didn? put this in the PRE-PROPOSAL email > since it was already so long. Please keep to the questions asked in the > PRE-PROPOSAL, and wait for a discussion until the PROPOSAL is sent. > > Roel > As I said before i believe the granularity can be addressed in your your approach as well. But this is not my major concern. My major concern is coupling data and metadata and complexities arising from it (additional parsing to get the encoding right for example). For the record my approach answers your issues B and C >> >>> B) This means javac will need to read every source file many times to >> >>> compile it. >> >>> C) Certain character sets, such as ISO-2022, can make the encoding >> >>> statement unreadable with the standard strategy if a comment including >> >>> non-ASCII characters precedes the encoding statement. These situations Igor Karp > On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp wrote: >> >> Reiner, >> >> please see the comments inline. >> >> On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot >> wrote: >> > Igor, >> > >> > how could the command line options be expanded? Allow -encoding to >> > specify a >> > separate encoding for each file? I don't see how that can work. >> For example: allow multiple -encoding options and add optional path to >> encoding -encoding [,] >> Where path can be either a package (settings applied to the package >> and every package under it) or a single file for maximum precision. >> So one can have: >> -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding >> X,a.b.c.d.IAmSpecial >> IAMSpecial.java will get encoding X, >> everything else under a.b.c will get encoding Z, >> everything else under a.b will get encoding Y >> and the rest will get encoding X. >> Same approach can be applied to -source. >> >> > There's no >> > way I or anyone else is going to edit a build script (be it just javac, >> > a >> > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully >> > enumerate every file's source compatibility level. >> Sure, thats what argfiles are for: store the settings in a file and >> use javac @argfile. >> >> And doing it as proposed above on a package level would make it more >> manageable. >> Remember in your proposal the only option is to specify it on a file >> level (this is fixable i guess). >> >> > Changing the command line >> > options also incurs the neccessary wrath of all those build tool >> > developers >> > as they'd have to update their software to handle the new option (adding >> > an >> > option is a change too!) >> Not more than changing the language itself. >> >> > >> > Could you also elaborate on why you don't like it? For example, how can >> > the >> > benefits of having (more) portable source files, easier migration, and a >> > much cleaner solution to e.g. the assert-in-javac1.4 be achieved with >> > e.g. >> > command line options, or do you not consider any of those worthwhile? >> I fully support the goal. I even see it as is a bit too narrow (see >> below). But I do not see a need to change the language to achieve that >> goal. >> >> On a conceptual level I see these options as a metadata of the source >> files and I don't like the idea of coupling it with the file. >> One can avoid all this complexity of extra parsing by specifying the >> encoding in an external file. This external file does not have >> itself to be in that encoding. In fact it can be restricted to be >> always in ASCII. >> >> I think the addition of an optional path and allowing multiple use of >> the same option approach is much more scalable: it could be extended >> to the other existing options (like -deprecation, -Xlint, etc.) and to >> the options that might appear in the future. >> >> I wish I could concentrate on deprecations in a certain package and >> ignore them everywhere else for now: >> javac -deprecation,really.rusty.one ... >> Finished with (or gave up on ;) that one and want to switch to the next >> one: >> javac -deprecation,another.old.one >> >> Igor Karp >> >> > >> > As an aside, how do people approach project coin submissions? I tend to >> > look >> > at a proposal's value, which is its benefit divided by the disadvantages >> > (end-programmer complexity to learn, amount of changes needed to javac >> > and/or JVM, and restrictions on potential future expansions). One of the >> > reasons I'm writing this up with Roel is because the disadvantages >> > seemed to >> > be almost nonexistent on the outset (the encoding stuff made it more >> > complicated, but at least the complication is entirely hidden from java >> > developer's eyes, so it value proposal is still aces in my book). If >> > there's >> > a goal to keep the total language changes, no matter how simple they >> > are, >> > down to a small set, then benefit regardless of disadvantages is the >> > better >> > yardstick. >> > >> > ?--Reinier Zwitserloot >> > >> > >> > >> > On Mar 7, 2009, at 08:15, Igor Karp wrote: >> > >> >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot >> >> wrote: >> >>> >> >>> We have written up a proposal for adding a 'source' and 'encoding' >> >>> keyword (alternatives to the -source and -encoding keywords on the >> >>> command line; they work pretty much just as you expect). The keywords >> >>> are context sensitive and must both appear before anything else other >> >>> than comments to be parsed. In case the benefit isn't obvious: It is a >> >>> great help when you are trying to port a big project to a new source >> >>> language compatibility. Leaving half your sourcebase in v1.6 and the >> >>> other half in v1.7 is pretty much impossible today, it's all-or- >> >>> nothing. It should also be a much nicer solution to the 'assert in >> >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, given >> >>> that 'module' is most likely going to become a keyword. Finally, it >> >>> makes java files a lot more portable; you no longer run into your >> >>> strings looking weird when you move your Windows-1252 codefile java >> >>> source to a mac, for example. >> >>> >> >>> Before we finish it though, some open questions we'd like some >> >>> feedback on: >> >>> >> >>> A) Technically, starting a file with "source 1.4" is obviously silly; >> >>> javac v1.4 doesn't know about the source keyword and would thus fail >> >>> immediately. However, practically, its still useful. Example: if >> >>> you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 >> >>> syntax), but have a few files remaining on GWT v1.4 (which uses java >> >>> 1.4 syntax), then tossing a "source 1.4;" in those older files >> >>> eliminates all the generics warnings and serves as a reminder that you >> >>> should still convert those at some point. However, it isn't -actually- >> >>> compatible with a real javac 1.4. We're leaning to making "source >> >>> 1.6;" ?(and below) legal even when using a javac v1.7 or above, but >> >>> perhaps that's a bridge too far? We could go with magic comments but >> >>> that seems like a very bad solution. >> >>> >> >>> also: >> >>> >> >>> Encoding is rather a hairy issue; javac will need to read the file to >> >>> find the encoding, but to read a file, it needs to know about >> >>> encoding! Fortunately, *every single* popular encoding on wikipedia's >> >>> popular encoding list at: >> >>> >> >>> >> >>> >> >>> http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings >> >>> >> >>> will encode "encoding own-name-in-that-encoding;" the same as ASCII >> >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt >> >>> anyone ever uses to program java). >> >>> >> >>> Therefore, the proposal includes the following strategy to find the >> >>> encoding statement in a java source file without knowing the encoding >> >>> beforehand: >> >>> >> >>> An entirely separate parser (the encoding parser) is run repeatedly >> >>> until the right encoding is found. First it'll decode the input with >> >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per >> >>> the java standard), then as UTF-32 (BE if no BOM), then the current >> >>> behaviour (-encoding parameter's value if any, otherwise platform >> >>> default encoding). This separate parser works as follows: >> >>> >> >>> 1. Ignore any comments and whitespace. >> >>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if >> >>> that pattern matches partially but is not correctly completed, that >> >>> parser run exits without finding an encoding, immediately. >> >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches >> >>> partially but is not correctly completed, that parser run exists >> >>> without finding an encoding, immediately. If it does complete, the >> >>> parser also exists immediately and returns the captured value. >> >>> 5. If it finds anything else, stop immediately, returning no encoding >> >>> found. >> >>> >> >>> Once it's found something, the 'real' java parser will run using the >> >>> found encoding (this overrides any -encoding on the command line). >> >>> Note that the encoding parser stops quickly; For example, if it finds >> >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an >> >>> import statement), it'll stop immediately. >> >>> >> >>> If an encoding is encountered that was not found during the standard >> >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to >> >>> a platform default/command line encoding param, (e.g. a platform that >> >>> defaults to UTF-16LE without a byte order mark) a warning explaining >> >>> that the encoding statement isn't doing anything is generated. Of >> >>> course, if the encoding doesn't match itself, you get an error >> >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If >> >>> there is no encoding statement, the 'real' java parser does what it >> >>> does now: Use the -encoding parameter of javac, and if that wasn't >> >>> present, the platform default. >> >>> >> >>> However, there is 1 major and 1 minor problem with this approach: >> >>> >> >>> B) This means javac will need to read every source file many times to >> >>> compile it. >> >>> >> >>> Worst case (no encoding keyword): 5 times. >> >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). >> >>> >> >>> Fortunately all runs should stop quickly, due to the encoding parser's >> >>> penchant to quit very early. Javacs out there will either stuff the >> >>> entire source file into memory, or if not, disk cache should take care >> >>> of it, but we can't prove beyond a doubt that this repeated parsing >> >>> will have no significant impact on compile time. Is this a >> >>> showstopper? Is the need to include a new (but small) parser into >> >>> javac a showstopper? >> >>> >> >>> C) Certain character sets, such as ISO-2022, can make the encoding >> >>> statement unreadable with the standard strategy if a comment including >> >>> non-ASCII characters precedes the encoding statement. These situations >> >>> are very rare (in fact, I haven't managed to find an example), so is >> >>> it okay to just ignore this issue? If you add the encoding statement >> >>> after a bunch of comments that make it invisible, and then compile it >> >>> with the right -encoding parameter, you WILL get a warning that the >> >>> encoding statement isn't going to help a javac on another platform / >> >>> without that encoding parameter to figure it out, so you just get the >> >>> current status quo: your source file won't compile without an explicit >> >>> -encoding parameter (or if that happens to be the platform default). >> >>> Should this be mentioned in the proposal? Should the compiler (and the >> >>> proposal) put effort into generating a useful warning message, such as >> >>> figuring out if it WOULD parse correctly if the encoding statement is >> >>> at the very top of the source file, vs. suggesting to recode in UTF-8? >> >>> >> >>> and a final dilemma: >> >>> >> >>> D) Should we separate the proposals for source and encoding keywords? >> >>> The source keyword is more useful and a lot simpler overall than the >> >>> encoding keyword, but they do sort of go together. >> >> >> >> Separate. Another reason is: the argument of applying different >> >> settings >> >> to >> >> different parts of the project is much less valid with encoding than >> >> with source. >> >> >> >>> >> >>> --Reinier Zwitserloot and Roel Spilker >> >>> >> >>> >> >> Overall: I would prefer command line options enhanced to handle the >> >> situation >> >> rather than language change. >> >> >> >> Igor Karp >> > >> > >> > > From scolebourne at joda.org Sat Mar 7 11:04:24 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 07 Mar 2009 19:04:24 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> Message-ID: <49B2C538.1030005@joda.org> Joshua Bloch wrote: > On Sat, Mar 7, 2009 at 10:21 AM, Neal Gafter wrote: >> I don't see how that solves the problem. Are you suggesting that >> everywhere someone handles an exception they should also check for a >> chain of ignored exceptions and log them? > > I am not suggesting this. Most people have no need to look at these > exceptions. Those who do can read them by calling the > getSuppressedExceptions()method. Most of the time, there are no exceptions in closing. Sometimes there are. And of those, just a few we care about. So its a small %age. Thus, we shouldn't necessarily worry too much about it. The proposal does allows the supressed exceptions to be checked immediately: try (Writer w = open()) { // process } catch (IOException ex) { if (ex.getSuppressedExceptions() > 0) { // handle exceptions } } which is pretty neat. > If people think it's worth it, the stack > trace printing code could be modified to include suppressed exceptions. In > many cases, that would cause suppressed exceptions to be logged > automatically. But I have some misgivings about this approach: I suspect > there are programs that parse stack traces. While I frown on this behavior, > and the spec does not guarantee that it works, I'd hate to be responsible > for breaking these programs. When excepion causes were added, the stack traces changed. This has precedent and is a good idea (as it makes stack traces, the standard debugging tool, more useful). Stephen From neal at gafter.com Sat Mar 7 11:06:07 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 11:06:07 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B2C538.1030005@joda.org> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> <49B2C538.1030005@joda.org> Message-ID: <15e8b9d20903071106g34b65d1asc841780756b3d068@mail.gmail.com> On Sat, Mar 7, 2009 at 11:04 AM, Stephen Colebourne wrote: > The proposal does allows the supressed exceptions to be checked immediately: > > try (Writer w = open()) { > ? // process > } catch (IOException ex) { > ? if (ex.getSuppressedExceptions() > 0) { > ? ? // handle exceptions > ? } > } > > which is pretty neat. It would be neat if you had a way of knowing ahead of time where this code needed to be put. I don't see how you could know it ahead of time. From neal at gafter.com Sat Mar 7 11:12:38 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 11:12:38 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> Message-ID: <15e8b9d20903071112u3d961e78w5c19c075f4d5aa78@mail.gmail.com> On Sat, Mar 7, 2009 at 10:31 AM, Joshua Bloch wrote: >> I don't see how that solves the problem. ?Are you suggesting that >> everywhere someone handles an exception they should also check for a >> chain of ignored exceptions and log them? > > I am not suggesting this. Most people have no need to look at these > exceptions. Given that they may represent programming errors, I don't see how you can conclude that. > Those who do can read them by calling > the?getSuppressedExceptions()method. While one may be interested in a small number of these dynamically occurring exceptions, there is no reasonable way to know ahead of time where, statically in the program, they might occur. Therefore taking your advice would require doing this everywhere an exception is caught, which seems cumbersome in the extreme. The right solution is to allow programmers to register handlers for them, to filter and/or log them centrally. > If people think it's worth it, the > stack trace printing code could be modified to include suppressed > exceptions. ? In many cases, that would cause suppressed exceptions to be > logged automatically. But?I have some misgivings about this approach: I > suspect there are programs that parse stack traces. ?While I frown on this > behavior, and the spec does not guarantee that it works, I'd hate to be > responsible for breaking these programs. I agree this is a poor 'solution' to the problem. From neal at gafter.com Sat Mar 7 11:45:25 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 11:45:25 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903071040y40fe7a02oe72f93f59569bb8f@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> <49B2B9AC.1040703@e-spirit.de> <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> <17b2302a0903071040y40fe7a02oe72f93f59569bb8f@mail.gmail.com> Message-ID: <15e8b9d20903071145k44ef6a51r87dfbedbbd4065e3@mail.gmail.com> On Sat, Mar 7, 2009 at 10:40 AM, Joshua Bloch wrote: > Neal, > Sorry, I should have defined my terms. ?I define a "true resource" as an > object that can only used once, and then must be disposed of, never to be > used again. That's not the usual definition, (see ), but OK. This definition would appear to include classes and interfaces such as java.sql.Statement (close) java.nio.channels.FileLock (release) org.ietf.jgss.GSSCredential (dispose) java.awt.image.VolatileImage (flush) I think one of these use cases is currently supported by the proposal. From reinier at zwitserloot.com Sat Mar 7 12:13:34 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 7 Mar 2009 21:13:34 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> Replies to Neal Gafter, Jeremy Manson, Igor Karp, Vilya Harvey, and Stefan Schultz. Jeremy Manson: We don't discuss the API compatibilty because that's not what source does. That's what jigsaw might help with at some point. I don't really understand your complaint - it applies today as well - the "-source" parameter isn't a new invention, it's been part of javac for years. - source won't even set the class file format properly, that's what - target does. The "-source" parameter just doesn't guarantee producing a class file that works on old systems, and it also doesn't guarantee that the source file will compile on old systems. It's never done that. This proposal does not aim to solve that problem. After all, this is project coin. Not project Franklin, as Neal is so apt to remind us. Igor, and to a lesser extent Stefan: I get the feeling we're not understand each other. I dismantled just about every argument you replied. An 'argfile' is obviously a 'build script'. See my previous post about why moving file-level meta-data into a build script is utterly unacceptable and doesn't have nearly the same advantages. A major point you seem to ignore completely: Meta-data (at least the source and encoding keyword) is part of *EVERY* java file already. If you give me a UTF-16 encoded file, that fact is part of that file, period. I can't compile it without knowing. Same with source compatibility. Making it an explicit part of the file (with our proposal) is therefore only good news. To illustrate the problem I have with yoru arugment: I could argue with equal fervour that import statements ought to be part of a compiler switch or a separate meta-data file using your arguments. Which is clearly a bad idea. Stefan: Magic Comments is a very bad idea because it is first of all obviously a kludge, but it also sets a bad precedent: All java parsers out there now need to parse comments instead of skipping them, which causes very big differences in tokenizer architecture. The tokenizer is also not allowed to quit with an error when it can't parse a magic comment, because there's no telling if it might be some future magic comment syntax that was also introduced to avoid backward incompatibilities. It's technically not backwards compatible, and finally: it's ugly. Note that the proposal has already stated that encoding and source keywords must precede everything else except comments. You can't really demand that these precede all comments, because many tools add a comment at the top of every file (for e.g. a licence). Vilya: javac doesn't parse javadoc tags. It used to go in just to find any @deprecated, but java is moving away from that via the @Deprecated annotation. If anything, these could be annotations on class/interface declarations, but not everything in a java file IS a member. By that time we've passed the package statement, import statements, module- info and package-info directives, and other annotations on the first member (if any) in the source file. It's not flexible enough. We've also just gone, on this mailing list, through a big argument where many contributors jumped on the notion of an annotation changing the way the compiler works (the ARM discussion). Clearly the tone has been set: Don't use annotations (and I think javadoc tags fall under the same distinction) to fundamentally change how the compiler works. Neal: I don't think I understand. All javacs have shipped with the -source parameter, and undoubtedly javac7 will be no exception. Adding the 'source' keyword doesn't mean the JLS all of a sudden needs to embody every version of java that's every existed. The existing of the - source parameter doesn't create that requirement either, and there's no X in front of source, so the -source parameter is part of the java specification. There is going to be no rule in the JLS that states that a compatible compiler -must- support an enumerated list of versions. It just says: This is an alternative to the -source parameter. That's it. That's all. That's a tiny change. I just don't understand why you think this proposal requires a massive change to the JLS. Even if a single javac invocation hits multiple files that have different source keywords in them, I also see no issue. Javac separately stubs out and compiles each file in the end; the only change between compiling every file one-by-one and compiling many at once is for co-dependencies. The groovy/javac mixed compiler, which creates java stubs for groovy files first so a mixed groovy/java source base can be compiled even with many co-dependencies, proves this is an easy problem to solve. Even if that is a bridge too far for project coin, the compiler always has an alternative available: Just Quit. If the compiler can't make a mixed source tree work in one go, just quit. With the appropriate error. This is still an improvement over a vomitous stream of warnings and errors. Tools will be built that use the stubbing approach to get the job done. Javac itself can integrate one of them in a minor point release. --Reinier Zwitserloot On Mar 7, 2009, at 18:27, Igor Karp wrote: > Reiner, > > please see the comments inline. > > On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot > wrote: >> Igor, >> >> how could the command line options be expanded? Allow -encoding to >> specify a >> separate encoding for each file? I don't see how that can work. > For example: allow multiple -encoding options and add optional path to > encoding -encoding [,] > Where path can be either a package (settings applied to the package > and every package under it) or a single file for maximum precision. > So one can have: > -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding > X,a.b.c.d.IAmSpecial > IAMSpecial.java will get encoding X, > everything else under a.b.c will get encoding Z, > everything else under a.b will get encoding Y > and the rest will get encoding X. > Same approach can be applied to -source. > >> There's no >> way I or anyone else is going to edit a build script (be it just >> javac, a >> home-rolled thing, ant, rake, make, maven, ivy, etcetera) to >> carefully >> enumerate every file's source compatibility level. > Sure, thats what argfiles are for: store the settings in a file and > use javac @argfile. > > And doing it as proposed above on a package level would make it more > manageable. > Remember in your proposal the only option is to specify it on a file > level (this is fixable i guess). > >> Changing the command line >> options also incurs the neccessary wrath of all those build tool >> developers >> as they'd have to update their software to handle the new option >> (adding an >> option is a change too!) > Not more than changing the language itself. > >> >> Could you also elaborate on why you don't like it? For example, how >> can the >> benefits of having (more) portable source files, easier migration, >> and a >> much cleaner solution to e.g. the assert-in-javac1.4 be achieved >> with e.g. >> command line options, or do you not consider any of those worthwhile? > I fully support the goal. I even see it as is a bit too narrow (see > below). But I do not see a need to change the language to achieve that > goal. > > On a conceptual level I see these options as a metadata of the source > files and I don't like the idea of coupling it with the file. > One can avoid all this complexity of extra parsing by specifying the > encoding in an external file. This external file does not have > itself to be in that encoding. In fact it can be restricted to be > always in ASCII. > > I think the addition of an optional path and allowing multiple use of > the same option approach is much more scalable: it could be extended > to the other existing options (like -deprecation, -Xlint, etc.) and to > the options that might appear in the future. > > I wish I could concentrate on deprecations in a certain package and > ignore them everywhere else for now: > javac -deprecation,really.rusty.one ... > Finished with (or gave up on ;) that one and want to switch to the > next one: > javac -deprecation,another.old.one > > Igor Karp > >> >> As an aside, how do people approach project coin submissions? I >> tend to look >> at a proposal's value, which is its benefit divided by the >> disadvantages >> (end-programmer complexity to learn, amount of changes needed to >> javac >> and/or JVM, and restrictions on potential future expansions). One >> of the >> reasons I'm writing this up with Roel is because the disadvantages >> seemed to >> be almost nonexistent on the outset (the encoding stuff made it more >> complicated, but at least the complication is entirely hidden from >> java >> developer's eyes, so it value proposal is still aces in my book). >> If there's >> a goal to keep the total language changes, no matter how simple >> they are, >> down to a small set, then benefit regardless of disadvantages is >> the better >> yardstick. >> >> --Reinier Zwitserloot >> >> >> >> On Mar 7, 2009, at 08:15, Igor Karp wrote: >> >>> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot >>> wrote: >>>> >>>> We have written up a proposal for adding a 'source' and 'encoding' >>>> keyword (alternatives to the -source and -encoding keywords on the >>>> command line; they work pretty much just as you expect). The >>>> keywords >>>> are context sensitive and must both appear before anything else >>>> other >>>> than comments to be parsed. In case the benefit isn't obvious: It >>>> is a >>>> great help when you are trying to port a big project to a new >>>> source >>>> language compatibility. Leaving half your sourcebase in v1.6 and >>>> the >>>> other half in v1.7 is pretty much impossible today, it's all-or- >>>> nothing. It should also be a much nicer solution to the 'assert in >>>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, >>>> given >>>> that 'module' is most likely going to become a keyword. Finally, it >>>> makes java files a lot more portable; you no longer run into your >>>> strings looking weird when you move your Windows-1252 codefile java >>>> source to a mac, for example. >>>> >>>> Before we finish it though, some open questions we'd like some >>>> feedback on: >>>> >>>> A) Technically, starting a file with "source 1.4" is obviously >>>> silly; >>>> javac v1.4 doesn't know about the source keyword and would thus >>>> fail >>>> immediately. However, practically, its still useful. Example: if >>>> you've mostly converted a GWT project to GWT 1.5 (which uses java >>>> 1.5 >>>> syntax), but have a few files remaining on GWT v1.4 (which uses >>>> java >>>> 1.4 syntax), then tossing a "source 1.4;" in those older files >>>> eliminates all the generics warnings and serves as a reminder >>>> that you >>>> should still convert those at some point. However, it isn't - >>>> actually- >>>> compatible with a real javac 1.4. We're leaning to making "source >>>> 1.6;" (and below) legal even when using a javac v1.7 or above, but >>>> perhaps that's a bridge too far? We could go with magic comments >>>> but >>>> that seems like a very bad solution. >>>> >>>> also: >>>> >>>> Encoding is rather a hairy issue; javac will need to read the >>>> file to >>>> find the encoding, but to read a file, it needs to know about >>>> encoding! Fortunately, *every single* popular encoding on >>>> wikipedia's >>>> popular encoding list at: >>>> >>>> >>>> http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings >>>> >>>> will encode "encoding own-name-in-that-encoding;" the same as ASCII >>>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I >>>> doubt >>>> anyone ever uses to program java). >>>> >>>> Therefore, the proposal includes the following strategy to find the >>>> encoding statement in a java source file without knowing the >>>> encoding >>>> beforehand: >>>> >>>> An entirely separate parser (the encoding parser) is run repeatedly >>>> until the right encoding is found. First it'll decode the input >>>> with >>>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as >>>> per >>>> the java standard), then as UTF-32 (BE if no BOM), then the current >>>> behaviour (-encoding parameter's value if any, otherwise platform >>>> default encoding). This separate parser works as follows: >>>> >>>> 1. Ignore any comments and whitespace. >>>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; >>>> - if >>>> that pattern matches partially but is not correctly completed, that >>>> parser run exits without finding an encoding, immediately. >>>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern >>>> matches >>>> partially but is not correctly completed, that parser run exists >>>> without finding an encoding, immediately. If it does complete, the >>>> parser also exists immediately and returns the captured value. >>>> 5. If it finds anything else, stop immediately, returning no >>>> encoding >>>> found. >>>> >>>> Once it's found something, the 'real' java parser will run using >>>> the >>>> found encoding (this overrides any -encoding on the command line). >>>> Note that the encoding parser stops quickly; For example, if it >>>> finds >>>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an >>>> import statement), it'll stop immediately. >>>> >>>> If an encoding is encountered that was not found during the >>>> standard >>>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only >>>> due to >>>> a platform default/command line encoding param, (e.g. a platform >>>> that >>>> defaults to UTF-16LE without a byte order mark) a warning >>>> explaining >>>> that the encoding statement isn't doing anything is generated. Of >>>> course, if the encoding doesn't match itself, you get an error >>>> (putting "encoding UTF-16;" into a UTF-8 encoded file for >>>> example). If >>>> there is no encoding statement, the 'real' java parser does what it >>>> does now: Use the -encoding parameter of javac, and if that wasn't >>>> present, the platform default. >>>> >>>> However, there is 1 major and 1 minor problem with this approach: >>>> >>>> B) This means javac will need to read every source file many >>>> times to >>>> compile it. >>>> >>>> Worst case (no encoding keyword): 5 times. >>>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). >>>> >>>> Fortunately all runs should stop quickly, due to the encoding >>>> parser's >>>> penchant to quit very early. Javacs out there will either stuff the >>>> entire source file into memory, or if not, disk cache should take >>>> care >>>> of it, but we can't prove beyond a doubt that this repeated parsing >>>> will have no significant impact on compile time. Is this a >>>> showstopper? Is the need to include a new (but small) parser into >>>> javac a showstopper? >>>> >>>> C) Certain character sets, such as ISO-2022, can make the encoding >>>> statement unreadable with the standard strategy if a comment >>>> including >>>> non-ASCII characters precedes the encoding statement. These >>>> situations >>>> are very rare (in fact, I haven't managed to find an example), so >>>> is >>>> it okay to just ignore this issue? If you add the encoding >>>> statement >>>> after a bunch of comments that make it invisible, and then >>>> compile it >>>> with the right -encoding parameter, you WILL get a warning that the >>>> encoding statement isn't going to help a javac on another >>>> platform / >>>> without that encoding parameter to figure it out, so you just get >>>> the >>>> current status quo: your source file won't compile without an >>>> explicit >>>> -encoding parameter (or if that happens to be the platform >>>> default). >>>> Should this be mentioned in the proposal? Should the compiler >>>> (and the >>>> proposal) put effort into generating a useful warning message, >>>> such as >>>> figuring out if it WOULD parse correctly if the encoding >>>> statement is >>>> at the very top of the source file, vs. suggesting to recode in >>>> UTF-8? >>>> >>>> and a final dilemma: >>>> >>>> D) Should we separate the proposals for source and encoding >>>> keywords? >>>> The source keyword is more useful and a lot simpler overall than >>>> the >>>> encoding keyword, but they do sort of go together. >>> >>> Separate. Another reason is: the argument of applying different >>> settings >>> to >>> different parts of the project is much less valid with encoding than >>> with source. >>> >>>> >>>> --Reinier Zwitserloot and Roel Spilker >>>> >>>> >>> Overall: I would prefer command line options enhanced to handle the >>> situation >>> rather than language change. >>> >>> Igor Karp >> >> From neal at gafter.com Sat Mar 7 12:39:47 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 12:39:47 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> Message-ID: <15e8b9d20903071239i7345eff1x784448a851b8aaaa@mail.gmail.com> On Sat, Mar 7, 2009 at 12:13 PM, Reinier Zwitserloot wrote: > I don't think I understand. All javacs have shipped with the -source > parameter, and undoubtedly javac7 will be no exception. Adding the > 'source' keyword doesn't mean the JLS all of a sudden needs to embody > every version of java that's every existed. Yes, it does. The JLS is supposed to document the meaning of the programming language, so if you move this into the domain of the language, it must be specified. > The groovy/javac mixed compiler, which creates java stubs for groovy > files first so a mixed groovy/java source base can be compiled even > with many co-dependencies, proves this is an easy problem to solve. Yes, perhaps an easy problem to *implement* (though I suspect it's much more difficult than you seem to think) if you don't mind not having a language specification. > Even if that is a bridge too far for project coin, the compiler always > has an alternative available: Just Quit. If the compiler can't make a > mixed source tree work in one go, just quit. With the appropriate > error. This is still an improvement over a vomitous stream of warnings > and errors. Tools will be built that use the stubbing approach to get > the job done. Javac itself can integrate one of them in a minor point > release. If that's all you want, the javac compiler already does it: T.java:1: class, interface, or enum expected source 1.4; ^ 1 error See, a nice clear error message saying it can't handle it. If you want any more than that, you'll have to specify it more precisely. "Whatever the compiler can handle" is no way to specify a language. From schulz at e-spirit.de Sat Mar 7 13:05:22 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 07 Mar 2009 22:05:22 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> Message-ID: <49B2E192.4080402@e-spirit.de> Reinier Zwitserloot schrieb: > Meta-data (at least the source and encoding keyword) is part of > *EVERY* java file already. If you give me a UTF-16 encoded file, that > fact is part of that file, period. I can't compile it without knowing. > Same with source compatibility. Making it an explicit part of the file > (with our proposal) is therefore only good news. Firstly, I was thinking about SVN already handling these meta-data, and of course external to the actual file. Secondly, a file may be encoded in UTF-8, but that does not make the meta-information be a required part of the file itself. In general, meta-information not necessarily has to be stored within the resource it is related to (although it might be more handy to do so). > Magic Comments is a very bad idea because it is first of all obviously > a kludge, but it also sets a bad precedent: All java parsers out there > now need to parse comments instead of skipping them, which causes very > big differences in tokenizer architecture. The tokenizer is also not > allowed to quit with an error when it can't parse a magic comment, > because there's no telling if it might be some future magic comment > syntax that was also introduced to avoid backward incompatibilities. > It's technically not backwards compatible, and finally: it's ugly. > Note that the proposal has already stated that encoding and source > keywords must precede everything else except comments. You can't > really demand that these precede all comments, because many tools add > a comment at the top of every file (for e.g. a licence). Well, as you said yourself, it is meta-information on the resource in question. As a consequence to me, these information do not belong to the Java Language and do not deserve keywords for themselves. There already is a notation for expressing meta-information in Java: Annotations. Your argument against Annotations is that they must not influence the outcome of the compilation. Well, for your cases of encoding and source they don't. These only flag the compiler on how to properly read the code. Stefan From r.spilker at gmail.com Sat Mar 7 14:22:28 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Sat, 7 Mar 2009 23:22:28 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: Good one :-) Javac won't even create a class file if the @Override annotation is present but shouldn't be there. On Sat, Mar 7, 2009 at 7:22 PM, Igor Karp wrote: > Roel, > > well, these were not my ideas anyway ;-). I would be equally unhappy > using javadoc appoach. > And as a side note: @Override does influence the result of the compiler > already. > > Igor > > On Sat, Mar 7, 2009 at 9:55 AM, Roel Spilker wrote: > > I'd say javadoc, as well as annotation, should never influence the result > of > > the compiler. That's just not the right vehicle. > > > > Roel > > > > On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp wrote: > >> > >> Reiner, > >> > >> please see the comments inline. > >> > >> On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot > >> wrote: > >> > Igor, > >> > > >> > how could the command line options be expanded? Allow -encoding to > >> > specify a > >> > separate encoding for each file? I don't see how that can work. > >> For example: allow multiple -encoding options and add optional path to > >> encoding -encoding [,] > >> Where path can be either a package (settings applied to the package > >> and every package under it) or a single file for maximum precision. > >> So one can have: > >> -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding > >> X,a.b.c.d.IAmSpecial > >> IAMSpecial.java will get encoding X, > >> everything else under a.b.c will get encoding Z, > >> everything else under a.b will get encoding Y > >> and the rest will get encoding X. > >> Same approach can be applied to -source. > >> > >> > There's no > >> > way I or anyone else is going to edit a build script (be it just > javac, > >> > a > >> > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to carefully > >> > enumerate every file's source compatibility level. > >> Sure, thats what argfiles are for: store the settings in a file and > >> use javac @argfile. > >> > >> And doing it as proposed above on a package level would make it more > >> manageable. > >> Remember in your proposal the only option is to specify it on a file > >> level (this is fixable i guess). > >> > >> > Changing the command line > >> > options also incurs the neccessary wrath of all those build tool > >> > developers > >> > as they'd have to update their software to handle the new option > (adding > >> > an > >> > option is a change too!) > >> Not more than changing the language itself. > >> > >> > > >> > Could you also elaborate on why you don't like it? For example, how > can > >> > the > >> > benefits of having (more) portable source files, easier migration, and > a > >> > much cleaner solution to e.g. the assert-in-javac1.4 be achieved with > >> > e.g. > >> > command line options, or do you not consider any of those worthwhile? > >> I fully support the goal. I even see it as is a bit too narrow (see > >> below). But I do not see a need to change the language to achieve that > >> goal. > >> > >> On a conceptual level I see these options as a metadata of the source > >> files and I don't like the idea of coupling it with the file. > >> One can avoid all this complexity of extra parsing by specifying the > >> encoding in an external file. This external file does not have > >> itself to be in that encoding. In fact it can be restricted to be > >> always in ASCII. > >> > >> I think the addition of an optional path and allowing multiple use of > >> the same option approach is much more scalable: it could be extended > >> to the other existing options (like -deprecation, -Xlint, etc.) and to > >> the options that might appear in the future. > >> > >> I wish I could concentrate on deprecations in a certain package and > >> ignore them everywhere else for now: > >> javac -deprecation,really.rusty.one ... > >> Finished with (or gave up on ;) that one and want to switch to the next > >> one: > >> javac -deprecation,another.old.one > >> > >> Igor Karp > >> > >> > > >> > As an aside, how do people approach project coin submissions? I tend > to > >> > look > >> > at a proposal's value, which is its benefit divided by the > disadvantages > >> > (end-programmer complexity to learn, amount of changes needed to javac > >> > and/or JVM, and restrictions on potential future expansions). One of > the > >> > reasons I'm writing this up with Roel is because the disadvantages > >> > seemed to > >> > be almost nonexistent on the outset (the encoding stuff made it more > >> > complicated, but at least the complication is entirely hidden from > java > >> > developer's eyes, so it value proposal is still aces in my book). If > >> > there's > >> > a goal to keep the total language changes, no matter how simple they > >> > are, > >> > down to a small set, then benefit regardless of disadvantages is the > >> > better > >> > yardstick. > >> > > >> > --Reinier Zwitserloot > >> > > >> > > >> > > >> > On Mar 7, 2009, at 08:15, Igor Karp wrote: > >> > > >> >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > >> >> wrote: > >> >>> > >> >>> We have written up a proposal for adding a 'source' and 'encoding' > >> >>> keyword (alternatives to the -source and -encoding keywords on the > >> >>> command line; they work pretty much just as you expect). The > keywords > >> >>> are context sensitive and must both appear before anything else > other > >> >>> than comments to be parsed. In case the benefit isn't obvious: It is > a > >> >>> great help when you are trying to port a big project to a new source > >> >>> language compatibility. Leaving half your sourcebase in v1.6 and the > >> >>> other half in v1.7 is pretty much impossible today, it's all-or- > >> >>> nothing. It should also be a much nicer solution to the 'assert in > >> >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, > given > >> >>> that 'module' is most likely going to become a keyword. Finally, it > >> >>> makes java files a lot more portable; you no longer run into your > >> >>> strings looking weird when you move your Windows-1252 codefile java > >> >>> source to a mac, for example. > >> >>> > >> >>> Before we finish it though, some open questions we'd like some > >> >>> feedback on: > >> >>> > >> >>> A) Technically, starting a file with "source 1.4" is obviously > silly; > >> >>> javac v1.4 doesn't know about the source keyword and would thus fail > >> >>> immediately. However, practically, its still useful. Example: if > >> >>> you've mostly converted a GWT project to GWT 1.5 (which uses java > 1.5 > >> >>> syntax), but have a few files remaining on GWT v1.4 (which uses java > >> >>> 1.4 syntax), then tossing a "source 1.4;" in those older files > >> >>> eliminates all the generics warnings and serves as a reminder that > you > >> >>> should still convert those at some point. However, it isn't > -actually- > >> >>> compatible with a real javac 1.4. We're leaning to making "source > >> >>> 1.6;" (and below) legal even when using a javac v1.7 or above, but > >> >>> perhaps that's a bridge too far? We could go with magic comments but > >> >>> that seems like a very bad solution. > >> >>> > >> >>> also: > >> >>> > >> >>> Encoding is rather a hairy issue; javac will need to read the file > to > >> >>> find the encoding, but to read a file, it needs to know about > >> >>> encoding! Fortunately, *every single* popular encoding on > wikipedia's > >> >>> popular encoding list at: > >> >>> > >> >>> > >> >>> > >> >>> > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > >> >>> > >> >>> will encode "encoding own-name-in-that-encoding;" the same as ASCII > >> >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I > doubt > >> >>> anyone ever uses to program java). > >> >>> > >> >>> Therefore, the proposal includes the following strategy to find the > >> >>> encoding statement in a java source file without knowing the > encoding > >> >>> beforehand: > >> >>> > >> >>> An entirely separate parser (the encoding parser) is run repeatedly > >> >>> until the right encoding is found. First it'll decode the input with > >> >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as > per > >> >>> the java standard), then as UTF-32 (BE if no BOM), then the current > >> >>> behaviour (-encoding parameter's value if any, otherwise platform > >> >>> default encoding). This separate parser works as follows: > >> >>> > >> >>> 1. Ignore any comments and whitespace. > >> >>> 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - > if > >> >>> that pattern matches partially but is not correctly completed, that > >> >>> parser run exits without finding an encoding, immediately. > >> >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern > matches > >> >>> partially but is not correctly completed, that parser run exists > >> >>> without finding an encoding, immediately. If it does complete, the > >> >>> parser also exists immediately and returns the captured value. > >> >>> 5. If it finds anything else, stop immediately, returning no > encoding > >> >>> found. > >> >>> > >> >>> Once it's found something, the 'real' java parser will run using the > >> >>> found encoding (this overrides any -encoding on the command line). > >> >>> Note that the encoding parser stops quickly; For example, if it > finds > >> >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > >> >>> import statement), it'll stop immediately. > >> >>> > >> >>> If an encoding is encountered that was not found during the standard > >> >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due > to > >> >>> a platform default/command line encoding param, (e.g. a platform > that > >> >>> defaults to UTF-16LE without a byte order mark) a warning explaining > >> >>> that the encoding statement isn't doing anything is generated. Of > >> >>> course, if the encoding doesn't match itself, you get an error > >> >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for example). > If > >> >>> there is no encoding statement, the 'real' java parser does what it > >> >>> does now: Use the -encoding parameter of javac, and if that wasn't > >> >>> present, the platform default. > >> >>> > >> >>> However, there is 1 major and 1 minor problem with this approach: > >> >>> > >> >>> B) This means javac will need to read every source file many times > to > >> >>> compile it. > >> >>> > >> >>> Worst case (no encoding keyword): 5 times. > >> >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). > >> >>> > >> >>> Fortunately all runs should stop quickly, due to the encoding > parser's > >> >>> penchant to quit very early. Javacs out there will either stuff the > >> >>> entire source file into memory, or if not, disk cache should take > care > >> >>> of it, but we can't prove beyond a doubt that this repeated parsing > >> >>> will have no significant impact on compile time. Is this a > >> >>> showstopper? Is the need to include a new (but small) parser into > >> >>> javac a showstopper? > >> >>> > >> >>> C) Certain character sets, such as ISO-2022, can make the encoding > >> >>> statement unreadable with the standard strategy if a comment > including > >> >>> non-ASCII characters precedes the encoding statement. These > situations > >> >>> are very rare (in fact, I haven't managed to find an example), so is > >> >>> it okay to just ignore this issue? If you add the encoding statement > >> >>> after a bunch of comments that make it invisible, and then compile > it > >> >>> with the right -encoding parameter, you WILL get a warning that the > >> >>> encoding statement isn't going to help a javac on another platform / > >> >>> without that encoding parameter to figure it out, so you just get > the > >> >>> current status quo: your source file won't compile without an > explicit > >> >>> -encoding parameter (or if that happens to be the platform default). > >> >>> Should this be mentioned in the proposal? Should the compiler (and > the > >> >>> proposal) put effort into generating a useful warning message, such > as > >> >>> figuring out if it WOULD parse correctly if the encoding statement > is > >> >>> at the very top of the source file, vs. suggesting to recode in > UTF-8? > >> >>> > >> >>> and a final dilemma: > >> >>> > >> >>> D) Should we separate the proposals for source and encoding > keywords? > >> >>> The source keyword is more useful and a lot simpler overall than the > >> >>> encoding keyword, but they do sort of go together. > >> >> > >> >> Separate. Another reason is: the argument of applying different > >> >> settings > >> >> to > >> >> different parts of the project is much less valid with encoding than > >> >> with source. > >> >> > >> >>> > >> >>> --Reinier Zwitserloot and Roel Spilker > >> >>> > >> >>> > >> >> Overall: I would prefer command line options enhanced to handle the > >> >> situation > >> >> rather than language change. > >> >> > >> >> Igor Karp > >> > > >> > > >> > > > > > From jeremy.manson at gmail.com Sat Mar 7 14:33:55 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 7 Mar 2009 14:33:55 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> <5DC1ED63-555D-4E2E-849F-7BE91C46A9DA@zwitserloot.com> Message-ID: <1631da7d0903071433id05f5bah9b27b599fd510db8@mail.gmail.com> On Sat, Mar 7, 2009 at 12:13 PM, Reinier Zwitserloot wrote: > Replies to Neal Gafter, Jeremy Manson, Igor Karp, Vilya Harvey, and > Stefan Schultz. > > Jeremy Manson: > > We don't discuss the API compatibilty because that's not what source > does. That's what jigsaw might help with at some point. I don't really > understand your complaint - it applies today as well - the "-source" > parameter isn't a new invention, it's been part of javac for years. - > source won't even set the class file format properly, that's what - > target does. The "-source" parameter just doesn't guarantee producing > a class file that works on old systems, and it also doesn't guarantee > that the source file will compile on old systems. It's never done > that. This proposal does not aim to solve that problem. After all, > this is project coin. Not project Franklin, as Neal is so apt to > remind us. Hi Reinier, I agree that -source doesn't do this now, and I think -source ends up not being a solution to the problem it thinks it is solving. There are many people out there who think that -source will ensure that their code will run on earlier versions of Java, when it won't. Instead, those people will get mysterious runtime errors when they try to use older JDKs. This has happened to me when trying to migrate a large source base from Java 5 to Java 6; once we started to compile with Java 6, people started using the Java 6 APIs in spite of the fact that we used -source 5. This was especially a problem in shared libraries; when people wanted to deploy with 1.5, they thought that -source would protect them. Instead, they found out after the fact, with a loud crash and a bang, that they couldn't use 1.5. Fundamentally, you can't realistically separate the Java language from the APIs (at least, the core APIs: lang, util, and probably net and io/nio). That's why if you want to solve this problem, it has to include a solution for the APIs as well. I think this makes it a fairly large project, outside the "small change" scope. Jeremy From r.spilker at gmail.com Sat Mar 7 14:40:05 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Sat, 7 Mar 2009 23:40:05 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> Message-ID: I'd really like to see getSuppressedExceptions() and addSuppressedException() in Throwable. This is also usefull in other scenario's as well. So maybe it is worth its own coin proposal. But then again, you'd get a dependency on that proposal. In that case I think it should be promoted to the body. About the stacktrace: it isn't really part of the stack. And if the close method throws an exception in the finally block, and no other exception has been thrown, you would get the exception anyway, right? So I think there is no need for any of the suppressed exceptions to be part of the stacktrace. Roel On Sat, Mar 7, 2009 at 7:31 PM, Joshua Bloch wrote: > > I am not suggesting this. Most people have no need to look at these > exceptions. Those who do can read them by calling the > getSuppressedExceptions()method. If people think it's worth it, the stack > trace printing code could be modified to include suppressed exceptions. > In > many cases, that would cause suppressed exceptions to be logged > automatically. But I have some misgivings about this approach: I suspect > there are programs that parse stack traces. While I frown on this > behavior, > and the spec does not guarantee that it works, I'd hate to be responsible > for breaking these programs. > > What do others think of the "Retaining suppressed exceptions" feature? > Should it be promoted to the body of the proposal? Should the suppressed > exceptions be included in the stack trace? > > Thanks, > > Josh > > From schulz at e-spirit.de Sat Mar 7 15:02:30 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 08 Mar 2009 00:02:30 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> Message-ID: <49B2FD06.9010605@e-spirit.de> It all depends on what one defines as "result" of a compilation. I am thinking of all the @SuppressWarnings Annotations in my code, which also influence the result of the compilation _process_. I'd say that Annotations should not influence the _binary output_ of a compilation. In the end, @Override and @SuppressWarnings as well as @Deprecated and @Retention are local compiler flags on how to treat specific code, i.e., meta-information being read and handled by the compiler. Stefan Roel Spilker wrote: > Good one :-) Javac won't even create a class file if the @Override > annotation is present but shouldn't be there. > > > On Sat, Mar 7, 2009 at 7:22 PM, Igor Karp wrote: > > > Roel, > > > > well, these were not my ideas anyway ;-). I would be equally unhappy > > using javadoc appoach. > > And as a side note: @Override does influence the result of the compiler > > already. > > > > Igor > > > > On Sat, Mar 7, 2009 at 9:55 AM, Roel Spilker wrote: > > > I'd say javadoc, as well as annotation, should never influence the > result > > of > > > the compiler. That's just not the right vehicle. > > > > > > Roel > > > > > > On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp > wrote: > > >> > > >> Reiner, > > >> > > >> please see the comments inline. > > >> > > >> On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot > > >> wrote: > > >> > Igor, > > >> > > > >> > how could the command line options be expanded? Allow -encoding to > > >> > specify a > > >> > separate encoding for each file? I don't see how that can work. > > >> For example: allow multiple -encoding options and add optional path to > > >> encoding -encoding [,] > > >> Where path can be either a package (settings applied to the package > > >> and every package under it) or a single file for maximum precision. > > >> So one can have: > > >> -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding > > >> X,a.b.c.d.IAmSpecial > > >> IAMSpecial.java will get encoding X, > > >> everything else under a.b.c will get encoding Z, > > >> everything else under a.b will get encoding Y > > >> and the rest will get encoding X. > > >> Same approach can be applied to -source. > > >> > > >> > There's no > > >> > way I or anyone else is going to edit a build script (be it just > > javac, > > >> > a > > >> > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to > carefully > > >> > enumerate every file's source compatibility level. > > >> Sure, thats what argfiles are for: store the settings in a file and > > >> use javac @argfile. > > >> > > >> And doing it as proposed above on a package level would make it more > > >> manageable. > > >> Remember in your proposal the only option is to specify it on a file > > >> level (this is fixable i guess). > > >> > > >> > Changing the command line > > >> > options also incurs the neccessary wrath of all those build tool > > >> > developers > > >> > as they'd have to update their software to handle the new option > > (adding > > >> > an > > >> > option is a change too!) > > >> Not more than changing the language itself. > > >> > > >> > > > >> > Could you also elaborate on why you don't like it? For example, how > > can > > >> > the > > >> > benefits of having (more) portable source files, easier > migration, and > > a > > >> > much cleaner solution to e.g. the assert-in-javac1.4 be achieved > with > > >> > e.g. > > >> > command line options, or do you not consider any of those > worthwhile? > > >> I fully support the goal. I even see it as is a bit too narrow (see > > >> below). But I do not see a need to change the language to achieve that > > >> goal. > > >> > > >> On a conceptual level I see these options as a metadata of the source > > >> files and I don't like the idea of coupling it with the file. > > >> One can avoid all this complexity of extra parsing by specifying the > > >> encoding in an external file. This external file does not have > > >> itself to be in that encoding. In fact it can be restricted to be > > >> always in ASCII. > > >> > > >> I think the addition of an optional path and allowing multiple use of > > >> the same option approach is much more scalable: it could be extended > > >> to the other existing options (like -deprecation, -Xlint, etc.) and to > > >> the options that might appear in the future. > > >> > > >> I wish I could concentrate on deprecations in a certain package and > > >> ignore them everywhere else for now: > > >> javac -deprecation,really.rusty.one ... > > >> Finished with (or gave up on ;) that one and want to switch to the > next > > >> one: > > >> javac -deprecation,another.old.one > > >> > > >> Igor Karp > > >> > > >> > > > >> > As an aside, how do people approach project coin submissions? I tend > > to > > >> > look > > >> > at a proposal's value, which is its benefit divided by the > > disadvantages > > >> > (end-programmer complexity to learn, amount of changes needed to > javac > > >> > and/or JVM, and restrictions on potential future expansions). One of > > the > > >> > reasons I'm writing this up with Roel is because the disadvantages > > >> > seemed to > > >> > be almost nonexistent on the outset (the encoding stuff made it more > > >> > complicated, but at least the complication is entirely hidden from > > java > > >> > developer's eyes, so it value proposal is still aces in my book). If > > >> > there's > > >> > a goal to keep the total language changes, no matter how simple they > > >> > are, > > >> > down to a small set, then benefit regardless of disadvantages is the > > >> > better > > >> > yardstick. > > >> > > > >> > --Reinier Zwitserloot > > >> > > > >> > > > >> > > > >> > On Mar 7, 2009, at 08:15, Igor Karp wrote: > > >> > > > >> >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > > >> >> wrote: > > >> >>> > > >> >>> We have written up a proposal for adding a 'source' and 'encoding' > > >> >>> keyword (alternatives to the -source and -encoding keywords on the > > >> >>> command line; they work pretty much just as you expect). The > > keywords > > >> >>> are context sensitive and must both appear before anything else > > other > > >> >>> than comments to be parsed. In case the benefit isn't obvious: > It is > > a > > >> >>> great help when you are trying to port a big project to a new > source > > >> >>> language compatibility. Leaving half your sourcebase in v1.6 > and the > > >> >>> other half in v1.7 is pretty much impossible today, it's all-or- > > >> >>> nothing. It should also be a much nicer solution to the 'assert in > > >> >>> v1.4' dilemma, which I guess is going to happen to v1.7 as well, > > given > > >> >>> that 'module' is most likely going to become a keyword. > Finally, it > > >> >>> makes java files a lot more portable; you no longer run into your > > >> >>> strings looking weird when you move your Windows-1252 codefile > java > > >> >>> source to a mac, for example. > > >> >>> > > >> >>> Before we finish it though, some open questions we'd like some > > >> >>> feedback on: > > >> >>> > > >> >>> A) Technically, starting a file with "source 1.4" is obviously > > silly; > > >> >>> javac v1.4 doesn't know about the source keyword and would > thus fail > > >> >>> immediately. However, practically, its still useful. Example: if > > >> >>> you've mostly converted a GWT project to GWT 1.5 (which uses java > > 1.5 > > >> >>> syntax), but have a few files remaining on GWT v1.4 (which > uses java > > >> >>> 1.4 syntax), then tossing a "source 1.4;" in those older files > > >> >>> eliminates all the generics warnings and serves as a reminder that > > you > > >> >>> should still convert those at some point. However, it isn't > > -actually- > > >> >>> compatible with a real javac 1.4. We're leaning to making "source > > >> >>> 1.6;" (and below) legal even when using a javac v1.7 or > above, but > > >> >>> perhaps that's a bridge too far? We could go with magic > comments but > > >> >>> that seems like a very bad solution. > > >> >>> > > >> >>> also: > > >> >>> > > >> >>> Encoding is rather a hairy issue; javac will need to read the file > > to > > >> >>> find the encoding, but to read a file, it needs to know about > > >> >>> encoding! Fortunately, *every single* popular encoding on > > wikipedia's > > >> >>> popular encoding list at: > > >> >>> > > >> >>> > > >> >>> > > >> >>> > > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > >> >>> > > >> >>> will encode "encoding own-name-in-that-encoding;" the same as > ASCII > > >> >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I > > doubt > > >> >>> anyone ever uses to program java). > > >> >>> > > >> >>> Therefore, the proposal includes the following strategy to > find the > > >> >>> encoding statement in a java source file without knowing the > > encoding > > >> >>> beforehand: > > >> >>> > > >> >>> An entirely separate parser (the encoding parser) is run > repeatedly > > >> >>> until the right encoding is found. First it'll decode the > input with > > >> >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as > > per > > >> >>> the java standard), then as UTF-32 (BE if no BOM), then the > current > > >> >>> behaviour (-encoding parameter's value if any, otherwise platform > > >> >>> default encoding). This separate parser works as follows: > > >> >>> > > >> >>> 1. Ignore any comments and whitespace. > > >> >>> 3. Ignore the pattern (regexp-like-syntax, ): > source\s+[^\s]+\s*; - > > if > > >> >>> that pattern matches partially but is not correctly completed, > that > > >> >>> parser run exits without finding an encoding, immediately. > > >> >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern > > matches > > >> >>> partially but is not correctly completed, that parser run exists > > >> >>> without finding an encoding, immediately. If it does complete, the > > >> >>> parser also exists immediately and returns the captured value. > > >> >>> 5. If it finds anything else, stop immediately, returning no > > encoding > > >> >>> found. > > >> >>> > > >> >>> Once it's found something, the 'real' java parser will run > using the > > >> >>> found encoding (this overrides any -encoding on the command line). > > >> >>> Note that the encoding parser stops quickly; For example, if it > > finds > > >> >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > > >> >>> import statement), it'll stop immediately. > > >> >>> > > >> >>> If an encoding is encountered that was not found during the > standard > > >> >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked > only due > > to > > >> >>> a platform default/command line encoding param, (e.g. a platform > > that > > >> >>> defaults to UTF-16LE without a byte order mark) a warning > explaining > > >> >>> that the encoding statement isn't doing anything is generated. Of > > >> >>> course, if the encoding doesn't match itself, you get an error > > >> >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for > example). > > If > > >> >>> there is no encoding statement, the 'real' java parser does > what it > > >> >>> does now: Use the -encoding parameter of javac, and if that wasn't > > >> >>> present, the platform default. > > >> >>> > > >> >>> However, there is 1 major and 1 minor problem with this approach: > > >> >>> > > >> >>> B) This means javac will need to read every source file many times > > to > > >> >>> compile it. > > >> >>> > > >> >>> Worst case (no encoding keyword): 5 times. > > >> >>> Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > >> >>> > > >> >>> Fortunately all runs should stop quickly, due to the encoding > > parser's > > >> >>> penchant to quit very early. Javacs out there will either > stuff the > > >> >>> entire source file into memory, or if not, disk cache should take > > care > > >> >>> of it, but we can't prove beyond a doubt that this repeated > parsing > > >> >>> will have no significant impact on compile time. Is this a > > >> >>> showstopper? Is the need to include a new (but small) parser into > > >> >>> javac a showstopper? > > >> >>> > > >> >>> C) Certain character sets, such as ISO-2022, can make the encoding > > >> >>> statement unreadable with the standard strategy if a comment > > including > > >> >>> non-ASCII characters precedes the encoding statement. These > > situations > > >> >>> are very rare (in fact, I haven't managed to find an example), > so is > > >> >>> it okay to just ignore this issue? If you add the encoding > statement > > >> >>> after a bunch of comments that make it invisible, and then compile > > it > > >> >>> with the right -encoding parameter, you WILL get a warning > that the > > >> >>> encoding statement isn't going to help a javac on another > platform / > > >> >>> without that encoding parameter to figure it out, so you just get > > the > > >> >>> current status quo: your source file won't compile without an > > explicit > > >> >>> -encoding parameter (or if that happens to be the platform > default). > > >> >>> Should this be mentioned in the proposal? Should the compiler (and > > the > > >> >>> proposal) put effort into generating a useful warning message, > such > > as > > >> >>> figuring out if it WOULD parse correctly if the encoding statement > > is > > >> >>> at the very top of the source file, vs. suggesting to recode in > > UTF-8? > > >> >>> > > >> >>> and a final dilemma: > > >> >>> > > >> >>> D) Should we separate the proposals for source and encoding > > keywords? > > >> >>> The source keyword is more useful and a lot simpler overall > than the > > >> >>> encoding keyword, but they do sort of go together. > > >> >> > > >> >> Separate. Another reason is: the argument of applying different > > >> >> settings > > >> >> to > > >> >> different parts of the project is much less valid with encoding > than > > >> >> with source. > > >> >> > > >> >>> > > >> >>> --Reinier Zwitserloot and Roel Spilker > > >> >>> > > >> >>> > > >> >> Overall: I would prefer command line options enhanced to handle the > > >> >> situation > > >> >> rather than language change. > > >> >> > > >> >> Igor Karp > > >> > > > >> > > > >> > > > > > > > > > > From r.spilker at gmail.com Sat Mar 7 15:58:52 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Sun, 8 Mar 2009 00:58:52 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <49B2FD06.9010605@e-spirit.de> References: <099DF40A-BCF2-4982-88E0-5AFF460FBE26@zwitserloot.com> <49B2FD06.9010605@e-spirit.de> Message-ID: No, for @Override it's not. If you compile both class Foo { @Override void bar() {} } and class Foo { void bar() {} } you will notice that the binary output is different, since the first one won't create Foo.class and the second will. But maybe that's just semantics... Roel On Sun, Mar 8, 2009 at 12:02 AM, Stefan Schulz wrote: > It all depends on what one defines as "result" of a compilation. I am > thinking of all the @SuppressWarnings Annotations in my code, which also > influence the result of the compilation _process_. I'd say that > Annotations should not influence the _binary output_ of a compilation. > > In the end, @Override and @SuppressWarnings as well as @Deprecated and > @Retention are local compiler flags on how to treat specific code, i.e., > meta-information being read and handled by the compiler. > > Stefan > > Roel Spilker wrote: > > Good one :-) Javac won't even create a class file if the @Override > > annotation is present but shouldn't be there. > > > > > > On Sat, Mar 7, 2009 at 7:22 PM, Igor Karp wrote: > > > > > Roel, > > > > > > well, these were not my ideas anyway ;-). I would be equally unhappy > > > using javadoc appoach. > > > And as a side note: @Override does influence the result of the > compiler > > > already. > > > > > > Igor > > > > > > On Sat, Mar 7, 2009 at 9:55 AM, Roel Spilker > wrote: > > > > I'd say javadoc, as well as annotation, should never influence the > > result > > > of > > > > the compiler. That's just not the right vehicle. > > > > > > > > Roel > > > > > > > > On Sat, Mar 7, 2009 at 6:27 PM, Igor Karp > > wrote: > > > >> > > > >> Reiner, > > > >> > > > >> please see the comments inline. > > > >> > > > >> On Fri, Mar 6, 2009 at 11:39 PM, Reinier Zwitserloot > > > >> wrote: > > > >> > Igor, > > > >> > > > > >> > how could the command line options be expanded? Allow -encoding > to > > > >> > specify a > > > >> > separate encoding for each file? I don't see how that can work. > > > >> For example: allow multiple -encoding options and add optional path > to > > > >> encoding -encoding [,] > > > >> Where path can be either a package (settings applied to the package > > > >> and every package under it) or a single file for maximum precision. > > > >> So one can have: > > > >> -encoding X - encoding Y,a.b -encoding Z,a.b.c -encoding > > > >> X,a.b.c.d.IAmSpecial > > > >> IAMSpecial.java will get encoding X, > > > >> everything else under a.b.c will get encoding Z, > > > >> everything else under a.b will get encoding Y > > > >> and the rest will get encoding X. > > > >> Same approach can be applied to -source. > > > >> > > > >> > There's no > > > >> > way I or anyone else is going to edit a build script (be it just > > > javac, > > > >> > a > > > >> > home-rolled thing, ant, rake, make, maven, ivy, etcetera) to > > carefully > > > >> > enumerate every file's source compatibility level. > > > >> Sure, thats what argfiles are for: store the settings in a file and > > > >> use javac @argfile. > > > >> > > > >> And doing it as proposed above on a package level would make it > more > > > >> manageable. > > > >> Remember in your proposal the only option is to specify it on a > file > > > >> level (this is fixable i guess). > > > >> > > > >> > Changing the command line > > > >> > options also incurs the neccessary wrath of all those build tool > > > >> > developers > > > >> > as they'd have to update their software to handle the new option > > > (adding > > > >> > an > > > >> > option is a change too!) > > > >> Not more than changing the language itself. > > > >> > > > >> > > > > >> > Could you also elaborate on why you don't like it? For example, > how > > > can > > > >> > the > > > >> > benefits of having (more) portable source files, easier > > migration, and > > > a > > > >> > much cleaner solution to e.g. the assert-in-javac1.4 be achieved > > with > > > >> > e.g. > > > >> > command line options, or do you not consider any of those > > worthwhile? > > > >> I fully support the goal. I even see it as is a bit too narrow (see > > > >> below). But I do not see a need to change the language to achieve > that > > > >> goal. > > > >> > > > >> On a conceptual level I see these options as a metadata of the > source > > > >> files and I don't like the idea of coupling it with the file. > > > >> One can avoid all this complexity of extra parsing by specifying > the > > > >> encoding in an external file. This external file does not have > > > >> itself to be in that encoding. In fact it can be restricted to be > > > >> always in ASCII. > > > >> > > > >> I think the addition of an optional path and allowing multiple use > of > > > >> the same option approach is much more scalable: it could be > extended > > > >> to the other existing options (like -deprecation, -Xlint, etc.) and > to > > > >> the options that might appear in the future. > > > >> > > > >> I wish I could concentrate on deprecations in a certain package and > > > >> ignore them everywhere else for now: > > > >> javac -deprecation,really.rusty.one ... > > > >> Finished with (or gave up on ;) that one and want to switch to the > > next > > > >> one: > > > >> javac -deprecation,another.old.one > > > >> > > > >> Igor Karp > > > >> > > > >> > > > > >> > As an aside, how do people approach project coin submissions? I > tend > > > to > > > >> > look > > > >> > at a proposal's value, which is its benefit divided by the > > > disadvantages > > > >> > (end-programmer complexity to learn, amount of changes needed to > > javac > > > >> > and/or JVM, and restrictions on potential future expansions). One > of > > > the > > > >> > reasons I'm writing this up with Roel is because the > disadvantages > > > >> > seemed to > > > >> > be almost nonexistent on the outset (the encoding stuff made it > more > > > >> > complicated, but at least the complication is entirely hidden > from > > > java > > > >> > developer's eyes, so it value proposal is still aces in my book). > If > > > >> > there's > > > >> > a goal to keep the total language changes, no matter how simple > they > > > >> > are, > > > >> > down to a small set, then benefit regardless of disadvantages is > the > > > >> > better > > > >> > yardstick. > > > >> > > > > >> > --Reinier Zwitserloot > > > >> > > > > >> > > > > >> > > > > >> > On Mar 7, 2009, at 08:15, Igor Karp wrote: > > > >> > > > > >> >> On Fri, Mar 6, 2009 at 10:03 PM, Reinier Zwitserloot > > > >> >> wrote: > > > >> >>> > > > >> >>> We have written up a proposal for adding a 'source' and > 'encoding' > > > >> >>> keyword (alternatives to the -source and -encoding keywords on > the > > > >> >>> command line; they work pretty much just as you expect). The > > > keywords > > > >> >>> are context sensitive and must both appear before anything else > > > other > > > >> >>> than comments to be parsed. In case the benefit isn't obvious: > > It is > > > a > > > >> >>> great help when you are trying to port a big project to a new > > source > > > >> >>> language compatibility. Leaving half your sourcebase in v1.6 > > and the > > > >> >>> other half in v1.7 is pretty much impossible today, it's > all-or- > > > >> >>> nothing. It should also be a much nicer solution to the 'assert > in > > > >> >>> v1.4' dilemma, which I guess is going to happen to v1.7 as > well, > > > given > > > >> >>> that 'module' is most likely going to become a keyword. > > Finally, it > > > >> >>> makes java files a lot more portable; you no longer run into > your > > > >> >>> strings looking weird when you move your Windows-1252 codefile > > java > > > >> >>> source to a mac, for example. > > > >> >>> > > > >> >>> Before we finish it though, some open questions we'd like some > > > >> >>> feedback on: > > > >> >>> > > > >> >>> A) Technically, starting a file with "source 1.4" is obviously > > > silly; > > > >> >>> javac v1.4 doesn't know about the source keyword and would > > thus fail > > > >> >>> immediately. However, practically, its still useful. Example: > if > > > >> >>> you've mostly converted a GWT project to GWT 1.5 (which uses > java > > > 1.5 > > > >> >>> syntax), but have a few files remaining on GWT v1.4 (which > > uses java > > > >> >>> 1.4 syntax), then tossing a "source 1.4;" in those older files > > > >> >>> eliminates all the generics warnings and serves as a reminder > that > > > you > > > >> >>> should still convert those at some point. However, it isn't > > > -actually- > > > >> >>> compatible with a real javac 1.4. We're leaning to making > "source > > > >> >>> 1.6;" (and below) legal even when using a javac v1.7 or > > above, but > > > >> >>> perhaps that's a bridge too far? We could go with magic > > comments but > > > >> >>> that seems like a very bad solution. > > > >> >>> > > > >> >>> also: > > > >> >>> > > > >> >>> Encoding is rather a hairy issue; javac will need to read the > file > > > to > > > >> >>> find the encoding, but to read a file, it needs to know about > > > >> >>> encoding! Fortunately, *every single* popular encoding on > > > wikipedia's > > > >> >>> popular encoding list at: > > > >> >>> > > > >> >>> > > > >> >>> > > > >> >>> > > > > > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > > >> >>> > > > >> >>> will encode "encoding own-name-in-that-encoding;" the same as > > ASCII > > > >> >>> would, except for KOI-7 and UTF-7, (both 7 bit encodings that I > > > doubt > > > >> >>> anyone ever uses to program java). > > > >> >>> > > > >> >>> Therefore, the proposal includes the following strategy to > > find the > > > >> >>> encoding statement in a java source file without knowing the > > > encoding > > > >> >>> beforehand: > > > >> >>> > > > >> >>> An entirely separate parser (the encoding parser) is run > > repeatedly > > > >> >>> until the right encoding is found. First it'll decode the > > input with > > > >> >>> ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, > as > > > per > > > >> >>> the java standard), then as UTF-32 (BE if no BOM), then the > > current > > > >> >>> behaviour (-encoding parameter's value if any, otherwise > platform > > > >> >>> default encoding). This separate parser works as follows: > > > >> >>> > > > >> >>> 1. Ignore any comments and whitespace. > > > >> >>> 3. Ignore the pattern (regexp-like-syntax, ): > > source\s+[^\s]+\s*; - > > > if > > > >> >>> that pattern matches partially but is not correctly completed, > > that > > > >> >>> parser run exits without finding an encoding, immediately. > > > >> >>> 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern > > > matches > > > >> >>> partially but is not correctly completed, that parser run > exists > > > >> >>> without finding an encoding, immediately. If it does complete, > the > > > >> >>> parser also exists immediately and returns the captured value. > > > >> >>> 5. If it finds anything else, stop immediately, returning no > > > encoding > > > >> >>> found. > > > >> >>> > > > >> >>> Once it's found something, the 'real' java parser will run > > using the > > > >> >>> found encoding (this overrides any -encoding on the command > line). > > > >> >>> Note that the encoding parser stops quickly; For example, if it > > > finds > > > >> >>> a stray \0 or e.g. the letter 'i' (perhaps the first letter of > an > > > >> >>> import statement), it'll stop immediately. > > > >> >>> > > > >> >>> If an encoding is encountered that was not found during the > > standard > > > >> >>> decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked > > only due > > > to > > > >> >>> a platform default/command line encoding param, (e.g. a > platform > > > that > > > >> >>> defaults to UTF-16LE without a byte order mark) a warning > > explaining > > > >> >>> that the encoding statement isn't doing anything is generated. > Of > > > >> >>> course, if the encoding doesn't match itself, you get an error > > > >> >>> (putting "encoding UTF-16;" into a UTF-8 encoded file for > > example). > > > If > > > >> >>> there is no encoding statement, the 'real' java parser does > > what it > > > >> >>> does now: Use the -encoding parameter of javac, and if that > wasn't > > > >> >>> present, the platform default. > > > >> >>> > > > >> >>> However, there is 1 major and 1 minor problem with this > approach: > > > >> >>> > > > >> >>> B) This means javac will need to read every source file many > times > > > to > > > >> >>> compile it. > > > >> >>> > > > >> >>> Worst case (no encoding keyword): 5 times. > > > >> >>> Standard case if an encoding keyword: 2 times (3 times if > UTF-16). > > > >> >>> > > > >> >>> Fortunately all runs should stop quickly, due to the encoding > > > parser's > > > >> >>> penchant to quit very early. Javacs out there will either > > stuff the > > > >> >>> entire source file into memory, or if not, disk cache should > take > > > care > > > >> >>> of it, but we can't prove beyond a doubt that this repeated > > parsing > > > >> >>> will have no significant impact on compile time. Is this a > > > >> >>> showstopper? Is the need to include a new (but small) parser > into > > > >> >>> javac a showstopper? > > > >> >>> > > > >> >>> C) Certain character sets, such as ISO-2022, can make the > encoding > > > >> >>> statement unreadable with the standard strategy if a comment > > > including > > > >> >>> non-ASCII characters precedes the encoding statement. These > > > situations > > > >> >>> are very rare (in fact, I haven't managed to find an example), > > so is > > > >> >>> it okay to just ignore this issue? If you add the encoding > > statement > > > >> >>> after a bunch of comments that make it invisible, and then > compile > > > it > > > >> >>> with the right -encoding parameter, you WILL get a warning > > that the > > > >> >>> encoding statement isn't going to help a javac on another > > platform / > > > >> >>> without that encoding parameter to figure it out, so you just > get > > > the > > > >> >>> current status quo: your source file won't compile without an > > > explicit > > > >> >>> -encoding parameter (or if that happens to be the platform > > default). > > > >> >>> Should this be mentioned in the proposal? Should the compiler > (and > > > the > > > >> >>> proposal) put effort into generating a useful warning message, > > such > > > as > > > >> >>> figuring out if it WOULD parse correctly if the encoding > statement > > > is > > > >> >>> at the very top of the source file, vs. suggesting to recode in > > > UTF-8? > > > >> >>> > > > >> >>> and a final dilemma: > > > >> >>> > > > >> >>> D) Should we separate the proposals for source and encoding > > > keywords? > > > >> >>> The source keyword is more useful and a lot simpler overall > > than the > > > >> >>> encoding keyword, but they do sort of go together. > > > >> >> > > > >> >> Separate. Another reason is: the argument of applying different > > > >> >> settings > > > >> >> to > > > >> >> different parts of the project is much less valid with encoding > > than > > > >> >> with source. > > > >> >> > > > >> >>> > > > >> >>> --Reinier Zwitserloot and Roel Spilker > > > >> >>> > > > >> >>> > > > >> >> Overall: I would prefer command line options enhanced to handle > the > > > >> >> situation > > > >> >> rather than language change. > > > >> >> > > > >> >> Igor Karp > > > >> > > > > >> > > > > >> > > > > > > > > > > > > > > > > > From Joe.Darcy at Sun.COM Sat Mar 7 17:38:34 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 07 Mar 2009 17:38:34 -0800 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: Message-ID: <49B3219A.2080008@sun.com> Reinier Zwitserloot wrote: > We have written up a proposal for adding a 'source' and 'encoding' > keyword (alternatives to the -source and -encoding keywords on the > command line; they work pretty much just as you expect). The keywords > are context sensitive and must both appear before anything else other > than comments to be parsed. In case the benefit isn't obvious: It is a > great help when you are trying to port a big project to a new source > language compatibility. Leaving half your sourcebase in v1.6 and the > other half in v1.7 is pretty much impossible today, it's all-or- > nothing. It should also be a much nicer solution to the 'assert in > v1.4' dilemma, which I guess is going to happen to v1.7 as well, given > that 'module' is most likely going to become a keyword. Your assumption about 1.7 is incorrect. As explained here http://openjdk.java.net/projects/jigsaw/doc/language.html "module" will be a restricted keyword, that is, it is only a keyword in a module-info file and can otherwise still appear as the name of a method or field, etc. We no not plan to add anymore keywords that would invalidate existing code. > Finally, it > makes java files a lot more portable; you no longer run into your > strings looking weird when you move your Windows-1252 codefile java > source to a mac, for example. > For good build hygiene, one should always specify -source and -encoding. > Before we finish it though, some open questions we'd like some > feedback on: > > A) Technically, starting a file with "source 1.4" is obviously silly; > javac v1.4 doesn't know about the source keyword and would thus fail > immediately. However, practically, its still useful. Example: if > you've mostly converted a GWT project to GWT 1.5 (which uses java 1.5 > syntax), but have a few files remaining on GWT v1.4 (which uses java > 1.4 syntax), then tossing a "source 1.4;" in those older files > eliminates all the generics warnings and serves as a reminder that you > should still convert those at some point. However, it isn't -actually- > compatible with a real javac 1.4. We're leaning to making "source > 1.6;" (and below) legal even when using a javac v1.7 or above, but > perhaps that's a bridge too far? We could go with magic comments but > that seems like a very bad solution. > > also: > > Encoding is rather a hairy issue; javac will need to read the file to > find the encoding, but to read a file, it needs to know about > encoding! Fortunately, *every single* popular encoding on wikipedia's > popular encoding list at: > > http://en.wikipedia.org/wiki/Character_encoding#Popular_character_encodings > > will encode "encoding own-name-in-that-encoding;" the same as ASCII > would, except for KOI-7 and UTF-7, (both 7 bit encodings that I doubt > anyone ever uses to program java). > Yes, not all encodings have the ASCII subset in a one-byte format. Both of these pre-proposals are far to complicated and offer too little value for inclusion in Project Coin. -Joe > Therefore, the proposal includes the following strategy to find the > encoding statement in a java source file without knowing the encoding > beforehand: > > An entirely separate parser (the encoding parser) is run repeatedly > until the right encoding is found. First it'll decode the input with > ISO-8859-1. If that doesn't work, UTF-16 (assume BE if no BOM, as per > the java standard), then as UTF-32 (BE if no BOM), then the current > behaviour (-encoding parameter's value if any, otherwise platform > default encoding). This separate parser works as follows: > > 1. Ignore any comments and whitespace. > 3. Ignore the pattern (regexp-like-syntax, ): source\s+[^\s]+\s*; - if > that pattern matches partially but is not correctly completed, that > parser run exits without finding an encoding, immediately. > 4. Find the pattern: encoding\s+([^\s]+)\s*; - if that pattern matches > partially but is not correctly completed, that parser run exists > without finding an encoding, immediately. If it does complete, the > parser also exists immediately and returns the captured value. > 5. If it finds anything else, stop immediately, returning no encoding > found. > > Once it's found something, the 'real' java parser will run using the > found encoding (this overrides any -encoding on the command line). > Note that the encoding parser stops quickly; For example, if it finds > a stray \0 or e.g. the letter 'i' (perhaps the first letter of an > import statement), it'll stop immediately. > > If an encoding is encountered that was not found during the standard > decoding strategy (ISO-8859-1, UTF-16, UTF-32), but worked only due to > a platform default/command line encoding param, (e.g. a platform that > defaults to UTF-16LE without a byte order mark) a warning explaining > that the encoding statement isn't doing anything is generated. Of > course, if the encoding doesn't match itself, you get an error > (putting "encoding UTF-16;" into a UTF-8 encoded file for example). If > there is no encoding statement, the 'real' java parser does what it > does now: Use the -encoding parameter of javac, and if that wasn't > present, the platform default. > > However, there is 1 major and 1 minor problem with this approach: > > B) This means javac will need to read every source file many times to > compile it. > > Worst case (no encoding keyword): 5 times. > Standard case if an encoding keyword: 2 times (3 times if UTF-16). > > Fortunately all runs should stop quickly, due to the encoding parser's > penchant to quit very early. Javacs out there will either stuff the > entire source file into memory, or if not, disk cache should take care > of it, but we can't prove beyond a doubt that this repeated parsing > will have no significant impact on compile time. Is this a > showstopper? Is the need to include a new (but small) parser into > javac a showstopper? > > C) Certain character sets, such as ISO-2022, can make the encoding > statement unreadable with the standard strategy if a comment including > non-ASCII characters precedes the encoding statement. These situations > are very rare (in fact, I haven't managed to find an example), so is > it okay to just ignore this issue? If you add the encoding statement > after a bunch of comments that make it invisible, and then compile it > with the right -encoding parameter, you WILL get a warning that the > encoding statement isn't going to help a javac on another platform / > without that encoding parameter to figure it out, so you just get the > current status quo: your source file won't compile without an explicit > -encoding parameter (or if that happens to be the platform default). > Should this be mentioned in the proposal? Should the compiler (and the > proposal) put effort into generating a useful warning message, such as > figuring out if it WOULD parse correctly if the encoding statement is > at the very top of the source file, vs. suggesting to recode in UTF-8? > > and a final dilemma: > > D) Should we separate the proposals for source and encoding keywords? > The source keyword is more useful and a lot simpler overall than the > encoding keyword, but they do sort of go together. > > --Reinier Zwitserloot and Roel Spilker > > From jodastephen at gmail.com Sat Mar 7 10:23:37 2009 From: jodastephen at gmail.com (Stephen Colebourne) Date: Sat, 07 Mar 2009 18:23:37 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <685C7A2B-36FE-4607-BA27-8EC4646DDF70@googlemail.com> <63b4e4050903041440k61fd90bdi1e7b9e70698e9de3@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> Message-ID: <49B2BBA9.5040500@gmail.com> Jeremy Manson wrote: > The "right" fix, if we want to support this pattern, is to allow the > try resource statement to accept expressions that return Disposables, > and to retrofit the relevant lock APIs with disposables and lock > methods that return this: > > class Lock implements Disposable { > public Lock dlock() { > return this; > } > @Override public void dispose() { > unlock(); > } > } > Lock is an interface. No changes are possible. Stephen From jjb at google.com Sat Mar 7 20:15:54 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 7 Mar 2009 20:15:54 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903071112u3d961e78w5c19c075f4d5aa78@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> <15e8b9d20903071112u3d961e78w5c19c075f4d5aa78@mail.gmail.com> Message-ID: <17b2302a0903072015m20e6f455x17f00cdb4d3653e1@mail.gmail.com> Neal, > > > > If people think it's worth it, the > > stack trace printing code could be modified to include suppressed > > exceptions. In many cases, that would cause suppressed exceptions to be > > logged automatically. But I have some misgivings about this approach: I > > suspect there are programs that parse stack traces. While I frown on > this > > behavior, and the spec does not guarantee that it works, I'd hate to be > > responsible for breaking these programs. > > I agree this is a poor 'solution' to the problem. No, we don't agree on this one: I don't believe there is a problem. Josh From jjb at google.com Sat Mar 7 20:45:14 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 7 Mar 2009 20:45:14 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903071145k44ef6a51r87dfbedbbd4065e3@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <1631da7d0903070952mfa076c7y71117b455c7b8606@mail.gmail.com> <49B2B9AC.1040703@e-spirit.de> <17b2302a0903071019r68a6ae33ld551e3e842e91e72@mail.gmail.com> <15e8b9d20903071028o547d73b7rb409467ca65d7715@mail.gmail.com> <17b2302a0903071040y40fe7a02oe72f93f59569bb8f@mail.gmail.com> <15e8b9d20903071145k44ef6a51r87dfbedbbd4065e3@mail.gmail.com> Message-ID: <17b2302a0903072045p750710a1s486b1a008abeb432@mail.gmail.com> Neal, On Sat, Mar 7, 2009 at 11:45 AM, Neal Gafter wrote: > On Sat, Mar 7, 2009 at 10:40 AM, Joshua Bloch wrote: > > Neal, > > Sorry, I should have defined my terms. I define a "true resource" as an > > object that can only used once, and then must be disposed of, never to be > > used again. > > That's not the usual definition, (see > ), The words "true resource" don't occur in this article. And Wikipedia is far from authoritative. > This definition would appear to include classes and interfaces such as > > java.sql.Statement (close) > java.nio.channels.FileLock (release) > org.ietf.jgss.GSSCredential (dispose) > java.awt.image.VolatileImage (flush) > > I think one of these use cases is currently supported by the proposal. Nothing is currently supported: types must be retrofitted to mark them as resources. So the question is, which of these types can be retrofitted? On a quick reading, it would appear that only GSSCredential presents a problem: it's an interface (not a class) and it's disposal method is named "flush." Luckily, it's not commonly used (only 3k google hits vs. 300k for java.sql.Statement). The goal here is simply to hit the common cases. I believe the proposed feature will do that, even if we elect to implement the simple (interface-based) version. Josh From neal at gafter.com Sat Mar 7 22:09:23 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 7 Mar 2009 22:09:23 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903072015m20e6f455x17f00cdb4d3653e1@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> <15e8b9d20903071112u3d961e78w5c19c075f4d5aa78@mail.gmail.com> <17b2302a0903072015m20e6f455x17f00cdb4d3653e1@mail.gmail.com> Message-ID: <15e8b9d20903072209od390dd4iec3f862d6cbe8428@mail.gmail.com> On Sat, Mar 7, 2009 at 8:15 PM, Joshua Bloch wrote: > No, we don't agree on this one: I don't believe there is a problem. I guess we disagree on that. I believe it is not appropriate for a language construct to generate code equivalent to catch (Exception ignored) { /* discarded */ } when the exception may represent program/programmer error. From crazybob at crazybob.org Sat Mar 7 22:22:53 2009 From: crazybob at crazybob.org (Bob Lee) Date: Sat, 7 Mar 2009 22:22:53 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903072209od390dd4iec3f862d6cbe8428@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20902272143y95d742brdf47cc72c49a3919@mail.gmail.com> <17b2302a0902272229ycc7bf2dx36e03429aa629e05@mail.gmail.com> <15e8b9d20903070928p44818fi1a2b2830daa9bd76@mail.gmail.com> <17b2302a0903070948n7ddc4b1h77f3c5c8494b1eaf@mail.gmail.com> <15e8b9d20903071021gdc5d71cud0d518c0d3ea23cd@mail.gmail.com> <17b2302a0903071031s2b3468b3id5f02e05e563b5c8@mail.gmail.com> <15e8b9d20903071112u3d961e78w5c19c075f4d5aa78@mail.gmail.com> <17b2302a0903072015m20e6f455x17f00cdb4d3653e1@mail.gmail.com> <15e8b9d20903072209od390dd4iec3f862d6cbe8428@mail.gmail.com> Message-ID: On Sat, Mar 7, 2009 at 10:09 PM, Neal Gafter wrote: > I guess we disagree on that. I believe it is not appropriate for a > language construct to generate code equivalent to > > catch (Exception ignored) { /* discarded */ } > > when the exception may represent program/programmer error. > Throwable.printStackTrace() should print the suppressed stack traces. Instead of saying "caused by", it'll say "suppressed". It's better to err on the side of too much information so long as it's not repetitive. As someone who futilly tried parsing the default stack trace format a few years back, I doubt adding a "suppressed" line in there will make existing parsers any less stable. Bob From jeremy.manson at gmail.com Sat Mar 7 23:58:02 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 7 Mar 2009 23:58:02 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B2BBA9.5040500@gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <17b2302a0903041517t3b05d48aw88ae62fd24fd4c82@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> Message-ID: <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> I am aware Lock is an interface. You wouldn't actually change the Lock interface, you would change the classes. Just as they retrofit Iterable everywhere. That's why I put "class Lock" there; perhaps it would have been clearer if it said "class MyLock". Jeremy On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne wrote: > Jeremy Manson wrote: >> The "right" fix, if we want to support this pattern, is to allow the >> try resource statement to accept expressions that return Disposables, >> and to retrofit the relevant lock APIs with disposables and lock >> methods that return this: >> >> class Lock implements Disposable { >> ? public Lock dlock() { >> ? ? return this; >> ? } >> ? @Override public void dispose() { >> ? ? unlock(); >> ? } >> } >> > Lock is an interface. No changes are possible. > > Stephen > > > From peter at retep.org.uk Sun Mar 8 00:03:17 2009 From: peter at retep.org.uk (Peter Mount) Date: Sun, 8 Mar 2009 08:03:17 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> Message-ID: <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson wrote: > I am aware Lock is an interface. You wouldn't actually change the > Lock interface, you would change the classes. Just as they retrofit > Iterable everywhere. That's why I put "class Lock" there; perhaps it > would have been clearer if it said "class MyLock". What about when someone just references the lock as Lock rather than the implementing class? Javac won't be able to determine that the lock implements Disposable so in that case it will fail.. > > > Jeremy > > On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne > wrote: > > Jeremy Manson wrote: > >> The "right" fix, if we want to support this pattern, is to allow the > >> try resource statement to accept expressions that return Disposables, > >> and to retrofit the relevant lock APIs with disposables and lock > >> methods that return this: > >> > >> class Lock implements Disposable { > >> public Lock dlock() { > >> return this; > >> } > >> @Override public void dispose() { > >> unlock(); > >> } > >> } > >> > > Lock is an interface. No changes are possible. > > > > Stephen > > > > > > > > -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From reinier at zwitserloot.com Sun Mar 8 01:00:37 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 8 Mar 2009 10:00:37 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> Message-ID: <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> We're veering waaay offtopic here; the ARM proposal does not address locks. Period. Would everyone be happy if this was added in the 'major disadvantages' section? If locks are truly deemed crucial, or the consensus is that, eventhough evidently ARM-as-is can't do locks, people will try anyway and the resulting confusion must be avoided, I suggest that the ARM proposal is updated to do the right thing when an expression of type Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else proposed this before and I can't see any downside to this. It would be bad if, for every release, a bunch more types get special uniquely defined semantics in relation to the ARM expression, but that seems very unlikely. Nobody else has named a use-case that doesn't work in vanilla ARM yet seems likely to be abused, other than Lock, IIRC. --Reinier Zwitserloot On Mar 8, 2009, at 09:03, Peter Mount wrote: > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson > wrote: > >> I am aware Lock is an interface. You wouldn't actually change the >> Lock interface, you would change the classes. Just as they retrofit >> Iterable everywhere. That's why I put "class Lock" there; perhaps it >> would have been clearer if it said "class MyLock". > > > What about when someone just references the lock as Lock rather than > the > implementing class? Javac won't be able to determine that the lock > implements Disposable so in that case it will fail.. > > > > >> >> >> Jeremy >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne >> wrote: >>> Jeremy Manson wrote: >>>> The "right" fix, if we want to support this pattern, is to allow >>>> the >>>> try resource statement to accept expressions that return >>>> Disposables, >>>> and to retrofit the relevant lock APIs with disposables and lock >>>> methods that return this: >>>> >>>> class Lock implements Disposable { >>>> public Lock dlock() { >>>> return this; >>>> } >>>> @Override public void dispose() { >>>> unlock(); >>>> } >>>> } >>>> >>> Lock is an interface. No changes are possible. >>> >>> Stephen >>> >>> >>> >> >> > > > -- > Peter Mount > e: peter at retep.org.uk > w: http://retep.org > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > From peter at retep.org.uk Sun Mar 8 01:39:33 2009 From: peter at retep.org.uk (Peter Mount) Date: Sun, 8 Mar 2009 09:39:33 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> Message-ID: <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot wrote: > We're veering waaay offtopic here; the ARM proposal does not address > locks. Period. Would everyone be happy if this was added in the 'major > disadvantages' section? Yes this is becoming more offtopic but hopefully my comments have brought up two points: 1: Although Locks are a form of resource, the ARM proposal as is cannot support them 2: Someone will abuse it to support Lock's at some point with potentially disastrous consequences. > > If locks are truly deemed crucial, or the consensus is that, > eventhough evidently ARM-as-is can't do locks, people will try anyway > and the resulting confusion must be avoided, I suggest that the ARM > proposal is updated to do the right thing when an expression of type > Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else > proposed this before and I can't see any downside to this. It would be > bad if, for every release, a bunch more types get special uniquely > defined semantics in relation to the ARM expression, but that seems > very unlikely. Nobody else has named a use-case that doesn't work in > vanilla ARM yet seems likely to be abused, other than Lock, IIRC. Yes I did yesterday. The one thing I've learned from experience is that a lot of programmers are lazy when it comes to resources. Although for some resources are cleaned up occasionally by the garbage collector, most are not and unless the system is under heavy load the problem doesn't show itself until it's in the live environment. For this reason I do feel that the ARM proposal would alleviate this as long as the programmers know that the new construct exists. Now I do feel that Locks are a form of resource but one that is actively short lived. Although it seems simple to just write them manually with a try finally block you'll be surprised how easy it is for someone to miss the finally block or refactor it out without noticing. In a large system this can be costly (my gaming background coming in here). Over the last few years I've ended up wasting so much time debugging a complex system to locate a deadlock just to find that someone has forgotten to release a lock. It is this reason why I think the ARM proposal should support Lock's as a separate use-case. The main issues with Disposable and Lock that I can see are: 1: Lock is an interface and cannot extend Disposable as that would break existing code. Also implementing Disposable in the Lock implementations would not work if you use try( Lock ) as javac would not see it as being Disposable. 2: Normal resources are already open/active before the try so with Disposable the try(Disposable) would simply call Disposable.close() at the end. With Locks they are not active until lock() is called so try(Lock) would have to call Lock.lock() before the method body and then Lock.unlock() at the end. As I said in an earlier email I implement this pattern in JDK1.6 by having a set of annotations which with a processor inject the try...finally block around a method thats locked (yes I know annotation processors shouldn't do this but it's removed the problem completely). Having the ARM proposal would not just obsolete the hack but make it more flexible (as the hack only works at the method level). As for any other use-cases that don't work with the current proposal other than Lock, I can't think of any at the moment. > > --Reinier Zwitserloot > > > On Mar 8, 2009, at 09:03, Peter Mount wrote: > > > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson > > wrote: > > > >> I am aware Lock is an interface. You wouldn't actually change the > >> Lock interface, you would change the classes. Just as they retrofit > >> Iterable everywhere. That's why I put "class Lock" there; perhaps it > >> would have been clearer if it said "class MyLock". > > > > > > What about when someone just references the lock as Lock rather than > > the > > implementing class? Javac won't be able to determine that the lock > > implements Disposable so in that case it will fail.. > > > > > > > > > >> > >> > >> Jeremy > >> > >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne > >> wrote: > >>> Jeremy Manson wrote: > >>>> The "right" fix, if we want to support this pattern, is to allow > >>>> the > >>>> try resource statement to accept expressions that return > >>>> Disposables, > >>>> and to retrofit the relevant lock APIs with disposables and lock > >>>> methods that return this: > >>>> > >>>> class Lock implements Disposable { > >>>> public Lock dlock() { > >>>> return this; > >>>> } > >>>> @Override public void dispose() { > >>>> unlock(); > >>>> } > >>>> } > >>>> > >>> Lock is an interface. No changes are possible. > >>> > >>> Stephen > >>> > >>> > >>> > >> > >> > > > > > > -- > > Peter Mount > > e: peter at retep.org.uk > > w: http://retep.org > > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > > > > > -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From schulz at e-spirit.de Sun Mar 8 04:19:39 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 08 Mar 2009 12:19:39 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com><15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com><15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com><49B24624.7080708@gmail.com><1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com><49B2BBA9.5040500@gmail.com><1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com><85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com><59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> Message-ID: <49B3A9CB.2000706@e-spirit.de> Just a thought (although I contradict one of my earlier posts): If Locks seem important for being handled by ARM (and I think they are), why not allow a seperate Interface for ARM that results in the appropriate code? Maybe a reduced Lock-Interface (e.g. ManagableLock) only containing the methods lock() and unlock(). The main argument to me for treating Locks additionally to closable resources is to give a more complete resource management construct to developers that prevents the (to be expected) ugly solution as being discussed on this list. Stefan From peter at retep.org.uk Sun Mar 8 06:02:42 2009 From: peter at retep.org.uk (Peter Mount) Date: Sun, 8 Mar 2009 13:02:42 +0000 Subject: Proposal: Automatic Resource Management Message-ID: <176582169-1236517426-cardhu_decombobulator_blackberry.rim.net-1481848380-@bxe1126.bisx.produk.on.blackberry> ManagedLock sounds like a good idea as it wouldn't break existing code and could then be used for other mechanisms than concurrent Lock's. Peter ------Original Message------ From: Stefan Schulz Sender: coin-dev-bounces at openjdk.java.net To: coin-dev at openjdk.java.net ReplyTo: schulz at e-spirit.de Subject: Re: Proposal: Automatic Resource Management Sent: Mar 8, 2009 11:19 Just a thought (although I contradict one of my earlier posts): If Locks seem important for being handled by ARM (and I think they are), why not allow a seperate Interface for ARM that results in the appropriate code? Maybe a reduced Lock-Interface (e.g. ManagableLock) only containing the methods lock() and unlock(). The main argument to me for treating Locks additionally to closable resources is to give a more complete resource management construct to developers that prevents the (to be expected) ugly solution as being discussed on this list. Stefan -- Peter Mount (from my BlackBerry) e: peter at retep.org.uk w: http://retep.org m: +44 (0)7838 191423 / +44 (0)7903 155887 Instant Messaging: Contact me directly via Jabber or GoogleTalk at peter at retep.org or via MSN at retep207 at hotmail.com Alternatively via my BlackBerry at 2542ABDA or via GoogleTalk: petermount at gmail.com From peter at retep.org.uk Sun Mar 8 06:03:21 2009 From: peter at retep.org.uk (Peter Mount) Date: Sun, 8 Mar 2009 13:03:21 +0000 Subject: Proposal: Automatic Resource Management Message-ID: <176582169-1236517430-cardhu_decombobulator_blackberry.rim.net-284753882-@bxe1126.bisx.produk.on.blackberry> ManagedLock sounds like a good idea as it wouldn't break existing code and could then be used for other mechanisms than concurrent Lock's. Peter ------Original Message------ From: Stefan Schulz Sender: coin-dev-bounces at openjdk.java.net To: coin-dev at openjdk.java.net ReplyTo: schulz at e-spirit.de Subject: Re: Proposal: Automatic Resource Management Sent: Mar 8, 2009 11:19 Just a thought (although I contradict one of my earlier posts): If Locks seem important for being handled by ARM (and I think they are), why not allow a seperate Interface for ARM that results in the appropriate code? Maybe a reduced Lock-Interface (e.g. ManagableLock) only containing the methods lock() and unlock(). The main argument to me for treating Locks additionally to closable resources is to give a more complete resource management construct to developers that prevents the (to be expected) ugly solution as being discussed on this list. Stefan -- Peter Mount (from my BlackBerry) e: peter at retep.org.uk w: http://retep.org m: +44 (0)7838 191423 / +44 (0)7903 155887 Instant Messaging: Contact me directly via Jabber or GoogleTalk at peter at retep.org or via MSN at retep207 at hotmail.com Alternatively via my BlackBerry at 2542ABDA or via GoogleTalk: petermount at gmail.com From neal at gafter.com Sun Mar 8 08:14:53 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 8 Mar 2009 07:14:53 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061519v3398f00el1118a7ed4cac97e4@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> Message-ID: <15e8b9d20903080814udaf2a36l480043c6258ead36@mail.gmail.com> On Sat, Mar 7, 2009 at 11:58 PM, Jeremy Manson wrote: > I am aware Lock is an interface. ?You wouldn't actually change the > Lock interface, you would change the classes. ?Just as they retrofit > Iterable everywhere. Iterable was retrofitted onto the collection interfaces as well as the classes. That's necessary to allow programmers to continue to program against interfaces rather than concrete classes. A proposal that retrofits behavior on classes but not the related interfaces guides programmers away from the preferred idiom of programming against an interface. From schulz at e-spirit.de Sun Mar 8 10:17:04 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 08 Mar 2009 18:17:04 +0100 Subject: PROPOSAL: Multiline strings In-Reply-To: References: Message-ID: <49B3FD90.6040805@e-spirit.de> I quite liked the idea of handling newlines by adding methods to String, to overcome magic conversions. When reading back about indentation etc., I wonder, why not to apply a similar technique to get rid of indent-related white spaces. Another question on multi-line Strings I have: does it make sense to allow a multi-line String only having one line? If not, why not using the sequence double-quote plus newline as marker for multi-line Strings? But maybe I overlook the significance in using a seperate marker here or problems that might occur during compilation. According to the above thoughts, the following would assign a multi-line String: String myString = " SELECT name FROM persons WHERE age > 21"; And one could invoke some additional methods on it, e.g.: myString.removeIndents(); // first line defines indent myString.removeWhitespaces(); // HTML style space removal I don't think that wrong indentation inside a String should lead to a compiler error, that's why methods like above would suffice IMO. All the compiler would have to do is to automatically add (platform specific) line breaks. Stefan From jeremy.manson at gmail.com Sun Mar 8 10:43:16 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 8 Mar 2009 09:43:16 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B3A9CB.2000706@e-spirit.de> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> <49B3A9CB.2000706@e-spirit.de> Message-ID: <1631da7d0903081043n4560fecw9df9eb98f4aae1e8@mail.gmail.com> I was going to write this, but now I won't. People will just have to write to this interface. It is worth pointing out that this topic came up (repeatedly) when Josh was writing this proposal, which is why he did allow for the possibility that the try guard be changed to accept expressions. Jeremy On Sun, Mar 8, 2009 at 3:19 AM, Stefan Schulz wrote: > Just a thought (although I contradict one of my earlier posts): If Locks > seem important for being handled by ARM (and I think they are), why not > allow a seperate Interface for ARM that results in the appropriate code? > Maybe a reduced Lock-Interface (e.g. ManagableLock) only containing the > methods lock() and unlock(). > > The main argument to me for treating Locks additionally to closable > resources is to give a more complete resource management construct to > developers that prevents the (to be expected) ugly solution as being > discussed on this list. > > Stefan > > From jjb at google.com Sun Mar 8 11:20:28 2009 From: jjb at google.com (Joshua Bloch) Date: Sun, 8 Mar 2009 11:20:28 -0700 Subject: Pre-Proposal: Linguistic support for locks Message-ID: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> Folks, I agree with Reinier on both counts; the proposal was specifically designed not to address locks. If people really want it to work for locks, I like the idea of adding a new statement form: try () { } that desugars to: Lock $lock = ; lock.lock(); try { } finally { lock.unlock(); } The new statement form looks exactly like a synchronized block, except that the keyword synchronized is replaced by try; the desugaring comes straight from the java.util.concurrent.locks.Lock page. The compiler would generate a warning if you used an ordinary synchronized block on an expression that is assignment compatible with type Lock (because it's almost certainly a bug). I don't think it's worth allowing multiple locks in a single statement. This statement form is both simpler and less useful than the automatic resource management statement. A quick Google code search shows that java.util.concurrent.locks.Lock usage is two orders of magnitude less common that Java monitor lock usage. And I have no indication that people get it wrong most of the time (as I do for "true resources"). Because I see this functionality as largely orthogonal to that offered by the automatic resource management statement, I think it belongs in a separate proposal. If Joe Darcy (who leads the project) thinks it's a good idea, I'm willing to write that proposal. Josh P.S. Two minor design alternatives present themselves: 1. Use the protected keyword in place of try. 2. If we do decide to use the try keyword, allow catch and finally for consistency (even though they have nothing to do with locking). On Sun, Mar 8, 2009 at 1:00 AM, Reinier Zwitserloot wrote: > We're veering waaay offtopic here; the ARM proposal does not address > locks. Period. Would everyone be happy if this was added in the 'major > disadvantages' section? > > If locks are truly deemed crucial, or the consensus is that, > eventhough evidently ARM-as-is can't do locks, people will try anyway > and the resulting confusion must be avoided, I suggest that the ARM > proposal is updated to do the right thing when an expression of type > Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else > proposed this before and I can't see any downside to this. It would be > bad if, for every release, a bunch more types get special uniquely > defined semantics in relation to the ARM expression, but that seems > very unlikely. Nobody else has named a use-case that doesn't work in > vanilla ARM yet seems likely to be abused, other than Lock, IIRC. > > --Reinier Zwitserloot > > From jeremy.manson at gmail.com Sun Mar 8 13:09:56 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 8 Mar 2009 12:09:56 -0800 Subject: Pre-Proposal: Linguistic support for locks In-Reply-To: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> References: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> Message-ID: <1631da7d0903081309i3c614d7es23ab488eb0fe9e41@mail.gmail.com> I'm not sure about this. I believe that locks are being used as a discussion proxy for any object that lives longer than the try scope, but needs to be opened and closed. For example (all taken from a random sampling of real code), you might have a logger that logs messages at the beginning and ending of the block scope. You might want to swap out your existing logger so that it has different logging properties during the block scope. You might have a reference counter that is bumped and then reset. You might have a method that takes a Disposable resource as a parameter, but needs to close the resource at the end. You might have a cache with a pinning strategy, and want to pin and unpin the item in the cache during the block scope. You can do these things with try / finally, but I think that underlying this discussion is the principle that no one really likes using try / finally for this pattern. It's a construct that sadly lends itself to cut-and-paste code -- you always have to put the finally block in and call the dispose() method (or equivalent). Jeremy On Sun, Mar 8, 2009 at 10:20 AM, Joshua Bloch wrote: > Folks, > > I agree with Reinier on both counts; the proposal was specifically designed not > to address locks. ?If people really want it to work for locks, I like the > idea of adding a new statement form: > ? ?try () { > ? ? ? ? > ? ?} > > that desugars to: > > Lock $lock = ; > > ? ? lock.lock(); > ? ? try { > ? ? ? ? > ? ? } finally { > ? ? ? ? lock.unlock(); > ? ? } > > The new statement form looks exactly like a synchronized block, except that > the keyword synchronized is replaced by try; the desugaring comes straight > from the java.util.concurrent.locks.Lock page. The compiler would generate a > warning if you used an ordinary synchronized block ?on an expression that is > assignment compatible with type Lock (because it's almost certainly a bug). > I don't think it's worth allowing multiple locks in a single statement. > > This statement form is both simpler and less useful than the automatic > resource management statement. ?A quick Google code search shows that > java.util.concurrent.locks.Lock usage is two orders of magnitude less common > that Java monitor lock usage. And I have no indication that people get it > wrong most of the time (as I do for "true resources"). Because I see this > functionality as largely orthogonal to that offered by the automatic > resource management statement, I think it belongs in a separate proposal. > ?If Joe Darcy (who leads the project) thinks it's a good idea, I'm willing > to write that proposal. > > ? ? ? ? ? ? ? ? ?Josh > > P.S. ?Two minor design alternatives present themselves: > > ? 1. Use the protected keyword in place of try. > ? 2. If we do decide to use the try keyword, allow catch and finally for > ? consistency (even though they have nothing to do with locking). > > On Sun, Mar 8, 2009 at 1:00 AM, Reinier Zwitserloot > wrote: > >> We're veering waaay offtopic here; the ARM proposal does not address >> locks. Period. Would everyone be happy if this was added in the 'major >> disadvantages' section? >> >> If locks are truly deemed crucial, or the consensus is that, >> eventhough evidently ARM-as-is can't do locks, people will try anyway >> and the resulting confusion must be avoided, I suggest that the ARM >> proposal is updated to do the right thing when an expression of type >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else >> proposed this before and I can't see any downside to this. It would be >> bad if, for every release, a bunch more types get special uniquely >> defined semantics in relation to the ARM expression, but that seems >> very unlikely. Nobody else has named a use-case that doesn't work in >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. >> >> ?--Reinier Zwitserloot >> >> > > From crazybob at crazybob.org Sun Mar 8 15:29:45 2009 From: crazybob at crazybob.org (Bob Lee) Date: Sun, 8 Mar 2009 15:29:45 -0700 Subject: PROPOSAL: Simplified Varargs Method Invocation (Round II) Message-ID: Simplified Varargs Method Invocation AUTHOR: Bob Lee OVERVIEW FEATURE SUMMARY: When a programmer tries to invoke a varargs (variable arity) method with a non-reifiable varargs type, the compiler currently generates an "unsafe operation" warning. This proposal moves the warning from the call site to the method declaration. MAJOR ADVANTAGE: Safely and significantly reduces the total number of warnings reported to and suppressed by programmers. Reduces programmer confusion. Enables API designers to use varargs with non-reifiable types. MAJOR BENEFITS: - Plugs a leaky abstraction. Creating an array when you call a varargs method is an implementation detail that we needn't expose to users. - Most programmers are surprised to find out they can only clear this warning by suppressing it. They expect two language features introduced in the same version to work well together. Programmers will no longer waste time looking for alternatives that don't exist. - Google Code Search finds almost 90k callers of Arrays.asList() ( http://tinyurl.com/dept4d). We can safely suppress the warning once and for all on asList()'s declaration instead of unnecessarily warning every caller that uses a non-reifiable type. MAJOR DISADVANTAGE: The compiler will generate a warning for a method declaration whether or not someone actually calls the method with a non-reifiable type. Allows loss of type safety if the varargs method suppresses the warning and uses the varargs array unsafely. Introduces a small risk of not reporting warnings if you compile against code compiled with Java 7 but run against code compiled with an earlier version. ALTERNATIVES: a) Don't mix varargs with generics. Use the more verbose and less straightforward but warning-free builder pattern. Most API designers choose this route. b) Improve the warning message. Current message: "uses unchecked or unsafe operations" c) Reify generics. d) Introduce a second varargs syntax (perhaps using "...." instead of "...") that uses List instead of T[]. e) Defile the type system. f) List literals: [a, b, c] instead of Arrays.asList(a, b, c) Note: This proposal doesn't preclude any of these other approaches. EXAMPLES SIMPLE EXAMPLE: Before this change: static List asList(T... elements) { ... } static List> stringFactories() { Callable a, b, c; ... // Warning: "uses unchecked or unsafe operations" return asList(a, b, c); } After this change: // Warning: "enables unsafe generic array creation" static List asList(T... elements) { ... } static List> stringFactories() { Callable a, b, c; ... return asList(a, b, c); } If asList() prohibits storing elements that aren't of type T in the elements array, we can safely suppress the warning: @SuppressWarnings("generic-varargs") // Ensures only values of type T can be stored in elements. static List asList(T... elements) { ... } OVERRIDE VARARGS WITH ARRAY: Before this change: interface Sink { void add(T... a); } interface BrokenSink extends Sink { /** Overrides Sink.add(T...). */ void add(T[] a); // no varargs } This code compiles and runs: BrokenSink s = ...; s.add("a", "b", "c"); // varargs A BrokenSink implementation could do something unsafe to the T[], so after this change, we generate a warning: interface BrokenSink extends Sink { // Warning: "Overriddes non-reifiable varargs type with array" void add(T[] a); } To clear the warning, the programmer should use varargs instead of an array: interface BrokenSink extends Sink { void add(T... a); } VARARGS TYPE ERASURE NARROWED BY OVERRIDE: The following method adds a non-null element to a Sink. Before this proposal, the call to Sink.add() generates a warning: static void addUnlessNull(Sink sink, T t) { if (t != null) // Warning: "uses unchecked or unsafe operations" sink.add(t); } Type T is unknown, so the method creates a single-element Object[] containing t and passes it to Sink.add(). After erasure, this String-based implementation of Sink produces a more narrow erased varargs type, specifically String[] instead of the Object[] accepted by Sink.add(): class StringSink implements Sink { public void add(String... a) { ... } } If you run the following code, the bridge method StringSink.add(Object[]) will throw a ClassCastException when it tries to cast the Object[] created in addUnlessNull() to the String[] required by StringSink.add(String[]): Sink ss = new StringSink(); addUnlessNull(ss, "Bob"); // ClassCastException! After this change, the compiler warning moves to the vargs method declaration that results in a more narrow erased array type: static void addUnlessNull(Sink sink, T t) { if (t != null) sink.add(t); // no warning } class StringSink implements Sink { // Warning: "override generates a more specific varargs type erasure" public void add(String... a) {} } At this point, the API designer would likely choose a different design without an overridable varargs method. For example: interface Sink { void add(T t); // no varargs } static void addNonNull(Sink sink, T... a) { for (T t : a) if (t != null) sink.add(t); } DETAILS SPECIFICATION: - A varargs type is reifiable if its component type is reifiable (see JLS 4.7). - When compiling code that calls a varargs method with a non-reifiable varargs type, if the target method was compiled with Java 7 or later, the compiler needn't generate a warning for the caller. (Note: This won't help if you then run against code compiled with an earlier version, but the risk is very low.) - When compiling a varargs method that could accept a non-reifiable varargs type, the compiler should generate a warning on the varargs method declaration. - If a non-varargs method overrides a varargs method with a non-reifiable varargs type, generate a warning. The warning a) makes it clear that the method can still be used like a varargs method, and b) warns the implementor to prevent unsafe operations on the array. - If a varargs method with a non-reifiable varargs type overrides another varargs method and the varargs parameter erases to a more-specific array type than that of the overridden method, generate a warning. If a client invokes the sub type implementation through the super type's interface, the client may pass in a super type of the array type expected by the sub type's method which will result in a ClassCastException at run time. - For a varargs argument with a component type T, the programmer can safely suppress the warning using @SuppressWarnings("generic-varargs") so long as the varargs method ensures that only elements of type T can be stored in the varargs array. COMPILATION: Tools should no longer generate a warning for varargs method callers. Instead, they should generate a warning on certain varargs method declarations. TESTING: Compile test programs and ensure that the compiler generates the expected warnings. LIBRARY SUPPORT: Suppress warnings on the following varargs methods in the JDK: - Arrays.asList(T... a) - Collections.addAll(Collection c, T... elements) - EnumSet.of(E first, E... rest) REFLECTIVE APIS: n/a OTHER CHANGES: n/a MIGRATION: Existing callers may be able to remove @SuppressWarnings("unchecked") from their code. Existing libraries should add @SuppressWarnings("generic-varargs") to methods with signatures containing non-reifiable varargs types. COMPATIBILITY BREAKING CHANGES: None EXISTING PROGRAMS: If you recompile an existing program with "-target 7", the compiler will generate warnings for method declarations containing non-reifiable varargs types. REFERENCES Bug #5048776: "promote varargs/non-varargs overrider diagnostics to errors" http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5048776 Bug #6227971: "generic inferrence bug in varargs" http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6227971 JLS Section 15.12.4.2 "Evaluate Arguments" ( http://java.sun.com/docs/books/jls/third_edition/html/expressions.html) "If the method being invoked is a variable arity method (?8.4.1) m, it necessarily has n>0 formal parameters. The final formal parameter of m necessarily has type T[] for some T, and m is necessarily being invoked with k0 actual argument expressions. If m is being invoked with kn actual argument expressions, or, if m is being invoked with k=n actual argument expressions and the type of the kth argument expression is not assignment compatible with T[], then the argument list (e1, ... , en-1, en, ...ek) is evaluated as if it were written as (e1, ..., en-1, new T[]{en, ..., ek}). The argument expressions (possibly rewritten as described above) are now evaluated to yield argument values. Each argument value corresponds to exactly one of the method's n formal parameters." Angelika Langer's Java Generics FAQ, "Why does the compiler sometimes issue an unchecked warning when I invoke a 'varargs' method?" ( http://tinyurl.com/8w2dk) Josh Bloch's "Effective Java" 2nd Edition, page 120 ( http://tinyurl.com/chtgbd) Alex Miller's blog, "Generics puzzler - array construction" ( http://tech.puredanger.com/2007/02/27/generics-array-construction/) "Java Generic and Collections", page 95 (http://tinyurl.com/c53pnu) From jesse at swank.ca Sun Mar 8 16:56:45 2009 From: jesse at swank.ca (Jesse Wilson) Date: Sun, 8 Mar 2009 16:56:45 -0700 Subject: Pre-Proposal: Linguistic support for locks In-Reply-To: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> References: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> Message-ID: On Sun, Mar 8, 2009 at 11:20 AM, Joshua Bloch wrote: > try () { > > } try is definitely the wrong keyword here. Mostly because there's already a method Lock.tryLock() that is not at all related to this sweet sugar. http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Lock.html#tryLock() 1. Use the protected keyword in place of try. > This is fantastic. I especially like that proper Locks would become just as easy-to-use as the built-in monitor on Object. From brucechapman at paradise.net.nz Mon Mar 9 02:42:33 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Mon, 09 Mar 2009 22:42:33 +1300 (NZDT) Subject: PROPOSAL: Extend Scope of Imports to Include Package Annotations Message-ID: <1236591753.49b4e489344d7@www.paradise.net.nz> html version at http://docs.google.com/Doc?id=dcvp3mkv_3fc5hqngp Extend Scope of Imports to Include Package Annotations AUTHOR(S): Bruce Chapman OVERVIEW FEATURE SUMMARY: JLS3 says Import statements do not apply to package statements and therefore by implication they do not apply to annotations on package statements. However JDK6's javac does use import statements to resolve types in package annotations, for which a Bug has been accepted. This proposal is to change the language specification to be consistent with the compiler in order to yield a more pragmatic solution than fixing the bug in the compiler. MAJOR ADVANTAGE: Annotations on packages will no longer need to fully qualify type names for annotation types, and for any class literals used as annotation values. MAJOR DISADVANTAGE: With millions of developers someone somewhere might find this counterproductive. I cannot imagine how. ALTERNATIVES: The alternative to changing the language spec is to fix the bug, which may well be a breaking change for anyone who has inadvertently or knowingly taken advantage of the bug. EXAMPLES SIMPLE EXAMPLE: @Generated("something") package a.b; import java.lang.annotations.Generated; is currently illegal and must be written as @java.lang.annotations.Generated("something") package a.b; ADVANCED EXAMPLE: Currently this is illegal @Deprecated package my.package; because the implicit import of java.lang.Deprecated is out of scope of the package statement's annotation. This change would bring all imports into scope and make the example legal (regardless of any arguments for or against annotating a package as deprecated - it's just an example) DETAILS SPECIFICATION: JLS Section 7.5 needs additions (in bold) The scope of a type imported by a single-type-import declaration (?7.5.1) or a type-import-on-demand declaration (?7.5.2) is all the class and interface type declarations (?7.6) in the compilation unit in which the import declaration appears, as well as any annotations on the compilation unit's package statement if present. and The scope of the entities(s) it introduces specifically does not include the package statement's PackageName, other import declarations in the current compilation unit, or other compilation units in the same package. COMPILATION: JDK 6 already implements this feature (unless bug 6470991 has been fixed). Implementation is just a JLS change. If the bug has been fixed, implementation involves reversing the changes that fixed the bug. TESTING: Check that annotations are resolved using import statements. Check both annotation types and class literals used in annotation element values. Check both implicit imports from java.lang as well as single-type-import and type-import-on-demand imports. Check that an import correctly shadows a type with the same simple name in the same package. LIBRARY SUPPORT: No library support required. REFLECTIVE APIS: No change OTHER CHANGES: none MIGRATION: Tools can apply their existing import statement management logic to annotations on package statements. COMPATIBILITY BREAKING CHANGES: It is possible to contrive a breaking change where a single-type-import declaration d in a compilation unit c of package p that imports a type named n shadows the declaration of a top level annotation type named n declared in another compilation unit of p and c's package declaration has an annotation using the type n. Prior to this change n should mean p.n and after this change will refer to the type in d. However the the bug means that it will already be refering to the type in d. Due to the bug this theoretical situation can be discounted as no worse than the converse situation caused by fixing the bug. EXISTING PROGRAMS: This is a compile time name resolution issue and will not affect exisitng source or class files except as noted under breaking changes. REFERENCES EXISTING BUGS: Bug 6470991 This documents how the compiler differs from the JLS, and behaves according to this proposal. URL FOR PROTOTYPE (optional): Due to the bug, the existing JDK can be used as a prototype. http://java.sun.com/javase/downloads From reinier at zwitserloot.com Mon Mar 9 03:05:37 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 9 Mar 2009 11:05:37 +0100 Subject: Pre-Proposal: Linguistic support for locks In-Reply-To: References: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> Message-ID: <0AE1CCC1-F23D-4FF4-9097-5F013DCBAE89@zwitserloot.com> Ditto - try is the wrong keyword for this one. protected works great. Also gets rid of the 'you can add catch / finally blocks at the end for consistency' device, which really doesn't make too much sense for locks. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 9, 2009, at 00:56, Jesse Wilson wrote: > On Sun, Mar 8, 2009 at 11:20 AM, Joshua Bloch wrote: > >> try () { >> >> } > > > try is definitely the wrong keyword here. Mostly because there's > already a > method Lock.tryLock() that is not at all related to this sweet sugar. > http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Lock.html#tryLock() > > 1. Use the protected keyword in place of try. >> > > This is fantastic. I especially like that proper Locks would become > just as > easy-to-use as the built-in monitor on Object. > From peter at retep.org.uk Mon Mar 9 03:15:33 2009 From: peter at retep.org.uk (Peter Mount) Date: Mon, 9 Mar 2009 10:15:33 +0000 Subject: Pre-Proposal: Linguistic support for locks In-Reply-To: <0AE1CCC1-F23D-4FF4-9097-5F013DCBAE89@zwitserloot.com> References: <17b2302a0903081120m4fa83ebfn47a82aed9694c81d@mail.gmail.com> <0AE1CCC1-F23D-4FF4-9097-5F013DCBAE89@zwitserloot.com> Message-ID: <85bf933e0903090315w7c0a314i77f0bd1ce64fbc65@mail.gmail.com> Agreed. try's been mentioned in these threads mainly because of the scope of ARM, but as we quite rightly move locks away from the ARM proposal then protected makes more sense. On Mon, Mar 9, 2009 at 10:05 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Ditto - try is the wrong keyword for this one. protected works great. > Also gets rid of the 'you can add catch / finally blocks at the end > for consistency' device, which really doesn't make too much sense for > locks. > > --Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On Mar 9, 2009, at 00:56, Jesse Wilson wrote: > > > On Sun, Mar 8, 2009 at 11:20 AM, Joshua Bloch wrote: > > > >> try () { > >> > >> } > > > > > > try is definitely the wrong keyword here. Mostly because there's > > already a > > method Lock.tryLock() that is not at all related to this sweet sugar. > > > http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Lock.html#tryLock() > > > > 1. Use the protected keyword in place of try. > >> > > > > This is fantastic. I especially like that proper Locks would become > > just as > > easy-to-use as the built-in monitor on Object. > > > > > -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From tim at peierls.net Mon Mar 9 10:26:33 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 9 Mar 2009 13:26:33 -0400 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> Message-ID: <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Attractive as the finally modifier seemed to me, I see the handwriting on the wall. I'd like to get back to the core of the original proposal, which still seems compelling and achievable: a small language change to make it easy for users to avoid a common class of deadly mistakes. That's something worth pursuing. I really, really don't like the thought of having two "magic" interfaces, Disposable and Resource. For one thing, we would have to deal with types that extend/implement both Disposable *and* Resource by disallowing them in ARM initialization. More importantly, there's historical precedent: At one point during the JSR-201 discussions on for-each, the possibility of allowing both Iterable and Iterator in the right-hand slot was seriously considered but ultimately rejected. I think that was the right choice, and I bet the majority of people on this list think so, too. In addition, I don't like the names Disposable and Resource for two reasons: (1) They are names that are already in use out there, Resource especially, and even though there's no risk of ambiguity (they'd be in a package that isn't automatically imported), it's impolite to promote these fairly generic names for such a narrowly-targeted use. (2) They are not particularly good names for things that are closeable, and "things that are tricky to close() properly" is what motivated the whole ARM proposal. I'd be happier with a less graceful but more accurate name that is less likely to be in common use. For example: public interface AutoCloseable { void close() throws Exception; } public interface Closeable extends AutoCloseable { void close() throws IOException; } (JBoss has an AutoCloseable, but it extends the standard Closeable, so that works out OK.) Yes, this forces the maintainers of resource-ish types that don't use close() as the clean-up method to write adapters if they want their users to take advantage of ARM. That's OK -- if getting the clean-up right is sufficiently difficult and important, it will be worth adding those adapters and documenting how to use them. And yes, this will frustrate designers of new resource-ish types who want ARM support but for whom "close" is not at all the appropriate verb. But designers of new types are at least free to design abstractions that aren't as delicate in their clean-up requirements as the current crop of Closeables. --tim On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: > Mark, > Hi. > > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > > > From: Joshua Bloch > > > > > It is perhaps worth reiterating that the "finally" (or other keyword) > > > solution really does make things more complex. > > > > Yes, but the complexity might be worthwhile. > > > Agreed. I wasn't saying that we shouldn't do it; just that we should only > do it with our eyes open. > > > > On the surface, at least, > > doing this in the language makes a lot more sense to me than doing it > > with an interface. > > > On the one hand, we did for-each with an interface. But on the other that > was targeted at a more limited set of types, and it was no real hardship > that the method that they had to implement Iterable. > > > > > > The superclass of a resource must not be a resource. > > > > Not clear. We could, e.g., allow a superclass to be a resource so long > > as the subclass does not override the disposal method, > > > Yep. That's what I meant to say, but now what I said. Oops;) > > > > > > Remember that Coin means "small change";) > > > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > > keyword-based disposal methods could still meet the threshold of "small > > change". > > > Well, I'm happy to work it out. Then we'll have two alternatives to > compare. > > Regards, > > Josh > > From jjb at google.com Mon Mar 9 10:35:07 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 9 Mar 2009 09:35:07 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Message-ID: <17b2302a0903091035v535d4771hf1778f83cb623a27@mail.gmail.com> Tim, This is an excellent solution! AutoCloseable it is. I will do a minor revision of the proposal in the very near future. Josh On Mon, Mar 9, 2009 at 9:26 AM, Tim Peierls wrote: > Attractive as the finally modifier seemed to me, I see the handwriting on > the wall. I'd like to get back to the core of the original proposal, which > still seems compelling and achievable: a small language change to make it > easy for users to avoid a common class of deadly mistakes. That's something > worth pursuing. > > I really, really don't like the thought of having two "magic" interfaces, > Disposable and Resource. For one thing, we would have to deal with types > that extend/implement both Disposable *and* Resource by disallowing them in > ARM initialization. More importantly, there's historical precedent: At one > point during the JSR-201 discussions on for-each, the possibility of > allowing both Iterable and Iterator in the right-hand slot was seriously > considered but ultimately rejected. I think that was the right choice, and > I > bet the majority of people on this list think so, too. > > In addition, I don't like the names Disposable and Resource for two > reasons: > (1) They are names that are already in use out there, Resource especially, > and even though there's no risk of ambiguity (they'd be in a package that > isn't automatically imported), it's impolite to promote these fairly > generic > names for such a narrowly-targeted use. (2) They are not particularly good > names for things that are closeable, and "things that are tricky to close() > properly" is what motivated the whole ARM proposal. > > I'd be happier with a less graceful but more accurate name that is less > likely to be in common use. For example: > > public interface AutoCloseable { > void close() throws Exception; > } > > public interface Closeable extends AutoCloseable { > void close() throws IOException; > } > > (JBoss has an AutoCloseable, but it extends the standard Closeable, so that > works out OK.) > > Yes, this forces the maintainers of resource-ish types that don't use > close() as the clean-up method to write adapters if they want their users > to > take advantage of ARM. That's OK -- if getting the clean-up right is > sufficiently difficult and important, it will be worth adding those > adapters > and documenting how to use them. > > And yes, this will frustrate designers of new resource-ish types who want > ARM support but for whom "close" is not at all the appropriate verb. But > designers of new types are at least free to design abstractions that aren't > as delicate in their clean-up requirements as the current crop of > Closeables. > > --tim > > > On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: > > > Mark, > > Hi. > > > > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > > > > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > > > > From: Joshua Bloch > > > > > > > It is perhaps worth reiterating that the "finally" (or other keyword) > > > > solution really does make things more complex. > > > > > > Yes, but the complexity might be worthwhile. > > > > > > Agreed. I wasn't saying that we shouldn't do it; just that we should > only > > do it with our eyes open. > > > > > > > On the surface, at least, > > > doing this in the language makes a lot more sense to me than doing it > > > with an interface. > > > > > > On the one hand, we did for-each with an interface. But on the other > that > > was targeted at a more limited set of types, and it was no real hardship > > that the method that they had to implement Iterable. > > > > > > > > > The superclass of a resource must not be a resource. > > > > > > Not clear. We could, e.g., allow a superclass to be a resource so long > > > as the subclass does not override the disposal method, > > > > > > Yep. That's what I meant to say, but now what I said. Oops;) > > > > > > > > > Remember that Coin means "small change";) > > > > > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > > > keyword-based disposal methods could still meet the threshold of "small > > > change". > > > > > > Well, I'm happy to work it out. Then we'll have two alternatives to > > compare. > > > > Regards, > > > > Josh > > > > > > From crazybob at crazybob.org Mon Mar 9 10:36:33 2009 From: crazybob at crazybob.org (Bob Lee) Date: Mon, 9 Mar 2009 09:36:33 -0800 Subject: Proposal: Automatic Resource Management In-Reply-To: <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Message-ID: +1 on all counts. Thanks, Tim! Bob On Mon, Mar 9, 2009 at 9:26 AM, Tim Peierls wrote: > Attractive as the finally modifier seemed to me, I see the handwriting on > the wall. I'd like to get back to the core of the original proposal, which > still seems compelling and achievable: a small language change to make it > easy for users to avoid a common class of deadly mistakes. That's something > worth pursuing. > > I really, really don't like the thought of having two "magic" interfaces, > Disposable and Resource. For one thing, we would have to deal with types > that extend/implement both Disposable *and* Resource by disallowing them in > ARM initialization. More importantly, there's historical precedent: At one > point during the JSR-201 discussions on for-each, the possibility of > allowing both Iterable and Iterator in the right-hand slot was seriously > considered but ultimately rejected. I think that was the right choice, and > I > bet the majority of people on this list think so, too. > > In addition, I don't like the names Disposable and Resource for two > reasons: > (1) They are names that are already in use out there, Resource especially, > and even though there's no risk of ambiguity (they'd be in a package that > isn't automatically imported), it's impolite to promote these fairly > generic > names for such a narrowly-targeted use. (2) They are not particularly good > names for things that are closeable, and "things that are tricky to close() > properly" is what motivated the whole ARM proposal. > > I'd be happier with a less graceful but more accurate name that is less > likely to be in common use. For example: > > public interface AutoCloseable { > void close() throws Exception; > } > > public interface Closeable extends AutoCloseable { > void close() throws IOException; > } > > (JBoss has an AutoCloseable, but it extends the standard Closeable, so that > works out OK.) > > Yes, this forces the maintainers of resource-ish types that don't use > close() as the clean-up method to write adapters if they want their users > to > take advantage of ARM. That's OK -- if getting the clean-up right is > sufficiently difficult and important, it will be worth adding those > adapters > and documenting how to use them. > > And yes, this will frustrate designers of new resource-ish types who want > ARM support but for whom "close" is not at all the appropriate verb. But > designers of new types are at least free to design abstractions that aren't > as delicate in their clean-up requirements as the current crop of > Closeables. > > --tim > > > On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: > > > Mark, > > Hi. > > > > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > > > > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > > > > From: Joshua Bloch > > > > > > > It is perhaps worth reiterating that the "finally" (or other keyword) > > > > solution really does make things more complex. > > > > > > Yes, but the complexity might be worthwhile. > > > > > > Agreed. I wasn't saying that we shouldn't do it; just that we should > only > > do it with our eyes open. > > > > > > > On the surface, at least, > > > doing this in the language makes a lot more sense to me than doing it > > > with an interface. > > > > > > On the one hand, we did for-each with an interface. But on the other > that > > was targeted at a more limited set of types, and it was no real hardship > > that the method that they had to implement Iterable. > > > > > > > > > The superclass of a resource must not be a resource. > > > > > > Not clear. We could, e.g., allow a superclass to be a resource so long > > > as the subclass does not override the disposal method, > > > > > > Yep. That's what I meant to say, but now what I said. Oops;) > > > > > > > > > Remember that Coin means "small change";) > > > > > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > > > keyword-based disposal methods could still meet the threshold of "small > > > change". > > > > > > Well, I'm happy to work it out. Then we'll have two alternatives to > > compare. > > > > Regards, > > > > Josh > > > > > > From scolebourne at joda.org Mon Mar 9 10:39:54 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Mon, 9 Mar 2009 17:39:54 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Message-ID: <4b4f45e00903091039x6c0d590av1445425cb5af7983@mail.gmail.com> If I were naming, I'd call it CloseableResource, but thats just me ;-) Stephen 2009/3/9 Bob Lee : > +1 on all counts. Thanks, Tim! > > Bob > > On Mon, Mar 9, 2009 at 9:26 AM, Tim Peierls wrote: > >> Attractive as the finally modifier seemed to me, I see the handwriting on >> the wall. I'd like to get back to the core of the original proposal, which >> still seems compelling and achievable: a small language change to make it >> easy for users to avoid a common class of deadly mistakes. That's something >> worth pursuing. >> >> I really, really don't like the thought of having two "magic" interfaces, >> Disposable and Resource. For one thing, we would have to deal with types >> that extend/implement both Disposable *and* Resource by disallowing them in >> ARM initialization. More importantly, there's historical precedent: At one >> point during the JSR-201 discussions on for-each, the possibility of >> allowing both Iterable and Iterator in the right-hand slot was seriously >> considered but ultimately rejected. I think that was the right choice, and >> I >> bet the majority of people on this list think so, too. >> >> In addition, I don't like the names Disposable and Resource for two >> reasons: >> (1) They are names that are already in use out there, Resource especially, >> and even though there's no risk of ambiguity (they'd be in a package that >> isn't automatically imported), it's impolite to promote these fairly >> generic >> names for such a narrowly-targeted use. (2) They are not particularly good >> names for things that are closeable, and "things that are tricky to close() >> properly" is what motivated the whole ARM proposal. >> >> I'd be happier with a less graceful but more accurate name that is less >> likely to be in common use. For example: >> >> public interface AutoCloseable { >> ? ?void close() throws Exception; >> } >> >> public interface Closeable extends AutoCloseable { >> ? ?void close() throws IOException; >> } >> >> (JBoss has an AutoCloseable, but it extends the standard Closeable, so that >> works out OK.) >> >> Yes, this forces the maintainers of resource-ish types that don't use >> close() as the clean-up method to write adapters if they want their users >> to >> take advantage of ARM. That's OK -- if getting the clean-up right is >> sufficiently difficult and important, it will be worth adding those >> adapters >> and documenting how to use them. >> >> And yes, this will frustrate designers of new resource-ish types who want >> ARM support but for whom "close" is not at all the appropriate verb. But >> designers of new types are at least free to design abstractions that aren't >> as delicate in their clean-up requirements as the current crop of >> Closeables. >> >> --tim >> >> >> On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: >> >> > Mark, >> > Hi. >> > >> > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: >> > >> > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 >> > > > From: Joshua Bloch >> > > >> > > > It is perhaps worth reiterating that the "finally" (or other keyword) >> > > > solution really does make things more complex. >> > > >> > > Yes, but the complexity might be worthwhile. >> > >> > >> > Agreed. ?I wasn't saying that we shouldn't do it; just that we should >> only >> > do it with our eyes open. >> > >> > >> > > ?On the surface, at least, >> > > doing this in the language makes a lot more sense to me than doing it >> > > with an interface. >> > >> > >> > On the one hand, we did for-each with an interface. ?But on the other >> that >> > was targeted at a more limited set of types, and it was no real hardship >> > that the method that they had to implement Iterable. >> > >> > > >> > > > ?The superclass of a resource must not be a resource. >> > > >> > > Not clear. ?We could, e.g., allow a superclass to be a resource so long >> > > as the subclass does not override the disposal method, >> > >> > >> > Yep. ?That's what I meant to say, but now what I said. ?Oops;) >> > >> > > >> > > > ?Remember that Coin means "small change";) >> > > >> > > Indeed. ?Joe might disagree, but to my eye a worked-out proposal for >> > > keyword-based disposal methods could still meet the threshold of "small >> > > change". >> > >> > >> > Well, I'm happy to work it out. ?Then we'll have two alternatives to >> > compare. >> > >> > ? ? ? ?Regards, >> > >> > ? ? ? ?Josh >> > >> > >> >> > > From rzwitserloot.pop at gmail.com Sun Mar 8 14:37:43 2009 From: rzwitserloot.pop at gmail.com (Reinier Zwitserloot) Date: Sun, 8 Mar 2009 22:37:43 +0100 Subject: PROPOSAL: Multiline strings In-Reply-To: <49B3FD90.6040805@e-spirit.de> References: <49B3FD90.6040805@e-spirit.de> Message-ID: <3B9FC5E6-A34F-4376-9793-6FB7168D576F@gmail.com> Triple dquotes means you don't have to escape any single dquotes except at the end. The default should clearly be to strip indent; NOT doing this is the exception, some toying about with exact syntax rules, and a good review of YAML should help sort it out. --Reinier Zwitserloot On 8 mrt 2009, at 18:17, Stefan Schulz wrote: > I quite liked the idea of handling newlines by adding methods to > String, > to overcome magic conversions. When reading back about indentation > etc., > I wonder, why not to apply a similar technique to get rid of > indent-related white spaces. > > Another question on multi-line Strings I have: does it make sense to > allow a multi-line String only having one line? If not, why not using > the sequence double-quote plus newline as marker for multi-line > Strings? > But maybe I overlook the significance in using a seperate marker > here or > problems that might occur during compilation. > > According to the above thoughts, the following would assign a multi- > line > String: > > String myString = " > SELECT name > FROM persons > WHERE age > 21"; > > And one could invoke some additional methods on it, e.g.: > > myString.removeIndents(); // first line defines indent > myString.removeWhitespaces(); // HTML style space removal > > I don't think that wrong indentation inside a String should lead to a > compiler error, that's why methods like above would suffice IMO. All > the > compiler would have to do is to automatically add (platform specific) > line breaks. > > Stefan > From tim at peierls.net Mon Mar 9 10:51:24 2009 From: tim at peierls.net (Tim Peierls) Date: Mon, 9 Mar 2009 13:51:24 -0400 Subject: Proposal: Automatic Resource Management In-Reply-To: <4b4f45e00903091039x6c0d590av1445425cb5af7983@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <4b4f45e00903091039x6c0d590av1445425cb5af7983@mail.gmail.com> Message-ID: <63b4e4050903091051g431fdaebn7ca85f8dc90cef67@mail.gmail.com> CloseableResource is good, too. I have a mild preference for AutoCloseable, because it leaves open the possibility of blessing other AutoXxx classes in the future. Maybe the name of the proposal is misleading, since not all resources can be managed automatically, just those that have a void close() method. --tim On Mon, Mar 9, 2009 at 1:39 PM, Stephen Colebourne wrote: > If I were naming, I'd call it CloseableResource, but thats just me ;-) > Stephen > > > 2009/3/9 Bob Lee : > > +1 on all counts. Thanks, Tim! > > > > Bob > > > > On Mon, Mar 9, 2009 at 9:26 AM, Tim Peierls wrote: > > > >> Attractive as the finally modifier seemed to me, I see the handwriting > on > >> the wall. I'd like to get back to the core of the original proposal, > which > >> still seems compelling and achievable: a small language change to make > it > >> easy for users to avoid a common class of deadly mistakes. That's > something > >> worth pursuing. > >> > >> I really, really don't like the thought of having two "magic" > interfaces, > >> Disposable and Resource. For one thing, we would have to deal with types > >> that extend/implement both Disposable *and* Resource by disallowing them > in > >> ARM initialization. More importantly, there's historical precedent: At > one > >> point during the JSR-201 discussions on for-each, the possibility of > >> allowing both Iterable and Iterator in the right-hand slot was seriously > >> considered but ultimately rejected. I think that was the right choice, > and > >> I > >> bet the majority of people on this list think so, too. > >> > >> In addition, I don't like the names Disposable and Resource for two > >> reasons: > >> (1) They are names that are already in use out there, Resource > especially, > >> and even though there's no risk of ambiguity (they'd be in a package > that > >> isn't automatically imported), it's impolite to promote these fairly > >> generic > >> names for such a narrowly-targeted use. (2) They are not particularly > good > >> names for things that are closeable, and "things that are tricky to > close() > >> properly" is what motivated the whole ARM proposal. > >> > >> I'd be happier with a less graceful but more accurate name that is less > >> likely to be in common use. For example: > >> > >> public interface AutoCloseable { > >> void close() throws Exception; > >> } > >> > >> public interface Closeable extends AutoCloseable { > >> void close() throws IOException; > >> } > >> > >> (JBoss has an AutoCloseable, but it extends the standard Closeable, so > that > >> works out OK.) > >> > >> Yes, this forces the maintainers of resource-ish types that don't use > >> close() as the clean-up method to write adapters if they want their > users > >> to > >> take advantage of ARM. That's OK -- if getting the clean-up right is > >> sufficiently difficult and important, it will be worth adding those > >> adapters > >> and documenting how to use them. > >> > >> And yes, this will frustrate designers of new resource-ish types who > want > >> ARM support but for whom "close" is not at all the appropriate verb. But > >> designers of new types are at least free to design abstractions that > aren't > >> as delicate in their clean-up requirements as the current crop of > >> Closeables. > >> > >> --tim > >> > >> > >> On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: > >> > >> > Mark, > >> > Hi. > >> > > >> > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > >> > > >> > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > >> > > > From: Joshua Bloch > >> > > > >> > > > It is perhaps worth reiterating that the "finally" (or other > keyword) > >> > > > solution really does make things more complex. > >> > > > >> > > Yes, but the complexity might be worthwhile. > >> > > >> > > >> > Agreed. I wasn't saying that we shouldn't do it; just that we should > >> only > >> > do it with our eyes open. > >> > > >> > > >> > > On the surface, at least, > >> > > doing this in the language makes a lot more sense to me than doing > it > >> > > with an interface. > >> > > >> > > >> > On the one hand, we did for-each with an interface. But on the other > >> that > >> > was targeted at a more limited set of types, and it was no real > hardship > >> > that the method that they had to implement Iterable. > >> > > >> > > > >> > > > The superclass of a resource must not be a resource. > >> > > > >> > > Not clear. We could, e.g., allow a superclass to be a resource so > long > >> > > as the subclass does not override the disposal method, > >> > > >> > > >> > Yep. That's what I meant to say, but now what I said. Oops;) > >> > > >> > > > >> > > > Remember that Coin means "small change";) > >> > > > >> > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > >> > > keyword-based disposal methods could still meet the threshold of > "small > >> > > change". > >> > > >> > > >> > Well, I'm happy to work it out. Then we'll have two alternatives to > >> > compare. > >> > > >> > Regards, > >> > > >> > Josh > >> > > >> > > >> > >> > > > > > > From vilya.harvey at gmail.com Mon Mar 9 10:55:39 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Mon, 9 Mar 2009 17:55:39 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Message-ID: <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> 2009/3/9 Tim Peierls > And yes, this will frustrate designers of new resource-ish types who want > ARM support but for whom "close" is not at all the appropriate verb. But > designers of new types are at least free to design abstractions that aren't > as delicate in their clean-up requirements as the current crop of > Closeables. Just as a data point, the equivalent to this in Python - the with block - uses the method names __enter__ and __exit__ (you can ignore the double underscore, that's just a Python convention). I joined this mailing list too late to see the proposal when it was posted; does it include calling any kind of setup method on entering the block? If not, this may be worth considering as well? BTW, is there anywhere online where I can read the proposal? Vil. From reinier at zwitserloot.com Mon Mar 9 11:09:11 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 9 Mar 2009 19:09:11 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> Message-ID: <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> Vilya, you can check the entire history of this mailing list over at: http://mail.openjdk.java.net/pipermail/coin-dev/ Afaik, the latest version of the ARM proposal is here. Assuming Josh turned auto-republish on, this URL should always point at the latest version: http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh AutoClosable idea sounds good to me too, FWIW. --Reinier Zwitserloot On Mar 9, 2009, at 18:55, Vilya Harvey wrote: > 2009/3/9 Tim Peierls > >> And yes, this will frustrate designers of new resource-ish types >> who want >> ARM support but for whom "close" is not at all the appropriate >> verb. But >> designers of new types are at least free to design abstractions >> that aren't >> as delicate in their clean-up requirements as the current crop of >> Closeables. > > > Just as a data point, the equivalent to this in Python - the with > block - > uses the method names __enter__ and __exit__ (you can ignore the > double > underscore, that's just a Python convention). > > I joined this mailing list too late to see the proposal when it was > posted; > does it include calling any kind of setup method on entering the > block? If > not, this may be worth considering as well? > > BTW, is there anywhere online where I can read the proposal? > > Vil. > From jjb at google.com Mon Mar 9 11:16:12 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 9 Mar 2009 11:16:12 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> Message-ID: <17b2302a0903091116u1069487an3a6665b7cf2ae70@mail.gmail.com> Reinier, > > Afaik, the latest version of the ARM proposal is here. Assuming Josh > turned auto-republish on, this URL should always point at the latest > version: > > http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh > I don't have auto-republish on, but it will always point to the latest version (unless I'm forced to branch, in which case I'll tell the list). > AutoClosable idea sounds good to me too, FWIW. > > Great, thanks! Josh From markmahieu at googlemail.com Mon Mar 9 11:18:26 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 9 Mar 2009 18:18:26 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Message-ID: I fear the question will come up again, but +1 from me if it allows the proposal to move forward. Best regards, Mark 2009/3/9 Tim Peierls > Attractive as the finally modifier seemed to me, I see the handwriting on > the wall. I'd like to get back to the core of the original proposal, which > still seems compelling and achievable: a small language change to make it > easy for users to avoid a common class of deadly mistakes. That's something > worth pursuing. > > I really, really don't like the thought of having two "magic" interfaces, > Disposable and Resource. For one thing, we would have to deal with types > that extend/implement both Disposable *and* Resource by disallowing them in > ARM initialization. More importantly, there's historical precedent: At one > point during the JSR-201 discussions on for-each, the possibility of > allowing both Iterable and Iterator in the right-hand slot was seriously > considered but ultimately rejected. I think that was the right choice, and > I > bet the majority of people on this list think so, too. > > In addition, I don't like the names Disposable and Resource for two > reasons: > (1) They are names that are already in use out there, Resource especially, > and even though there's no risk of ambiguity (they'd be in a package that > isn't automatically imported), it's impolite to promote these fairly > generic > names for such a narrowly-targeted use. (2) They are not particularly good > names for things that are closeable, and "things that are tricky to close() > properly" is what motivated the whole ARM proposal. > > I'd be happier with a less graceful but more accurate name that is less > likely to be in common use. For example: > > public interface AutoCloseable { > void close() throws Exception; > } > > public interface Closeable extends AutoCloseable { > void close() throws IOException; > } > > (JBoss has an AutoCloseable, but it extends the standard Closeable, so that > works out OK.) > > Yes, this forces the maintainers of resource-ish types that don't use > close() as the clean-up method to write adapters if they want their users > to > take advantage of ARM. That's OK -- if getting the clean-up right is > sufficiently difficult and important, it will be worth adding those > adapters > and documenting how to use them. > > And yes, this will frustrate designers of new resource-ish types who want > ARM support but for whom "close" is not at all the appropriate verb. But > designers of new types are at least free to design abstractions that aren't > as delicate in their clean-up requirements as the current crop of > Closeables. > > --tim > > > On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: > > > Mark, > > Hi. > > > > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > > > > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > > > > From: Joshua Bloch > > > > > > > It is perhaps worth reiterating that the "finally" (or other keyword) > > > > solution really does make things more complex. > > > > > > Yes, but the complexity might be worthwhile. > > > > > > Agreed. I wasn't saying that we shouldn't do it; just that we should > only > > do it with our eyes open. > > > > > > > On the surface, at least, > > > doing this in the language makes a lot more sense to me than doing it > > > with an interface. > > > > > > On the one hand, we did for-each with an interface. But on the other > that > > was targeted at a more limited set of types, and it was no real hardship > > that the method that they had to implement Iterable. > > > > > > > > > The superclass of a resource must not be a resource. > > > > > > Not clear. We could, e.g., allow a superclass to be a resource so long > > > as the subclass does not override the disposal method, > > > > > > Yep. That's what I meant to say, but now what I said. Oops;) > > > > > > > > > Remember that Coin means "small change";) > > > > > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > > > keyword-based disposal methods could still meet the threshold of "small > > > change". > > > > > > Well, I'm happy to work it out. Then we'll have two alternatives to > > compare. > > > > Regards, > > > > Josh > > > > > > From felixf977 at gmail.com Mon Mar 9 11:23:49 2009 From: felixf977 at gmail.com (Felix Frost) Date: Mon, 9 Mar 2009 14:23:49 -0400 Subject: Proposal: Enhanced String constructs for Java Message-ID: Enhanced String constructs for Java AUTHOR(S): Felix Frost (felixf977 at gmail.com) *OVERVIEW* Java is aging and failing to keep up with the needs of the modern internet age. This proposal conservatively extends Java with some features found in more modern internet ready language in order to ensure its continued relevance. FEATURE SUMMARY: This proposal extends Java with two new multi-line capable String constructs. One is primarily concerned with embedded text, while the other simplifies the construction of helpful error messages. The HAI ... KTHXBAI string expressions allow the use of embedded emoticons. This multi-line string construct begins after the HAI keyword and ends with a KTHXBAI keyword. It also allows the use of emoticons as literals in strings. :o is usable as the system bell character ('\g'). :) should be synonymous with character U-263A(White Smiley) (?) (available from windows arial font) :( should be synonymous with unicode character 0x2639 (Sad Smiley) (?) :0 should be synonymous with character U-203C(Double Exclamation) (?) (available from windows arial font) :: parses as a regular : characters The OMG ... DO NOT WANT string expressions allow for easier throwing of runtime exception. This multi-line string construct begins after OMG and end with DO NOT WANT. It converts directly into "throw new RuntimeException("");" This string also supports the embedded emoticons listed above. MAJOR ADVANTAGE: Emoticons are common occurrence in most internet conversations. They can be more expressive than words, and are fun to type. MAJOR BENEFIT: This would help improve Java's popularity among the new internet generation. It will continue to stay relevant, as well as support feline developers. MAJOR DISADVANTAGE: Associated costs in documentation, tutorials and overall language size. The principle perceived disadvantage, however, is that it encourages, rather than discourages, the leveraging of hilarity in code. There are some software shops in which humor is not appreciated. For these shops, the author(s) recommend using the traditional java syntax ALTERNATIVES: It is possible to continue using the \g escape for bells, however this will likely decrease LOLs and general happiness of java developers. *EXAMPLES* SIMPLE EXAMPLE: Exclaiming in Strings - try { if(unexpectedError) { System.out.println(HAI O NOES :o KTHXBYE); OMG Sistemz iz no gud! DO NOT WANT } } catch(RuntimeException e) { //We will make it here } *DETAILS* SPECIFICATION: Lexical: HAI := 'HAI' KTHXBYE := 'KTHXBYE' OMG := 'OMG' DO_NOT_WANT := 'DO NOT WANT' Syntax: lolteral := HAI any_char* KTHXBYE can_haz_string := string_literal | lolteral o_noes := OMG any_char* DO_NOT_WANT //Replace all occurences of string_literal with can_haz_string TESTING: This feature can be tested by presenting the new java compiler to the developers pet cats, and determining the new level of programming ability. LIBRARY SUPPORT: No library support is required. REFLECTIVE APIS: No reflective APIs require any changes. OTHER CHANGES: No other platform changes are required. MIGRATION: No migration of existing code is recommended. These new language features are mainly to be used for feline developers. *COMPATIBILITY* BREAKING CHANGES: No breaking changes are caused by this proposal. EXISTING PROGRAMS: Because the changes are purely the introduction of new expression forms, there is no impact on the meaning of existing code. *REFERENCES* URL FOR PROTOTYPE: No Java prototype exists at this time. However, LOLCode[1] is the closest implementation. OTHER REFERENCES [1] LOLCode 1.2 Specification - http://lolcode.com/specs/1.2 From jjb at google.com Mon Mar 9 11:29:26 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 9 Mar 2009 11:29:26 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> Message-ID: <17b2302a0903091129h5a2234e5ve51c86103b1c6b7@mail.gmail.com> Mark, Thanks. Actually I'm impressed that you, Tim, Bob, Reinier, Stephen and I can all agree on this in the span of an hour:) Josh On Mon, Mar 9, 2009 at 11:18 AM, Mark Mahieu wrote: > I fear the question will come up again, but +1 from me if it allows the > proposal to move forward. > Best regards, > > Mark > > > 2009/3/9 Tim Peierls > > > Attractive as the finally modifier seemed to me, I see the handwriting on > > the wall. I'd like to get back to the core of the original proposal, > which > > still seems compelling and achievable: a small language change to make it > > easy for users to avoid a common class of deadly mistakes. That's > something > > worth pursuing. > > > > I really, really don't like the thought of having two "magic" interfaces, > > Disposable and Resource. For one thing, we would have to deal with types > > that extend/implement both Disposable *and* Resource by disallowing them > in > > ARM initialization. More importantly, there's historical precedent: At > one > > point during the JSR-201 discussions on for-each, the possibility of > > allowing both Iterable and Iterator in the right-hand slot was seriously > > considered but ultimately rejected. I think that was the right choice, > and > > I > > bet the majority of people on this list think so, too. > > > > In addition, I don't like the names Disposable and Resource for two > > reasons: > > (1) They are names that are already in use out there, Resource > especially, > > and even though there's no risk of ambiguity (they'd be in a package that > > isn't automatically imported), it's impolite to promote these fairly > > generic > > names for such a narrowly-targeted use. (2) They are not particularly > good > > names for things that are closeable, and "things that are tricky to > close() > > properly" is what motivated the whole ARM proposal. > > > > I'd be happier with a less graceful but more accurate name that is less > > likely to be in common use. For example: > > > > public interface AutoCloseable { > > void close() throws Exception; > > } > > > > public interface Closeable extends AutoCloseable { > > void close() throws IOException; > > } > > > > (JBoss has an AutoCloseable, but it extends the standard Closeable, so > that > > works out OK.) > > > > Yes, this forces the maintainers of resource-ish types that don't use > > close() as the clean-up method to write adapters if they want their users > > to > > take advantage of ARM. That's OK -- if getting the clean-up right is > > sufficiently difficult and important, it will be worth adding those > > adapters > > and documenting how to use them. > > > > And yes, this will frustrate designers of new resource-ish types who want > > ARM support but for whom "close" is not at all the appropriate verb. But > > designers of new types are at least free to design abstractions that > aren't > > as delicate in their clean-up requirements as the current crop of > > Closeables. > > > > --tim > > > > > > On Wed, Mar 4, 2009 at 11:54 PM, Joshua Bloch wrote: > > > > > Mark, > > > Hi. > > > > > > On Wed, Mar 4, 2009 at 7:35 PM, Mark Reinhold wrote: > > > > > > > > Date: Wed, 04 Mar 2009 16:37:41 -0800 > > > > > From: Joshua Bloch > > > > > > > > > It is perhaps worth reiterating that the "finally" (or other > keyword) > > > > > solution really does make things more complex. > > > > > > > > Yes, but the complexity might be worthwhile. > > > > > > > > > Agreed. I wasn't saying that we shouldn't do it; just that we should > > only > > > do it with our eyes open. > > > > > > > > > > On the surface, at least, > > > > doing this in the language makes a lot more sense to me than doing it > > > > with an interface. > > > > > > > > > On the one hand, we did for-each with an interface. But on the other > > that > > > was targeted at a more limited set of types, and it was no real > hardship > > > that the method that they had to implement Iterable. > > > > > > > > > > > > The superclass of a resource must not be a resource. > > > > > > > > Not clear. We could, e.g., allow a superclass to be a resource so > long > > > > as the subclass does not override the disposal method, > > > > > > > > > Yep. That's what I meant to say, but now what I said. Oops;) > > > > > > > > > > > > Remember that Coin means "small change";) > > > > > > > > Indeed. Joe might disagree, but to my eye a worked-out proposal for > > > > keyword-based disposal methods could still meet the threshold of > "small > > > > change". > > > > > > > > > Well, I'm happy to work it out. Then we'll have two alternatives to > > > compare. > > > > > > Regards, > > > > > > Josh > > > > > > > > > > > > From Joe.Darcy at Sun.COM Mon Mar 9 12:06:03 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 09 Mar 2009 12:06:03 -0700 Subject: Proposal: Enhanced String constructs for Java In-Reply-To: References: Message-ID: <49B5689B.7040709@sun.com> Felix Frost wrote: > Enhanced String constructs for Java > AUTHOR(S): > Felix Frost (felixf977 at gmail.com) > > > *OVERVIEW* > Java is aging and failing to keep up with the needs of the modern > internet age. This proposal > conservatively extends Java with some features found in more modern > internet ready language in > order to ensure its continued relevance. > > FEATURE SUMMARY: > This proposal extends Java with two new multi-line capable String > constructs. One is primarily > concerned with embedded text, while the other simplifies the > construction of helpful error messages. > > The HAI ... KTHXBAI string expressions allow the use of embedded > emoticons. This multi-line > string construct begins after the HAI keyword and ends with a KTHXBAI > keyword. It also allows > the use of emoticons as literals in strings. > > :o is usable as the system bell character ('\g'). > :) should be synonymous with character U-263A(White Smiley) (?) > (available from windows arial font) > :( should be synonymous with unicode character 0x2639 (Sad Smiley) (?) > :0 should be synonymous with character U-203C(Double Exclamation) (?) > (available from windows arial font) > :: parses as a regular : characters > > The OMG ... DO NOT WANT string expressions allow for easier throwing > of runtime exception. This multi-line string > construct begins after OMG and end with DO NOT WANT. It converts > directly into "throw new RuntimeException("");" > This string also supports the embedded emoticons listed above. > NFW! -Joe From neal at gafter.com Mon Mar 9 12:42:42 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 12:42:42 -0700 Subject: Proposal: Enhanced String constructs for Java In-Reply-To: <49B5689B.7040709@sun.com> References: <49B5689B.7040709@sun.com> Message-ID: <15e8b9d20903091242x3e3561et4784e4241186a54c@mail.gmail.com> On Mon, Mar 9, 2009 at 12:06 PM, Joseph D. Darcy wrote: > NFW! Not For Work perhaps, but maybe just for fun. From vilya.harvey at gmail.com Mon Mar 9 12:52:00 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Mon, 9 Mar 2009 19:52:00 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> Message-ID: <6aef848f0903091252i37421675u68c00a98b05b0dd1@mail.gmail.com> 2009/3/9 Reinier Zwitserloot > Vilya, you can check the entire history of this mailing list over at: > > http://mail.openjdk.java.net/pipermail/coin-dev/ > > Afaik, the latest version of the ARM proposal is here. Assuming Josh > turned auto-republish on, this URL should always point at the latest > version: > > http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh > > AutoClosable idea sounds good to me too, FWIW. > Thanks a lot Reiner, I've just read the proposal. The only thing in it I wasn't too sure about was having variable declarations inside the parentheses. It works well in the examples given, but I can think of a few cases where it gets a bit ugly: - using an anonymous class as an adapter to implement AutoCloseable when an existing class doesn't implement it; - using with a resource managing class which requires you to call a void connect() method or similar to actually get the resource, instead of grabbing it in the constructor. Both of these would be slightly better if expressions (i.e. references to existing variables) were allowed inside the parentheses. You can work around this under the existing proposal: AutoCloseable ac = ... ; try (AutoCloseable acRef = ac) { ... } but that seems (to me) to obscure the fact that ac will be closed afterwards even more than if ac was listed on it's own inside the parentheses. Apologies if any of the above is unclear, or if this has already been discussed - I'm still going through the earlier posts in the archive. Vil. From neal at gafter.com Mon Mar 9 13:06:49 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 13:06:49 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903091116u1069487an3a6665b7cf2ae70@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> <17b2302a0903091116u1069487an3a6665b7cf2ae70@mail.gmail.com> Message-ID: <15e8b9d20903091306h343d77eag5192f241b9f9f305@mail.gmail.com> On Mon, Mar 9, 2009 at 11:16 AM, Joshua Bloch wrote: > This URL should always point at the latest version: > http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh The static exception analysis implied by the proposal's translation doesn't match its dynamic semantics. In the following program snippet, the proposal requires an error message where shown, while the dynamic semantics never allow the reported exception to occur. static BufferedReader getReader(String name) { // any implementation here } public static void main(String[] args) { { try (BufferedReader localVar = getReader(args[0])) { throw new NullPointerException(args[0]); } // required language error: IOException not caught } } From brucechapman at paradise.net.nz Mon Mar 9 13:39:42 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Tue, 10 Mar 2009 09:39:42 +1300 (NZDT) Subject: Proposal: Enhanced String constructs for Java In-Reply-To: <49B5689B.7040709@sun.com> References: <49B5689B.7040709@sun.com> Message-ID: <1236631182.49b57e8e24328@www.paradise.net.nz> Joe, "NFW" ??? Is it somewhat like the OMDB response I once got from Gilad? OMG Sit Aprfools orrdy? Iv mist da coin dedln 4 my otha propOsls KTHXBAI Bruce Quoting "Joseph D. Darcy" : > Felix Frost wrote: > > The OMG ... DO NOT WANT string expressions allow for easier throwing > > of runtime exception. This multi-line string > > construct begins after OMG and end with DO NOT WANT. It converts > > directly into "throw new RuntimeException("");" > > This string also supports the embedded emoticons listed above. > > > > NFW! > > -Joe > > From jeremy.manson at gmail.com Mon Mar 9 13:51:01 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Mon, 9 Mar 2009 12:51:01 -0800 Subject: Proposal: Enhanced String constructs for Java In-Reply-To: <15e8b9d20903091242x3e3561et4784e4241186a54c@mail.gmail.com> References: <49B5689B.7040709@sun.com> <15e8b9d20903091242x3e3561et4784e4241186a54c@mail.gmail.com> Message-ID: <1631da7d0903091351k5db91b7ana85ee6d1e47ec57b@mail.gmail.com> I think it means "No Flipping Way", actually :) Jeremy On Mon, Mar 9, 2009 at 11:42 AM, Neal Gafter wrote: > On Mon, Mar 9, 2009 at 12:06 PM, Joseph D. Darcy wrote: >> NFW! > > Not For Work perhaps, but maybe just for fun. > > From Joe.Darcy at Sun.COM Mon Mar 9 14:11:50 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 09 Mar 2009 14:11:50 -0700 Subject: Proposal: Enhanced String constructs for Java In-Reply-To: <1631da7d0903091351k5db91b7ana85ee6d1e47ec57b@mail.gmail.com> References: <49B5689B.7040709@sun.com> <15e8b9d20903091242x3e3561et4784e4241186a54c@mail.gmail.com> <1631da7d0903091351k5db91b7ana85ee6d1e47ec57b@mail.gmail.com> Message-ID: <49B58616.3080407@sun.com> Jeremy Manson wrote: > I think it means "No Flipping Way", actually :) > There are multiple meanings for the acronym, several of which apply ;-) -Joe > Jeremy > > On Mon, Mar 9, 2009 at 11:42 AM, Neal Gafter wrote: > >> On Mon, Mar 9, 2009 at 12:06 PM, Joseph D. Darcy wrote: >> >>> NFW! >>> >> Not For Work perhaps, but maybe just for fun. >> >> >> > > From markmahieu at googlemail.com Mon Mar 9 16:17:55 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 9 Mar 2009 23:17:55 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903091306h343d77eag5192f241b9f9f305@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> <17b2302a0903091116u1069487an3a6665b7cf2ae70@mail.gmail.com> <15e8b9d20903091306h343d77eag5192f241b9f9f305@mail.gmail.com> Message-ID: <6D206A84-27FD-4960-BF17-1FE6E28CDD32@googlemail.com> Yuck. I guess one way to deal with this would be to track exceptions 'definitely thrown' by statements, and use different translations depending on whether there are any exceptions 'definitely' thrown by the body. Not exactly a trivial addition to the spec though. Mark On 9 Mar 2009, at 20:06, Neal Gafter wrote: > On Mon, Mar 9, 2009 at 11:16 AM, Joshua Bloch wrote: >> This URL should always point at the latest version: >> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh > > The static exception analysis implied by the proposal's translation > doesn't match its dynamic semantics. In the following program > snippet, the proposal requires an error message where shown, while the > dynamic semantics never allow the reported exception to occur. > > static BufferedReader getReader(String name) { > // any implementation here > } > public static void main(String[] args) { > { > try (BufferedReader localVar = getReader(args[0])) { > throw new NullPointerException(args[0]); > } // required language error: IOException not caught > } > } > From jjb at google.com Mon Mar 9 16:24:35 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 9 Mar 2009 16:24:35 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <49B576EE.40703@sun.com> References: <49B576EE.40703@sun.com> Message-ID: <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> Joe, Hi. Thanks so much for the comments (both typos and substantive)! I have some reservations about the ARM proposal. > Many of your comments don't sound like reservations to me:) I may be misunderstanding you, but it sounds like you're saying that Java does need better support for resources with a block structured life cycle pattern. Then you rule out other approaches for various reasons. Next, you say that "There are limitations in how well the desugaring fits all the use-cases of interest." This does sound like a reservation, but I'm not sure I understand it. I believe the proposed desugaring is good for the great majority of use-cases of interest. Moreover, it is *far* better than what people do today. Could you please provide examples of important use-cases where the proposed desugaring falls short? Then you say "While managing block structure resources surely is a problem, a language solution is at or near the limit of the size of a coin." That too sounds like a reservation. But "at or near" is not "beyond." As proposed (and in the revision that I'll be issuing soon), the feature is a straightforward syntactic transformation, with no affect on the type system, class file format, backward compatibility, etc. The worst one can say is that it's a new statement form (like for-each). I do hope that such statement forms are in scope for Project Coin! All else being equal and given the effort that would be involved, I'd prefer > a change that generally supported block-structured resources rather than > "just" the IO related "Closeable" ones. I think doing this would include > handling "close" methods that are not declared or expected to throw > exceptions. > The proposed construct *was* designed to go beyond IO-related "Closeable" resources. I mentioned java.net.socket; java.sql.Connection, Statement, ResultSet, and java.awt.Graphics in the proposal, and the list was not meant to be exhaustive. I sincerely hope the construct works for the great majority of block-structured resources, whether or not their close/dispose/release/whatever method is defined to throw an exception. In fact, I'm not clear on the impact of whether the close method throws an exception. Please clarify. > ( If any distinct handling is done for close methods that are not expected > to throw exceptions, the test would probably need to be done on the dynamic > type of the Throwable so that the Liskov substitution principle was > followed. Assuming a degenerate exception could indicate it did and did not > have a close method that threw exceptions, the runtime treatment of such an > exception should not depend on the static type of the variable referring to > the exception. > > For example, perhaps reasonable semantics are for a Disposable resource to > have a secondary exception during close added to the original exception's > suppressed exception list while if "DisposableQuiet" resource gets an > exception during close, the *new* exception should be propagated out with > the old exception being suppressed?) > I am confused by this. Perhaps a concrete example would make it clear? Here are a few responses to your interspersed comments: > Like the for-each statement (introduced in Java 1.5), the automatic > resource management statement is a small piece of syntactic sugar with a > very high power-to-weight ratio. > > > The for-each statement in JDK 5 was a clear win. While there were details > of the design to be debated (what interface should be accepted, etc.) the > basic semantics were uncontested: starting with the first element, one by > one visit the next element of the structure until reaching the end. As has > been discussed on the list, the desired semantics of the ARM blocks are less > clear, such as how any secondary exception should be handled. I would > expect the same behavior would not be appropriate in all cases. Also as > noted on the list and in the proposal itself, there is a big difference in > getting an exception on closing an input stream versus an output stream. > Only in retrospect do the for-each semantics seem clear. When we were working on the design, there were many tricky issues, some of which we got wrong initially (remember SimpleIterator?). There was great debate over exactly which types should qualify for the new construct (now I wish we had included CharSequence). I see the automatic resource management as another clear win, with a comparable amount of complexity. > * Is method resolution impacted? > > No; although if multiple clean-up methods are supported, "close", "flush", > there will need to be rules about which ones are called if more than one is > present. > At this point, I think only one name will be supported (close), so the problem goes away. We went through the same conniptions with the for-each statement (Does it work on Iterator as well as Iterable? What happens if you implement both?). > > > *Ignoring certain **close failures* - One shortcoming of the construct as > described is that it does not provide a way for the programmer to indicate > that exceptions thrown when closing a resource should be ignored. In the > case of the copy method, ideally the program would ignore exceptions thrown > when closing the InputStream, but not the OutputStream. There are several > ways this could be achieved. > > > What did you have in mind here? Different disposable interfaces? > Annotations on the resource type? > Two interfaces is one possibility. Another is a second form of the statement, where the client code says "I don't care if this close succeeds or not." The former makes for cleaner client code, the latter allows finer-grained control. I'm ruling out annotations on previously discussed grounds ("the Hamilton principle"). > > Thinking a bit speculatively, if multi-catch and final rethrow are added, > would that have any weird interactions if used with ARM blocks? > Not weird ones, but there is a synergy (noted in the proposa)l: implementation of automatic resource management would be easier with rethrow. > > In related matters, I'm working on a writeup on the "finally" variation, an > alternative I don't favor, and will send it out in the next day or two. > I think you needn't bother. Its main adherents are now happy with an interface-based version. Thanks again, Josh From reinier at zwitserloot.com Mon Mar 9 16:27:21 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 10 Mar 2009 00:27:21 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <6D206A84-27FD-4960-BF17-1FE6E28CDD32@googlemail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> <17b2302a0903091116u1069487an3a6665b7cf2ae70@mail.gmail.com> <15e8b9d20903091306h343d77eag5192f241b9f9f305@mail.gmail.com> <6D206A84-27FD-4960-BF17-1FE6E28CDD32@googlemail.com> Message-ID: There are plenty of low hanging fruit in the JVM for ridiculous exception catching requirements (the rash of UnsupportedEncodingException comes to mind). If project coin can't handle adding semantics for this, then I say: so be it. It's not -that- hard to fix. Javac already has a 'reachability' concept. It would have to be expanded slightly to consider the type of 'unambiguous exit'. If it's an exception, then the ARM block no longer desugars the if (#suppressSecondary) block; it just assumes suppressSecondary is neccessarily true. --Reinier Zwitserloot On Mar 10, 2009, at 00:17, Mark Mahieu wrote: > Yuck. > > I guess one way to deal with this would be to track exceptions > 'definitely thrown' by statements, and use different translations > depending on whether there are any exceptions 'definitely' thrown by > the body. Not exactly a trivial addition to the spec though. > > Mark > > > On 9 Mar 2009, at 20:06, Neal Gafter wrote: > >> On Mon, Mar 9, 2009 at 11:16 AM, Joshua Bloch wrote: >>> This URL should always point at the latest version: >>> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh >> >> The static exception analysis implied by the proposal's translation >> doesn't match its dynamic semantics. In the following program >> snippet, the proposal requires an error message where shown, while >> the >> dynamic semantics never allow the reported exception to occur. >> >> static BufferedReader getReader(String name) { >> // any implementation here >> } >> public static void main(String[] args) { >> { >> try (BufferedReader localVar = getReader(args[0])) { >> throw new NullPointerException(args[0]); >> } // required language error: IOException not caught >> } >> } >> > > From jjb at google.com Mon Mar 9 16:27:29 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 9 Mar 2009 16:27:29 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <6aef848f0903091252i37421675u68c00a98b05b0dd1@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> <6aef848f0903091252i37421675u68c00a98b05b0dd1@mail.gmail.com> Message-ID: <17b2302a0903091627l443d0953o8a09ad1ac40f1930@mail.gmail.com> Vilya, Thanks for the feedback. I am glad that you like the proposal. On Mon, Mar 9, 2009 at 12:52 PM, Vilya Harvey wrote: > > > The only thing in it I wasn't too sure about was having variable > declarations inside the parentheses. It works well in the examples given, > but I can think of a few cases where it gets a bit ugly: > > - using an anonymous class as an adapter to implement AutoCloseable when > an existing class doesn't implement it; > - using with a resource managing class which requires you to call a void > connect() method or similar to actually get the resource, instead of > grabbing it in the constructor. > > Both of these would be slightly better if expressions (i.e. references to > existing variables) were allowed inside the parentheses. You can work > around > this under the existing proposal: > > AutoCloseable ac = ... ; > try (AutoCloseable acRef = ac) { ... } > > but that seems (to me) to obscure the fact that ac will be closed > afterwards > even more than if ac was listed on it's own inside the parentheses. > The tradeoff is that allowing an expression in place of a declaration ups the odds of someone accidentally accessing a resource that's already closed. I could go either way on this. Josh From reinier at zwitserloot.com Mon Mar 9 16:35:12 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 10 Mar 2009 00:35:12 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <6D206A84-27FD-4960-BF17-1FE6E28CDD32@googlemail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <99877211-46DE-4CC8-A884-4E382337EBCE@zwitserloot.com> <17b2302a0903091116u1069487an3a6665b7cf2ae70@mail.gmail.com> <15e8b9d20903091306h343d77eag5192f241b9f9f305@mail.gmail.com> <6D206A84-27FD-4960-BF17-1FE6E28CDD32@googlemail.com> Message-ID: <2A6377F4-5ABC-4337-B195-021769611149@zwitserloot.com> A general note on the issue of InputStream.close(): It's a non-issue in my book. Yes - if you've read it all, received an EOF (or otherwise read all you've ever wanted from it), and then closing it fails, then it seems logical to just ignore that exception, but: That's *never* ever happened in my entire history of java usage. If an ARM block operating on an inputstream completes normally, and the close() operation throws an exception, then that exception would not be swallowed, which seems like an 'error', so to speak, but that happens (almost) never. Not worth hacking about by offering a way to choose between swallowing an exception on close or propagating it. If an API developer thinks it makes more sense to swallow exceptions on close, he should not be declaring them as thrown them in the first place. I'm sure any redesign of InputStream would strongly consider not letting its close() method throw IOException in the first place. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 10, 2009, at 00:17, Mark Mahieu wrote: > Yuck. > > I guess one way to deal with this would be to track exceptions > 'definitely thrown' by statements, and use different translations > depending on whether there are any exceptions 'definitely' thrown by > the body. Not exactly a trivial addition to the spec though. > > Mark > > > On 9 Mar 2009, at 20:06, Neal Gafter wrote: > >> On Mon, Mar 9, 2009 at 11:16 AM, Joshua Bloch wrote: >>> This URL should always point at the latest version: >>> http://docs.google.com/Doc?id=ddv8ts74_0vnstdfdh >> >> The static exception analysis implied by the proposal's translation >> doesn't match its dynamic semantics. In the following program >> snippet, the proposal requires an error message where shown, while >> the >> dynamic semantics never allow the reported exception to occur. >> >> static BufferedReader getReader(String name) { >> // any implementation here >> } >> public static void main(String[] args) { >> { >> try (BufferedReader localVar = getReader(args[0])) { >> throw new NullPointerException(args[0]); >> } // required language error: IOException not caught >> } >> } >> > > From r.spilker at gmail.com Mon Mar 9 16:37:42 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Tue, 10 Mar 2009 00:37:42 +0100 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> Message-ID: A bit off-topic, and just out of curiosity: What is the reason the for-each cannot work on Iterators? Is it just the problem when both Iterable and Iterator are implemented, or were there other reasons as well? Roel > At this point, I think only one name will be supported (close), so the > problem goes away. We went through the same conniptions with the for-each > statement (Does it work on Iterator as well as Iterable? What happens if > you implement both?). > > From schulz at e-spirit.de Mon Mar 9 16:43:52 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Tue, 10 Mar 2009 00:43:52 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com><20090305033541.B4CF2D06B@callebaut.niobe.net><17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com><63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> Message-ID: <49B5A9B8.3030908@e-spirit.de> Vilya Harvey wrote: > I joined this mailing list too late to see the proposal when it was posted; > does it include calling any kind of setup method on entering the block? If > not, this may be worth considering as well? The current proposal only has an exit method (close()). But I quite like the idea to generalize using resources with ARM instead of splitting it into two proposals. Wouldn't it be much more useful, if one introduces a completely new interface like the following: interface ManagableResource { void acquire() throws Exception; void release() throws Exception; } Have a resource definition with an optional assignment: try ( ) { // dostuff } That translates to (simple case): $resource = ; $resource; $resource.acquire(); try { // dostuff } finally { $resource.release(); } And retrofit Streams etc. (which are classes anyway) to implement ManagableResource (having an empty acquire() and a release() forwarding to close()) and add a ManagableLock that extends Lock and ManagableResource (does not support Lock directly, but code can be refactored to ManagableLock). The try on a lock might be a bit misleading (like it is on a resource, as it does not try to get the resource), but I'd rather like to see one consistent solution than a half-hearty ARM plus some newly introduced construct re-using a modifier out of place. Such a solution would require a bit more JDK-work though. Stefan From r.spilker at gmail.com Mon Mar 9 17:17:31 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Tue, 10 Mar 2009 01:17:31 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <49B5A9B8.3030908@e-spirit.de> References: <17b2302a0903041637j77268621n483f10cabca929cc@mail.gmail.com> <20090305033541.B4CF2D06B@callebaut.niobe.net> <17b2302a0903041954i7fcb6423j4e7f779285cd53b3@mail.gmail.com> <63b4e4050903091026o23c3c177l1e9b80f6b27a68fb@mail.gmail.com> <6aef848f0903091055t43bf2c0bl299ca5c2c778e0f7@mail.gmail.com> <49B5A9B8.3030908@e-spirit.de> Message-ID: Josh, Another benefit of the AutoClosable interface is that static code analyzers, such as findbugs and Eclipse, could find AutoClosable instances that are never closed if they are used outside ARM blocks and don't escape out of the method, or if they are accessed after close has been called. SWT has an abstract class Resource that is the base class of all OS-dependent system resources, like Color, Cursor, Font, Image etc. The contract states you have to call dispose on them manually to release the resource to the OS again. It would be trivial for the SWT developers to retrofit the Resource class to implement the AutoClosable interface so the application programmer can benefit from the ARM blocks. Roel From Joe.Darcy at Sun.COM Mon Mar 9 17:21:44 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 09 Mar 2009 17:21:44 -0700 Subject: Feedback and comments on ARM proposal - resend Message-ID: <49B5B298.9050502@sun.com> There was a problem with this message getting through to the list earlier today; resending. -Joe -=-=-=- Hello. Josh, thanks for sending in a proposal which has garnered so much discussion! To begin, a handful of typos: under syntax, "Disposable" should now be "Disposable", in semantics and compilation, the desugaring of an ARM block with a Finally or Catches portion should list them not as "Finally_opt Catches_opt" but as "Catches_opt Finally_opt"; for migration, the SQL classes are in package javax.sql rather than java.sql and the relevant type names are bit different than the listed ones. Onto more substantive matters. I have some reservations about the ARM proposal. A few background thoughts, the design of Java assumes garbage collection is available as the primary resource reclamation mechanism. When your resource reclamation can map into garbage collection, things work fairly well and naturally benefit from the many ongoing engineering improvements in that area. However, that leaves resources with a block structured life cyle pattern (open files, etc.) without an elegant solution in Java today. Finalizers have serious limitations and while nested try-catch-finally blocks are possible, they are verbose and tricky to get right, as detailed in the proposal. There are a few possible solutions to managing the block structured resources: Library-based solutions: * Weak references: Reference queues to process less-than-strong references can be used to call a method after an object is no longer reachable. However, this approach shares some of the problems of finalizers, including no guarantees of prompt execution and exceptions occurring in separate thread. * Closures: If something like BGGA closures were in the platform, the tricky cleanup code could be implemented as a library wrapping around the application logic. Better still, variants of the library could be implemented tailored to the needs of different kinds of resources. Closures will certainly *not* be in JDK 7, so a closure-based solution is not an option for this release. Language-based solutions: * Destructors as in C++: Destructors in C++ rely on objects having different "storage classes," that is living on the stack versus the heap. Java has a uniform allocation model and adding storage classes would be impractical and undesirable. * New statement form: As discussed in this proposal, given a good desugaring, the tricky cleanup code could be generated by the compiler. That change doesn't fundamentally depend on any features not currently in the platform, but there are limitations in how well the desugaring fits all the use-cases of interest. While managing block structure resources surely is a problem, a language solution is at or near the limit of the size of a coin. All else being equal and given the effort that would be involved, I'd prefer a change that generally supported block-structured resources rather than "just" the IO related "Closeable" ones. I think doing this would include handling "close" methods that are not declared or expected to throw exceptions. ( If any distinct handling is done for close methods that are not expected to throw exceptions, the test would probably need to be done on the dynamic type of the Throwable so that the Liskov substitution principle was followed. Assuming a degenerate exception could indicate it did and did not have a close method that threw exceptions, the runtime treatment of such an exception should not depend on the static type of the variable referring to the exception. For example, perhaps reasonable semantics are for a Disposable resource to have a secondary exception during close added to the original exception's suppressed exception list while if "DisposableQuiet" resource gets an exception during close, the *new* exception should be propagated out with the old exception being suppressed?) Other comments interspersed. > > Automatic Resource Management > > *AUTHOR: *Joshua Bloch > > *OVERVIEW* > > FEATURE SUMMARY: A /resource/ is as an object that must be closed > manually, such as > a java.io.InputStream, OutputStream, Reader, Writer, Formatter; java.nio.Channel; java.net.socket; java.sql.Connection, Statement, ResultSet, > or java.awt.Graphics. > > [snip] > Like the for-each statement (introduced in Java 1.5), the automatic > resource management statement is a small piece of syntactic sugar with > a very high power-to-weight ratio. > The for-each statement in JDK 5 was a clear win. While there were details of the design to be debated (what interface should be accepted, etc.) the basic semantics were uncontested: starting with the first element, one by one visit the next element of the structure until reaching the end. As has been discussed on the list, the desired semantics of the ARM blocks are less clear, such as how any secondary exception should be handled. I would expect the same behavior would not be appropriate in all cases. Also as noted on the list and in the proposal itself, there is a big difference in getting an exception on closing an input stream versus an output stream. > MAJOR DISADVANTAGE: Like all syntactic sugar, this construct removes a > bit of Java's "what you see is what you get" character ("transparency"). > Another disadvantage is further coupling between the language specification and libraries. [snip] > > > *DETAILS* > > * * > > SPECIFICATION: What follows is not intended to be a formal JLS-quality > specification. It emphasizes brevity and clarity over thoroughness. > Adding in some analysis of the specification areas of concerns listed in http://blogs.sun.com/darcy/entry/so_you_want_to_change > * How does the grammar need to be revised? Understood. > * How is the type system affected? The handling of resource-ness could be considered a minor type system change. > * Are any new conversions defined? No. > * Are naming conventions or name visibility modified? Shouldn't be. > * Is the existing structure of packages, classes, or interfaces changed? No. > * How can the new feature be annotated? Yes; the resource declarations can be annotated. > * Is method resolution impacted? No; although if multiple clean-up methods are supported, "close", "flush", there will need to be rules about which ones are called if more than one is present. At present, the desugaring appears to call MyResource.close rather than Disposable.close, which seems to be the right thing to do. > * How does the change impact source compatibility? Removing resource-ness will affect code that uses that type as a resource, but removing the implementation of an interface is already source-incompatible. > * How does the change impact binary compatibility? Depending on how the desugaring is structured, removing the resource-ness of a class, but leaving the close method, may or may not impact pre-existing class files which use the class as a resource. (Removing the implementation of an interface is already binary incompatible.) > * Does the feature affect the reachability of code or the definite > assignment of variables? Yes; while the desguraring should cover this, future drafts should verify there are no complications. [snip] > > > An automatic resource management statement with multiple local > variable declarations and no /Finally/ or /Catches/ would behave as if > (recursively) replaced by the following source code: > > > > { > > final /LocalVariableDeclaration/ ; // First variable > declaration > > try( /ResourceDeclarations/ ) /Block/ finally { // Remaining > resource declarations > > /localVar/.close(); // /localVar/ is the variable declared > in /LocalVariableDeclaration/ > > } > > } > Hmm, if the resource declarations wanted to misbehave, they could prematurely call close on earlier declarations; something like: try(Resource1 resource1 = new Resource1(); Resource2 = closeAndAllocate(resource1) ) {...} static Resouce2 closeAndAllocate(Closable closeable) { try { closeable.close(); catch(Exception exception) { ; // bye-bye } return new Resource2(); } That should still mostly be okay since the second call to close is a no-op by the Closeable specification, but suppressing the exception from close could be thwarted. What other naughty things could be done to or with close methods? [snip] > > These simple semantics solve most of the problems described above, but > they leave one problem unsolved: if the /Block/ throws one exception, > and the automatically generated close invocation throws another, the > latter exception supplants the former. This could be corrected by > using a slightly more complex de-sugaring for the > single-local-variable-declaration form of the construct: > > > > { > > final LocalVariableDeclaration ; > > boolean #suppressSecondaryException = false; > > try Block catch (final Throwable #t) { > > #suppressSecondaryException = true; > > throw #t; > > } finally { > > if (#suppressSecondaryException) > > try { localVar.close(); } catch(Exception #ignore) { } > > else > > localVar.close(); > > } > > } > In this more involved desugaring that suppresses a secondary exception, a slight modification may be needed to call any new methods to add the suppressed exceptions to the primary one. Perhaps the state variable could be eliminated by a lower-level desugaring including gotos, but that is a minor implementation detail. > > > The variables #t, #suppressSecondaryException, and #ignore are > compiler-generated identifiers that are distinct from one and other, > and from any other identifiers (compiler-generated or otherwise) that > are in scope (JLS ?6.3) at the point where the automatic resource > management statement occurs. > > > This de-sugaring takes advantage of the ability to rethrow a final > caught exception, which has been proposed for Java 7. The present > proposal does /not/ depend on this ability. In its absence, one could > use a method such as sneakyThrow (/Java Puzzlers/, Puzzle 43). > Care would need to be taken to generate an appropriate line number table for debugging purposes. [snip] > > > *Retaining suppressed exceptions* - As described above, the construct > simply discards exceptions that are suppressed. It would probably be > better to attach them to the exception in whose favor they are being > suppressed. This would entail adding two new methods > to Throwable, void addSuppressedException(Throwable) and Throwable[] getSuppressedExceptions(). > Having more mutable state in a Throwable is a bit disconcerting, but I suppose necessary. An external reference to the original exception could be stashed away somewhere so creating and propagating an augmented copy of the exception with the additional suppressing information wouldn't be correct in general. > > > > *Ignoring certain **close failures* - One shortcoming of the construct > as described is that it does not provide a way for the programmer to > indicate that exceptions thrown when closing a resource should be > ignored. In the case of the copy method, ideally the program would > ignore exceptions thrown when closing the InputStream, but not > the OutputStream. There are several ways this could be achieved. > What did you have in mind here? Different disposable interfaces? Annotations on the resource type? [snip] Thinking a bit speculatively, if multi-catch and final rethrow are added, would that have any weird interactions if used with ARM blocks? In related matters, I'm working on a writeup on the "finally" variation, an alternative I don't favor, and will send it out in the next day or two. -Joe From neal at gafter.com Mon Mar 9 18:02:53 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 18:02:53 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <49B5B298.9050502@sun.com> References: <49B5B298.9050502@sun.com> Message-ID: <15e8b9d20903091802i12da0b68of2ce7600fe1a31e@mail.gmail.com> On Mon, Mar 9, 2009 at 5:21 PM, Joseph D. Darcy wrote: > Language-based solutions: > > * Destructors as in C++: Destructors in C++ rely on objects having > different "storage classes," that is living on the stack versus the > heap. ?Java has a uniform allocation model and adding storage classes > would be impractical and undesirable. The destructor model does not require allocating objects on the stack. A language change along these lines analogous to this ARM proposal would provide a new modifier on a local variable, and treat the code from the declaration point to the point where the variable goes out of scope much the same way as the ARM proposal treats the try block. From neal at gafter.com Mon Mar 9 18:44:10 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 18:44:10 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <49B5B298.9050502@sun.com> References: <49B5B298.9050502@sun.com> Message-ID: <15e8b9d20903091844j6b93e7c8tc7f943180586af75@mail.gmail.com> On Mon, Mar 9, 2009 at 5:21 PM, Joseph D. Darcy wrote: > Having more mutable state in a Throwable is a bit disconcerting, but I > suppose necessary. To address this problem, that is neither a necessary or particularly useful technique. It is not useful because using this technique to properly report or log these suppressed exceptions would be very difficult using this API. One would effectively have to add code to most catch clauses in a code base - even the ones generated by this desugaring - because any one of them may have suppressed exceptions attached. It is not necessary because a system API can be provided to define how suppressed exceptions are to be handled. Either way, though, the problem is best solved in the context of this proposal, as this proposal requires that the language itself do the exception suppression. From neal at gafter.com Mon Mar 9 18:52:18 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 18:52:18 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> Message-ID: <15e8b9d20903091852m2bf9262eya8acca04f6a49665@mail.gmail.com> The for-each construct generated less controversy or concern than the ARM construct, as the desired semantics and the desugaring are much more straightforward. Most of the discussion revolved around extending it in various ways. The trickiest part was getting the interfaces just right to allow maximal interoperability. Regarding Iterator, the Iterable/Iterator ambiguity was a concern but a minor point: we could have simply defined it as a compile-time error to use such a type in a for-each loop. We were more concerned with allowing the programmer access to the variable that's directly manipulated by compiler-generated code, possibly undermining the generated code's assumptions about the state of the Iterator. On Mon, Mar 9, 2009 at 4:37 PM, Roel Spilker wrote: > A bit off-topic, and just out of curiosity: What is the reason the for-each > cannot work on Iterators? Is it just the problem when both Iterable and > Iterator are implemented, or were there other reasons as well? > > Roel > > >> At this point, I think only one name will be supported (close), so the >> problem goes away. ?We went through the same conniptions with the for-each >> statement (Does it work on Iterator as well as Iterable? ?What happens if >> you implement both?). >> >> > > From jjb at google.com Mon Mar 9 20:13:27 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 9 Mar 2009 20:13:27 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> Message-ID: <17b2302a0903092013p1dec9c1cj1ce98d8076c9377e@mail.gmail.com> Roel, There were several reasons. The main reason was that we wanted the for-each loop to be side-effect free. Had we allowed Iterators, two consecutive for-each statements on the same Iterator would have been legal, but would have had very different semantics from two consecutive for-each statements over the same Iterable. The former would have traversed the collection once, while the latter traversed it twice. We thought this might lead to bugs. Also it allowed us to avoid the issue of what to do if the object to be iterated over implemented both Iterable and Iterator. There were people on the expert group who argued to allow Iterator, but in the end it was decided we decided that it was best not to support it. Regards, Josh On Mon, Mar 9, 2009 at 4:37 PM, Roel Spilker wrote: > A bit off-topic, and just out of curiosity: What is the reason the for-each > cannot work on Iterators? Is it just the problem when both Iterable and > Iterator are implemented, or were there other reasons as well? > > Roel > > > > At this point, I think only one name will be supported (close), so the > > problem goes away. We went through the same conniptions with the > for-each > > statement (Does it work on Iterator as well as Iterable? What happens if > > you implement both?). > > > > > > From neal at gafter.com Mon Mar 9 20:25:13 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 20:25:13 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> Message-ID: <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> On the one hand, you say On Mon, Mar 9, 2009 at 4:24 PM, Joshua Bloch wrote: > The proposed construct *was* ?designed to go beyond IO-related "Closeable" > resources. ?... ?I sincerely hope the construct works for the great > majority of block-structured resources, whether or not their > close/dispose/release/whatever method is defined to throw an exception. And then... > At this point, I think only one name will be supported (close), so the > problem goes away. You've avoided one problem by narrowing the applicability of the construct. Given your hopes (above), that is quite a drawback. From crazybob at crazybob.org Mon Mar 9 20:35:43 2009 From: crazybob at crazybob.org (Bob Lee) Date: Mon, 9 Mar 2009 20:35:43 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903091844j6b93e7c8tc7f943180586af75@mail.gmail.com> References: <49B5B298.9050502@sun.com> <15e8b9d20903091844j6b93e7c8tc7f943180586af75@mail.gmail.com> Message-ID: On Mon, Mar 9, 2009 at 6:44 PM, Neal Gafter wrote: > To address this problem, that is neither a necessary or particularly > useful technique. It is not useful because using this technique to > properly report or log these suppressed exceptions would be very > difficult using this API. One would effectively have to add code to > most catch clauses in a code base - even the ones generated by this > desugaring - because any one of them may have suppressed exceptions > attached. I can't disagree more, mostly because I don't know why you'd have to "add code to most of the catch clauses in a code base." It sounds like you're complaining about how hard it's going to be to handle this useful new information that we don't have access to at all today. As someone who has spent a long time thinking about exception handling in Java apps (from the 1.3 days: http://weblogs.java.net/blog/crazybob/archive/2004/02/exception_handl.html), I think the suppressed exception API is a brilliant general solution. Without this feature, you'd normally just log the suppressed exception. In other words, at run time you have two exceptions that you know go together, but you're forced to send them down separate paths (throw one, log one), only to have the programmer later try to re-correlate them using a server ID, timestamp and thread ID. In contrast, the suppressed exception list keeps everything tied together in a nice little package. The suppressed exceptions are logged automatically if you just print the stack trace. Or you can can handle them accordingly in your customized exception handler, but doing so will usually require a code change in only one place within your system, not every catch block. In other words, I think the suppressed exception API is both "necessary" and "particularly useful" independent of this proposal. Also, we already have a system API: java.util.logging.Handler :-) Bob From neal at gafter.com Mon Mar 9 20:54:18 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 9 Mar 2009 20:54:18 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: References: <49B5B298.9050502@sun.com> <15e8b9d20903091844j6b93e7c8tc7f943180586af75@mail.gmail.com> Message-ID: <15e8b9d20903092054u2e343dadx743fc440d21592b0@mail.gmail.com> On Mon, Mar 9, 2009 at 8:35 PM, Bob Lee wrote: > On Mon, Mar 9, 2009 at 6:44 PM, Neal Gafter wrote: >> >> To address this problem, that is neither a necessary or particularly >> useful technique. ?It is not useful because using this technique to >> properly report or log these suppressed exceptions would be very >> difficult using this API. ?One would effectively have to add code to >> most catch clauses in a code base - even the ones generated by this >> desugaring - because any one of them may have suppressed exceptions >> attached. > > I can't disagree more, mostly because I don't know why you'd have to "add > code to most of the catch clauses in a code base." It sounds like you're > complaining about how hard it's going to be to handle this useful new > information that we don't have access to at all today. No, I'm complaining about where and how the information is provided. Moreover, it only addresses a small part of the problem. Every try-finally block in which one exception propagates out of the try block and another from the finally block causes the exception from the try block to be discarded, whether the try-finally is a result of attempting to manage a true-resource-with-close, to manage a resource that doesn't quite match what this proposal supports, or for any other reason. Given the narrow applicability of the proposed construct, I would hope to see at least some attempt to address the underlying problem. From r.spilker at gmail.com Tue Mar 10 01:59:51 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Tue, 10 Mar 2009 09:59:51 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903092054u2e343dadx743fc440d21592b0@mail.gmail.com> References: <49B5B298.9050502@sun.com> <15e8b9d20903091844j6b93e7c8tc7f943180586af75@mail.gmail.com> <15e8b9d20903092054u2e343dadx743fc440d21592b0@mail.gmail.com> Message-ID: Having the addSuppressedException and getSuppressedExceptions would indeed allow java to add the Exception from the try-block to the one from the finally-block in existing code. Are you suggesting that for each try-finally block (and I mean the current ones) the programmer should have the possibility to declare if the try-exception of the finally-exception is leading, defaulting to the finally-exception? > Moreover, it only addresses a small part of the problem. Every > try-finally block in which one exception propagates out of the try > block and another from the finally block causes the exception from the > try block to be discarded, whether the try-finally is a result of > attempting to manage a true-resource-with-close, to manage a resource > that doesn't quite match what this proposal supports, or for any other > reason. Given the narrow applicability of the proposed construct, I > would hope to see at least some attempt to address the underlying > problem. > > From belingueres at gmail.com Tue Mar 10 07:01:20 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 10 Mar 2009 12:01:20 -0200 Subject: PROPOSAL: fold keyword In-Reply-To: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> References: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> Message-ID: Hi, First, thanks you for the input. The main issue I wanted to avoid was creating new objects/anonymous classes for executing the body of the loop, acting on the elements of the collection. The ideal case would be to have closures in place, but since this was not possible, using the current code in the for body was my second choice. There might be two benefits on doing it this way though, assuming the following simple example: Integer sum = 0; for (Integer n : list) sum += n;: 1) In the current way, you want to compute a unique value from the collection, but you are accumulating on the same variable unwanted values of the target result, meaning this could potentially introduce bugs if in the middle of the iteration an exception is thrown, leaving your variable with garbage. With the fold version, the resulting variable is scoped to the for loop, therefore an exception doesn't touch the final result variable. 2) In the current way, you can't assign the result to a "final" variable, which is something a programmer might want to do: final Integer sum = 0; // wrong for (Integer n : list) sum += n; so you need to introduce the code inside a new method: final Integer sum = sumAll(list); private Integer sumAll(List l) { Integer sum = 0; for(Integer x : l) sum += x; return sum; } with the fold keyword: final Integer sum = fold(Integer n : list; Integer s = 0) { s += n; } You are right in that the current for is somewhat simpler, and maybe this is all because I don't like to see "break" or "continue" in loops, but I think that the idiom would be a little more readable when you introduce the break condition in the loop. For example: sum all elements in the collection until the first prime number is found: Now: Integer sum = 0; for(Integer x: list) if (isPrimeNumber(x)) break; else sum += x; with fold: Integer sum = fold(Integer x : list; Integer s = 0; isPrimeNumber(x)) { s += x; } Regards, Gabriel 2009/3/5 Joshua Bloch : > Gabriel, > > This doesn't seem compelling. > > Here's your simple example: > > ? ? // sum all numbers in the list > ??? Integer sum = > ??? fold(Integer n : list;???? // iterating collection element n > ???????? Integer result = 0) { // Where to accumulate the result, and > ???????????? the initial value > ???????????? result += n; > ???????? }; > ??? } > > And here's how it looks today (with no change to the language or libraries): > > ??? Integer sum = 0; > ??? for (Integer n : list) > ??????? sum += n; > > > Here's one of your complex examples: > > ? // returns a new collection with the salaries of the employees not on > vacation > ?List salaries = > ? ?fold(Employee e : emps; > ? ? ? ? List newList = new ArrayList()) { > ? ? ?if (!e.onVacation()) { > ? ? ? ?newList.add(e.getSalary()); > ? ? ?} > ? ?} > > And here's how it looks today: > > ???? List salaries = new ArrayList(); > ???? for (Employee e : emps) > ???????? if (!e.onVacation()) > ???????????? salaries.add(e.getSalary()); > > To my eyes, the current version is clearer as well as shorter. > > ??????????? Josh > > > > > From tim at peierls.net Tue Mar 10 08:36:01 2009 From: tim at peierls.net (Tim Peierls) Date: Tue, 10 Mar 2009 11:36:01 -0400 Subject: Feedback and comments on ARM proposal In-Reply-To: <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> Message-ID: <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> Neal Gafter wrote: > You've avoided one problem by narrowing the applicability of the > construct. Given your hopes (above), that is quite a drawback. > That was my initial reaction to the ARM proposal, but I now think the applicability of the construct is as wide as it needs to be in practice. When Josh writes that he hopes "the construct works for the great majority of block-structured resources", I don't think he means that he expects to suddenly uncover a forgotten trove of resources with a close() method. I think he means that we want to make it easy for library writers and maintainers to provide ARM support wherever it's really needed. I believe that the current proposal achieves this goal; the coin-dev list has yet to come up with an example where ARM support is both appropriate and difficult to provide under the proposal. Speaking of appropriateness (and moving to a new topic), a common response to ARM is to be disappointed that it doesn't handle j.u.c.locks.Locks, to the point where a second, separate quasi-proposal is floating around with "protected" as a potential keyword to mark an automatic unlock() construct. I think this particular enhancement is a bad idea. Lock was added to handle some special cases that built-in synchronization doesn't support, like non-block-structured locking, and most people shouldn't use it. There's no sense in promoting a convenience construct for an interface that most people shouldn't use, a convenience that wouldn't even be useful most of the time for the few legitimate users of that interface. Getting a little OT: If you're using Lock.lock() and Lock.unlock() exclusively now, unless you are using Conditions, you might as well just use regular built-in synchronization. Your code will be easier to understand. If you're using tryLock() or lockInterruptibly() then you really do want try-finally. And even if you are using Conditions, you should use try-finally to make it easier for people to follow your code -- using Conditions correctly is hard enough without people burying details in the sugar. Moreover, apart from non-block-structured locking, which is really for experts only, I have yet to see Lock/Condition (or notify/wait, for that matter) used in a way that couldn't be improved by replacing it with a higher-level j.u.c abstraction like Semaphore, CountDownLatch, or CyclicBarrier/Phaser. --tim On Mon, Mar 9, 2009 at 11:25 PM, Neal Gafter wrote: > On the one hand, you say > > On Mon, Mar 9, 2009 at 4:24 PM, Joshua Bloch wrote: > > The proposed construct *was* designed to go beyond IO-related > "Closeable" > > resources. ... I sincerely hope the construct works for the great > > majority of block-structured resources, whether or not their > > close/dispose/release/whatever method is defined to throw an exception. > > And then... > > > At this point, I think only one name will be supported (close), so the > > problem goes away. > > You've avoided one problem by narrowing the applicability of the > construct. Given your hopes (above), that is quite a drawback. From belingueres at gmail.com Tue Mar 10 08:51:11 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 10 Mar 2009 13:51:11 -0200 Subject: PROPOSAL: fold keyword In-Reply-To: <63b4e4050903051424k5806158as698cfbf580bf6043@mail.gmail.com> References: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> <63b4e4050903051424k5806158as698cfbf580bf6043@mail.gmail.com> Message-ID: Tim thanks for the input. I apologize for taking so long to answer. I'm not specially familiar with this library, but seems like it is the concurrent equivalent to what can be done with the Apache Commons Collections. Though the method call is very readable (given the appropriate naming of the predicates and mapping), this need the extra objects and anonymous classes I wanted to avoid creating. Not that there is anything wrong with that, it is just I wanted to find a more straightforward way to do it (if there is any). Regards, Gabriel 2009/3/5 Tim Peierls : > Also check out ParallelArray, which is built on top of the ForkJoin > framework proposed for Java 7: > http://gee.cs.oswego.edu/dl/jsr166/dist/extra166ydocs/extra166y/ParallelArray.html > The simple example becomes trivial: > ?? ?long sum = parallelLongArray.sum(); > > The more complex example that Josh mentioned would look like this: > ?? ParallelArray emps = ... > > ?? // Salaries of employees not on vacation: > ?? return emps > ?? ? ? .withFilter(notPredicate(isOnVacation)) > ?? ? ? .withMapping(salaryField) > ?? ? ? .all(); > where notPredicate is a static import from CommonOps, and isOnVacation and > salaryField could be defined as: > ?? static final Predicate isOnVacation = new Predicate { > ?? ? ? public boolean op(Employee e) { return e.onVacation(); } > ?? }; > ?? static final Op salaryField = new Op BigDecimal> { > ?? ? ? public BigDecimal op(Employee e) { return e.getSalary(); } > ?? }; > These examples are likely to outperform the sequential versions on a > multiprocessor for moderately large inputs. > --tim > > On Thu, Mar 5, 2009 at 4:28 PM, Joshua Bloch wrote: >> >> Gabriel, >> >> This doesn't seem compelling. >> >> Here's your simple example: >> >> ? ?// sum all numbers in the list >> ? ?Integer sum = >> ? ?fold(Integer n : list; ? ? // iterating collection element n >> ? ? ? ? Integer result = 0) { // Where to accumulate the result, and >> ? ? ? ? ? ? the initial value >> ? ? ? ? ? ? result += n; >> ? ? ? ? }; >> ? ?} >> >> And here's how it looks today (with no change to the language or >> libraries): >> >> ? ?Integer sum = 0; >> ? ?for (Integer n : list) >> ? ? ? ?sum += n; >> >> >> Here's one of your complex examples: >> >> ?// returns a new collection with the salaries of the employees not on >> vacation >> ?List salaries = >> ? fold(Employee e : emps; >> ? ? ? ?List newList = new ArrayList()) { >> ? ? if (!e.onVacation()) { >> ? ? ? newList.add(e.getSalary()); >> ? ? } >> ? } >> >> And here's how it looks today: >> >> ? ? List salaries = new ArrayList(); >> ? ? for (Employee e : emps) >> ? ? ? ? if (!e.onVacation()) >> ? ? ? ? ? ? salaries.add(e.getSalary()); >> >> To my eyes, the current version is clearer as well as shorter. >> >> ? ? ? ? ? ?Josh >> > > From peter at retep.org.uk Tue Mar 10 08:51:31 2009 From: peter at retep.org.uk (Peter Mount) Date: Tue, 10 Mar 2009 15:51:31 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> Message-ID: <85bf933e0903100851s4e182b69w7f28d0e830a80302@mail.gmail.com> On Tue, Mar 10, 2009 at 3:36 PM, Tim Peierls wrote: > Neal Gafter wrote: > > > Speaking of appropriateness (and moving to a new topic), a common response > to ARM is to be disappointed that it doesn't handle j.u.c.locks.Locks, to > the point where a second, separate quasi-proposal is floating around with > "protected" as a potential keyword to mark an automatic unlock() > construct. I think this particular enhancement is a bad idea. I think a lot of us have agreed that ARM in it's original proposal wouldn't handle Locks, hence why there's now another proposal. I'm not certain about the use of they protected keyword although it does make more sense than try in this case. > > Lock was added to handle some special cases that built-in synchronization > doesn't support, like non-block-structured locking, and most people > shouldn't use it. There's no sense in promoting a convenience construct for > an interface that most people shouldn't use, a convenience that wouldn't > even be useful most of the time for the few legitimate users of that > interface. Do you have any references on why it shouldn't be used? > > Getting a little OT: If you're using Lock.lock() and Lock.unlock() > exclusively now, unless you are using Conditions, you might as well just > use > regular built-in synchronization. Your code will be easier to understand. > If > you're using tryLock() or lockInterruptibly() then you really do want > try-finally. And even if you are using Conditions, you should use > try-finally to make it easier for people to follow your code -- using > Conditions correctly is hard enough without people burying details in the > sugar. For a simple Lock like RentrantLock then there's not much difference between it and synchronization and I tend to use synchronization for that purpose. However what you cannot do with synchronization is RentrantReadWriteLock (i.e. multiple readers but one writer). Now as I (and others) have stated before in other threads there's many reasons why having a construct for Locks, specifically when you are dealing with a lot of copy and paste of the finally clause (I'm keeping this short as it's already in the list archives and this is a bit OT now). > > > Moreover, apart from non-block-structured locking, which is really for > experts only, I have yet to see Lock/Condition (or notify/wait, for that > matter) used in a way that couldn't be improved by replacing it with a > higher-level j.u.c abstraction like Semaphore, CountDownLatch, or > CyclicBarrier/Phaser. How about when you are providing access to multiple collections representing game state where updates to those collections have to be atomic but reads should not be blocking multiple threads on multiple cores when they are accessed? There's a lot of reasons where Locks are far superior than just synchronization and moving to them have prooved to provide a serious performance improvement in a heavily loaded multi-threaded environment. > > > --tim > > > On Mon, Mar 9, 2009 at 11:25 PM, Neal Gafter wrote: > > > On the one hand, you say > > > > On Mon, Mar 9, 2009 at 4:24 PM, Joshua Bloch wrote: > > > The proposed construct *was* designed to go beyond IO-related > > "Closeable" > > > resources. ... I sincerely hope the construct works for the great > > > majority of block-structured resources, whether or not their > > > close/dispose/release/whatever method is defined to throw an exception. > > > > And then... > > > > > At this point, I think only one name will be supported (close), so the > > > problem goes away. > > > > You've avoided one problem by narrowing the applicability of the > > construct. Given your hopes (above), that is quite a drawback. > > -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From vilya.harvey at gmail.com Tue Mar 10 09:09:18 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 10 Mar 2009 16:09:18 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes Message-ID: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> I've attached a draft of a proposal to allow classes which implement the Comparable interface to be used as operands for the relational operators. So for example if you had two Strings, a and b, you would be able to write if (a < b) { ... } instead of if (a.compareTo(b) < 0) { ... } and you could do the same with your own classes as well. Thanks in advance for any feedback, Vil. -------------- next part -------------- Proposal to allow the use of relational operators with Comparable classes. AUTHOR Vilya Harvey OVERVIEW: Feature Summary --------------- Using the results of the compareTo method can be confusing: it's easy to get the values the wrong way around. I propose allowing classes that implement the Comparable interface to be used with Java's relational operators, to help avoid this confusion. Major Advantage --------------- Clearer code. Major Disadvantage ------------------ Could create some confusion with the equality operators as == and != would still be checking for reference equality rather than using the results of the compareTo method. Would need to decide how to handle cases where Comparable objects could be unboxed to numeric values (i.e. instances of java.lang.Integer, etc.). In that situation, should you treat them as Comparable objects or should you unbox them and perform a numeric comparison? Alternatives ------------ It is currently possible to use the result of compareTo() directly and that's a well known idiom, although still prone to the occasional mistake. It is also possible to write utility methods isLessThan(), isGreaterThan(), etc. which use the results of compareTo in the same way as suggested above. The isLessThan() et al. could be added to the Comparable interface, although this would break a lot of existing code. EXAMPLES Simple Example -------------- The simplest case is where an existing class already implements the Comparable interface: String a = ... ; String b = ... ; System.out.println("Is a < b? " + (a < b)); At present, the above would have to be written as: String a = ... ; String b = ... ; System.out.println("Is a < b? " + (a.compareTo(b) < 0)); which is a bit less clear. Advanced Example ---------------- The trickier details would be around handling of nulls and unboxing of numeric objects. String a = null; String b = "hello"; if (a > b) { ... } // Throws a NullPointerException? if (b < a) { ... } // Only throws a NullPointerException if // b.compareTo(a) throws a NullPointerException? Integer c = 10; Double d = 10.1; if (c < d) { ... } // Compile error or numeric comparison? The above could be written in today's Java, with the consequences: String a = null; String b = "hello"; if (a.compareTo(b) > 0) { ... } // Throws NullPointerException. if (b.compareTo(a) < 0) { ... } // Throws NullPointerException. Integer c = 10; Double d = 10.1; if (c.compareTo(d) < 0) { ... } // Compile error. DETAILS Specification ------------- This proposal would require changing the semantics of the relational operators, to allow for the case of objects which implement the Comparable interface as the operands. In this case, it is proposed that the operators be treated as syntactic sugar for an invocation of the compareTo method of the left operand with the right operand as an argument, with the result compared to zero. The expression a OP b where OP is any one of the four relational operators (<, >, <=, >=) defined in section 15.20 of the Java Language Specification and both a & b are objects implementing the Comparable interface; should be de-sugared to a.compareTo(b) OP 0 where OP is the same relational operator as in the sugared form. In the case where both a and b are Comparable objects which can be unboxed into primitive numeric types, it is proposed that the unboxing should be given precedence. That is, the unboxing should be performed and the operator be evaluated as per it's current semantics. This will maintain the semantics of existing code. No grammar modifications are necessary for this change. Likewise no new bytecodes are needed. It can be implemented purely as a modification to the compiler. Compilation ----------- As above. Testing ------- Library Support --------------- This feature requires that classes implement the existing java.lang.Comparable interface in order to be used with the relational operators. No other library support is required. Reflective APIs --------------- No changes necessary. Other Changes ------------- None requried. Migration --------- Where existing code calls compareTo() and compares the result to 0, simply replace that with the appropriate relational operator. COMPATIBILITY Breaking Changes ---------------- No existing programs would be broken by this change, providing unboxing occurs before the comparison is performed. Existing Programs ----------------- Existing programs should be completely unaffected by this change. REFERENCES Existing Bugs ------------- URL for Prototype ----------------- From neal at gafter.com Tue Mar 10 09:18:21 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 10 Mar 2009 09:18:21 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> Message-ID: <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> On Tue, Mar 10, 2009 at 8:36 AM, Tim Peierls wrote: > the coin-dev list has yet to > come up with an example where ARM support is both appropriate and difficult > to provide under the proposal. We identified a whole pile of them. java.awt.Graphics, org.eclipse.swt.graphic.Path, java.nio.channels.FileLock, org.ietf.jgss.GSSCredential, and java.awt.image.VolatileImage to pick a few. > Getting a little OT: If you're using Lock.lock() and Lock.unlock() > exclusively now, unless you are using Conditions, you might as well just use > regular built-in synchronization. Your code will be easier to understand. Easier to understand, but unfortunately incorrect. I use Lock where fairness is required. From neal at gafter.com Tue Mar 10 09:21:16 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 10 Mar 2009 09:21:16 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> Message-ID: <15e8b9d20903100921p1c919622tc443205d9d4823e7@mail.gmail.com> This proposal is incompatible with the existing behavior of the comparison operators on the boxed value classes, particularly for Float and Double. On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey wrote: > I've attached a draft of a proposal to allow classes which implement the > Comparable interface to be used as operands for the relational operators. So > for example if you had two Strings, a and b, you would be able to write > > if (a < b) { > ? ?... > } > > instead of > > if (a.compareTo(b) < 0) { > ? ?... > } > > and you could do the same with your own classes as well. > > Thanks in advance for any feedback, > > Vil. > > > > From jeremy.manson at gmail.com Tue Mar 10 09:21:24 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 10 Mar 2009 09:21:24 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> Message-ID: <1631da7d0903100921i249d85edt11c9b22771cdc36e@mail.gmail.com> My major concerns with this is how consistent it is with the rest of the system: 1) There is no guarantee that if a < b and b < c, then a < c. This is not true in general in Java. 2) It is inconsistent to have a < b call compareTo(), but to have == not call equals(). 3) If a < b means compareTo, and a == b means reference equality, then you can't specify reasonable behavior for <= and >=. To fix this, we'd have to go back in time and have == mean object equality instead of reference equality. That would be nice, but we can't do it. Jeremy On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey wrote: > I've attached a draft of a proposal to allow classes which implement the > Comparable interface to be used as operands for the relational operators. So > for example if you had two Strings, a and b, you would be able to write > > if (a < b) { > ? ?... > } > > instead of > > if (a.compareTo(b) < 0) { > ? ?... > } > > and you could do the same with your own classes as well. > > Thanks in advance for any feedback, > > Vil. > > > > From tim at peierls.net Tue Mar 10 09:33:15 2009 From: tim at peierls.net (Tim Peierls) Date: Tue, 10 Mar 2009 12:33:15 -0400 Subject: Feedback and comments on ARM proposal In-Reply-To: <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> Message-ID: <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> On Tue, Mar 10, 2009 at 12:18 PM, Neal Gafter wrote: > On Tue, Mar 10, 2009 at 8:36 AM, Tim Peierls wrote: > > the coin-dev list has yet to > > come up with an example where ARM support is both appropriate and > difficult > > to provide under the proposal. > > We identified a whole pile of them. java.awt.Graphics, > org.eclipse.swt.graphic.Path, java.nio.channels.FileLock, > org.ietf.jgss.GSSCredential, and java.awt.image.VolatileImage to pick > a few. Even if you think that all of these are appropriate, I don't believe that it's difficult to provide adapters. > > Getting a little OT: If you're using Lock.lock() and Lock.unlock() > > exclusively now, unless you are using Conditions, you might as well just > use > > regular built-in synchronization. Your code will be easier to understand. > > Easier to understand, but unfortunately incorrect. I use Lock > where fairness is required. Yes, fairness is another thing that synchronization doesn't provide. Let me rephrase: Don't use Lock unless you really need to. Most people don't need to. We don't need a special construct for it. --tim From tim at peierls.net Tue Mar 10 09:46:04 2009 From: tim at peierls.net (Tim Peierls) Date: Tue, 10 Mar 2009 12:46:04 -0400 Subject: Feedback and comments on ARM proposal In-Reply-To: <85bf933e0903100851s4e182b69w7f28d0e830a80302@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <85bf933e0903100851s4e182b69w7f28d0e830a80302@mail.gmail.com> Message-ID: <63b4e4050903100946w49e8f4bax2426caaf63dcca33@mail.gmail.com> On Tue, Mar 10, 2009 at 11:51 AM, Peter Mount wrote: > There's no sense in promoting a convenience construct for an interface that >> most people shouldn't use, a convenience that wouldn't even be useful most >> of the time for the few legitimate users of that interface. > > > Do you have any references on why it shouldn't be used? > http://jcip.net -- see especially Chapter 5 and Section 13.4. > However what you cannot do with synchronization is ReentrantReadWriteLock >> ... > > I think most cases where many-reader-one-writer access is needed are best expressed using higher-level constructs (that might use RRWL in the plumbing). Anything else I would classify as an advanced application, where the explicit try-finally is better than implicit behavior. > Moreover, apart from non-block-structured locking, which is really >> for experts only, I have yet to see Lock/Condition (or notify/wait, for >> that matter) used in a way that couldn't be improved by replacing it with >> a higher-level j.u.c abstraction like Semaphore, CountDownLatch, >> or CyclicBarrier/Phaser. > > > How about when you are providing access to multiple collections > representing game state where updates to those collections have to be atomic > but reads should not be blocking multiple threads on multiple cores when > they are accessed? > Sounds like you want a higher-level concurrency utility. You don't want your game developer to have to work with a bunch of Locks and Conditions with a complicated pattern of use; you want them encapsulated nicely. If you can't find the right utility in j.u.c, write your own. If you can't write your own, get an expert to do it for you. My point is not that it is never appropriate to use a Lock but that Lock is geared towards experts, the people who build stuff that application-level developers use. But experts make more diverse use of Lock than is supported by the "protected" construct. > There's a lot of reasons where Locks are far superior than just > synchronization and moving to them have proved to provide a serious > performance improvement in a heavily loaded multi-threaded environment. > Lock offers features that built-in synchronization doesn't, most of which don't work well with the "protected" construct, but it's not at all clear that Lock outperforms synchronized, even under heavy contention on multiprocessor machines. --tim From tim at peierls.net Tue Mar 10 10:01:01 2009 From: tim at peierls.net (Tim Peierls) Date: Tue, 10 Mar 2009 13:01:01 -0400 Subject: PROPOSAL: fold keyword In-Reply-To: References: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> <63b4e4050903051424k5806158as698cfbf580bf6043@mail.gmail.com> Message-ID: <63b4e4050903101001j5e40d8e9h3490962f3df83018@mail.gmail.com> On Tue, Mar 10, 2009 at 11:51 AM, Gabriel Belingueres wrote: > I'm not specially familiar with this library, but seems like it is the > concurrent equivalent to what can be done with the Apache Commons > Collections. It's a bit different from Apache Commons Collections. I think of it loosely as MapReduce for an in-memory array. The big reason to use ParallelArray is that is performs very well on multiprocessors without the user having to write special code to take advantage of parallelism. Interestingly, when I first experimented with it I saw a speedup of ParallelArray over equivalent sequential code on a machine with one hyper-threaded physical processor (2 logical processors). That really surprised me. > Though the method call is very readable (given the > appropriate naming of the predicates and mapping), this need the extra > objects and anonymous classes I wanted to avoid creating. Not that > there is anything wrong with that, it is just I wanted to find a more > straightforward way to do it (if there is any). Simple sequential code is more straightforward, as Josh demonstrated. Why does creating the extra objects bother you? You're not creating those objects in the inner loop. One Predicate object can be used for gazillions of predicate tests and it takes up almost no memory. --tim From Joe.Darcy at Sun.COM Tue Mar 10 10:43:41 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 10 Mar 2009 10:43:41 -0700 Subject: PROPOSAL: fold keyword In-Reply-To: <63b4e4050903101001j5e40d8e9h3490962f3df83018@mail.gmail.com> References: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> <63b4e4050903051424k5806158as698cfbf580bf6043@mail.gmail.com> <63b4e4050903101001j5e40d8e9h3490962f3df83018@mail.gmail.com> Message-ID: <49B6A6CD.8030701@sun.com> Tim Peierls wrote: > On Tue, Mar 10, 2009 at 11:51 AM, Gabriel Belingueres >> wrote: >> > > >> I'm not specially familiar with this library, but seems like it is the >> >> > concurrent equivalent to what can be done with the Apache Commons > >> Collections. >> > > > It's a bit different from Apache Commons Collections. I think of it loosely > as MapReduce for an in-memory array. > > The big reason to use ParallelArray is that is performs very well on > multiprocessors without the user having to write special code to take > advantage of parallelism. Interestingly, when I first experimented with it I > saw a speedup of ParallelArray over equivalent sequential code on a machine > with one hyper-threaded physical processor (2 logical processors). That > really surprised me. > > > > >> Though the method call is very readable (given the >> appropriate naming of the predicates and mapping), this need the extra >> objects and anonymous classes I wanted to avoid creating. Not that >> there is anything wrong with that, it is just I wanted to find a more >> straightforward way to do it (if there is any). >> > > > Simple sequential code is more straightforward, as Josh demonstrated. > > Why does creating the extra objects bother you? You're not creating those > objects in the inner loop. One Predicate object can be used for gazillions > of predicate tests and it takes up almost no memory. > ... and even so generational garbage collectors and designed to efficiently deal with short-lived objects; additionally current VMs can quickly allocate objects first into thread-local storage areas. -Joe From belingueres at gmail.com Tue Mar 10 11:47:45 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 10 Mar 2009 16:47:45 -0200 Subject: PROPOSAL: fold keyword In-Reply-To: <63b4e4050903101001j5e40d8e9h3490962f3df83018@mail.gmail.com> References: <17b2302a0903051328g5a98b084nd49d37339a0fa642@mail.gmail.com> <63b4e4050903051424k5806158as698cfbf580bf6043@mail.gmail.com> <63b4e4050903101001j5e40d8e9h3490962f3df83018@mail.gmail.com> Message-ID: Not that it bothers me, but it is more a matter of how I could write the code: IMHO, readability is important because code is read more times than it is written, but written it right the first time is a goal we would need to point to. I mean, sugarizing some language constructions or idioms are not only about writing less code, or that the resulting code will be more readable, but I think the ultimate goal of sugarizing something is (but don't know if it is the Sun's goal too): 1) it helps to preserve the "line of thought" of the programmer (that is, not distracting him from what he wanted to do), and even better, 2) do it in a way that it reduces the probability of introducing a bug. In this case (If we follow this criteria for a moment) creating two static final objects, though efficient in run time and easy to read, I see them as a distracting activity in the process of programming that functionality. However, using a well tested library like this one would reduce the chances of introducing bugs. The simple for loop would certainly comply with 1) because all the code would be there, but it would now comply with point 2) because it does not protect us from certain kind of bugs (or side effects at least), like using the same variable for iteration to generate and accumulate a unique result and to hold that final result (like in the sum example). My goal was to find something in between. Anyway, that were my two cents. Best regards, Gabriel 2009/3/10 Tim Peierls : > On Tue, Mar 10, 2009 at 11:51 AM, Gabriel Belingueres > wrote: >> >> I'm not specially familiar with this library, but seems like it is the >> >> concurrent equivalent to what can be done with the Apache Commons >> Collections. > > It's a bit different from Apache Commons Collections. I think of it loosely > as MapReduce for an in-memory array. > The big reason to use ParallelArray is that is performs very well on > multiprocessors without the user having to write special code to take > advantage of parallelism. Interestingly, when I first experimented with it I > saw a speedup of ParallelArray over equivalent sequential code on a machine > with one hyper-threaded physical processor (2 logical processors). That > really surprised me. > >> >> Though the method call is very readable (given the >> appropriate naming of the predicates and mapping), this need the extra >> objects and anonymous classes I wanted to avoid creating. Not that >> there is anything wrong with that, it is just I wanted to find a more >> straightforward way to do it (if there is any). > > Simple sequential code is more straightforward, as Josh demonstrated. > Why does creating the extra objects bother you??You're not creating those > objects in the inner loop.?One Predicate object can be used for gazillions > of predicate tests and it takes up almost no memory. > --tim From markmahieu at googlemail.com Tue Mar 10 13:50:33 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 10 Mar 2009 20:50:33 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> Message-ID: On 10 Mar 2009, at 16:33, Tim Peierls wrote: > On Tue, Mar 10, 2009 at 12:18 PM, Neal Gafter wrote: > >> On Tue, Mar 10, 2009 at 8:36 AM, Tim Peierls wrote: >>> the coin-dev list has yet to >>> come up with an example where ARM support is both appropriate and >> difficult >>> to provide under the proposal. >> >> We identified a whole pile of them. java.awt.Graphics, >> org.eclipse.swt.graphic.Path, java.nio.channels.FileLock, >> org.ietf.jgss.GSSCredential, and java.awt.image.VolatileImage to pick >> a few. > > > Even if you think that all of these are appropriate, I don't > believe that > it's difficult to provide adapters. > I've been trying to flesh this out with real examples of adapters, and have ended up following a strangely circular path... no modifiers this time (promise!), but I'm starting to wonder whether a two- interface solution might not be such a bad idea after all, only with a twist. Taking the SWT Resource class as an example, which cannot be retrofitted with AutoCloseable due to the clash with the Path resource's close() method, one might envisage a simple adaptation to look something like: class Resource { public void dispose() { // existing SWT clean-up method } public AutoCloseable toAutoCloseable() { return new AutoClosable() { public void close() { dispose(); } }; } // etc } Which could then be used: Path path = new Path(display); try (AutoCloseable dummyVar = path.toAutoCloseable()) { path.whatever(); // etc } Apart from the awkwardness of having to declare the dummy AutoCloseable variable, this quickly shows itself to be overly simple, as soon as we add a second Resource: Path path = new Path(display); Color color = new Color(display, r, g, b); try (AutoCloseable dummyVar = path.toAutoCloseable(), dummyVar2 = color.toAutoCloseable()) { path.setForeground(color); // etc } Now we have the distinct possibility that the constructor invocation for 'color' will throw an exception, in which case 'path' will not be cleaned up. And we can't use ARM to help. We could extract interfaces for each of the Resource classes (IPath, IColor etc I'd imagine) and add toAutoCloseable() methods to each, which would return something that implements the appropriate interface + AutoCloseable. I can't imagine the SWT API designers being wildly enthusiastic about that, but the resulting value could be used with ARM: try (AutoCloseablePath path = new Path(display).toAutoCloseable()) { path.whatever(); // etc } Muted applause all around. But, what if there were an AutoCloseAdaptable interface, in addition to AutoCloseable: interface AutoCloseAdaptable { AutoCloseable toAutoCloseable(); } If ARM recognised this interface, and called the toAutoCloseable() method behind the scenes (waves hands), Resource could be made to implement AutoCloseAdaptable very simply, and we could write this: try (Path path = new Path(display)) { path.whatever(); // etc } Which is exactly what we'd want, I think. It's just a thought, but does that sound vaguely workable, or have I drunk too much coffee again? Mark From jjb at google.com Tue Mar 10 14:51:39 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 10 Mar 2009 14:51:39 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> Message-ID: <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> Hi Mark, On Tue, Mar 10, 2009 at 1:50 PM, Mark Mahieu wrote: > > >>> come up with an example where ARM support is both appropriate and > >> difficult > >>> to provide under the proposal. > >> > >> We identified a whole pile of them. java.awt.Graphics, > >> org.eclipse.swt.graphic.Path, java.nio.channels.FileLock, > >> org.ietf.jgss.GSSCredential, and java.awt.image.VolatileImage to pick > >> a few. > > > > > > Even if you think that all of these are appropriate, I don't > > believe that t's difficult to provide adapters. > > > > I've been trying to flesh this out with real examples of adapters, > and have ended up following a strangely circular path... no modifiers > this time (promise!), but I'm starting to wonder whether a two- > interface solution might not be such a bad idea after all, only with > a twist. Tim is a bigger fan of adapters than I am (for this purpose). To the best of my recollection, 3 of the 5 types above could be retrofitted to implement AutomaticallyCloseable, and I think that's a better solution where it works. > Taking the SWT Resource class as an example, which cannot be > retrofitted with AutoCloseable due to the clash with the Path > resource's close() method, one might envisage a simple adaptation to > look something like: > > > class Resource { > > public void dispose() { > // existing SWT clean-up method > } > > public AutoCloseable toAutoCloseable() { > return new AutoClosable() { > public void close() { dispose(); } > }; > } > > // etc > } > > > Which could then be used: > > > Path path = new Path(display); > try (AutoCloseable dummyVar = path.toAutoCloseable()) { > path.whatever(); > // etc > } > > > Apart from the awkwardness of having to declare the dummy > AutoCloseable variable, this quickly shows itself to be overly > simple, as soon as we add a second Resource: > > > Path path = new Path(display); > Color color = new Color(display, r, g, b); > try (AutoCloseable dummyVar = path.toAutoCloseable(), dummyVar2 = > color.toAutoCloseable()) { > path.setForeground(color); > // etc > } > > > Now we have the distinct possibility that the constructor invocation > for 'color' will throw an exception, in which case 'path' will not be > cleaned up. And we can't use ARM to help. Yep:( You can get around the problem by nesting two automatic resource management statements, but it's a but verbose for my tastes: Path path = new Path(display); try (AutoCloseable dummyVar = path.toAutoCloseable() Color color = new Color(display, r, g, b); try (AutoCloseable dummyVar2 = color.toAutoCloseable()) { path.setForeground(color); // etc } } > > We could extract interfaces for each of the Resource classes (IPath, > IColor etc I'd imagine) and add toAutoCloseable() methods to each, > which would return something that implements the appropriate > interface + AutoCloseable. I can't imagine the SWT API designers > being wildly enthusiastic about that, but the resulting value could > be used with ARM: > > > try (AutoCloseablePath path = new Path(display).toAutoCloseable()) { > path.whatever(); > // etc > } > > I agree: yuck. > > But, what if there were an AutoCloseAdaptable interface, in addition > to AutoCloseable: > > > interface AutoCloseAdaptable { > AutoCloseable toAutoCloseable(); > } > > > If ARM recognised this interface, and called the toAutoCloseable() > method behind the scenes (waves hands), Resource could be made to > implement AutoCloseAdaptable very simply, and we could write this: > > > try (Path path = new Path(display)) { > path.whatever(); > // etc > } > > > Which is exactly what we'd want, I think. This is a possibility. It still doesn't work for interfaces, but I can't imagine a class for which it doesn't work. That said, I'm not sure I prefer it to a simple two-interface proposal (AutoCloseable + AutoDisposable). I suspect that this combination would enable retrofitting of nearly every class that could benefit from the facility. I understand that it's unsatisfying, but it's simpler than the AutoCloseAdaptable approach. Thanks, Josh From markmahieu at googlemail.com Tue Mar 10 16:36:52 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 10 Mar 2009 23:36:52 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> Message-ID: <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> Hi Josh, On 10 Mar 2009, at 21:51, Joshua Bloch wrote: > Tim is a bigger fan of adapters than I am (for this purpose). To > the best of my recollection, 3 of the 5 types above could be > retrofitted to implement AutomaticallyCloseable, and I think that's > a better solution where it works. No argument there :) > > > If ARM recognised this interface, and called the toAutoCloseable() > method behind the scenes (waves hands), Resource could be made to > implement AutoCloseAdaptable very simply, and we could write this: > > > try (Path path = new Path(display)) { > path.whatever(); > // etc > } > > > Which is exactly what we'd want, I think. > > This is a possibility. It still doesn't work for interfaces, but I > can't imagine a class for which it doesn't work. That said, I'm > not sure I prefer it to a simple two-interface proposal > (AutoCloseable + AutoDisposable). I suspect that this combination > would enable retrofitting of nearly every class that could benefit > from the facility. I understand that it's unsatisfying, but it's > simpler than the AutoCloseAdaptable approach. Perhaps this does come down to how well a given variation meshes with interfaces. I mean, I pity poor Jean-Luc, who brushes his teeth before bed every night, pays his taxes on time, and prefers to expose interfaces from his APIs. Sadly, he named his disposal method 'fermer', and can't retrofit AutoCloseable or AutoDisposable onto his interfaces without breaking code downstream. So he's stuck with an adapter approach anyway, only he can't decide whether it should return an AutoCloseable or an AutoDisposable, poor guy. ;) But seriously, it probably is a minor detail. Thanks for taking the time to read through my suggestion. Regards, Mark From david at walend.net Tue Mar 10 16:38:11 2009 From: david at walend.net (David Walend) Date: Tue, 10 Mar 2009 19:38:11 -0400 Subject: Method Bodies in Interfaces -- Why Not? Message-ID: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> A lot of us spend energy dealing with the fact that we can not add methods to interfaces. We can't add methods to interfaces because everything that implements those interfaces would break. We could get around that by letting interface-defined methods have method bodies. The resulting problem is that the compiler would not be able to choose between or order method bodies with the same signature. (As I understand it, that's why interfaces can't have method bodies.) It's modestly rare for classes to inherit two interfaces that define methods with the same signature in the wild. What happens if the JLS were to relax the constraint? I imagine a few options: With multiple inheritance, if different implemented interfaces define bodies for methods with the same signature then: 1) Give the developer a compile error or 2) Inherit neither method body and force the developer to implement something himself or 3) Inherit neither method body, force the developer to implement something himself, and give him some way to access to all the inherited implementations. That would let us out of some of our more painful contortions. What are the holes in that idea? Thanks, Dave david at walend.net From rssh at gradsoft.com.ua Tue Mar 10 16:51:25 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 11 Mar 2009 01:51:25 +0200 (EET) Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> Message-ID: <0b845c7f849d61deccd649f620c41e52.squirrel@wmail.gradsoft.ua> IMHO, would have sense with addition of symbol for equality check: ('===' ?) > I've attached a draft of a proposal to allow classes which implement the > Comparable interface to be used as operands for the relational operators. > So > for example if you had two Strings, a and b, you would be able to write > > if (a < b) { > ... > } > > instead of > > if (a.compareTo(b) < 0) { > ... > } > > and you could do the same with your own classes as well. > > Thanks in advance for any feedback, > > Vil. > > From reinier at zwitserloot.com Tue Mar 10 16:54:57 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Mar 2009 00:54:57 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <0b845c7f849d61deccd649f620c41e52.squirrel@wmail.gradsoft.ua> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <0b845c7f849d61deccd649f620c41e52.squirrel@wmail.gradsoft.ua> Message-ID: In languages with both == and ===, the == is more like .equals(), and the === is more like java's ==. Making them the reverse in java is a really really bad idea. I'd far rather have a way to specify that you're on 'new mode' java, and have == imply equals, and remove object identity altogether; it's just not a relevant operation. Shove it off to a java.lang library call. That's what we did with System.arrayCopy too, and that was clearly a good idea. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 11, 2009, at 00:51, rssh at gradsoft.com.ua wrote: > > IMHO, would have sense with addition of symbol for equality check: > ('===' > ?) > > >> I've attached a draft of a proposal to allow classes which >> implement the >> Comparable interface to be used as operands for the relational >> operators. >> So >> for example if you had two Strings, a and b, you would be able to >> write >> >> if (a < b) { >> ... >> } >> >> instead of >> >> if (a.compareTo(b) < 0) { >> ... >> } >> >> and you could do the same with your own classes as well. >> >> Thanks in advance for any feedback, >> >> Vil. >> >> > > > From reinier at zwitserloot.com Tue Mar 10 16:57:52 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Mar 2009 00:57:52 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <1631da7d0903100921i249d85edt11c9b22771cdc36e@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <1631da7d0903100921i249d85edt11c9b22771cdc36e@mail.gmail.com> Message-ID: <6180302A-7503-4066-80BC-57047D7EE523@zwitserloot.com> Replies inline. --Reinier Zwitserloot On Mar 10, 2009, at 17:21, Jeremy Manson wrote: > My major concerns with this is how consistent it is with the rest of > the system: > > 1) There is no guarantee that if a < b and b < c, then a < c. This is > not true in general in Java. But Comparator's contract states you should adhere to this. HashMaps/ Sets randomly fail if you screw up the contract, too. The notion that stuff breaks if you don't adhere to contract so far hasn't been a powerful enough reason to hold java improvements back. > > > 2) It is inconsistent to have a < b call compareTo(), but to have == > not call equals(). > And yet that's exactly what happens now with Integer, Double, Float, Short, Byte, and Long. > 3) If a < b means compareTo, and a == b means reference equality, then > you can't specify reasonable behavior for <= and >=. > Sure you can. <= means: the compareTo job returns either 0 or a negative number. Don't get me wrong, the notion that '==' doesn't mean equality in java is an unfortunate brainfart I'd love to see fixed, but I see absolutely no way for this to happen in project coin's scope. There's also nothing in this proposal that would stop a future fix; in fact, it sort of sets it up. That's good. > To fix this, we'd have to go back in time and have == mean object > equality instead of reference equality. That would be nice, but we > can't do it. > That's not an argument against this particular proposal. > Jeremy > > On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey > wrote: >> I've attached a draft of a proposal to allow classes which >> implement the >> Comparable interface to be used as operands for the relational >> operators. So >> for example if you had two Strings, a and b, you would be able to >> write >> >> if (a < b) { >> ... >> } >> >> instead of >> >> if (a.compareTo(b) < 0) { >> ... >> } >> >> and you could do the same with your own classes as well. >> >> Thanks in advance for any feedback, >> >> Vil. >> >> >> >> > From rssh at gradsoft.com.ua Tue Mar 10 16:57:53 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 11 Mar 2009 01:57:53 +0200 (EET) Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <0b845c7f849d61deccd649f620c41e52.squirrel@wmail.gradsoft.ua> Message-ID: > In languages with both == and ===, the == is more like .equals(), and > the === is more like java's ==. Making them the reverse in java is a > really really bad idea. I'd far rather have a way to specify that > you're on 'new mode' java, and have == imply equals, and remove object > identity altogether; it's just not a relevant operation. Shove it off > to a java.lang library call. That's what we did with System.arrayCopy > too, and that was clearly a good idea. > This will break a lot of code. Better find better symbol :) > --Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On Mar 11, 2009, at 00:51, rssh at gradsoft.com.ua wrote: > >> >> IMHO, would have sense with addition of symbol for equality check: >> ('===' >> ?) >> >> >>> I've attached a draft of a proposal to allow classes which >>> implement the >>> Comparable interface to be used as operands for the relational >>> operators. >>> So >>> for example if you had two Strings, a and b, you would be able to >>> write >>> >>> if (a < b) { >>> ... >>> } >>> >>> instead of >>> >>> if (a.compareTo(b) < 0) { >>> ... >>> } >>> >>> and you could do the same with your own classes as well. >>> >>> Thanks in advance for any feedback, >>> >>> Vil. >>> >>> >> >> >> > > > From reinier at zwitserloot.com Tue Mar 10 17:03:53 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Mar 2009 01:03:53 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <15e8b9d20903100921p1c919622tc443205d9d4823e7@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903100921p1c919622tc443205d9d4823e7@mail.gmail.com> Message-ID: <8C5656F2-65EA-4BE3-B412-BD5AFF999763@zwitserloot.com> Reply inline --Reinier Zwitserloot On Mar 10, 2009, at 17:21, Neal Gafter wrote: > This proposal is incompatible with the existing behavior of the > comparison operators on the boxed value classes, particularly for > Float and Double. > I'll help Neal out and be a bit more verbose: Existing behaviour unboxes first, which also means that you get type promotion to make parts fit. You can do this: Float x = 10.0; Double y = 12.0; if ( x < y ) /* stuff */; but you can not call x.compareTo(y), or y.compareTo(x). (AFAIK - it would be nice if someone tests this theory. Don't have a javac available at the moment). Easily fixed in the proposal by stating: If the operation would succeed under old unboxing rules, use those. After all, there are ambiguous rules regarding == as well (if I == two autoboxed values, is it reference comparison, or an equals check)? A choice was made there too. > On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey > wrote: >> I've attached a draft of a proposal to allow classes which >> implement the >> Comparable interface to be used as operands for the relational >> operators. So >> for example if you had two Strings, a and b, you would be able to >> write >> >> if (a < b) { >> ... >> } >> >> instead of >> >> if (a.compareTo(b) < 0) { >> ... >> } >> >> and you could do the same with your own classes as well. >> >> Thanks in advance for any feedback, >> >> Vil. >> >> >> >> > From reinier at zwitserloot.com Tue Mar 10 17:04:49 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Mar 2009 01:04:49 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <0b845c7f849d61deccd649f620c41e52.squirrel@wmail.gradsoft.ua> Message-ID: <4D4682C8-7DC0-4140-9CDF-57F66D8EFCEC@zwitserloot.com> .... hence the reference to "A way to specify you're on 'new mode' java". And the idea that it's far too ambitious for Project Coin. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 11, 2009, at 00:57, rssh at gradsoft.com.ua wrote: >> In languages with both == and ===, the == is more like .equals(), and >> the === is more like java's ==. Making them the reverse in java is a >> really really bad idea. I'd far rather have a way to specify that >> you're on 'new mode' java, and have == imply equals, and remove >> object >> identity altogether; it's just not a relevant operation. Shove it off >> to a java.lang library call. That's what we did with System.arrayCopy >> too, and that was clearly a good idea. >> > > This will break a lot of code. Better find better symbol :) > > > > >> --Reinier Zwitserloot >> Like it? Tip it! >> http://tipit.to >> >> >> >> On Mar 11, 2009, at 00:51, rssh at gradsoft.com.ua wrote: >> >>> >>> IMHO, would have sense with addition of symbol for equality check: >>> ('===' >>> ?) >>> >>> >>>> I've attached a draft of a proposal to allow classes which >>>> implement the >>>> Comparable interface to be used as operands for the relational >>>> operators. >>>> So >>>> for example if you had two Strings, a and b, you would be able to >>>> write >>>> >>>> if (a < b) { >>>> ... >>>> } >>>> >>>> instead of >>>> >>>> if (a.compareTo(b) < 0) { >>>> ... >>>> } >>>> >>>> and you could do the same with your own classes as well. >>>> >>>> Thanks in advance for any feedback, >>>> >>>> Vil. >>>> >>>> >>> >>> >>> >> >> >> > > From reinier at zwitserloot.com Tue Mar 10 17:09:16 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 11 Mar 2009 01:09:16 +0100 Subject: Method Bodies in Interfaces -- Why Not? In-Reply-To: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> Message-ID: <18E3DBE6-5C77-4B98-981C-DD6AE51D043D@zwitserloot.com> Unless I'm gravely mistaken about the idea behind Project Coin, your idea isn't even remotely close to what's considered 'small' enough for project coin. I proposed relaxing interfaces just a little and allow adding static methods (that don't even inherit to avoid the pitfalls of that idea). That one is walking the line already. Not trying to cast aspersions against the idea (on the contrary, I've long considered such a system to be preferable, and many languages including Scala allow it), just saying that project coin isn't the right venue for it. --Reinier Zwitserloot On Mar 11, 2009, at 00:38, David Walend wrote: > A lot of us spend energy dealing with the fact that we can not add > methods to interfaces. We can't add methods to interfaces because > everything that implements those interfaces would break. We could get > around that by letting interface-defined methods have method bodies. > The resulting problem is that the compiler would not be able to choose > between or order method bodies with the same signature. (As I > understand it, that's why interfaces can't have method bodies.) > > It's modestly rare for classes to inherit two interfaces that define > methods with the same signature in the wild. What happens if the JLS > were to relax the constraint? > > I imagine a few options: > > With multiple inheritance, if different implemented interfaces define > bodies for methods with the same signature then: > > 1) Give the developer a compile error or > 2) Inherit neither method body and force the developer to implement > something himself or > 3) Inherit neither method body, force the developer to implement > something himself, and give him some way to access to all the > inherited > implementations. > > That would let us out of some of our more painful contortions. What > are the holes in that idea? > > Thanks, > > Dave > david at walend.net > > From vilya.harvey at gmail.com Tue Mar 10 17:19:53 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Wed, 11 Mar 2009 00:19:53 +0000 Subject: Fwd: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903101717n2ebe4ae5nf8eeb20a71bd378f@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903100921p1c919622tc443205d9d4823e7@mail.gmail.com> <6aef848f0903101717n2ebe4ae5nf8eeb20a71bd378f@mail.gmail.com> Message-ID: <6aef848f0903101719q61d8c43u82a722f1dc5d1533@mail.gmail.com> Accidentally hit reply instead of reply-all when responding to Neal. Here's the response. ---------- Forwarded message ---------- From: Vilya Harvey Date: 2009/3/11 Subject: Re: Draft proposal: allow the use of relational operators on Comparable classes To: Neal Gafter Hi Neal & thanks for the feedback. I mentioned that in the proposal as one of the problem areas & suggested giving precedence to the unboxing operation as a solution (i.e. if a type can be unboxed, unbox it and do the comparison; otherwise, call compareTo). Does that create further problems that I'm missing? I guess it would make the desugaring a bit more complex than I'd written in the proposal, for one thing. Vil. 2009/3/10 Neal Gafter This proposal is incompatible with the existing behavior of the > comparison operators on the boxed value classes, particularly for > Float and Double. > > On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey > wrote: > > I've attached a draft of a proposal to allow classes which implement the > > Comparable interface to be used as operands for the relational operators. > So > > for example if you had two Strings, a and b, you would be able to write > > > > if (a < b) { > > ... > > } > > > > instead of > > > > if (a.compareTo(b) < 0) { > > ... > > } > > > > and you could do the same with your own classes as well. > > > > Thanks in advance for any feedback, > > > > Vil. > > > > > > > > > From neal at gafter.com Tue Mar 10 17:21:28 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 10 Mar 2009 17:21:28 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <8C5656F2-65EA-4BE3-B412-BD5AFF999763@zwitserloot.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903100921p1c919622tc443205d9d4823e7@mail.gmail.com> <8C5656F2-65EA-4BE3-B412-BD5AFF999763@zwitserloot.com> Message-ID: <15e8b9d20903101721n1f17aec3l205f311b1a7c202c@mail.gmail.com> Actually, I was referring to issues like the treatment of NaN, negative zero, and the like. Given Float x1 = NaN; Float x2 = NaN; currently x1 <= x2 is false. Under this proposal it would be true. That's a breaking change. -Neal On Tue, Mar 10, 2009 at 5:03 PM, Reinier Zwitserloot wrote: > Reply inline > > ?--Reinier Zwitserloot > > > > On Mar 10, 2009, at 17:21, Neal Gafter wrote: > >> This proposal is incompatible with the existing behavior of the >> comparison operators on the boxed value classes, particularly for >> Float and Double. >> > > I'll help Neal out and be a bit more verbose: > > Existing behaviour unboxes first, which also means that you get type > promotion to make parts fit. You can do this: > > Float x = 10.0; > Double y = 12.0; > > if ( x < y ) /* stuff */; > > but you can not call x.compareTo(y), or y.compareTo(x). (AFAIK - it > would be nice if someone tests this theory. Don't have a javac > available at the moment). > > Easily fixed in the proposal by stating: If the operation would > succeed under old unboxing rules, use those. > > After all, there are ambiguous rules regarding == as well (if I == two > autoboxed values, is it reference comparison, or an equals check)? A > choice was made there too. > >> On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey >> wrote: >>> I've attached a draft of a proposal to allow classes which >>> implement the >>> Comparable interface to be used as operands for the relational >>> operators. So >>> for example if you had two Strings, a and b, you would be able to >>> write >>> >>> if (a < b) { >>> ? ?... >>> } >>> >>> instead of >>> >>> if (a.compareTo(b) < 0) { >>> ? ?... >>> } >>> >>> and you could do the same with your own classes as well. >>> >>> Thanks in advance for any feedback, >>> >>> Vil. >>> >>> >>> >>> >> > > > From rssh at gradsoft.com.ua Tue Mar 10 17:30:16 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 11 Mar 2009 02:30:16 +0200 (EET) Subject: PROPOSAL: Multiline strings In-Reply-To: <3B9FC5E6-A34F-4376-9793-6FB7168D576F@gmail.com> References: <49B3FD90.6040805@e-spirit.de> <3B9FC5E6-A34F-4376-9793-6FB7168D576F@gmail.com> Message-ID: <52b1fbeecf426219f14164bf9cbd684d.squirrel@wmail.gradsoft.ua> > > On 8 mrt 2009, at 18:17, Stefan Schulz wrote: > >> I quite liked the idea of handling newlines by adding methods to >> String, >> to overcome magic conversions. When reading back about indentation >> etc., >> I wonder, why not to apply a similar technique to get rid of >> indent-related white spaces. >> In principle possible. But when you write multiline string, you really mean string with whitespace processing by default. So, with approach of whitespace-processing method, typical programs will contains call of this method near any multiline string constant. So, information density of program with such calls will be lower then information density of analogical program without ones. I think better changes to language must increase information density of typical program, not decrease one. >> Another question on multi-line Strings I have: does it make sense to >> allow a multi-line String only having one line? If not, why not using >> the sequence double-quote plus newline as marker for multi-line >> Strings? I afraid this is question of taste. I choose """ because this is in groovy and scala; codebase of our organization are in java, groovy as main development languages, also we have some experimental parts on scala. So, """ will mean near the same in near all languages. But difference between """ and "\n is not principal: one quote is also good variant. Generally, I prefer to resolve such questing by voting; from other side reaction on my previous voting-like messages in this list was zero ;). >> >> I don't think that wrong indentation inside a String should lead to a >> compiler error, that's why methods like above would suffice IMO. All Agree, change to waring. >> the >> compiler would have to do is to automatically add (platform specific) >> line breaks. >> platform specifics line breaks principle 'Write one, run anywhere'. I think '\n' breaks and just processing next lines without removing indentation should be ok. >> Stefan >> > > From Joe.Darcy at Sun.COM Tue Mar 10 17:30:43 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 10 Mar 2009 17:30:43 -0700 Subject: Method Bodies in Interfaces -- Why Not? In-Reply-To: <18E3DBE6-5C77-4B98-981C-DD6AE51D043D@zwitserloot.com> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> <18E3DBE6-5C77-4B98-981C-DD6AE51D043D@zwitserloot.com> Message-ID: <49B70633.5010102@sun.com> Reinier Zwitserloot wrote: > Unless I'm gravely mistaken about the idea behind Project Coin, your > idea isn't even remotely close to what's considered 'small' enough for > project coin. > Correct; adding traits or true mix-ins are far out of scope for Project Coin. -Joe > I proposed relaxing interfaces just a little and allow adding static > methods (that don't even inherit to avoid the pitfalls of that idea). > That one is walking the line already. > > Not trying to cast aspersions against the idea (on the contrary, I've > long considered such a system to be preferable, and many languages > including Scala allow it), just saying that project coin isn't the > right venue for it. > > --Reinier Zwitserloot > > > > On Mar 11, 2009, at 00:38, David Walend wrote: > > >> A lot of us spend energy dealing with the fact that we can not add >> methods to interfaces. We can't add methods to interfaces because >> everything that implements those interfaces would break. We could get >> around that by letting interface-defined methods have method bodies. >> The resulting problem is that the compiler would not be able to choose >> between or order method bodies with the same signature. (As I >> understand it, that's why interfaces can't have method bodies.) >> >> It's modestly rare for classes to inherit two interfaces that define >> methods with the same signature in the wild. What happens if the JLS >> were to relax the constraint? >> >> I imagine a few options: >> >> With multiple inheritance, if different implemented interfaces define >> bodies for methods with the same signature then: >> >> 1) Give the developer a compile error or >> 2) Inherit neither method body and force the developer to implement >> something himself or >> 3) Inherit neither method body, force the developer to implement >> something himself, and give him some way to access to all the >> inherited >> implementations. >> >> That would let us out of some of our more painful contortions. What >> are the holes in that idea? >> >> Thanks, >> >> Dave >> david at walend.net >> >> >> > > > From rssh at gradsoft.com.ua Tue Mar 10 17:36:25 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 11 Mar 2009 02:36:25 +0200 (EET) Subject: Open-JDK infrastructure : is mercurial running ? In-Reply-To: <49B70633.5010102@sun.com> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> <18E3DBE6-5C77-4B98-981C-DD6AE51D043D@zwitserloot.com> <49B70633.5010102@sun.com> Message-ID: <90966f476a348d5f59b04c4127bc003b.squirrel@wmail.gradsoft.ua> Sorry, if this is wrong place to ask. Are all ok with OpenJDK infrastructure ? My attempt to clone mercurial repository failed with message: [rssh at q jdk7]$ hg fclone http://hg.openjdk.java.net/jdk7/t1 t1 abort: requirement ' -->' not supported! Are anybody can work (especially - run clone) with openjdk repository now ? From vilya.harvey at gmail.com Tue Mar 10 17:40:10 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Wed, 11 Mar 2009 00:40:10 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <8C5656F2-65EA-4BE3-B412-BD5AFF999763@zwitserloot.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903100921p1c919622tc443205d9d4823e7@mail.gmail.com> <8C5656F2-65EA-4BE3-B412-BD5AFF999763@zwitserloot.com> Message-ID: <6aef848f0903101740g255e8c9aua852e798671f00b@mail.gmail.com> Hi Reiner, Your replies to the earlier messages have said pretty much exactly what I would have said; thanks for that! Just one thing: 2009/3/11 Reinier Zwitserloot > Easily fixed in the proposal by stating: If the operation would > succeed under old unboxing rules, use those. > You'll notice I actually said just that (although not quite as clearly or succinctly) in the proposal. :-) but you can not call x.compareTo(y), or y.compareTo(x). (AFAIK - it > would be nice if someone tests this theory. Don't have a javac > available at the moment). > I tested that while writing the proposal. x.compareTo(y) fails to compile because Comparable is a generic interface: x actually implements Comparable, which requires a Float as the argument to compareTo. Likewise y implements Comparable. Cheers, Vil. From markmahieu at googlemail.com Tue Mar 10 17:42:02 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 11 Mar 2009 00:42:02 +0000 Subject: Open-JDK infrastructure : is mercurial running ? In-Reply-To: <90966f476a348d5f59b04c4127bc003b.squirrel@wmail.gradsoft.ua> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> <18E3DBE6-5C77-4B98-981C-DD6AE51D043D@zwitserloot.com> <49B70633.5010102@sun.com> <90966f476a348d5f59b04c4127bc003b.squirrel@wmail.gradsoft.ua> Message-ID: It's working for me. That should be tl with a lowercase letter 'L'. 2009/3/11 > > Sorry, if this is wrong place to ask. > > Are all ok with OpenJDK infrastructure ? > My attempt to clone mercurial repository failed with message: > > [rssh at q jdk7]$ hg fclone http://hg.openjdk.java.net/jdk7/t1 t1 > abort: requirement ' size="-5"> -->' not supported! > > Are anybody can work (especially - run clone) with openjdk repository now > ? > > > From jesse at swank.ca Tue Mar 10 19:49:47 2009 From: jesse at swank.ca (Jesse Wilson) Date: Tue, 10 Mar 2009 19:49:47 -0700 Subject: PROPOSAL: Method and Field Literals Message-ID: Rich text (preferred) here: http://docs.google.com/View?docID=dhfm3hw2_62dxg677jn Proposal: Method and Field Literals AUTHOR(S): Jesse Wilson OVERVIEW FEATURE SUMMARY: Add syntax for method and field literals. Enables compile-time checking of member references and avoids an impossible checked exception. MAJOR ADVANTAGE: The Java language neatly balances dynamic behaviour with type safety. Many Java frameworks are successful because they leverage this balance. Class literals like ArrayList.class are popular because of the powerful APIs they enable. Unfortunately methods and fields are missing literal syntax. As a consequence, code that reflects on a specific method or field is significantly more clumsy. The member must be referenced using a String, which hinders refactoring. Code that looks up specific members must cope with a checked exception that will never be thrown. Adding literals for method and fields allows the compiler to catch typos earlier. IDEs will be able to find and fix member references that were previously obscured by Strings. Finally, it reduces the amount of boilerplate code to create and use frameworks. MAJOR DISADVANTAGE: Like annotations and generics, member literals can be abused. Excessive use of reflection makes applications more difficult to maintain, and this proposal encourages reflection. The member literal syntax is easily confused with regular dereferencing syntax, which can be a source of confusion. ALTERNATIVES: Frameworks like EasyMock[1] obtain method references via invocation. Users invoke a factory method to construct a dynamic proxy, and invoke methods on that proxy to reference them. This approach is full of compromises and doesn't support fields, static methods, or final classes. One can lookup methods using an identifying annotation. This requires a possibly-unwanted layer of indirection, and it cannot be used with third-party code. One can obtain a method reference via its String name. Instead of method and field literals it may be desirable to add property support to the JDK. This proposal does not preclude that. EXAMPLES: BEFORE: Method get; Method set; try { get = List.class.getMethod("get"); set = List.class.getMethod("set", Object.class); } catch (NoSuchMethodException e) { throw new AssertionError(); } AFTER: Method get = List#get(); Method set = List#set(Object); DETAILS SPECIFICATION: The following new grammar rules are added: Expression: MethodLiteral FieldLiteral ... MethodLiteral: Typeopt # MethodName (TypeList) FieldLiteral: Typeopt # FieldName TypeList: Type [, TypeList] If the type is omitted, the literal refers to a visible member in the current scope. This may be a member of the current type, of an enclosing type, or a statically imported member. The rules for resolution are the same as those for invocation. COMPILATION: Each member reference would be replaced with a call to an internal desugaring API method. The helper method will handle runtime inheritance and visibility issues: public class A { public void main(String[] args) { Method driveMethod = Corvette#drive(Direction,Speed); Field brakeField = Corvette#brake; } } would be desugared to : public class A { public void main(String[] args) { Method driveMethod = $Internal.methodLiteral( A.class, Corvette.class, "drive", Direction.class, Speed.class); Field brakeField = $Internal.fieldLiteral(A.class, Corvette.class, "brake"); } } VISIBILITY: Unlike the java.lang.reflect() API, only visible methods may be referenced in literals. To illustrate: // file A.java public class A { public String visible; private String secret; } // file B.java { public class B { private String mine; private Field myField = B#mine; // ok private Field visibleField = A#visible; // ok private Field secretField = A#secret; // compile error, accessing a private method private Field nonexistentField = A#nonexistent; // compile error, no such field } The standard rules of visibility will apply: If you can invoke a method, you can reference it. We will leverage the compiler's existing visibility behaviour to implement this. INHERITANCE: When a literal references a member inherited from a supertype, the specific supertype method will be resolved at runtime. Although this adds additional runtime cost, it ensures that literals and invocations always have the same behaviour. For example, consider: // file Car.java public class Car { public void honk() { System.out.println("honk"); } } // file Corvette.java public class Corvette extends Car { } // file Main.java public class Main { public static void main(String[] args) { Method honk = Corvette#honk(); System.out.println(honk.getDeclaringClass()); // prints "Car" } } Now change the source code for Corvette.java to override the honk() method. Recompile only Corvette.java: // file Corvette.java public class Corvette extends Car { public void honk() { System.out.println("beep"); } } Now when we run Main.main(), it should print "Corvette" to illustrate that method resolution occurs at runtime. STATIC DISPATCH: Java method overloading uses the compile-time type of method arguments to determine which method is invoked. During desugaring, the argument method's types are replaced with the compile-time types of the target method. This ensures that a reference and invocation always refer to the same overload, even if the target method's class is recompiled. For example: Method removeMethod = List#remove(String) is desugared to: Method removeMethod = $Internal.methodLiteral( A.class, List.class, "remove", Object.class); STATIC RESOLUTION: Members must be specified fully using constant types. The following is not supported: Class argument = ... Method remove = List#remove(argument); MODIFIERS: This syntax applies equally to members with any modifier. Synthetic members are not supported. RAW TYPES: The Method and Field classes are not parameterized types. This proposal does not preclude adding type parameters to these classes. TESTING: It is necessary to test all combinations of visibility and inheritance on both fields and methods. Both success and failure cases need to be tested. LIBRARY SUPPORT: It's necessary to add internal-use static methods to do runtime method resolution. The existing APIs Class.getMethod() and Class.getDeclaredMethod() are insufficient because they do not take the caller's visibility into account. REFLECTIVE APIS: No changes to java.lang.reflect. The unreleased javac tree API will need expressions for member literals. OTHER CHANGES: None. COMPATIBILITY BREAKING CHANGES: None. EXISTING PROGRAMS: Classes that use this feature cannot be targeted to earlier JVMs. DESIGN ALTERNATIVES: It is tempting to also support constructor literals, but coming up with an intuitive syntax is difficult. Some options: #ArrayList(Collection) ArrayList#(Collection) ArrayList#new(Collection) REFERENCES [1] EasyMock: http://www.easymock.org/EasyMock2_4_Documentation.html EXISTING BUGS: From joshua.suereth at gmail.com Tue Mar 10 20:01:25 2009 From: joshua.suereth at gmail.com (Josh Suereth) Date: Tue, 10 Mar 2009 23:01:25 -0400 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: Message-ID: +1. This is a very neat and helpfull metaprogramming syntax! On Mar 10, 2009, at 10:49 PM, Jesse Wilson wrote: > Rich text (preferred) here: > http://docs.google.com/View?docID=dhfm3hw2_62dxg677jn > > Proposal: Method and Field Literals > > AUTHOR(S): > Jesse Wilson > > OVERVIEW > > FEATURE SUMMARY: > Add syntax for method and field literals. Enables compile-time > checking of member references and avoids an impossible checked > exception. > > MAJOR ADVANTAGE: > The Java language neatly balances dynamic behaviour with type safety. > Many Java frameworks are successful because they leverage this > balance. Class literals like ArrayList.class are popular because of > the powerful APIs they enable. > > Unfortunately methods and fields are missing literal syntax. As a > consequence, code that reflects on a specific method or field is > significantly more clumsy. The member must be referenced using a > String, which hinders refactoring. Code that looks up specific members > must cope with a checked exception that will never be thrown. > > Adding literals for method and fields allows the compiler to catch > typos earlier. IDEs will be able to find and fix member references > that were previously obscured by Strings. Finally, it reduces the > amount of boilerplate code to create and use frameworks. > > MAJOR DISADVANTAGE: > Like annotations and generics, member literals can be abused. > Excessive use of reflection makes applications more difficult to > maintain, and this proposal encourages reflection. > > The member literal syntax is easily confused with regular > dereferencing syntax, which can be a source of confusion. > > ALTERNATIVES: > Frameworks like EasyMock[1] obtain method references via invocation. > Users invoke a factory method to construct a dynamic proxy, and invoke > methods on that proxy to reference them. This approach is full of > compromises and doesn't support fields, static methods, or final > classes. > > One can lookup methods using an identifying annotation. This requires > a possibly-unwanted layer of indirection, and it cannot be used with > third-party code. > > One can obtain a method reference via its String name. > > Instead of method and field literals it may be desirable to add > property support to the JDK. This proposal does not preclude that. > > EXAMPLES: > > BEFORE: > Method get; > Method set; > try { > get = List.class.getMethod("get"); > set = List.class.getMethod("set", Object.class); > } catch (NoSuchMethodException e) { > throw new AssertionError(); > } > > AFTER: > Method get = List#get(); > Method set = List#set(Object); > > DETAILS > > SPECIFICATION: > The following new grammar rules are added: > > Expression: > MethodLiteral > FieldLiteral > ... > > MethodLiteral: > Typeopt # MethodName (TypeList) > > FieldLiteral: > Typeopt # FieldName > > TypeList: > Type [, TypeList] > > If the type is omitted, the literal refers to a visible member in the > current scope. This may be a member of the current type, of an > enclosing type, or a statically imported member. The rules for > resolution are the same as those for invocation. > > COMPILATION: > Each member reference would be replaced with a call to an internal > desugaring API method. The helper method will handle runtime > inheritance and visibility issues: > > public class A { > public void main(String[] args) { > Method driveMethod = Corvette#drive(Direction,Speed); > Field brakeField = Corvette#brake; > } > } > > would be desugared to : > > public class A { > public void main(String[] args) { > Method driveMethod = $Internal.methodLiteral( > A.class, Corvette.class, "drive", Direction.class, > Speed.class); > Field brakeField = $Internal.fieldLiteral(A.class, > Corvette.class, "brake"); > } > } > > VISIBILITY: > Unlike the java.lang.reflect() API, only visible methods may be > referenced in literals. To illustrate: > > // file A.java > public class A { > public String visible; > private String secret; > } > > // file B.java { > public class B { > private String mine; > private Field myField = B#mine; // ok > private Field visibleField = A#visible; // ok > private Field secretField = A#secret; // compile error, accessing a > private method > private Field nonexistentField = A#nonexistent; // compile error, no > such field > } > > The standard rules of visibility will apply: If you can invoke a > method, you can reference it. We will leverage the compiler's existing > visibility behaviour to implement this. > > INHERITANCE: > When a literal references a member inherited from a supertype, the > specific supertype method will be resolved at runtime. Although this > adds additional runtime cost, it ensures that literals and invocations > always have the same behaviour. For example, consider: > > // file Car.java > public class Car { > public void honk() { > System.out.println("honk"); > } > } > > // file Corvette.java > public class Corvette extends Car { > } > > // file Main.java > public class Main { > public static void main(String[] args) { > Method honk = Corvette#honk(); > System.out.println(honk.getDeclaringClass()); // prints "Car" > } > } > > Now change the source code for Corvette.java to override the honk() > method. Recompile only Corvette.java: > > // file Corvette.java > public class Corvette extends Car { > public void honk() { > System.out.println("beep"); > } > } > > Now when we run Main.main(), it should print "Corvette" to illustrate > that method resolution occurs at runtime. > > STATIC DISPATCH: > Java method overloading uses the compile-time type of method arguments > to determine which method is invoked. During desugaring, the argument > method's types are replaced with the compile-time types of the target > method. This ensures that a reference and invocation always refer to > the same overload, even if the target method's class is recompiled. > For example: > Method removeMethod = List#remove(String) > is desugared to: > Method removeMethod = $Internal.methodLiteral( > A.class, List.class, "remove", Object.class); > > > STATIC RESOLUTION: > Members must be specified fully using constant types. The following is > not supported: > Class argument = ... > Method remove = List#remove(argument); > > MODIFIERS: > This syntax applies equally to members with any modifier. Synthetic > members are not supported. > > RAW TYPES: > The Method and Field classes are not parameterized types. This > proposal does not preclude adding type parameters to these classes. > > TESTING: > It is necessary to test all combinations of visibility and inheritance > on both fields and methods. Both success and failure cases need to be > tested. > > LIBRARY SUPPORT: > It's necessary to add internal-use static methods to do runtime method > resolution. The existing APIs Class.getMethod() and > Class.getDeclaredMethod() are insufficient because they do not take > the caller's visibility into account. > > REFLECTIVE APIS: > No changes to java.lang.reflect. The unreleased javac tree API will > need expressions for member literals. > > OTHER CHANGES: > None. > > COMPATIBILITY > > BREAKING CHANGES: > None. > > EXISTING PROGRAMS: > Classes that use this feature cannot be targeted to earlier JVMs. > > DESIGN ALTERNATIVES: > It is tempting to also support constructor literals, but coming up > with an intuitive syntax is difficult. Some options: > #ArrayList(Collection) > ArrayList#(Collection) > ArrayList#new(Collection) > > REFERENCES > [1] EasyMock: http://www.easymock.org/EasyMock2_4_Documentation.html > > EXISTING BUGS: > From neal at gafter.com Tue Mar 10 20:48:57 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 10 Mar 2009 20:48:57 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: Message-ID: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> This seems like a fairly simple change for a longstanding pain point. Besides moving errors from runtime to compile-time, I expect IDEs will start offering autocompletion. I have one small concern regarding the lookup rules for the name before the "#". I would expect the name before the "#" to be resolved the same way as the name before a "." in a normal method invocation: first look for a variable and then a type. But this proposal resolves it only as a type. Therefore, one could construct a puzzler where A#f() finds one method but invoking A.f() invokes another. The same puzzler could turn into a language wart if we ever generalize this to method references compatible with closures (see Stephen Colebourne's FCM proposal). Addressing this is easy: do the lookup the same way as it is done for normal overload resolution with ".", but require an error if the qualifier is not a type. As a practical matter, naming conventions would make it hard to tell the difference, but the result is one less puzzler in the language. -Neal On Tue, Mar 10, 2009 at 7:49 PM, Jesse Wilson wrote: > Rich text (preferred) here: > http://docs.google.com/View?docID=dhfm3hw2_62dxg677jn > > Proposal: Method and Field Literals > > AUTHOR(S): > Jesse Wilson > > OVERVIEW > > FEATURE SUMMARY: > Add syntax for method and field literals. Enables compile-time > checking of member references and avoids an impossible checked > exception. > > MAJOR ADVANTAGE: > The Java language neatly balances dynamic behaviour with type safety. > Many Java frameworks are successful because they leverage this > balance. Class literals like ArrayList.class are popular because of > the powerful APIs they enable. > > Unfortunately methods and fields are missing literal syntax. As a > consequence, code that reflects on a specific method or field is > significantly more clumsy. The member must be referenced using a > String, which hinders refactoring. Code that looks up specific members > must cope with a checked exception that will never be thrown. > > Adding literals for method and fields allows the compiler to catch > typos earlier. IDEs will be able to find and fix member references > that were previously obscured by Strings. Finally, it reduces the > amount of boilerplate code to create and use frameworks. > > MAJOR DISADVANTAGE: > Like annotations and generics, member literals can be abused. > Excessive use of reflection makes applications more difficult to > maintain, and this proposal encourages reflection. > > The member literal syntax is easily confused with regular > dereferencing syntax, which can be a source of confusion. > > ALTERNATIVES: > Frameworks like EasyMock[1] obtain method references via invocation. > Users invoke a factory method to construct a dynamic proxy, and invoke > methods on that proxy to reference them. This approach is full of > compromises and doesn't support fields, static methods, or final > classes. > > One can lookup methods using an identifying annotation. This requires > a possibly-unwanted layer of indirection, and it cannot be used with > third-party code. > > One can obtain a method reference via its String name. > > Instead of method and field literals it may be desirable to add > property support to the JDK. This proposal does not preclude that. > > EXAMPLES: > > BEFORE: > Method get; > Method set; > try { > get = List.class.getMethod("get"); > set = List.class.getMethod("set", Object.class); > } catch (NoSuchMethodException e) { > throw new AssertionError(); > } > > AFTER: > Method get = List#get(); > Method set = List#set(Object); > > DETAILS > > SPECIFICATION: > The following new grammar rules are added: > > Expression: > MethodLiteral > FieldLiteral > ... > > MethodLiteral: > Typeopt # MethodName (TypeList) > > FieldLiteral: > Typeopt # FieldName > > TypeList: > Type [, TypeList] > > If the type is omitted, the literal refers to a visible member in the > current scope. This may be a member of the current type, of an > enclosing type, or a statically imported member. The rules for > resolution are the same as those for invocation. > > COMPILATION: > Each member reference would be replaced with a call to an internal > desugaring API method. The helper method will handle runtime > inheritance and visibility issues: > > public class A { > public void main(String[] args) { > Method driveMethod = Corvette#drive(Direction,Speed); > Field brakeField = Corvette#brake; > } > } > > would be desugared to : > > public class A { > public void main(String[] args) { > Method driveMethod = $Internal.methodLiteral( > A.class, Corvette.class, "drive", Direction.class, Speed.class); > Field brakeField = $Internal.fieldLiteral(A.class, Corvette.class, > "brake"); > } > } > > VISIBILITY: > Unlike the java.lang.reflect() API, only visible methods may be > referenced in literals. To illustrate: > > // file A.java > public class A { > public String visible; > private String secret; > } > > // file B.java { > public class B { > private String mine; > private Field myField = B#mine; // ok > private Field visibleField = A#visible; // ok > private Field secretField = A#secret; // compile error, accessing a > private method > private Field nonexistentField = A#nonexistent; // compile error, no > such field > } > > The standard rules of visibility will apply: If you can invoke a > method, you can reference it. We will leverage the compiler's existing > visibility behaviour to implement this. > > INHERITANCE: > When a literal references a member inherited from a supertype, the > specific supertype method will be resolved at runtime. Although this > adds additional runtime cost, it ensures that literals and invocations > always have the same behaviour. For example, consider: > > // file Car.java > public class Car { > public void honk() { > System.out.println("honk"); > } > } > > // file Corvette.java > public class Corvette extends Car { > } > > // file Main.java > public class Main { > public static void main(String[] args) { > Method honk = Corvette#honk(); > System.out.println(honk.getDeclaringClass()); // prints "Car" > } > } > > Now change the source code for Corvette.java to override the honk() > method. Recompile only Corvette.java: > > // file Corvette.java > public class Corvette extends Car { > public void honk() { > System.out.println("beep"); > } > } > > Now when we run Main.main(), it should print "Corvette" to illustrate > that method resolution occurs at runtime. > > STATIC DISPATCH: > Java method overloading uses the compile-time type of method arguments > to determine which method is invoked. During desugaring, the argument > method's types are replaced with the compile-time types of the target > method. This ensures that a reference and invocation always refer to > the same overload, even if the target method's class is recompiled. > For example: > Method removeMethod = List#remove(String) > is desugared to: > Method removeMethod = $Internal.methodLiteral( > A.class, List.class, "remove", Object.class); > > > STATIC RESOLUTION: > Members must be specified fully using constant types. The following is > not supported: > Class argument = ... > Method remove = List#remove(argument); > > MODIFIERS: > This syntax applies equally to members with any modifier. Synthetic > members are not supported. > > RAW TYPES: > The Method and Field classes are not parameterized types. This > proposal does not preclude adding type parameters to these classes. > > TESTING: > It is necessary to test all combinations of visibility and inheritance > on both fields and methods. Both success and failure cases need to be > tested. > > LIBRARY SUPPORT: > It's necessary to add internal-use static methods to do runtime method > resolution. The existing APIs Class.getMethod() and > Class.getDeclaredMethod() are insufficient because they do not take > the caller's visibility into account. > > REFLECTIVE APIS: > No changes to java.lang.reflect. The unreleased javac tree API will > need expressions for member literals. > > OTHER CHANGES: > None. > > COMPATIBILITY > > BREAKING CHANGES: > None. > > EXISTING PROGRAMS: > Classes that use this feature cannot be targeted to earlier JVMs. > > DESIGN ALTERNATIVES: > It is tempting to also support constructor literals, but coming up > with an intuitive syntax is difficult. Some options: > #ArrayList(Collection) > ArrayList#(Collection) > ArrayList#new(Collection) > > REFERENCES > [1] EasyMock: http://www.easymock.org/EasyMock2_4_Documentation.html > > EXISTING BUGS: > > From forax at univ-mlv.fr Tue Mar 10 22:54:32 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Wed, 11 Mar 2009 06:54:32 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> References: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> Message-ID: <49B75218.40303@univ-mlv.fr> Neal Gafter a ?crit : > This seems like a fairly simple change for a longstanding pain point. > Besides moving errors from runtime to compile-time, I expect IDEs will start > offering autocompletion. > > I have one small concern regarding the lookup rules for the name before the > "#". I would expect the name before the "#" to be resolved the same way as > the name before a "." in a normal method invocation: first look for a > variable and then a type. But this proposal resolves it only as a type. > Therefore, one could construct a puzzler where A#f() finds one method but > invoking A.f() invokes another. The same puzzler could turn into a language > wart if we ever generalize this to method references compatible with > closures (see Stephen Colebourne's FCM proposal). Addressing this is easy: > do the lookup the same way as it is done for normal overload resolution with > ".", but require an error if the qualifier is not a type. As a practical > matter, naming conventions would make it hard to tell the difference, but > the result is one less puzzler in the language. > > -Neal > The major pain point of this proposal is, in my opinion, to have a concensus on the type of field#fieldame and type#methodName(). The proposal uses java.lang.reflect.Field and java.lang.reflect.Method, I would prefer java.lang.reflect.Property and java.dyn.MethodHandle. (with java.lang.reflect.Property a pair of method handles (getter/setter)). R?mi > On Tue, Mar 10, 2009 at 7:49 PM, Jesse Wilson wrote: > > >> Rich text (preferred) here: >> http://docs.google.com/View?docID=dhfm3hw2_62dxg677jn >> >> Proposal: Method and Field Literals >> >> AUTHOR(S): >> Jesse Wilson >> >> OVERVIEW >> >> FEATURE SUMMARY: >> Add syntax for method and field literals. Enables compile-time >> checking of member references and avoids an impossible checked >> exception. >> >> MAJOR ADVANTAGE: >> The Java language neatly balances dynamic behaviour with type safety. >> Many Java frameworks are successful because they leverage this >> balance. Class literals like ArrayList.class are popular because of >> the powerful APIs they enable. >> >> Unfortunately methods and fields are missing literal syntax. As a >> consequence, code that reflects on a specific method or field is >> significantly more clumsy. The member must be referenced using a >> String, which hinders refactoring. Code that looks up specific members >> must cope with a checked exception that will never be thrown. >> >> Adding literals for method and fields allows the compiler to catch >> typos earlier. IDEs will be able to find and fix member references >> that were previously obscured by Strings. Finally, it reduces the >> amount of boilerplate code to create and use frameworks. >> >> MAJOR DISADVANTAGE: >> Like annotations and generics, member literals can be abused. >> Excessive use of reflection makes applications more difficult to >> maintain, and this proposal encourages reflection. >> >> The member literal syntax is easily confused with regular >> dereferencing syntax, which can be a source of confusion. >> >> ALTERNATIVES: >> Frameworks like EasyMock[1] obtain method references via invocation. >> Users invoke a factory method to construct a dynamic proxy, and invoke >> methods on that proxy to reference them. This approach is full of >> compromises and doesn't support fields, static methods, or final >> classes. >> >> One can lookup methods using an identifying annotation. This requires >> a possibly-unwanted layer of indirection, and it cannot be used with >> third-party code. >> >> One can obtain a method reference via its String name. >> >> Instead of method and field literals it may be desirable to add >> property support to the JDK. This proposal does not preclude that. >> >> EXAMPLES: >> >> BEFORE: >> Method get; >> Method set; >> try { >> get = List.class.getMethod("get"); >> set = List.class.getMethod("set", Object.class); >> } catch (NoSuchMethodException e) { >> throw new AssertionError(); >> } >> >> AFTER: >> Method get = List#get(); >> Method set = List#set(Object); >> >> DETAILS >> >> SPECIFICATION: >> The following new grammar rules are added: >> >> Expression: >> MethodLiteral >> FieldLiteral >> ... >> >> MethodLiteral: >> Typeopt # MethodName (TypeList) >> >> FieldLiteral: >> Typeopt # FieldName >> >> TypeList: >> Type [, TypeList] >> >> If the type is omitted, the literal refers to a visible member in the >> current scope. This may be a member of the current type, of an >> enclosing type, or a statically imported member. The rules for >> resolution are the same as those for invocation. >> >> COMPILATION: >> Each member reference would be replaced with a call to an internal >> desugaring API method. The helper method will handle runtime >> inheritance and visibility issues: >> >> public class A { >> public void main(String[] args) { >> Method driveMethod = Corvette#drive(Direction,Speed); >> Field brakeField = Corvette#brake; >> } >> } >> >> would be desugared to : >> >> public class A { >> public void main(String[] args) { >> Method driveMethod = $Internal.methodLiteral( >> A.class, Corvette.class, "drive", Direction.class, Speed.class); >> Field brakeField = $Internal.fieldLiteral(A.class, Corvette.class, >> "brake"); >> } >> } >> >> VISIBILITY: >> Unlike the java.lang.reflect() API, only visible methods may be >> referenced in literals. To illustrate: >> >> // file A.java >> public class A { >> public String visible; >> private String secret; >> } >> >> // file B.java { >> public class B { >> private String mine; >> private Field myField = B#mine; // ok >> private Field visibleField = A#visible; // ok >> private Field secretField = A#secret; // compile error, accessing a >> private method >> private Field nonexistentField = A#nonexistent; // compile error, no >> such field >> } >> >> The standard rules of visibility will apply: If you can invoke a >> method, you can reference it. We will leverage the compiler's existing >> visibility behaviour to implement this. >> >> INHERITANCE: >> When a literal references a member inherited from a supertype, the >> specific supertype method will be resolved at runtime. Although this >> adds additional runtime cost, it ensures that literals and invocations >> always have the same behaviour. For example, consider: >> >> // file Car.java >> public class Car { >> public void honk() { >> System.out.println("honk"); >> } >> } >> >> // file Corvette.java >> public class Corvette extends Car { >> } >> >> // file Main.java >> public class Main { >> public static void main(String[] args) { >> Method honk = Corvette#honk(); >> System.out.println(honk.getDeclaringClass()); // prints "Car" >> } >> } >> >> Now change the source code for Corvette.java to override the honk() >> method. Recompile only Corvette.java: >> >> // file Corvette.java >> public class Corvette extends Car { >> public void honk() { >> System.out.println("beep"); >> } >> } >> >> Now when we run Main.main(), it should print "Corvette" to illustrate >> that method resolution occurs at runtime. >> >> STATIC DISPATCH: >> Java method overloading uses the compile-time type of method arguments >> to determine which method is invoked. During desugaring, the argument >> method's types are replaced with the compile-time types of the target >> method. This ensures that a reference and invocation always refer to >> the same overload, even if the target method's class is recompiled. >> For example: >> Method removeMethod = List#remove(String) >> is desugared to: >> Method removeMethod = $Internal.methodLiteral( >> A.class, List.class, "remove", Object.class); >> >> >> STATIC RESOLUTION: >> Members must be specified fully using constant types. The following is >> not supported: >> Class argument = ... >> Method remove = List#remove(argument); >> >> MODIFIERS: >> This syntax applies equally to members with any modifier. Synthetic >> members are not supported. >> >> RAW TYPES: >> The Method and Field classes are not parameterized types. This >> proposal does not preclude adding type parameters to these classes. >> >> TESTING: >> It is necessary to test all combinations of visibility and inheritance >> on both fields and methods. Both success and failure cases need to be >> tested. >> >> LIBRARY SUPPORT: >> It's necessary to add internal-use static methods to do runtime method >> resolution. The existing APIs Class.getMethod() and >> Class.getDeclaredMethod() are insufficient because they do not take >> the caller's visibility into account. >> >> REFLECTIVE APIS: >> No changes to java.lang.reflect. The unreleased javac tree API will >> need expressions for member literals. >> >> OTHER CHANGES: >> None. >> >> COMPATIBILITY >> >> BREAKING CHANGES: >> None. >> >> EXISTING PROGRAMS: >> Classes that use this feature cannot be targeted to earlier JVMs. >> >> DESIGN ALTERNATIVES: >> It is tempting to also support constructor literals, but coming up >> with an intuitive syntax is difficult. Some options: >> #ArrayList(Collection) >> ArrayList#(Collection) >> ArrayList#new(Collection) >> >> REFERENCES >> [1] EasyMock: http://www.easymock.org/EasyMock2_4_Documentation.html >> >> EXISTING BUGS: >> >> >> > > From rssh at gradsoft.com.ua Wed Mar 11 00:02:30 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 11 Mar 2009 09:02:30 +0200 (EET) Subject: Open-JDK infrastructure : is mercurial running ? In-Reply-To: References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> <18E3DBE6-5C77-4B98-981C-DD6AE51D043D@zwitserloot.com> <49B70633.5010102@sun.com> <90966f476a348d5f59b04c4127bc003b.squirrel@wmail.gradsoft.ua> Message-ID: <5c433817e2574a2abd9b336056a075df.squirrel@wmail.gradsoft.ua> > It's working for me. > That should be tl with a lowercase letter 'L'. > really. Thanks ! > > 2009/3/11 > >> >> Sorry, if this is wrong place to ask. >> >> Are all ok with OpenJDK infrastructure ? >> My attempt to clone mercurial repository failed with message: >> >> [rssh at q jdk7]$ hg fclone http://hg.openjdk.java.net/jdk7/t1 t1 >> abort: requirement '> size="-5"> -->' not supported! >> >> Are anybody can work (especially - run clone) with openjdk repository >> now >> ? >> >> >> > From brucechapman at paradise.net.nz Wed Mar 11 00:07:23 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Wed, 11 Mar 2009 20:07:23 +1300 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B75218.40303@univ-mlv.fr> References: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> <49B75218.40303@univ-mlv.fr> Message-ID: <49B7632B.3020301@paradise.net.nz> R?mi Forax wrote: > The major pain point of this proposal is, in my opinion, to have a concensus > on the type of field#fieldame and type#methodName(). > > The proposal uses java.lang.reflect.Field and java.lang.reflect.Method, > I would prefer java.lang.reflect.Property and java.dyn.MethodHandle. > (with java.lang.reflect.Property a pair of method handles (getter/setter)). > > R?mi > > But if the runtime type of type#name was a Property consisting of 2 MethodHandles then it is no longer a field literal is it? There would be no way to represent an actual field. And if you try to model a property, is the compiler going to attempt to find a BeanInfo and determine the getter setter method for the named property that way, or just take some shortcuts? If it does ask the BeanInfo (as it should) how will it do that if the BeanInfo exists only in source form (until the current compilation completes)? Bruce From jesse at swank.ca Wed Mar 11 00:26:32 2009 From: jesse at swank.ca (Jesse Wilson) Date: Wed, 11 Mar 2009 00:26:32 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B75218.40303@univ-mlv.fr> References: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> <49B75218.40303@univ-mlv.fr> Message-ID: On Tue, Mar 10, 2009 at 10:54 PM, R?mi Forax wrote: > The major pain point of this proposal is, in my opinion, to have a concensus > on the type of field#fieldame and type#methodName(). The hash symbol is already used in Javadoc for method and fields, so we shouldn't apply it to something else. > The proposal uses java.lang.reflect.Field and java.lang.reflect.Method, > I would prefer java.lang.reflect.Property and java.dyn.MethodHandle. > (with java.lang.reflect.Property a pair of method handles (getter/setter)). I'd prefer to limit the scope of this proposal to method and field literals. This proposal doesn't include properties, but it doesn't prevent them either. If you'd like to submit a competing properties proposal, that's fine by me. From pdoubleya at gmail.com Wed Mar 11 00:44:07 2009 From: pdoubleya at gmail.com (Patrick Wright) Date: Wed, 11 Mar 2009 08:44:07 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> <49B75218.40303@univ-mlv.fr> Message-ID: <64efa1ba0903110044h58476acbu4db5704b8b320190@mail.gmail.com> >> The proposal uses java.lang.reflect.Field and java.lang.reflect.Method, >> I would prefer java.lang.reflect.Property and java.dyn.MethodHandle. >> (with java.lang.reflect.Property a pair of method handles (getter/setter)). > I agree that MethodHandle[1] may well be a better option. As far as I understand the MH and related work (for the InvokeDynamic JSR), invocation through a MethodHandle should be much faster than via Method and standard reflection. Personally, I find # a little ugly. I realize this is used within JavaDoc, but I personally don't read a lot of raw JD so am not used to it. I don't have an alternative to suggest but I hope someone else does :). Patrick 1- http://blogs.sun.com/jrose/entry/method_handles_in_a_nutshell, among other docs, try googling From schulz at e-Spirit.de Wed Mar 11 00:54:28 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Wed, 11 Mar 2009 08:54:28 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC105DF2C0@osiris2.e-spirit.de> Surprisingly, I wholeheartly support this proposal (not that it would matter to anyone ;)). A question and a remark: 1. In the original idea, you said it would be great to support chained references. Wonder, if this could be somehow done. Especially, if using references for properties, having some A#foo#bar resolving to typeOfField(A#foo)#bar would be nice. As for the compiler (not knowing too much of it), wouldn't this only require some one-token-lookahead to not turn A#foo into the corresponding Field but to fetch it's type? 2. For Field, parameterization seems simple, although one could think of a subtype or wrapper of a Field being returned by a literal. Except for its return type, I cannot see a simple solution for Method, though, without employing some method or function type (which clearly is out of scope for coin). Stefan P.S.: You could have cited FCM btw. for some examples etc., as it is quite identical. It also contains the constructor stuff, which would be an intersting addition only, if one could pass it around. Otherwise, one would need to reference the concrete class for a constructor anyway. > -----Original Message----- > From: coin-dev-bounces at openjdk.java.net > [mailto:coin-dev-bounces at openjdk.java.net] On Behalf Of Jesse Wilson > Sent: Wednesday, March 11, 2009 3:50 AM > To: coin-dev at openjdk.java.net > Subject: PROPOSAL: Method and Field Literals From r.spilker at gmail.com Wed Mar 11 02:36:07 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Wed, 11 Mar 2009 10:36:07 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> <49B75218.40303@univ-mlv.fr> Message-ID: I think we SHOULD use the hash symbol, BECAUSE it is already used in Javadoc. The hash symbol is already used in Javadoc for method and fields, so > we shouldn't apply it to something else. > > From markmahieu at googlemail.com Wed Mar 11 03:21:59 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 11 Mar 2009 10:21:59 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <15e8b9d20903102048q45636338q43ed9092d585debd@mail.gmail.com> <49B75218.40303@univ-mlv.fr> Message-ID: Yes, as I recall the reaction to the use of '#' was very positive when it was suggested by FCM, and later adopted by BGGA. I certainly don't remember there being very many complaints about it. MethodHandles may well deserve syntactic support from the language, but if so there are other choices which don't already have precedent in Java. Mark 2009/3/11 Roel Spilker > I think we SHOULD use the hash symbol, BECAUSE it is already used in > Javadoc. > > The hash symbol is already used in Javadoc for method and fields, so > > we shouldn't apply it to something else. > > > > > > From scolebourne at joda.org Wed Mar 11 06:11:09 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 11 Mar 2009 13:11:09 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: Message-ID: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> I have thought for some time that this is one of the least controversial parts of FCM (http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc , which really should be referenced). My take on the comments so far: - Constructor literals have to be included. If you don't then developers will find it an unexplained gap. See FCM section 2.2 which uses Type#(argTypes) - I agree with Neal, in that the LHS should be a standard LHS. - I would use Field/Method/Constructor, as a key goal is to enable integration with existing frameworks. - I don't find MethodHandle especially compelling, as it feels too low level. It would also differ from the use of Field/Constructor. I assume that Method will be retrofitted with a way to get a MethodHandle. - I believe that adding generics to Field and Method (the return type) is a key part of this change. - One area that needs to be added to the spec is to allow member literals in annotations. Currently, annotations are defined to only accept a limited subset of types that are known to be safe and immutable. There is a use case for frameworks to link to methods and fields from annotations (currently it is done using strings). The problem is that Field/Method/Constructor are not immutable. However, it has been suggested to me previously that a clone can be returned each time from the annotation. - Properties are out of scope. Properties are (currently) a pair of get/set methods. As there is no language support for that, it doesn't fit the model being used here. I personally think that Java would be vastly better off with properties, but they would need to be very deeply integrated, and thats not currently on the agenda Finally, it must be noted that adopting this approach to member literals implies the equivalent of boxing should you want to support FCM method references or BGGA eta expansions (same concept and syntax, but different name). There is a way avoid the boxing, by using a double hash: String##substring(int). Thus, it could be argued that both member literals and method references should be designed together (and implemented together) to ensure a consistent design. Unfortunately, this leads on to the vexed question of BGGA function types which Coin cannot address. In summary, the real question with the proposal is whether we can implement member literals independently of method references and closures? The answer is definitely yes if we use the ## syntax, and probably yes if we use #. BTW, I do think that member literals are exactly the kind of change Java needs, as they remove a very painful use of strings and exceptions today. See http://incubator.apache.org/click/docs/why-click.html (section 3) for an example of strings for method names in use today. In all the FCM feedback, method literals and references have been clearly popular. Stephen 2009/3/11 Jesse Wilson : > Rich text (preferred) here: > http://docs.google.com/View?docID=dhfm3hw2_62dxg677jn > > Proposal: Method and Field Literals > > AUTHOR(S): > Jesse Wilson From kevinb at google.com Wed Mar 11 08:55:09 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Wed, 11 Mar 2009 08:55:09 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> Message-ID: <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com> On Wed, Mar 11, 2009 at 6:11 AM, Stephen Colebourne wrote: > - Constructor literals have to be included. If you don't then > developers will find it an unexplained gap. See FCM section 2.2 which > uses Type#(argTypes) Yes, and the worst case scenario is to mimic the Javadoc syntax: ArrayList#ArrayList(int). > - I would use Field/Method/Constructor, as a key goal is to enable > integration with existing frameworks. Absolutely positively. > - I believe that adding generics to Field and Method (the return type) > is a key part of this change. Is it possible to keep that API change and this language change orthogonal? -- Kevin Bourrillion @ Google internal: http://go/javalibraries google-collections.googlecode.com google-guice.googlecode.com From misterm at gmail.com Wed Mar 11 08:57:40 2009 From: misterm at gmail.com (Michael Nascimento) Date: Wed, 11 Mar 2009 12:57:40 -0300 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com> Message-ID: <389b9d740903110857t45fc1e7aje00e4fe296869227@mail.gmail.com> On Wed, Mar 11, 2009 at 12:55 PM, Kevin Bourrillion wrote: > On Wed, Mar 11, 2009 at 6:11 AM, Stephen Colebourne > wrote: > >> - Constructor literals have to be included. If you don't then >> developers will find it an unexplained gap. See FCM section 2.2 which >> uses Type#(argTypes) > > Yes, and the worst case scenario is to mimic the Javadoc syntax: > ArrayList#ArrayList(int). Nope, since this, unfortunately, is a valid method name :-( The ugly alternative would be Type#(argTypes). Regards, Michael Nascimento Santos https://genesis.dev.java.net/ https://jsr-310.dev.java.net/ From scolebourne at joda.org Wed Mar 11 09:18:02 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 11 Mar 2009 16:18:02 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com> Message-ID: <4b4f45e00903110918ma5a027dubbdaf301c74a5065@mail.gmail.com> 2009/3/11 Kevin Bourrillion : >> - I believe that adding generics to Field and Method (the return type) >> is a key part of this change. > > Is it possible to keep that API change and this language change orthogonal? You could, but I believe you get real benefits from doing both together. For existing code, everyone just adds . But for new code you really want the extra safety: Field f = Period#ZERO; Method m = String#toUpperCase(); public void process(Method method) { ... } This allows frameworks to be specific about the type of method or field they will accept. Stephen From mr at sun.com Wed Mar 11 09:23:05 2009 From: mr at sun.com (Mark Reinhold) Date: Wed, 11 Mar 2009 09:23:05 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: tim@peierls.net; Mon, 09 Mar 2009 13:51:24 EDT; <63b4e4050903091051g431fdaebn7ca85f8dc90cef67@mail.gmail.com> Message-ID: <20090311162306.0722128CFE3@eggemoggin.niobe.net> > Date: Mon, 09 Mar 2009 13:51:24 -0400 > From: Tim Peierls > CloseableResource is good, too. I have a mild preference for AutoCloseable, > because it leaves open the possibility of blessing other AutoXxx classes in > the future. Yes, that could prove to be a handy naming pattern in the long term. > Maybe the name of the proposal is misleading, since not all resources can be > managed automatically, just those that have a void close() method. Agreed. Thanks for the AutoCloseable idea; I like it a lot. - Mark From jesse at swank.ca Wed Mar 11 11:29:10 2009 From: jesse at swank.ca (Jesse Wilson) Date: Wed, 11 Mar 2009 11:29:10 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> Message-ID: Thanks Stephen. I've added a link to the FCM proposal. Naturally this proposal is heavily influenced by your work. I've added TODOs for your suggestions to the spec on Google Docs. On Wed, Mar 11, 2009 at 6:11 AM, Stephen Colebourne wrote: > - I believe that adding generics to Field and Method (the return type) > is a key part of this change. Agreed, but it does complicate things.... Should the type parameters include the declaring type, return type, or both? I prefer both. Method listIterator = List#iterator(); Field aToZ = String#CASE_INSENSITIVE_ORDER; Should we support only raw types in type parameters (as Class literals do) or fully parameterized types? I believe using the raw types is more correct but it will require warnings suppressions in practice. Method, Iterator> listIterator = List#iterator(); Field aToZ = String#CASE_INSENSITIVE_ORDER; If a type inherits a method, which type is valid for the type parameter? Consider ArrayList#iterator(), which is inherited from AbstractList. Which of these are valid? A: Method hashCode = ArrayList#iterator() B: Method hashCode = ArrayList#iterator() C: Method hashCode = ArrayList#iterator() Each solutions has it's own pros and cons. My preference is to allow A only. A is good because it means the code won't break if ever ArrayList overrides it's iterator() method. B is good because it means the Method.getDeclaringClass() return type is consistent with the first generic parameter. But it breaks if ArrayList overrides iterator(). C is bad because the method cannot be reflectively invoked with an arbitrary List. > In summary, the real question with the proposal is whether we can > implement member literals independently of method references and > closures? The answer is definitely yes if we use the ## syntax, and > probably yes if we use #. Is there something I should mention in the proposal? > BTW, I do think that member literals are exactly the kind of change > Java needs, as they remove a very painful use of strings and > exceptions today. See > http://incubator.apache.org/click/docs/why-click.html (section 3) for > an example of strings for method names in use today. In all the FCM > feedback, method literals and references have been clearly popular. Thanks. I'm hopeful that Project Coin will live up to its promise. From neal at gafter.com Wed Mar 11 14:11:03 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Mar 2009 14:11:03 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> Message-ID: <15e8b9d20903111411h1669ba4blcbc9ca239b7cd494@mail.gmail.com> Vilya- I suspect that if you narrowed the scope of this proposal to just enum types, it would have a much better chance of getting accepted for project Coin. Because enum types are instance-controlled by the language, you are guaranteed that == and != have a meaning that is consistent with the relational operators. Then, we could consider generalizing the mechanism to other types as a separate decision in Java 7 or 8 (or not). Regards, Neal On Tue, Mar 10, 2009 at 9:09 AM, Vilya Harvey wrote: > I've attached a draft of a proposal to allow classes which implement the > Comparable interface to be used as operands for the relational operators. > So > for example if you had two Strings, a and b, you would be able to write > > if (a < b) { > ... > } > > instead of > > if (a.compareTo(b) < 0) { > ... > } > > and you could do the same with your own classes as well. > > Thanks in advance for any feedback, > > Vil. > > > > From scolebourne at joda.org Wed Mar 11 16:37:39 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 11 Mar 2009 23:37:39 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> Message-ID: <49B84B43.1000800@joda.org> Jesse Wilson wrote: > Should the type parameters include the declaring type, return type, or > both? I prefer both. > Method listIterator = List#iterator(); > Field aToZ = String#CASE_INSENSITIVE_ORDER; I was only thinking of it being the return type: Method listIterator = List#iterator(); Field aToZ = String#CASE_INSENSITIVE_ORDER; > Should we support only raw types in type parameters (as Class literals > do) or fully parameterized types? I believe using the raw types is > more correct but it will require warnings suppressions in practice. I was thinking of parameterized Method> listIterator = List#iterator(); Field aToZ = String#CASE_INSENSITIVE_ORDER; > If a type inherits a method, which type is valid for the type > parameter? Consider ArrayList#iterator(), which is inherited from > AbstractList. Which of these are valid? By only specifying the return type, you avoid this issue. >> In summary, the real question with the proposal is whether we can >> implement member literals independently of method references and >> closures? The answer is definitely yes if we use the ## syntax, and >> probably yes if we use #. > Is there something I should mention in the proposal? I think the proposal needs to note that a resolution of the potential conflict with method reference/eta expansion is required. This could to let later changes handle it, to accept method references are boxed, or to use a different syntax. Perhaps there is another option too. (I know Neal has some concerns on this conflict of syntax) Stephen From neal at gafter.com Wed Mar 11 16:58:52 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Mar 2009 16:58:52 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B84B43.1000800@joda.org> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> Message-ID: <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> On Wed, Mar 11, 2009 at 4:37 PM, Stephen Colebourne wrote: > >> In summary, the real question with the proposal is whether we can > >> implement member literals independently of method references and > >> closures? The answer is definitely yes if we use the ## syntax, and > >> probably yes if we use #. > > Is there something I should mention in the proposal? > > I think the proposal needs to note that a resolution of the potential > conflict with method reference/eta expansion is required. This could to > let later changes handle it, to accept method references are boxed, or > to use a different syntax. Perhaps there is another option too. (I know > Neal has some concerns on this conflict of syntax) I may regret saying this later, but I am not concerned about the potential conflict. I believe we can use the exact same syntax and distinguish whether it should be a java.lang.reflect.Method or a closure from context.? Since we're doing Method first, it would take priority (just like a method invocation that requires no boxing is preferred during overload resolution to one that requires some argument to be boxed). From r.spilker at gmail.com Wed Mar 11 17:13:17 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Thu, 12 Mar 2009 01:13:17 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B84B43.1000800@joda.org> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> Message-ID: Another possible problem about the generified Field and Method literals is that there is no good support for the built-in types. class Foo { int bar; Field barField = Foo#bar; } This seems a bit strange, even though it seems barField.set(foo, Integer.valueOf(1)) would work just fine, just as int value = barField.get(foo); However barField.set(foo, null) does not give a compiler error, but would fail. Currently, the javadoc suggests it would throw an IllegalArgumentException instead of a NPE. The only way to distinguish an Integer field from an int field is to check barField.getType() and compare it to int.class. From neal at gafter.com Wed Mar 11 17:23:24 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 11 Mar 2009 17:23:24 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> Message-ID: <15e8b9d20903111723j227c093q370e3490c186379@mail.gmail.com> This was the best we could do given the generic type system. I don't think there is anything to be done about it now, particularly not in the context of this proposal. On Wed, Mar 11, 2009 at 5:13 PM, Roel Spilker wrote: > Another possible problem about the generified Field and Method literals is > that there is no good support for the built-in types. > > class Foo { > ? ?int bar; > > ? ?Field barField = Foo#bar; > } > > This seems a bit strange, even though it seems barField.set(foo, > Integer.valueOf(1)) would work just fine, just as int value = > barField.get(foo); > > However barField.set(foo, null) does not give a compiler error, but would > fail. Currently, the javadoc suggests it would throw an > IllegalArgumentException instead of a NPE. The only way to distinguish an > Integer field from an int field is to check barField.getType() and compare > it to int.class. > > From brucechapman at paradise.net.nz Wed Mar 11 19:32:00 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Thu, 12 Mar 2009 15:32:00 +1300 (NZDT) Subject: PROPOSAL: Method and Field Literals In-Reply-To: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> Message-ID: <1236825120.49b87420b2662@www.paradise.net.nz> Quoting Stephen Colebourne : > > - One area that needs to be added to the spec is to allow member > literals in annotations. Currently, annotations are defined to only > accept a limited subset of types that are known to be safe and > immutable. There is a use case for frameworks to link to methods and > fields from annotations (currently it is done using strings). The > problem is that Field/Method/Constructor are not immutable. However, > it has been suggested to me previously that a clone can be returned > each time from the annotation. > If that line of reasoning is followed (and I agree it is worth pursuing) then the proposal would then be incomplete if you did not extend it to cover type literals as well, both as type literals per se and allowing them as annotation element values. Currently class literals cannot represent instantiations of a generic type. If we allow field and method literals of generic types, but don't address the lack of a generic type literal, we haven't gone far enough. Following that line of reasoning, and that the type literal doesn't have a obvious place to put the # consistently with field and method literals, maybe the solution is to use # in a bounding form like these #ArrayList# #PrintWriter.out# #ArrayList.add(String)# but that might not play nicely with recent discussions about the nature of the LHS when # is used as a dereferencer, and with the FCM/BGGA stuff that it would be good to be considerate of. As well as the runtime reflection representation, we should also consider how these constants (partularly when used as annotation element values) would be represented in javax.lang.element. (it would appear to fit nicely into javax.lang.element.AnnotationValue.getValue() which can return a TypeMirror which can be used to represent all these (types, fields, methods, constructors) The use of these literals as annotation values may well force a change in the implementation strategy such that these are encoded in the classfile specially rather than merely be compiled with a desugaring to call a helper method at runtime. Annotation values neeed to have all three of a runtime (java.lang.reflect) representation as well as a compile time (javax.lang.model) representation, and a classfile representation. I would LOVE to see type literals added (generally and as annotation element values) for some of the annotation processing experiments I am doing) but my fear (hopefully unfounded) is that this is starting to maybe get a little large for coin. Bruce From reinier at zwitserloot.com Wed Mar 11 21:48:39 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Mar 2009 05:48:39 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B84B43.1000800@joda.org> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> Message-ID: <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> I have some problems with this proposal. Let's start with my big nit: What's this useful for, exactly? Can anyone name me one non-exotic use- case? I thought of something along the lines of a library call that will bind 2 fields together (javafx style!) but that can't really work without classloader meddling, which would have to occur before you even make the reference in the first place. The various java.lang.reflect.Method/Field using libraries I've written myself don't operate on specific fields. They operate on any field that matches a certain precondition (such as having an annotation - a common thread). These frameworks wouldn't be helped by field or method literals. I can see quite a lot of good coming from method /handles/ but if that's the only relevant use case, then this is some sort of closures light. The problem with that is future expansion: If closures do show up in java down the road (Closures are not going to be in java 7, but I don't think its valid to say they'll never be in java ever, either), then the one use case fizzles out, and this is going to be a niche feature almost never used that nevertheless has to be maintained forever, and the complexity tax on the parser can never be removed. Even if this + method handles would serve as java's only closure proposal, I don't really like it - I at least want a way to define a block on the spot. method handles are neither TCP-compliant (google "TCP BGGA" for info) nor do they even allow you the simple courtesy of in-place creation that anonymous inner class literals give you. A related nit: Even if there are common use-cases, Method and Field (the classes), well, suck. They aren't parameterized, and worse, they don't carry their type at runtime either in case of generified field types. In other words, a Field class does not carry, at compile time, the type of the field. However, it also doesn't carry the type of the field *at runtime* if the field is 'T' or 'List' or anything else with generics in there. The few use-cases I did think of just aren't going to work particularly well without this information. You also can't use them in annotations (only primitives, String, and Class). Between those two, not one use-case survived. If this proposal is going to add any real value, it would have to include a serious overhaul of those two classes along with changing annotations to allow these too. Possibly that might push this proposal outside the intent of project coin. And a very minor nit: # shows up in various closure proposals. I would at the very least require something on the LHS and not let just "#foo" default to "Field foo of my own class". For future expansion's sake. --Reinier Zwitserloot On Mar 12, 2009, at 00:37, Stephen Colebourne wrote: > Jesse Wilson wrote: >> Should the type parameters include the declaring type, return type, >> or >> both? I prefer both. >> Method listIterator = List#iterator(); >> Field aToZ = String#CASE_INSENSITIVE_ORDER; > > I was only thinking of it being the return type: > Method listIterator = List#iterator(); > Field aToZ = String#CASE_INSENSITIVE_ORDER; > >> Should we support only raw types in type parameters (as Class >> literals >> do) or fully parameterized types? I believe using the raw types is >> more correct but it will require warnings suppressions in practice. > > I was thinking of parameterized > > Method> listIterator = List#iterator(); > Field aToZ = String#CASE_INSENSITIVE_ORDER; > >> If a type inherits a method, which type is valid for the type >> parameter? Consider ArrayList#iterator(), which is inherited from >> AbstractList. Which of these are valid? > > By only specifying the return type, you avoid this issue. > >>> In summary, the real question with the proposal is whether we can >>> implement member literals independently of method references and >>> closures? The answer is definitely yes if we use the ## syntax, and >>> probably yes if we use #. >> Is there something I should mention in the proposal? > > I think the proposal needs to note that a resolution of the potential > conflict with method reference/eta expansion is required. This could > to > let later changes handle it, to accept method references are boxed, or > to use a different syntax. Perhaps there is another option too. (I > know > Neal has some concerns on this conflict of syntax) > > Stephen > From jesse at swank.ca Thu Mar 12 00:05:28 2009 From: jesse at swank.ca (Jesse Wilson) Date: Thu, 12 Mar 2009 00:05:28 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> Message-ID: On Wed, Mar 11, 2009 at 9:48 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > What's this useful for, exactly? Can anyone name me one non-exotic > use-case? In Glazed Lists we have an interface called TableFormatthat maps a value object to its columns for a table. A concise API to access methods would be convenient: TableFormat songsTableFormat = new TableFormat.Builder() .addColumn("Name", Song#getSongName()) .addColumn("Track #", Song#getTrackNumber()) .addColumn("Artist", Song#getArtist()) .addColumn("Album", Song#getAlbum()) .build(); Google Code Search suggests another 7,000 immediate candidates: http://www.google.com/codesearch?hl=en&lr=&q=%5C.class%5C.getMethod%5C%28%5C%22&sbtn=Search This includes code from Apache HTTP client, Log4J, Ant, JPA, SwingX, EJB, SAX, Google Collections, GWT, Hibernate, Seam, MySQL, Equinox, Eclipse... you name it. From reinier at zwitserloot.com Thu Mar 12 00:14:05 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Mar 2009 08:14:05 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> Message-ID: with getField, I only see 834 results. A search for "finally in.close", which only covers a small slice of ARM's bailiwick returns ~31100 results. A -lot- of the method literals in that google code search result involve checking if a certain method exists in a certain class. I would assume the module system takes care of most of these calls (as its effectively a version check). That should take care of about 3000 of those 7000 already. --Reinier Zwitserloot On Mar 12, 2009, at 08:05, Jesse Wilson wrote: > On Wed, Mar 11, 2009 at 9:48 PM, Reinier Zwitserloot > wrote: > What's this useful for, exactly? Can anyone name me one non-exotic > use-case? > > In Glazed Lists we have an interface called TableFormat that maps a > value object to its columns for a table. A concise API to access > methods would be convenient: > TableFormat songsTableFormat = new TableFormat.Builder() > .addColumn("Name", Song#getSongName()) > .addColumn("Track #", Song#getTrackNumber()) > .addColumn("Artist", Song#getArtist()) > .addColumn("Album", Song#getAlbum()) > .build(); > > Google Code Search suggests another 7,000 immediate candidates: > http://www.google.com/codesearch?hl=en&lr=&q=%5C.class%5C.getMethod%5C%28%5C%22&sbtn=Search > > This includes code from Apache HTTP client, Log4J, Ant, JPA, SwingX, > EJB, SAX, Google Collections, GWT, Hibernate, Seam, MySQL, Equinox, > Eclipse... you name it. > From akuhn at iam.unibe.ch Thu Mar 12 01:13:05 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Thu, 12 Mar 2009 09:13:05 +0100 Subject: PROPOSAL: Method and Field Literals Message-ID: <9B4A5287-9EF7-4519-AFEA-BFB2BD67656A@iam.unibe.ch> On Mar 11, 2009, at 22:47, Reinier Zwitserloot wrote: > What's this useful for, exactly? Can anyone name me one non-exotic > use-case? For example, http://smallwiki.unibe.ch/jexample Actually, any framework that calls methods with reflection will need this extension iff the choice of the called methods is up to the client. Thus, I assume this is a rather common problem. For such framework it is very important to allow method literals in annotations, as suggested by Stephen Colebourne: > - One area that needs to be added to the spec is to allow member > literals in annotations. Currently, annotations are defined to only > accept a limited subset of types that are known to be safe and > immutable. There is a use case for frameworks to link to methods and > fields from annotations (currently it is done using strings). The > problem is that Field/Method/Constructor are not immutable. However, > it has been suggested to me previously that a clone can be returned > each time from the annotation. Thus, +1 cheers, AA From noel at peralex.com Thu Mar 12 02:37:10 2009 From: noel at peralex.com (Noel Grandin) Date: Thu, 12 Mar 2009 11:37:10 +0200 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <4b4f45e00903110918ma5a027dubbdaf301c74a5065@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com> <4b4f45e00903110918ma5a027dubbdaf301c74a5065@mail.gmail.com> Message-ID: <49B8D7C6.3080500@peralex.com> Stephen Colebourne wrote: > Field f = Period#ZERO; > Method m = String#toUpperCase(); > > public void process(Method method) { ... } > > This allows frameworks to be specific about the type of method or > field they will accept. > > I can see the benefit for Field, but for Method I think you're wasting your time. Frameworks will be more interested in the parameters of a method rather then return type, but I can't see any way of encoding that into the generic parameters, because we can't do a variable number of type parameters. I would rather leave Method as a raw type, possibly something to solve in the future when Java's generic type system becomes more powerful :-) Regards, Noel Grandin Disclaimer: http://www.peralex.com/disclaimer.html From schulz at e-Spirit.de Thu Mar 12 02:48:21 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Thu, 12 Mar 2009 10:48:21 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B8D7C6.3080500@peralex.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <108fcdeb0903110855x67fc3759rd0d7a81eb4f10b06@mail.gmail.com><4b4f45e00903110918ma5a027dubbdaf301c74a5065@mail.gmail.com> <49B8D7C6.3080500@peralex.com> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC105DF4CF@osiris2.e-spirit.de> Noel Grandin wrote: > Stephen Colebourne wrote: > > Field f = Period#ZERO; > > Method m = String#toUpperCase(); > > > > public void process(Method method) { ... } > > > > This allows frameworks to be specific about the type of method or > > field they will accept. > > > > > > I can see the benefit for Field, but for Method I think you're wasting > your time. > > Frameworks will be more interested in the parameters of a > method rather > then return type, but I can't see any way of encoding that into the > generic parameters, > because we can't do a variable number of type parameters. > > I would rather leave Method as a raw type, possibly something to solve > in the future when Java's generic type system becomes more > powerful :-) I mostly agree. The return type of a method alone is of low value. I don't think, one wants to extend the generic type system so types can take generic definitions with variable number of parameters (at least not in the scope of this proposal). The issue of getting a method literal compile-time type-safe should be postponed until Java has method types. Stefan From schulz at e-Spirit.de Thu Mar 12 02:55:23 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Thu, 12 Mar 2009 10:55:23 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <1236825120.49b87420b2662@www.paradise.net.nz> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <1236825120.49b87420b2662@www.paradise.net.nz> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC105DF4D1@osiris2.e-spirit.de> Bruce wrote: > If that line of reasoning is followed (and I agree it is > worth pursuing) then > the proposal would then be incomplete if you did not extend > it to cover type > literals as well, both as type literals per se and allowing > them as annotation > element values. Currently class literals cannot represent > instantiations of a > generic type. If we allow field and method literals of > generic types, but don't > address the lack of a generic type literal, we haven't gone > far enough. Isn't this rather something to complement reification of generic types? I think this is out of scope for the given proposal, but maybe I am wrong and it's just a snap. > Following that line of reasoning, and that the type literal > doesn't have a > obvious place to put the # consistently with field and method > literals, maybe > the solution is to use # in a bounding form like these > #ArrayList# > #PrintWriter.out# > #ArrayList.add(String)# Well, one could reuse the class keyword: ArrayList#class Stefan From scolebourne at joda.org Thu Mar 12 03:36:51 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 12 Mar 2009 10:36:51 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> Message-ID: <49B8E5C3.7040006@joda.org> Reinier Zwitserloot wrote: > What's this useful for, exactly? Can anyone name me one non-exotic use- > case? This is a basic feature of most modern languages. Its certainly a lot better than using hard coded strings which happes today. I gave one use case in the Click framewok. IIRC the Genesis framework is similar. For example, consider bean validation as an example. Today, we at $job use this based on the OVal framework (custom extension): public class SearchRequirements { @MaxLength(length=30) private String search; @DateNotInFutue pivate LocalDate dateRangeStart; @DateNotInFutue @DateNotBefore(field="dateRongeStart") pivate LocalDate dateRangeEnd; } This allows validation of each of the three fields by a tool, and appopiate error messages to be produced. Of course, the above code has a bug - the reference in @DateNotBefore has mispelled the reference to the "dateRangeStart" field. What field literals allows is to replace the above with this: public class SearchRequirements { ... @DateNotInFutue @DateNotBefore(field=SearchRequirenents#dateRangeStart) pivate LocalDate dateRangeEnd; } which is now compile time checked. > I can see quite a lot of good coming from method /handles/ but if > that's the only relevant use case, then this is some sort of closures > light. The problem with that is future expansion: If closures do show > up in java down the road (Closures are not going to be in java 7, but > I don't think its valid to say they'll never be in java ever, either), > then the one use case fizzles out, and this is going to be a niche > feature almost never used that nevertheless has to be maintained > forever, and the complexity tax on the parser can never be removed. > Even if this + method handles would serve as java's only closure > proposal, I don't really like it - I at least want a way to define a > block on the spot. method handles are neither TCP-compliant (google > "TCP BGGA" for info) nor do they even allow you the simple courtesy of > in-place creation that anonymous inner class literals give you. By method "handles", I'm reading method references (handles are a whole other issue). Neal has already commented that he believes this proposal is forward compatible with method references, and I'm pretty certain its compatible with FCM or BGGA style closues. I don't believe the use case for this goes away when method references are added. You still need a compile-safe way to reference fields, mthods and constructors. If you didn't, then why would new languages be including this feature? > Even if there are common use-cases, Method and Field (the classes), > well, suck. They aren't parameterized, and worse, they don't carry > their type at runtime either in case of generified field types. In > other words, a Field class does not carry, at compile time, the type > of the field. However, it also doesn't carry the type of the field *at > runtime* if the field is 'T' or 'List' or anything else with > generics in there. The few use-cases I did think of just aren't going > to work particularly well without this information. I agree that the proposal is more useful with generified field/method. I disagree that the proposal isn't useful without them. I think its considerably better than what we have now. > You also can't use > them in annotations (only primitives, String, and Class). The proposal will probably have to address this. > And a very minor nit: # shows up in various closure proposals. I would > at the very least require something on the LHS and not let just "#foo" > default to "Field foo of my own class". For future expansion's sake. Currently, I'd tend to agree with requiring something on the LHS. It does offer more future growth. Stephen From scolebourne at joda.org Thu Mar 12 03:37:01 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 12 Mar 2009 10:37:01 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <1236825120.49b87420b2662@www.paradise.net.nz> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <1236825120.49b87420b2662@www.paradise.net.nz> Message-ID: <49B8E5CD.7080106@joda.org> brucechapman at paradise.net.nz wrote: > the proposal would then be incomplete if you did not extend it to cover type > literals as well, both as type literals per se and allowing them as annotation > element values. Currently class literals cannot represent instantiations of a > generic type. If we allow field and method literals of generic types, but don't > address the lack of a generic type literal, we haven't gone far enough. I agree that Java should have type literals, but I think that they are a separate Coin. Feel free to start writing ;-) > Following that line of reasoning, and that the type literal doesn't have a > obvious place to put the # consistently with field and method literals, maybe > the solution is to use # in a bounding form like these > #ArrayList# > #PrintWriter.out# > #ArrayList.add(String)# > > but that might not play nicely with recent discussions about the nature of the > LHS when # is used as a dereferencer, and with the FCM/BGGA stuff that it would > be good to be considerate of. Fan (http://fandev.org) uses a postfixed # ArrayList# The way to think of this is like the root of a URL, where the suffixes for Field/Method are like URL doc-internal references. Stephen From frederic.martini at gmail.com Thu Mar 12 03:41:54 2009 From: frederic.martini at gmail.com (=?ISO-8859-1?Q?Fr=E9d=E9ric_Martini?=) Date: Thu, 12 Mar 2009 11:41:54 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B8E5CD.7080106@joda.org> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <1236825120.49b87420b2662@www.paradise.net.nz> <49B8E5CD.7080106@joda.org> Message-ID: Hello, Before to start, sorry for my poor english. This is not my spoken language :( My advice for this proposal : this is a must-have : this will allow to use secure-code with reflection ! But I want to extends this proposal with the support of beans' property. In fact, access to field is very limited due to visibility : there are more often protected or private... For example: we cannot use Exception#message or Exception#cause :( It will be more interresting to use the beans' property notion, by exemple with a Property's class like this (this is a scratch exemple, with RuntimeException to be replaced by a more precise unchecked exception...) : ----------------------------------------------------------------------- /** * Immutable class * * @param The Bean's type * @param The property's type */ final class Property { /** Name of the property */ private final String name; /** Read-method of the property */ private final Method get; /** Write-method of the property */ private final Method set; /** * Private Constructor * @see Property#getReadableProperty(Class, Class, String) * @see Property#getWritableProperty(Class, Class, String) */ private Property(String name, Method get, Method set) { this.name = name; this.get = get; this.set = set; } /** * @return the property name */ public String name() { return this.name; } /** * Call the get-method on the specified instance. */ public T get(B beans) { try { @SuppressWarnings("unchecked") T result = (T) this.get.invoke(beans); return result; } catch (Exception e) { throw new RuntimeException("get()", e); } } /** * @return true if this property is writable (have write-method) */ public boolean isWritable() { return this.set!=null; } /** * Call the set-method on the specified instance. */ public void set(B beans, T value) { try { this.set.invoke(beans, value); } catch (Exception e) { throw new RuntimeException("set()", e); } } /** * Find an create an Property. * @param The Bean's type * @param The property's type * @param beanClass The Bean's type * @param propertyClass The property's type * @param propertyName The property's name * @return A Property for the specified beans-property * @throws RuntimeException if the property cannot be found */ private static Property findProperty(Class beanClass, Class propertyClass, String propertyName) { try { for (PropertyDescriptor descriptor : Introspector.getBeanInfo(beanClass).getPropertyDescriptors() ) { if (descriptor.getName().equals(propertyName) && propertyClass.equals(descriptor.getPropertyType())) { return new Property(descriptor.getName(), descriptor.getReadMethod(), descriptor.getWriteMethod()); } } } catch (IntrospectionException e) { throw new RuntimeException("Property not found : " + propertyName, e); } throw new RuntimeException("Property not found : " + propertyName); } /** * Get a read/write property * @param The Bean's type * @param The property's type * @param beanClass The Bean's type * @param propertyClass The property's type * @param propertyName The property's name * @return A Property for the specified beans-property, with get/set method * @throws RuntimeException if the property cannot be found, or is not writable */ public static Property getWritableProperty(Class beanClass, Class propertyClass, String propertyName) { Property property = findProperty(beanClass, propertyClass, propertyName); if (!property.isWritable()) { throw new RuntimeException("Non-writable property : " + propertyName); } return property; } /** * Get a read-only property. * The return type is Property in order to forbid the use of the set() method * @param The Bean's type * @param The property's type * @param beanClass The Bean's type * @param propertyClass The property's type * @param propertyName The property's name * @return A Property for the specified beans-property, with only get method * @throws RuntimeException if the property cannot be found */ public static Property getReadableProperty(Class beanClass, Class propertyClass, String propertyName) { return findProperty(beanClass, propertyClass, propertyName); } } ----------------------------------------------------------------------- Property.getWritableProperty() return a property with read/write access, and Property.getReadableProperty() return a property with read-only access, declared as Property in order to have compile-time error if the set method is used... Exemple of use : ----------------------------------------------------------------------- public class MyObject { private final String name; private int value; public MyObject(String name) { this.name = name; } public String getName() { return name; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public static void main(String[] args) { MyObject beans = new MyObject("name"); Property valueProperty = Property.getWritableProperty(MyObject.class, int.class, "value"); int value = valueProperty.get(beans); // OK valueProperty.set(beans, 100); // OK Property nameProperty = Property.getReadableProperty(MyObject.class, String.class, "name"); String name = nameProperty.get(beans); // OK nameProperty.set(beans, "hello"); // Compile error (is not applicable...) } } ----------------------------------------------------------------------- My proposal is to use a literal in order to replace the static method call (unsafe because based on a String) with a checked literral : So this : ----------------------------------------------------------------------- Property valueProperty = Property.getWritableProperty(MyObject.class, int.class, "value"); Property nameProperty = Property.getReadableProperty(MyObject.class, String.class, "name"); ----------------------------------------------------------------------- May be remplaced with something like (or equivalent) : ----------------------------------------------------------------------- Property value = MyObject#value; Property name = MyObject#name; ----------------------------------------------------------------------- (We can use the same notation that the Field literral, based on context, or any other syntaxe...) MyObject#value is matched to Property because the MyObject's class have a property called "value", with a getter (getValue()) and a setter (setValue()). MyObject#name is matched to Property because the name's property only have a getter and no-setter ! Of course the literral MyObject#value will be checked at compile time, to produce compile-time error on bad usage. This will allow the literral to be more useful and usable with almost all classes : ----------------------------------------------------------------------- Field message = Throwable#message; // ERROR : message don't exist or is private :( Property message = Throwable#message; // OK ----------------------------------------------------------------------- What do you think about this ? Thanks for reading ;) Fred, From david.goodenough at linkchoose.co.uk Thu Mar 12 03:57:59 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 12 Mar 2009 10:57:59 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <49B8E5CD.7080106@joda.org> Message-ID: <200903121058.01356.david.goodenough@linkchoose.co.uk> On Thursday 12 March 2009, Fr?d?ric Martini wrote: > Hello, > > > Before to start, sorry for my poor english. This is not my spoken language > :( > > > > My advice for this proposal : this is a must-have : this will allow to > use secure-code with reflection ! > > > > But I want to extends this proposal with the support of beans' property. > In fact, access to field is very limited due to visibility : there are > more often protected or private... > For example: we cannot use Exception#message or Exception#cause :( > > > It will be more interresting to use the beans' property notion, by > exemple with a Property's class like this (this is a scratch exemple, > with RuntimeException to be replaced by a more precise unchecked > exception...) : > > > > ----------------------------------------------------------------------- > > /** > * Immutable class > * > * @param The Bean's type > * @param The property's type > */ > final class Property { > > /** Name of the property */ > private final String name; > /** Read-method of the property */ > private final Method get; > /** Write-method of the property */ > private final Method set; > > /** > * Private Constructor > * @see Property#getReadableProperty(Class, Class, String) > * @see Property#getWritableProperty(Class, Class, String) > */ > private Property(String name, Method get, Method set) { > this.name = name; > this.get = get; > this.set = set; > } > > /** > * @return the property name > */ > public String name() { > return this.name; > } > > /** > * Call the get-method on the specified instance. > */ > public T get(B beans) { > try { > @SuppressWarnings("unchecked") > T result = (T) this.get.invoke(beans); > return result; > } catch (Exception e) { > throw new RuntimeException("get()", e); > } > } > > /** > * @return true if this property is writable (have write-method) > */ > public boolean isWritable() { > return this.set!=null; > } > > /** > * Call the set-method on the specified instance. > */ > public void set(B beans, T value) { > try { > this.set.invoke(beans, value); > } catch (Exception e) { > throw new RuntimeException("set()", e); > } > } > > /** > * Find an create an Property. > * @param The Bean's type > * @param The property's type > * @param beanClass The Bean's type > * @param propertyClass The property's type > * @param propertyName The property's name > * @return A Property for the specified beans-property > * @throws RuntimeException if the property cannot be found > */ > private static Property findProperty(Class beanClass, > Class propertyClass, String propertyName) { > try { > for (PropertyDescriptor descriptor : > Introspector.getBeanInfo(beanClass).getPropertyDescriptors() ) { > if (descriptor.getName().equals(propertyName) && > propertyClass.equals(descriptor.getPropertyType())) { > return new Property(descriptor.getName(), > descriptor.getReadMethod(), descriptor.getWriteMethod()); > } > } > } catch (IntrospectionException e) { > throw new RuntimeException("Property not found : " + propertyName, e); > } > throw new RuntimeException("Property not found : " + propertyName); > } > > /** > * Get a read/write property > * @param The Bean's type > * @param The property's type > * @param beanClass The Bean's type > * @param propertyClass The property's type > * @param propertyName The property's name > * @return A Property for the specified beans-property, with get/set > method * @throws RuntimeException if the property cannot be found, or is > not writable */ > public static Property getWritableProperty(Class > beanClass, Class propertyClass, String propertyName) { > Property property = findProperty(beanClass, propertyClass, > propertyName); if (!property.isWritable()) { > throw new RuntimeException("Non-writable property : " + propertyName); > } > return property; > } > > /** > * Get a read-only property. > * The return type is Property in order to forbid the > use of the set() method > * @param The Bean's type > * @param The property's type > * @param beanClass The Bean's type > * @param propertyClass The property's type > * @param propertyName The property's name > * @return A Property for the specified beans-property, with only get > method * @throws RuntimeException if the property cannot be found > */ > public static Property > getReadableProperty(Class beanClass, Class propertyClass, String > propertyName) { > return findProperty(beanClass, propertyClass, propertyName); > } > } > > ----------------------------------------------------------------------- > > > > > Property.getWritableProperty() return a property with read/write > access, and Property.getReadableProperty() return a property with > read-only access, declared as Property in order to have > compile-time error if the set method is used... > > > > Exemple of use : > > ----------------------------------------------------------------------- > > public class MyObject { > > private final String name; > private int value; > > public MyObject(String name) { > this.name = name; > } > > public String getName() { > return name; > } > public int getValue() { > return value; > } > public void setValue(int value) { > this.value = value; > } > > > public static void main(String[] args) { > MyObject beans = new MyObject("name"); > > Property valueProperty = > Property.getWritableProperty(MyObject.class, int.class, "value"); > int value = valueProperty.get(beans); // OK > valueProperty.set(beans, 100); // OK > > Property nameProperty = > Property.getReadableProperty(MyObject.class, String.class, "name"); > String name = nameProperty.get(beans); // OK > nameProperty.set(beans, "hello"); // Compile error (is not applicable...) > } > } > > ----------------------------------------------------------------------- > > > My proposal is to use a literal in order to replace the static method > call (unsafe because based on a String) with a checked literral : > > So this : > > ----------------------------------------------------------------------- > Property valueProperty = > Property.getWritableProperty(MyObject.class, int.class, "value"); > Property nameProperty = > Property.getReadableProperty(MyObject.class, String.class, "name"); > ----------------------------------------------------------------------- > > May be remplaced with something like (or equivalent) : > ----------------------------------------------------------------------- > Property value = MyObject#value; > Property name = MyObject#name; > ----------------------------------------------------------------------- > > (We can use the same notation that the Field literral, based on > context, or any other syntaxe...) > > > MyObject#value is matched to Property because the > MyObject's class have a property called "value", with a getter > (getValue()) and a setter (setValue()). > MyObject#name is matched to Property > because the name's property only have a getter and no-setter ! > > > Of course the literral MyObject#value will be checked at compile time, > to produce compile-time error on bad usage. > > This will allow the literral to be more useful and usable with almost > all classes : > ----------------------------------------------------------------------- > Field message = Throwable#message; // ERROR : message don't exist or > is private :( > Property message = Throwable#message; // OK > ----------------------------------------------------------------------- > > > What do you think about this ? > > > > Thanks for reading ;) > > Fred, Fred, This is a lot like my lightweight properties proposal. It only covers fields (not methods) but your Property class and mine have a lot in common. David From frederic.martini at gmail.com Thu Mar 12 04:14:26 2009 From: frederic.martini at gmail.com (=?ISO-8859-1?Q?Fr=E9d=E9ric_Martini?=) Date: Thu, 12 Mar 2009 12:14:26 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <200903121058.01356.david.goodenough@linkchoose.co.uk> References: <49B8E5CD.7080106@joda.org> <200903121058.01356.david.goodenough@linkchoose.co.uk> Message-ID: Sorry I don't see it ! I go to read it... Fred, 2009/3/12 David Goodenough : > On Thursday 12 March 2009, Fr?d?ric Martini wrote: > > This is a lot like my lightweight properties proposal. ?It only covers fields > (not methods) but your Property class and mine have a lot in common. > > David > > From r.spilker at gmail.com Thu Mar 12 07:30:25 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Thu, 12 Mar 2009 15:30:25 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> Message-ID: About the remaining 4000: the search did not take into account that the proposal could only be used in cases where you now use a String literal. The search also gives results for invocations with a String variable, for instance names that are read from a configuration file. So that will remove some more. Secondly, the proposal only allows Field and Method literals that are visible to the caller. But my experience is that I use reflection often to access private members of other classes. So more false positives in the search results. Roel On Thu, Mar 12, 2009 at 8:14 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > with getField, I only see 834 results. > > A search for "finally in.close", which only covers a small slice of > ARM's bailiwick returns ~31100 results. > > A -lot- of the method literals in that google code search result > involve checking if a certain method exists in a certain class. I > would assume the module system takes care of most of these calls (as > its effectively a version check). That should take care of about 3000 > of those 7000 already. > > --Reinier Zwitserloot > > > > On Mar 12, 2009, at 08:05, Jesse Wilson wrote: > > > On Wed, Mar 11, 2009 at 9:48 PM, Reinier Zwitserloot < > reinier at zwitserloot.com > > > wrote: > > What's this useful for, exactly? Can anyone name me one non-exotic > > use-case? > > > > In Glazed Lists we have an interface called TableFormat that maps a > > value object to its columns for a table. A concise API to access > > methods would be convenient: > > TableFormat songsTableFormat = new TableFormat.Builder() > > .addColumn("Name", Song#getSongName()) > > .addColumn("Track #", Song#getTrackNumber()) > > .addColumn("Artist", Song#getArtist()) > > .addColumn("Album", Song#getAlbum()) > > .build(); > > > > Google Code Search suggests another 7,000 immediate candidates: > > > http://www.google.com/codesearch?hl=en&lr=&q=%5C.class%5C.getMethod%5C%28%5C%22&sbtn=Search > > > > This includes code from Apache HTTP client, Log4J, Ant, JPA, SwingX, > > EJB, SAX, Google Collections, GWT, Hibernate, Seam, MySQL, Equinox, > > Eclipse... you name it. > > > > > From david.goodenough at linkchoose.co.uk Thu Mar 12 07:44:18 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 12 Mar 2009 14:44:18 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: Message-ID: <200903121444.20217.david.goodenough@linkchoose.co.uk> On Thursday 12 March 2009, Roel Spilker wrote: > About the remaining 4000: the search did not take into account that the > proposal could only be used in cases where you now use a String literal. > The search also gives results for invocations with a String variable, for > instance names that are read from a configuration file. So that will remove > some more. > > Secondly, the proposal only allows Field and Method literals that are > visible to the caller. But my experience is that I use reflection often to > access private members of other classes. So more false positives in the > search results. My Lightweight Properties proposal allows access to all Fields, and so uses getDeclaredField to find them. It makes the assumption that while the field might be private, it should follow the presumption that had you written your own getter and setter you would have made it public and therefore sets the bit in the Field object that allows access. It does not however cover Methods. David > > Roel > > > On Thu, Mar 12, 2009 at 8:14 AM, Reinier Zwitserloot < > > reinier at zwitserloot.com> wrote: > > with getField, I only see 834 results. > > > > A search for "finally in.close", which only covers a small slice of > > ARM's bailiwick returns ~31100 results. > > > > A -lot- of the method literals in that google code search result > > involve checking if a certain method exists in a certain class. I > > would assume the module system takes care of most of these calls (as > > its effectively a version check). That should take care of about 3000 > > of those 7000 already. > > > > --Reinier Zwitserloot > > > > On Mar 12, 2009, at 08:05, Jesse Wilson wrote: > > > On Wed, Mar 11, 2009 at 9:48 PM, Reinier Zwitserloot < > > > > reinier at zwitserloot.com > > > > > > wrote: > > > > > > What's this useful for, exactly? Can anyone name me one non-exotic > > > use-case? > > > > > > In Glazed Lists we have an interface called TableFormat that maps a > > > value object to its columns for a table. A concise API to access > > > methods would be convenient: > > > TableFormat songsTableFormat = new TableFormat.Builder() > > > .addColumn("Name", Song#getSongName()) > > > .addColumn("Track #", Song#getTrackNumber()) > > > .addColumn("Artist", Song#getArtist()) > > > .addColumn("Album", Song#getAlbum()) > > > .build(); > > > > > > Google Code Search suggests another 7,000 immediate candidates: > > > > http://www.google.com/codesearch?hl=en&lr=&q=%5C.class%5C.getMethod%5C%28 > >%5C%22&sbtn=Search > > > > > This includes code from Apache HTTP client, Log4J, Ant, JPA, SwingX, > > > EJB, SAX, Google Collections, GWT, Hibernate, Seam, MySQL, Equinox, > > > Eclipse... you name it. From reinier at zwitserloot.com Thu Mar 12 07:57:44 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 12 Mar 2009 15:57:44 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B8E5C3.7040006@joda.org> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> <49B8E5C3.7040006@joda.org> Message-ID: <4E202F5B-15CA-49D9-B815-5521F5E293CB@zwitserloot.com> I find both use-cases given so far not very compelling. Stephen Colebourne's Use-Case 'annotations for OVal framework': That can't work with this proposal because Fields aren't allowed in annotations. This was part of my point: You need to do quite a job on the rest of the JLS and a good chunk of the reflection API to make this useful. It's not a bad idea perse, but the value of this proposal divided by the effort and impact isn't a very high number (IMO). Adrian Kuhn's 'jexample' jUnit extension: Again with the annotations. Also, that's rather exotic. I'd just solve this differently. First off, between checking the stacktrace at the point of a failed assertion, -or- doing some class-file-fu to see that a given fixture calls another unit test method, any fixtures calling another fixture for setup purposes can be skipped without any annotation. Most unit tests are sequential in design so an annotation of the form "@Sequential" would tell the unit test framework to skip the test if any previous tests failed. Methods are given in order in the class file itself, but technically Class.getMethods() does not return the methods in order according to the javadoc, though in practice it does. A proposal to make that official works for me. If I compare this to other project coin proposals, the use cases just don't have the wow factor for me. The intent of this nit is to improve the proposal by making sure it lists all the changes needed to make it useful, and includes a listing of excellent use-cases so that, if the proposal is adopted, the proposal can be explained to the masses that use java in a way that makes them go: Ah, how useful! It would be a shame if they went: Why is this in here? Proposal is so much simpler and has so much better value. Java7 sucks! Bad java7! I'm going to go blog about it now! - Developers are a bunch of whiny kids sometimes :P Alternatively they forget all about it because it wasn't compelling to them and then you get the unfortunate situation that there's another piece of syntax that most java developers don't know about. I'd prefer to keep such niches of the JLS (like strictfp) to a minimum. It's not good for the language. --Reinier Zwitserloot On Mar 12, 2009, at 11:36, Stephen Colebourne wrote: > Reinier Zwitserloot wrote: >> What's this useful for, exactly? Can anyone name me one non-exotic >> use- >> case? > > This is a basic feature of most modern languages. Its certainly a lot > better than using hard coded strings which happes today. I gave one > use > case in the Click framewok. IIRC the Genesis framework is similar. > > For example, consider bean validation as an example. Today, we at $job > use this based on the OVal framework (custom extension): > > public class SearchRequirements { > @MaxLength(length=30) > private String search; > @DateNotInFutue > pivate LocalDate dateRangeStart; > @DateNotInFutue > @DateNotBefore(field="dateRongeStart") > pivate LocalDate dateRangeEnd; > } > > This allows validation of each of the three fields by a tool, and > appopiate error messages to be produced. Of course, the above code > has a > bug - the reference in @DateNotBefore has mispelled the reference to > the > "dateRangeStart" field. What field literals allows is to replace the > above with this: > > public class SearchRequirements { > ... > @DateNotInFutue > @DateNotBefore(field=SearchRequirenents#dateRangeStart) > pivate LocalDate dateRangeEnd; > } > > which is now compile time checked. > >> I can see quite a lot of good coming from method /handles/ but if >> that's the only relevant use case, then this is some sort of closures >> light. The problem with that is future expansion: If closures do show >> up in java down the road (Closures are not going to be in java 7, but >> I don't think its valid to say they'll never be in java ever, >> either), >> then the one use case fizzles out, and this is going to be a niche >> feature almost never used that nevertheless has to be maintained >> forever, and the complexity tax on the parser can never be removed. >> Even if this + method handles would serve as java's only closure >> proposal, I don't really like it - I at least want a way to define a >> block on the spot. method handles are neither TCP-compliant (google >> "TCP BGGA" for info) nor do they even allow you the simple courtesy >> of >> in-place creation that anonymous inner class literals give you. > > By method "handles", I'm reading method references (handles are a > whole > other issue). Neal has already commented that he believes this > proposal > is forward compatible with method references, and I'm pretty certain > its > compatible with FCM or BGGA style closues. > > I don't believe the use case for this goes away when method references > are added. You still need a compile-safe way to reference fields, > mthods > and constructors. If you didn't, then why would new languages be > including this feature? > >> Even if there are common use-cases, Method and Field (the classes), >> well, suck. They aren't parameterized, and worse, they don't carry >> their type at runtime either in case of generified field types. In >> other words, a Field class does not carry, at compile time, the type >> of the field. However, it also doesn't carry the type of the field >> *at >> runtime* if the field is 'T' or 'List' or anything else with >> generics in there. The few use-cases I did think of just aren't going >> to work particularly well without this information. > > I agree that the proposal is more useful with generified field/ > method. I > disagree that the proposal isn't useful without them. I think its > considerably better than what we have now. > >> You also can't use >> them in annotations (only primitives, String, and Class). > > The proposal will probably have to address this. > >> And a very minor nit: # shows up in various closure proposals. I >> would >> at the very least require something on the LHS and not let just >> "#foo" >> default to "Field foo of my own class". For future expansion's sake. > > Currently, I'd tend to agree with requiring something on the LHS. It > does offer more future growth. > > Stephen > > > > > From david.goodenough at linkchoose.co.uk Thu Mar 12 08:16:27 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 12 Mar 2009 15:16:27 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <4E202F5B-15CA-49D9-B815-5521F5E293CB@zwitserloot.com> References: <49B8E5C3.7040006@joda.org> <4E202F5B-15CA-49D9-B815-5521F5E293CB@zwitserloot.com> Message-ID: <200903121516.28384.david.goodenough@linkchoose.co.uk> There are several good use cases for Field literals. All of them remove the need to have field names expressed as String values, and all of them allow a compiler/IDE to check the correctness of the code in a way that can not (sensibly) be done with String values. 1) If you look at Bean Binding systems, such as JSR-295 BeansBinding or JGoodies Bean Binding or the SWT JFace bindings, you will find lots of cases where bindings are done using String field names. Assuming the code was originally coded correctly (and we are all after all human and therefore prone to mistooks) if the field name is changed the compiler or IDE can not flag up the problem. The code will compile cleanly, and will load cleanly, but will then do sneaky things like ignoring an existing value or failing to save a new value. And that might not happen until an end user gets to the program. 2) If you look at JPA, its new incarnation has what is known as a Criteria API. This means that rather than writing JPQL (a variant of SQL) statements as Strings, you write what look a bit like expressions so express the JPQL. This is an improvement on writing native JPQL statements, but it is once again flawed in that it requires the field names to be encoded as Strings. You are right that getting Field or Method literals into Annotations would be difficult, because the Annotation rules require compile time constants as arguements (that is not what it says in the language spec but it is what it means). Because Field and Method objects are not stored in the class file directly (they are reconstructed at run time when they are used from a binary form) it would be extreemly difficult to regard these as compile time constants, and it would require not only a language syntax change, compiler changes and run time changes, but also a change to the class file format. David On Thursday 12 March 2009, Reinier Zwitserloot wrote: > I find both use-cases given so far not very compelling. > > Stephen Colebourne's Use-Case 'annotations for OVal framework': > > That can't work with this proposal because Fields aren't allowed in > annotations. This was part of my point: You need to do quite a job on > the rest of the JLS and a good chunk of the reflection API to make > this useful. It's not a bad idea perse, but the value of this proposal > divided by the effort and impact isn't a very high number (IMO). > > Adrian Kuhn's 'jexample' jUnit extension: > > Again with the annotations. Also, that's rather exotic. I'd just solve > this differently. First off, between checking the stacktrace at the > point of a failed assertion, -or- doing some class-file-fu to see that > a given fixture calls another unit test method, any fixtures calling > another fixture for setup purposes can be skipped without any > annotation. Most unit tests are sequential in design so an annotation > of the form "@Sequential" would tell the unit test framework to skip > the test if any previous tests failed. Methods are given in order in > the class file itself, but technically Class.getMethods() does not > return the methods in order according to the javadoc, though in > practice it does. A proposal to make that official works for me. > > > If I compare this to other project coin proposals, the use cases just > don't have the wow factor for me. > > The intent of this nit is to improve the proposal by making sure it > lists all the changes needed to make it useful, and includes a listing > of excellent use-cases so that, if the proposal is adopted, the > proposal can be explained to the masses that use java in a way that > makes them go: Ah, how useful! > > It would be a shame if they went: Why is this in here? Proposal > is so much simpler and has so much better > value. Java7 sucks! Bad java7! I'm going to go blog about it now! - > Developers are a bunch of whiny kids sometimes :P Alternatively they > forget all about it because it wasn't compelling to them and then you > get the unfortunate situation that there's another piece of syntax > that most java developers don't know about. I'd prefer to keep such > niches of the JLS (like strictfp) to a minimum. It's not good for the > language. > > --Reinier Zwitserloot > > On Mar 12, 2009, at 11:36, Stephen Colebourne wrote: > > Reinier Zwitserloot wrote: > >> What's this useful for, exactly? Can anyone name me one non-exotic > >> use- > >> case? > > > > This is a basic feature of most modern languages. Its certainly a lot > > better than using hard coded strings which happes today. I gave one > > use > > case in the Click framewok. IIRC the Genesis framework is similar. > > > > For example, consider bean validation as an example. Today, we at $job > > use this based on the OVal framework (custom extension): > > > > public class SearchRequirements { > > @MaxLength(length=30) > > private String search; > > @DateNotInFutue > > pivate LocalDate dateRangeStart; > > @DateNotInFutue > > @DateNotBefore(field="dateRongeStart") > > pivate LocalDate dateRangeEnd; > > } > > > > This allows validation of each of the three fields by a tool, and > > appopiate error messages to be produced. Of course, the above code > > has a > > bug - the reference in @DateNotBefore has mispelled the reference to > > the > > "dateRangeStart" field. What field literals allows is to replace the > > above with this: > > > > public class SearchRequirements { > > ... > > @DateNotInFutue > > @DateNotBefore(field=SearchRequirenents#dateRangeStart) > > pivate LocalDate dateRangeEnd; > > } > > > > which is now compile time checked. > > > >> I can see quite a lot of good coming from method /handles/ but if > >> that's the only relevant use case, then this is some sort of closures > >> light. The problem with that is future expansion: If closures do show > >> up in java down the road (Closures are not going to be in java 7, but > >> I don't think its valid to say they'll never be in java ever, > >> either), > >> then the one use case fizzles out, and this is going to be a niche > >> feature almost never used that nevertheless has to be maintained > >> forever, and the complexity tax on the parser can never be removed. > >> Even if this + method handles would serve as java's only closure > >> proposal, I don't really like it - I at least want a way to define a > >> block on the spot. method handles are neither TCP-compliant (google > >> "TCP BGGA" for info) nor do they even allow you the simple courtesy > >> of > >> in-place creation that anonymous inner class literals give you. > > > > By method "handles", I'm reading method references (handles are a > > whole > > other issue). Neal has already commented that he believes this > > proposal > > is forward compatible with method references, and I'm pretty certain > > its > > compatible with FCM or BGGA style closues. > > > > I don't believe the use case for this goes away when method references > > are added. You still need a compile-safe way to reference fields, > > mthods > > and constructors. If you didn't, then why would new languages be > > including this feature? > > > >> Even if there are common use-cases, Method and Field (the classes), > >> well, suck. They aren't parameterized, and worse, they don't carry > >> their type at runtime either in case of generified field types. In > >> other words, a Field class does not carry, at compile time, the type > >> of the field. However, it also doesn't carry the type of the field > >> *at > >> runtime* if the field is 'T' or 'List' or anything else with > >> generics in there. The few use-cases I did think of just aren't going > >> to work particularly well without this information. > > > > I agree that the proposal is more useful with generified field/ > > method. I > > disagree that the proposal isn't useful without them. I think its > > considerably better than what we have now. > > > >> You also can't use > >> them in annotations (only primitives, String, and Class). > > > > The proposal will probably have to address this. > > > >> And a very minor nit: # shows up in various closure proposals. I > >> would > >> at the very least require something on the LHS and not let just > >> "#foo" > >> default to "Field foo of my own class". For future expansion's sake. > > > > Currently, I'd tend to agree with requiring something on the LHS. It > > does offer more future growth. > > > > Stephen From neal at gafter.com Thu Mar 12 08:23:27 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 12 Mar 2009 08:23:27 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <200903121516.28384.david.goodenough@linkchoose.co.uk> References: <49B8E5C3.7040006@joda.org> <4E202F5B-15CA-49D9-B815-5521F5E293CB@zwitserloot.com> <200903121516.28384.david.goodenough@linkchoose.co.uk> Message-ID: <15e8b9d20903120823p73c02ea9qa68006e8c25b5894@mail.gmail.com> On Thu, Mar 12, 2009 at 8:16 AM, David Goodenough wrote: > You are right that getting Field or Method literals into Annotations > would be difficult, because the Annotation rules require compile time > constants as arguements (that is not what it says in the language > spec but it is what it means). ?Because Field and Method objects are not > stored in the class file directly (they are reconstructed at run time when > they are used from a binary form) it would be extreemly difficult to regard > these as compile time constants, and it would require not only a language > syntax change, compiler changes and run time changes, but also a change > to the class file format. I think adding support for field and method literals to the language can be done as a separate step from supporting them in annotations. Doing the first step as a new expression form lays the groundwork for extending annotations as a separate step, possibly in JDK8, but to me the first step looks small enough for project coin. From david.goodenough at linkchoose.co.uk Thu Mar 12 08:41:28 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 12 Mar 2009 15:41:28 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <15e8b9d20903120823p73c02ea9qa68006e8c25b5894@mail.gmail.com> References: <200903121516.28384.david.goodenough@linkchoose.co.uk> <15e8b9d20903120823p73c02ea9qa68006e8c25b5894@mail.gmail.com> Message-ID: <200903121541.29347.david.goodenough@linkchoose.co.uk> On Thursday 12 March 2009, Neal Gafter wrote: > On Thu, Mar 12, 2009 at 8:16 AM, David Goodenough > > wrote: > > You are right that getting Field or Method literals into Annotations > > would be difficult, because the Annotation rules require compile time > > constants as arguements (that is not what it says in the language > > spec but it is what it means). ?Because Field and Method objects are not > > stored in the class file directly (they are reconstructed at run time > > when they are used from a binary form) it would be extreemly difficult to > > regard these as compile time constants, and it would require not only a > > language syntax change, compiler changes and run time changes, but also a > > change to the class file format. > > I think adding support for field and method literals to the language > can be done as a separate step from supporting them in annotations. > Doing the first step as a new expression form lays the groundwork for > extending annotations as a separate step, possibly in JDK8, but to me > the first step looks small enough for project coin. Well the good news is that modifying the compiler to handle Field expressions is not that hard. From no internals knowledge of the compiler I have gotten a compiler which parses them correctly, and when you use -printsource prints them correctly, and I know what needs to be done to desugar them in Lower - and I only started on this last week. While I do not presume to suggest that I have done it the correct way, or that further changes and checks might be needed, if it only takes me a week (along with all the other things I do) it should not take an experienced compiler engineer long to do it properly. I did have a little help along the way, I looked at the compiler changes that Remi Forax did for his full properties proposal, which can be found on kijaro. This gave me a check list of things to do, and pointed out a few things I did not realise from the other documentation that I found. Also I have only done field expressions, not method expressions. So yes, I believe that in a restricted form either this or my lightweight properties proposal should be given serious consideration as a Coin sized proposal. David From jesse at swank.ca Thu Mar 12 09:23:31 2009 From: jesse at swank.ca (Jesse Wilson) Date: Thu, 12 Mar 2009 09:23:31 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> Message-ID: On Thu, Mar 12, 2009 at 7:30 AM, Roel Spilker wrote: > Secondly, the proposal only allows Field and Method literals that are > visible to the caller. But my experience is that I use reflection often to > access private members of other classes. So more false positives in the > search results. No, non-visible members aren't included in these search results. Class.getMethod() returns only public methods. From r.spilker at gmail.com Thu Mar 12 09:29:52 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Thu, 12 Mar 2009 17:29:52 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <1D188E61-AB57-4AAC-9724-FE47C4357A2F@zwitserloot.com> Message-ID: Oh yes, you're right. On Thu, Mar 12, 2009 at 5:23 PM, Jesse Wilson wrote: > On Thu, Mar 12, 2009 at 7:30 AM, Roel Spilker wrote: > >> Secondly, the proposal only allows Field and Method literals that are >> visible to the caller. But my experience is that I use reflection often to >> access private members of other classes. So more false positives in the >> search results. > > > No, non-visible members aren't included in these search results. > Class.getMethod() returns only public methods. > From kevinb at google.com Thu Mar 12 09:32:44 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Thu, 12 Mar 2009 09:32:44 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <15e8b9d20903111411h1669ba4blcbc9ca239b7cd494@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903111411h1669ba4blcbc9ca239b7cd494@mail.gmail.com> Message-ID: <108fcdeb0903120932o1f689f65ob4df40322393b8ec@mail.gmail.com> On Wed, Mar 11, 2009 at 2:11 PM, Neal Gafter wrote: Vilya- > > I suspect that if you narrowed the scope of this proposal to just enum > types, it would have a much better chance of getting accepted for project > Coin. To the general proposal, I believe the problem of conflicting meanings of <=, >= and == make it a non-starter. But focusing on enum types sidesteps one set of problems in favor of another. That being that most user-defined enum types do not actually have any logical order, and many that _seem_ to have an order do not actually have that order guaranteed. For example, in the core Java class libraries (java.lang, util, etc.) I counted ten enums. Not a single one guaranteed what the order of its constants meant. And, there were only two for which you could even imagine an order that makes sense. One is RetentionPolicy -- as long as there is only SOURCE, CLASS, RUNTIME, you can sort of think of them as being increasing. The other is TImeUnit, but if PICOSECONDS are ever added, we have no way of knowing *where* it would be added. (Adding it in the expected place could break all those users who were somehow depending on the ordinal; they shouldn't have done that, but Sun doesn't like to break anyone whether they should have been doing what they were doing or not.) For these reasons, I believe that the automatic Comparable-ness of all enums was a mistake -- not a mistake I'm castigating anyone for, but not one that I think we should make even deeper, either. Adding the < > support would deepen confusion, but also, because only a small number of enums have meaningful order, it means that this language feature fails the "solves actual real-world pain" test. -- Kevin Bourrillion @ Google internal: http://go/javalibraries google-collections.googlecode.com google-guice.googlecode.com From vilya.harvey at gmail.com Thu Mar 12 10:02:31 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Thu, 12 Mar 2009 17:02:31 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <108fcdeb0903120932o1f689f65ob4df40322393b8ec@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903111411h1669ba4blcbc9ca239b7cd494@mail.gmail.com> <108fcdeb0903120932o1f689f65ob4df40322393b8ec@mail.gmail.com> Message-ID: <6aef848f0903121002g57b48225yc83d3c26cf099e38@mail.gmail.com> 2009/3/12 Kevin Bourrillion > On Wed, Mar 11, 2009 at 2:11 PM, Neal Gafter wrote: > > Vilya- >> >> I suspect that if you narrowed the scope of this proposal to just enum >> types, it would have a much better chance of getting accepted for project >> Coin. > > > To the general proposal, I believe the problem of conflicting meanings of > <=, >= and == make it a non-starter. > I tried implementing the change & it was remarkably simple - without having looked at any of the openjdk code before, it took me just one evening; hats off to the compiler designers! However even the first bit of example code I wrote to test it with looked a bit strange: String a, b; ... if (a < b) System.out.println("a < b"); else if (a > b) System.out.println("a > b"); else if (a == b) System.out.println("a == b"); else System.out.println("a.compareTo(b) == 0")'; It seems really odd that the else clause is actually reachable, but of course it is. I suspect that would catch a lot of people out. So given that experience and having read everyone's comments, I've come to the conclusion that the proposal would only make sense if it was part of a larger plan that included changing the meaning of == and !=. That would be such a breaking change that I doubt it will ever happen, much less in the jdk7 time frame, so I'm withdrawing the proposal. Thanks a lot to all of you who provided me with feedback! Vil. From neal at gafter.com Thu Mar 12 11:46:07 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 12 Mar 2009 11:46:07 -0700 Subject: Proposal: Improved Exception Handling for Java In-Reply-To: <49AF0ABB.20104@sun.com> References: <15e8b9d20902272122p6a21f193g35c2df0000996018@mail.gmail.com> <15e8b9d20902272132t214c30f3v23d0abf17b2f8c04@mail.gmail.com> <49ACCE49.8030103@sun.com> <15e8b9d20903022333x33e5fbe2kd69df4ca94543da2@mail.gmail.com> <08E77F6F-6D7F-4A0F-B389-4851039220F0@zwitserloot.com> <15e8b9d20903030704j4fbf2f31if64f59b381c8864f@mail.gmail.com> <49AF0ABB.20104@sun.com> Message-ID: <15e8b9d20903121146j3995df48p31311b73450961f1@mail.gmail.com> I've updated the "Improved Exception Handling" proposal. The current rich-text version can be found at http://docs.google.com/Doc?id=ddb3zt39_76dtz7bsg2 In the "Compatibility" section, I added the following: "Because the point of the rethrow proposal is to improve the precision of exception checking, and Java is sensitive to catch clauses that it determines to be unreachable, the most straightforward way to make this change fully compatible is to simply remove Java's requirement that catch clauses be reachable. The requirement could be eliminated or made a mandatory warning. "It is a bit harder to support muticatch alone without either special treatment for final catch parameters or disjunction types. The simplest way is to disallow assigning to multicatch parameters (i.e. making them implicitly final), and when they're rethrown use the types from the catch parameter's declaration as the thrown types for exception analysis. This would not be a breaking change, but would be more likely to create a breaking change later if special treatment for final catch clauses were added." I've also added the following tutorial material to the "advanced example" section: ADVANCED EXAMPLE: Catching Multiple Exception Types Sometimes you need to handle one of several exception types with the same code: try { return klass.newInstance(); } catch (InstantiationException e) { throw new AssertionError(e); } catch (IllegalAccessException e) { throw new AssertionError(e); } One alternative is to find a common supertype of these exceptions and catch just that type: // Broken - catches exceptions that should be allowed to propagate! try { return klass.newInstance(); } catch (Exception e) { throw new AssertionError(e); } Unfortunately, that can catch more exceptions than you intend. In this example, it wraps all unchecked exceptions in AssertionError. This proposal makes it possible to catch two or more exception types in a single catch clause: try { return klass.newInstance(); } catch (final InstantiationException | IllegalAccessException e) { throw new AssertionError(e); } Improved Checking for Rethrown Exceptions Occasionally you need to intercept all exceptions, do something with them, and allow them to propogate. Doing this today is awkward. One way is to catch Throwable. But how do you rethrow it, without declaring Throwable in the current method and everything above it on the call stack? try { doable.doIt(); // Specified to throw several different exceptions } catch (Throwable ex) { logger.log(ex); throw ex; // Won't compile unless method is specified to throw Throwable! } Because this code throws an expression whose dynamic type is Throwable, the compiler currently thinks that the throw statement can throw any checked exception type. Java Puzzlers describes a couple of ways of rethrowing an exception such that the compiler's exception checking is circumvented. Some folks would resort to secret sun.Misc APIs. Some programmers wrap the exception prior to rethrowing it: try { doable.doIt(); } catch (Throwable ex) { logger.log(ex); throw new WrappedException(ex); // Obscures exception type! } Unfortunately, this approach wraps all checked as well as unchecked exceptions. We really want the rethrown exception to be treated as if this try-finally block can only throw checked exceptions that are thrown in the try block. If a caught exception is declared final, it is safe to rethrow any caught exception: try { doable.doIt(); } catch (final Throwable ex) { logger.log(ex); throw ex; } Because the catch parameter is final, it can only hold exceptions that are thrown from the try block. This proposal enables exception checking to take advantage of that fact: a rethrown final catch parameter is treated as if it throws only exceptions that occur in the try block. From alexdmiller at yahoo.com Thu Mar 12 12:19:14 2009 From: alexdmiller at yahoo.com (Alex Miller) Date: Thu, 12 Mar 2009 12:19:14 -0700 (PDT) Subject: Draft proposal: allow the use of relational operators on Comparable classes References: Message-ID: <6431.74648.qm@web32208.mail.mud.yahoo.com> Kevin Bourrillion said: > But focusing on enum types sidesteps one set of problems in favor of > another. That being that most user-defined enum types do not actually have > any logical order, and many that _seem_ to have an order do not actually > have that order guaranteed. I would love to have the relational operators on enums...when it makes sense. What if there was a marker interface that your enum could implement? Something like OrderedEnum? I suppose it might be bad form to have the language behavior as to whether something is legal be dependent on a marker interface. But you guys are the experts. Alex From jjb at google.com Thu Mar 12 12:20:39 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 12 Mar 2009 12:20:39 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6431.74648.qm@web32208.mail.mud.yahoo.com> References: <6431.74648.qm@web32208.mail.mud.yahoo.com> Message-ID: <17b2302a0903121220r188ef614g9c275523e0b0adc3@mail.gmail.com> Alex, Arguably it's a bit too late: the marker (or whatever) should have triggered whether the enum implemented the Comparable interface as well:( Josh On Thu, Mar 12, 2009 at 12:19 PM, Alex Miller wrote: > > > Kevin Bourrillion said: > > > But focusing on enum types sidesteps one set of problems in favor of > > another. That being that most user-defined enum types do not actually > have > > any logical order, and many that _seem_ to have an order do not actually > > have that order guaranteed. > > I would love to have the relational operators on enums...when it makes > sense. What if there was a marker interface that your enum could implement? > Something like OrderedEnum? > > I suppose it might be bad form to have the language behavior as to whether > something is legal be dependent on a marker interface. But you guys are the > experts. > > Alex > > From neal at gafter.com Thu Mar 12 12:43:59 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 12 Mar 2009 12:43:59 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <17b2302a0903121220r188ef614g9c275523e0b0adc3@mail.gmail.com> References: <6431.74648.qm@web32208.mail.mud.yahoo.com> <17b2302a0903121220r188ef614g9c275523e0b0adc3@mail.gmail.com> Message-ID: <15e8b9d20903121243n5691698esc12f14bba115bedb@mail.gmail.com> Agreed. Like it or not, the language has already taken a position on this: all enum types are ordered and comparable. You can ignore that fact if you want, which as kevin pointed out most uses do, but when its helpful it is very nice to have it automatic. Given that all enums are already ordered, if anything is to be done with the relational operators for enums, they should all get support of the relational operators. On Thu, Mar 12, 2009 at 12:20 PM, Joshua Bloch wrote: > Alex, > > Arguably it's a bit too late: the marker (or whatever) should have triggered > whether the enum implemented the Comparable interface as well:( > > ? ? ? Josh > > On Thu, Mar 12, 2009 at 12:19 PM, Alex Miller wrote: > >> >> >> Kevin Bourrillion said: >> >> > But focusing on enum types sidesteps one set of problems in favor of >> > another. ?That being that most user-defined enum types do not actually >> have >> > any logical order, and many that _seem_ to have an order do not actually >> > have that order guaranteed. >> >> I would love to have the relational operators on enums...when it makes >> sense. ?What if there was a marker interface that your enum could implement? >> ?Something like OrderedEnum? >> >> I suppose it might be bad form to have the language behavior as to whether >> something is legal be dependent on a marker interface. ?But you guys are the >> experts. >> >> Alex >> >> > > From forax at univ-mlv.fr Thu Mar 12 13:55:30 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 12 Mar 2009 21:55:30 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> Message-ID: <49B976C2.4070902@univ-mlv.fr> Neal Gafter a ?crit : > On Wed, Mar 11, 2009 at 4:37 PM, Stephen Colebourne > wrote: > >>>> In summary, the real question with the proposal is whether we can >>>> implement member literals independently of method references and >>>> closures? The answer is definitely yes if we use the ## syntax, and >>>> probably yes if we use #. >>>> >>> Is there something I should mention in the proposal? >>> >> I think the proposal needs to note that a resolution of the potential >> conflict with method reference/eta expansion is required. This could to >> let later changes handle it, to accept method references are boxed, or >> to use a different syntax. Perhaps there is another option too. (I know >> Neal has some concerns on this conflict of syntax) >> > > I may regret saying this later, but I am not concerned about the > potential conflict. I believe we can use the exact same syntax and > distinguish whether it should be a java.lang.reflect.Method or a > closure from context. Since we're doing Method first, it would take > priority (just like a method invocation that requires no boxing is > preferred during overload resolution to one that requires some > argument to be boxed). > > Neal, I don't know if you will regret saying this but I will regret to not saying that it will create lot of puzzlers like this one: class A { static int f(int) { ... } } ... {int => int} c=A#f(int); A#f(int).equals(c) // false because A#f(int) is a java.lang.reflect.Method R?mi From markmahieu at googlemail.com Thu Mar 12 14:01:36 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 12 Mar 2009 21:01:36 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B976C2.4070902@univ-mlv.fr> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> Message-ID: <710FE828-BF9B-4AA3-9514-BE990D43F7BF@googlemail.com> On 12 Mar 2009, at 20:55, R?mi Forax wrote: > Neal Gafter a ?crit : >> >> I may regret saying this later, but I am not concerned about the >> potential conflict. I believe we can use the exact same syntax and >> distinguish whether it should be a java.lang.reflect.Method or a >> closure from context. Since we're doing Method first, it would take >> priority (just like a method invocation that requires no boxing is >> preferred during overload resolution to one that requires some >> argument to be boxed). >> >> > Neal, > I don't know if you will regret saying this but > I will regret to not saying that it will create lot of puzzlers like > this one: > > class A { > static int f(int) { ... } > } > ... > {int => int} c=A#f(int); > A#f(int).equals(c) // false because A#f(int) is a > java.lang.reflect.Method > > > R?mi > I expect that would rather depend on how closure equality is defined (or not). Mark From forax at univ-mlv.fr Thu Mar 12 14:24:05 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 12 Mar 2009 22:24:05 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <710FE828-BF9B-4AA3-9514-BE990D43F7BF@googlemail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> <710FE828-BF9B-4AA3-9514-BE990D43F7BF@googlemail.com> Message-ID: <49B97D75.8010206@univ-mlv.fr> Mark Mahieu a ?crit : > > On 12 Mar 2009, at 20:55, R?mi Forax wrote: > >> Neal Gafter a ?crit : >>> >>> I may regret saying this later, but I am not concerned about the >>> potential conflict. I believe we can use the exact same syntax and >>> distinguish whether it should be a java.lang.reflect.Method or a >>> closure from context. Since we're doing Method first, it would take >>> priority (just like a method invocation that requires no boxing is >>> preferred during overload resolution to one that requires some >>> argument to be boxed). >>> >>> >> Neal, >> I don't know if you will regret saying this but >> I will regret to not saying that it will create lot of puzzlers like >> this one: >> >> class A { >> static int f(int) { ... } >> } >> ... >> {int => int} c=A#f(int); >> A#f(int).equals(c) // false because A#f(int) is a >> java.lang.reflect.Method >> >> >> R?mi >> > > I expect that would rather depend on how closure equality is defined > (or not). Here equals() is called on Method. > > Mark > R?mi From markmahieu at googlemail.com Thu Mar 12 14:33:06 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 12 Mar 2009 21:33:06 +0000 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B97D75.8010206@univ-mlv.fr> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> <710FE828-BF9B-4AA3-9514-BE990D43F7BF@googlemail.com> <49B97D75.8010206@univ-mlv.fr> Message-ID: <0B401384-D109-4D32-B02E-A3D6FC7F1EBB@googlemail.com> On 12 Mar 2009, at 21:24, R?mi Forax wrote: >>> class A { >>> static int f(int) { ... } >>> } >>> ... >>> {int => int} c=A#f(int); >>> A#f(int).equals(c) // false because A#f(int) is a >>> java.lang.reflect.Method >>> >>> >>> R?mi >>> >> >> I expect that would rather depend on how closure equality is >> defined (or not). > > Here equals() is called on Method. I saw that, but I thought your point was that the programmer may *believe* it's two objects of closure/function type being compared, and therefore expect the result to be true in this example. Have I misunderstood? Mark From neal at gafter.com Thu Mar 12 14:45:17 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 12 Mar 2009 14:45:17 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B976C2.4070902@univ-mlv.fr> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> Message-ID: <15e8b9d20903121445l21dea13cqc328c0922bb8c27e@mail.gmail.com> On Thu, Mar 12, 2009 at 1:55 PM, R?mi Forax wrote: > Neal, > I don't know if you will regret saying this but > I will regret to not saying that ?it will create lot of puzzlers like this > one: > > class A { > ?static int f(int) { ... } > } > ... > {int => int} c=A#f(int); > A#f(int).equals(c) ? ? ? ? ? ? // false because A#f(int) is a > java.lang.reflect.Method It's hard for me to imagine how to turn this into a "real" puzzler rather than just a curiosity. How do you imagine a programmer could get "bitten" by this? From forax at univ-mlv.fr Thu Mar 12 14:57:22 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 12 Mar 2009 22:57:22 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <15e8b9d20903121445l21dea13cqc328c0922bb8c27e@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> <15e8b9d20903121445l21dea13cqc328c0922bb8c27e@mail.gmail.com> Message-ID: <49B98542.5020507@univ-mlv.fr> Neal Gafter a ?crit : > On Thu, Mar 12, 2009 at 1:55 PM, R?mi Forax wrote: > >> Neal, >> I don't know if you will regret saying this but >> I will regret to not saying that it will create lot of puzzlers like this >> one: >> >> class A { >> static int f(int) { ... } >> } >> ... >> {int => int} c=A#f(int); >> A#f(int).equals(c) // false because A#f(int) is a >> java.lang.reflect.Method >> > > It's hard for me to imagine how to turn this into a "real" puzzler > rather than just a curiosity. How do you imagine a programmer could > get "bitten" by this? > Come on, implicit conversion rules always creates a mismatch between what the compiler does and what the developer think. Here, I just alias an expression, why the result is not true. R?mi From neal at gafter.com Thu Mar 12 15:00:29 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 12 Mar 2009 15:00:29 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <49B98542.5020507@univ-mlv.fr> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> <15e8b9d20903121445l21dea13cqc328c0922bb8c27e@mail.gmail.com> <49B98542.5020507@univ-mlv.fr> Message-ID: <15e8b9d20903121500r706a84b5xbabe3a79bc6c7f56@mail.gmail.com> On Thu, Mar 12, 2009 at 2:57 PM, R?mi Forax wrote: > Come on, implicit conversion rules always creates a mismatch between what > the compiler does > and what the developer think. > > Here, I just alias an expression, why the result is not true. But you're not aliasing an expression, you're writing a second expression that doesn't reference the first. From neal at gafter.com Thu Mar 12 15:28:53 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 12 Mar 2009 15:28:53 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> Message-ID: <15e8b9d20903121528x7eb3a812pe851385802a53c48@mail.gmail.com> I'd like to suggest a solution to the problem of adapting existing APIs, based on experience with C#. There is an existing type in Java's language support libraries that is used in a one-shot way, but doesn't require explicit disposal. That is java.util.Iterator. Some particular API may elect to provide a subtype of Iterator that does require disposal. One can then use the proposed resource-management statement to ensure its proper termination, but one cannot then use the for-each loop, which works only on an Iterable. C# has both a for-each loop ("foreach") and a resource-management statement ("using"). The C# equivalent to this proposal's Resource interface is IDisposable, and C#'s close method is Dispose. Unlike the present resource managment proposal, however, C#'s foreach loop invokes the iterator's dispose method when the loop exits if the iterator's type extends IDisposable. Were this proposal to take the same approach for Java (that is, specify that the for-each statement calls iterator.close() at the end of the loop if its type extends Disposable), one could build an API to easily iterate over the lines in a file, automatically closing the file when done: for (String line : eachLine(fileName)) { System.out.println(s); } The implementation would begin something like this interface DisposableIterable extends Disposable, Iterable { void close() throws X; } static DisposableIterable eachLine(String fileName) throws IOException { // implementation left as an exercise for the reader } There are some interesting aspects to the implementation. For example, because Iterable's methods are not declared to throw IOException, such exceptions must be handled before returning. This can arranged by saving an IOException in the state of the DisposableIterable, and then rethrowing it from the close method. This mechanism can also be used to build concise adapters for other types. Consider, for example, SWT's Resource class. As you may recall SWT's Path class has a dispose method that releases the resource, but the existing close method is used to complete a "closed path" by adding a line back to the start of the path. Path can't be retrofitted to implement the new Disposable interface, and therefore its superclass, SWT's Resource abstract class, can't be retrofitted either. Here is how to adapt SWT's Resource class to allow auto-disposal: static DisposableIterable autoDispose(T t) { // implementation left as an exercise for the reader } The returned iterator would yield precisely one result, which is the value passed in to the method. It would be used like this: for (Path p : autoDispose(new Path(...))) { // use the path } This is a bit of a hack, as the for-each loop doesn't read quite right for this use case, and the definite assignment rules are not ideal. But it's better than anything else I've seen to address this issue with the proposal. If this approach is pursued, there remain some minor technical points to resolve. For example, should the test for whether the Iterable implements Disposable be a static test, performed at compile-time, or a dynamic test, performed at runtime? Performing it at runtime may allow more APIs to be retrofitted, as it is not always compatible to change types in an API. However, existing compiled for-each loops do not perform that test. This might not be a change that one could compatibly add to a later release, as it would change the behavior of existing code, so if this is worth considering it should be considered now. From forax at univ-mlv.fr Thu Mar 12 17:15:11 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 13 Mar 2009 01:15:11 +0100 Subject: PROPOSAL: Method and Field Literals In-Reply-To: <15e8b9d20903121500r706a84b5xbabe3a79bc6c7f56@mail.gmail.com> References: <4b4f45e00903110611s78e4fbe6r2be1558f786b1c32@mail.gmail.com> <49B84B43.1000800@joda.org> <15e8b9d20903111658k7da4a23eof4f81ee832fb98e7@mail.gmail.com> <49B976C2.4070902@univ-mlv.fr> <15e8b9d20903121445l21dea13cqc328c0922bb8c27e@mail.gmail.com> <49B98542.5020507@univ-mlv.fr> <15e8b9d20903121500r706a84b5xbabe3a79bc6c7f56@mail.gmail.com> Message-ID: <49B9A58F.4030104@univ-mlv.fr> Neal Gafter a ?crit : > On Thu, Mar 12, 2009 at 2:57 PM, R?mi Forax wrote: > >> Come on, implicit conversion rules always creates a mismatch between what >> the compiler does >> and what the developer think. >> >> Here, I just alias an expression, why the result is not true. >> > > But you're not aliasing an expression, you're writing a second > expression that doesn't reference the first. > Yes I know ! My point is how many will know ? R?mi From jjb at google.com Thu Mar 12 21:13:32 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 12 Mar 2009 21:13:32 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> Message-ID: <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> Mark, A problem with the AutoCloseAdaptable approach, which Bob Lee pointed out, is that the emitted code would end up calling the close method of an object whose static type was AutoCloseable. Unfortunately, AutoCloseable's close method throws Exception, which means that the enclosing automatic resource management statement would throw Exception. I'm afraid that that this rules out the approach:( Josh On Tue, Mar 10, 2009 at 4:36 PM, Mark Mahieu wrote: > Hi Josh, > > On 10 Mar 2009, at 21:51, Joshua Bloch wrote: > > Tim is a bigger fan of adapters than I am (for this purpose). To the best >> of my recollection, 3 of the 5 types above could be retrofitted to implement >> AutomaticallyCloseable, and I think that's a better solution where it works. >> > > No argument there :) > > >> >> If ARM recognised this interface, and called the toAutoCloseable() >> method behind the scenes (waves hands), Resource could be made to >> implement AutoCloseAdaptable very simply, and we could write this: >> >> >> try (Path path = new Path(display)) { >> path.whatever(); >> // etc >> } >> >> >> Which is exactly what we'd want, I think. >> >> This is a possibility. It still doesn't work for interfaces, but I can't >> imagine a class for which it doesn't work. That said, I'm not sure I prefer >> it to a simple two-interface proposal (AutoCloseable + AutoDisposable). I >> suspect that this combination would enable retrofitting of nearly every >> class that could benefit from the facility. I understand that it's >> unsatisfying, but it's simpler than the AutoCloseAdaptable approach. >> > > Perhaps this does come down to how well a given variation meshes with > interfaces. > > I mean, I pity poor Jean-Luc, who brushes his teeth before bed every night, > pays his taxes on time, and prefers to expose interfaces from his APIs. > Sadly, he named his disposal method 'fermer', and can't retrofit > AutoCloseable or AutoDisposable onto his interfaces without breaking code > downstream. So he's stuck with an adapter approach anyway, only he can't > decide whether it should return an AutoCloseable or an AutoDisposable, poor > guy. > > ;) > > But seriously, it probably is a minor detail. Thanks for taking the time > to read through my suggestion. > > Regards, > > Mark > > From matthias at mernst.org Fri Mar 13 02:47:28 2009 From: matthias at mernst.org (Matthias Ernst) Date: Fri, 13 Mar 2009 10:47:28 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> Message-ID: <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount wrote: > On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot > wrote: > >> We're veering waaay offtopic here; the ARM proposal does not address >> locks. Period. Would everyone be happy if this was added in the 'major >> disadvantages' section? > > > Yes this is becoming more offtopic but hopefully my comments have brought up > two points: > > 1: Although Locks are a form of resource, the ARM proposal as is cannot > support them > 2: Someone will abuse it to support Lock's at some point with potentially > disastrous consequences. What would be the problem with: package j.u.c: abstract class AbstractLock implements Lock { private final AutoCloseable locked = new AutoCloseable() { public void close() { AbstractLock.this.unlock(); } } public AutoCloseable locked() { lock(); return locked; } } Have the j.u.c locks inherit from AbstractLock. Add in class LockSupport: public static AutoCloseable locked(final Lock lock) { return (lock instanceof AbstractLock) ? ((AbstractLock)lock).locked() : new AutoCloseable() { public void close() { lock.unlock(); } }; } Use: import static LockSupport.locked; try(locked(guard)) { } Matthias > > >> >> If locks are truly deemed crucial, or the consensus is that, >> eventhough evidently ARM-as-is can't do locks, people will try anyway >> and the resulting confusion must be avoided, I suggest that the ARM >> proposal is updated to do the right thing when an expression of type >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else >> proposed this before and I can't see any downside to this. It would be >> bad if, for every release, a bunch more types get special uniquely >> defined semantics in relation to the ARM expression, but that seems >> very unlikely. Nobody else has named a use-case that doesn't work in >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. > > > Yes I did yesterday. > > The one thing I've learned from experience is that a lot of programmers are > lazy when it comes to resources. Although for some resources are cleaned up > occasionally by the garbage collector, most are not and unless the system is > under heavy load the problem doesn't show itself until it's in the live > environment. For this reason I do feel that the ARM proposal would alleviate > this as long as the programmers know that the new construct exists. > > Now I do feel that Locks are a form of resource but one that is actively > short lived. Although it seems simple to just write them manually with a try > finally block you'll be surprised how easy it is for someone to miss the > finally block or refactor it out without noticing. In a large system this > can be costly (my gaming background coming in here). > > Over the last few years I've ended up wasting so much time debugging a > complex system to locate a deadlock just to find that someone has forgotten > to release a lock. It is this reason why I think the ARM proposal should > support Lock's as a separate use-case. > > The main issues with Disposable and Lock that I can see are: > > 1: Lock is an interface and cannot extend Disposable as that would break > existing code. Also implementing Disposable in the Lock implementations > would not work if you use try( Lock ) as javac would not see it as being > Disposable. > > 2: Normal resources are already open/active before the try so with > Disposable the try(Disposable) would simply call Disposable.close() at the > end. With Locks they are not active until lock() is called so try(Lock) > would have to call Lock.lock() before the method body and then Lock.unlock() > at the end. > > As I said in an earlier email I implement this pattern in JDK1.6 by having a > set of annotations which with a processor inject the try...finally block > around a method thats locked (yes I know annotation processors shouldn't do > this but it's removed the problem completely). Having the ARM proposal would > not just obsolete the hack but make it more flexible (as the hack only works > at the method level). > > As for any other use-cases that don't work with the current proposal other > than Lock, I can't think of any at the moment. > > >> >> ?--Reinier Zwitserloot >> >> >> On Mar 8, 2009, at 09:03, Peter Mount wrote: >> >> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson >> > wrote: >> > >> >> I am aware Lock is an interface. ?You wouldn't actually change the >> >> Lock interface, you would change the classes. ?Just as they retrofit >> >> Iterable everywhere. ?That's why I put "class Lock" there; perhaps it >> >> would have been clearer if it said "class MyLock". >> > >> > >> > What about when someone just references the lock as Lock rather than >> > the >> > implementing class? Javac won't be able to determine that the lock >> > implements Disposable so in that case it will fail.. >> > >> > >> > >> > >> >> >> >> >> >> Jeremy >> >> >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne >> >> wrote: >> >>> Jeremy Manson wrote: >> >>>> The "right" fix, if we want to support this pattern, is to allow >> >>>> the >> >>>> try resource statement to accept expressions that return >> >>>> Disposables, >> >>>> and to retrofit the relevant lock APIs with disposables and lock >> >>>> methods that return this: >> >>>> >> >>>> class Lock implements Disposable { >> >>>> ?public Lock dlock() { >> >>>> ? ?return this; >> >>>> ?} >> >>>> ?@Override public void dispose() { >> >>>> ? ?unlock(); >> >>>> ?} >> >>>> } >> >>>> >> >>> Lock is an interface. No changes are possible. >> >>> >> >>> Stephen >> >>> >> >>> >> >>> >> >> >> >> >> > >> > >> > -- >> > Peter Mount >> > e: peter at retep.org.uk >> > w: http://retep.org >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> > >> >> >> > > > -- > Peter Mount > e: peter at retep.org.uk > w: http://retep.org > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > > From markmahieu at googlemail.com Fri Mar 13 07:25:53 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 13 Mar 2009 14:25:53 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> Message-ID: <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> Hi, Josh. Yes, I see, that's clearly unacceptable. And we know that adding an exception type parameter to AutoCloseable leads to other problems. I guess trying to silently slip the adapter into the Resource class structure, without requiring the user to go through any additional steps, is a trick too far. In any case, since that can't always be done when the resource types are interfaces, it's probably better to have a uniform approach to adapters if they're going to be necessary. I think we've now illustrated a couple of reasons why an adapter method returning an AutoCloseable directly, will not work well. It doesn't fit with ARM's variable declarations, and Bob's point about the exception type would be equally valid with that approach. It may be worth persevering with the Adapter interface for a little longer though, as it is something we can parameterize with the exception type. If it's going to be returned by an adapter method rather than implemented directly by the resources, perhaps the Adapter interface should extend AutoCloseable itself: interface AutoCloseableAdapter extends AutoCloseable { void close() throws X; } That's certainly simpler than the version I suggested previously, although the name probably isn't ideal. Another aspect of my earlier suggestion that I find somewhat troubling is the way in which ARM would need special handling for two essentially unrelated interfaces. That feels messy, but I think the version above improves matters in that respect, since AutoCloseableAdapter would now be a specialization of AutoCloseable. I can see where I'm going to end up with this. The next step will be that I suggest we add a method to the Adapter type in order to allow ARM to retrieve the resource. This would then give us all the information ARM requires in one neat little interface (which would still need a better name): interface AutoCloseableAdapter extends AutoCloseable { T resource(); void close() throws X; } At this point it's starting to look very similar to the interface which Neal has just put forward for consideration, but with slightly different trade-offs and applicability. The main concern I have about this approach in general is that the variable declaration might be a little too 'magical' : you appear to start out with a resource (a Path, to continue previous themes), call a method to turn it into something completely different, then assign that to a variable of the type you started out with. Possibly a bit confusing, given a syntax that uses the assignment operator anyway. Hmmm. Mark On 13 Mar 2009, at 04:13, Joshua Bloch wrote: > Mark, > > A problem with the AutoCloseAdaptable approach, which Bob Lee > pointed out, is that the emitted code would end up calling the > close method of an object whose static type was AutoCloseable. > Unfortunately, AutoCloseable's close method throws Exception, which > means that the enclosing automatic resource management statement > would throw Exception. I'm afraid that that this rules out the > approach:( > > Josh > > On Tue, Mar 10, 2009 at 4:36 PM, Mark Mahieu > wrote: > Hi Josh, > > > On 10 Mar 2009, at 21:51, Joshua Bloch wrote: > > Tim is a bigger fan of adapters than I am (for this purpose). To > the best of my recollection, 3 of the 5 types above could be > retrofitted to implement AutomaticallyCloseable, and I think that's > a better solution where it works. > > No argument there :) > > > > > If ARM recognised this interface, and called the toAutoCloseable() > method behind the scenes (waves hands), Resource could be made to > implement AutoCloseAdaptable very simply, and we could write this: > > > try (Path path = new Path(display)) { > path.whatever(); > // etc > } > > > Which is exactly what we'd want, I think. > > This is a possibility. It still doesn't work for interfaces, but I > can't imagine a class for which it doesn't work. That said, I'm > not sure I prefer it to a simple two-interface proposal > (AutoCloseable + AutoDisposable). I suspect that this combination > would enable retrofitting of nearly every class that could benefit > from the facility. I understand that it's unsatisfying, but it's > simpler than the AutoCloseAdaptable approach. > > Perhaps this does come down to how well a given variation meshes > with interfaces. > > I mean, I pity poor Jean-Luc, who brushes his teeth before bed > every night, pays his taxes on time, and prefers to expose > interfaces from his APIs. Sadly, he named his disposal method > 'fermer', and can't retrofit AutoCloseable or AutoDisposable onto > his interfaces without breaking code downstream. So he's stuck > with an adapter approach anyway, only he can't decide whether it > should return an AutoCloseable or an AutoDisposable, poor guy. > > ;) > > But seriously, it probably is a minor detail. Thanks for taking > the time to read through my suggestion. > > Regards, > > Mark > > From kuaw26 at mail.ru Fri Mar 13 08:51:20 2009 From: kuaw26 at mail.ru (=?windows-1251?Q?=C0=EB=E5=EA=F1=E5=E9_=CA=F3=E7=ED=E5=F6=EE=E2?=) Date: Fri, 13 Mar 2009 22:51:20 +0700 Subject: Extended arrays declaration and access syntax with use of enumerated types Message-ID: PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Alexey Kuznetsov OVERVIEW Extend arrays declaration and access syntax with use of enumerated types FEATURE SUMMARY: Self-explaining syntax for declaring and accessing arrays. See examples. MAJOR ADVANTAGE: 1) The code would be more typesafe. 2) The code would be more compact and self-explained MAJOR BENEFIT: More checks at compile time. MAJOR DISADVANTAGE: Associated costs in documentation, tutorials and overall language size. ALTERNATIVES: None. EXAMPLES SIMPLE EXAMPLE: String[] strs = new String[boolean]; strs[false] = "some str_1"; strs[true] = "some str_2"; boolean someFlag = true; System.out.println(strs[b]); ADVANCED EXAMPLE: public enum MyEnum { one, two, three; } Integer[] ints = new Integer[MyEnum]; ints[MyEnum.one] = 1; ints[MyEnum.two] = 2; ints[MyEnum.three] = 3; System.out.println(ints[MyEnum.one]); DETAILS SPECIFICATION: ? COMPILATION: As today. TESTING: ? LIBRARY SUPPORT: None. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: A trivial textual substitution can be used to translate old code to the new syntax. COMPATIBILITY BREAKING CHANGES: None. EXISTING PROGRAMS: No impact. REFERENCES EXISTING BUGS: None. URL FOR PROTOTYPE (optional): None. From kuaw26 at mail.ru Fri Mar 13 09:13:03 2009 From: kuaw26 at mail.ru (=?windows-1251?Q?=C0=EB=E5=EA=F1=E5=E9_=CA=F3=E7=ED=E5=F6=EE=E2?=) Date: Fri, 13 Mar 2009 23:13:03 +0700 Subject: Add more methods to array Message-ID: PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Alexey Kuznetsov OVERVIEW More useful methods for array object. FEATURE SUMMARY: No need for utility classes like java.util.Arrays. Most of those methods should be acessible through array object. And add more useful methods. MAJOR ADVANTAGE: The code would be more compatc, elegant and self-explaining. MAJOR BENEFIT: More compact and and uderstandable code. Array would be first-class objects. MAJOR DISADVANTAGE: Associated costs in documentation, tutorials and overall language size. ALTERNATIVES: None. EXAMPLES SIMPLE EXAMPLE: String[] strs = new String[10]; .. fill array ... String[] sorted = strs.sort(); int ix = sorted.binarySearch(key); strs.fill("sample"); ADVANCED EXAMPLE: Any ideas how to implement: Higher Level Functions - Filter, Map, and Reduce ? DETAILS SPECIFICATION: ? COMPILATION: As today. TESTING: ? LIBRARY SUPPORT: None. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: A trivial textual substitution can be used to translate old code to the new syntax. COMPATIBILITY BREAKING CHANGES: None. EXISTING PROGRAMS: No impact. REFERENCES EXISTING BUGS: None. URL FOR PROTOTYPE (optional): None. From jjb at google.com Fri Mar 13 09:26:09 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 13 Mar 2009 09:26:09 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <15e8b9d20903061736v5429a7f8k199a9e38e2a3a200@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> Message-ID: <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> Matthias, Hi. This would work, but I'd have concerns about the performance. Locks have to be really fast. If we want to solve the locking case (and I'm not so sure we do), I believe that we should do so with another construct. I made a "Preproposal" for such a construct, but no one showed any enthusiasm. Josh On Fri, Mar 13, 2009 at 2:47 AM, Matthias Ernst wrote: > On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount wrote: > > On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot < > reinier at zwitserloot.com > >> wrote: > > > >> We're veering waaay offtopic here; the ARM proposal does not address > >> locks. Period. Would everyone be happy if this was added in the 'major > >> disadvantages' section? > > > > > > Yes this is becoming more offtopic but hopefully my comments have brought > up > > two points: > > > > 1: Although Locks are a form of resource, the ARM proposal as is cannot > > support them > > 2: Someone will abuse it to support Lock's at some point with potentially > > disastrous consequences. > > What would be the problem with: > > package j.u.c: > abstract class AbstractLock implements Lock { > private final AutoCloseable locked = new AutoCloseable() { > public void close() { AbstractLock.this.unlock(); } > } > > > public AutoCloseable locked() { > lock(); > return locked; > } > } > > Have the j.u.c locks inherit from AbstractLock. > > Add in class LockSupport: > public static AutoCloseable locked(final Lock lock) { > return (lock instanceof AbstractLock) ? > ((AbstractLock)lock).locked() : new AutoCloseable() { > public void close() { lock.unlock(); } > }; > } > > Use: > > import static LockSupport.locked; > > try(locked(guard)) { > > } > > > Matthias > > > > > > >> > >> If locks are truly deemed crucial, or the consensus is that, > >> eventhough evidently ARM-as-is can't do locks, people will try anyway > >> and the resulting confusion must be avoided, I suggest that the ARM > >> proposal is updated to do the right thing when an expression of type > >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else > >> proposed this before and I can't see any downside to this. It would be > >> bad if, for every release, a bunch more types get special uniquely > >> defined semantics in relation to the ARM expression, but that seems > >> very unlikely. Nobody else has named a use-case that doesn't work in > >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. > > > > > > Yes I did yesterday. > > > > The one thing I've learned from experience is that a lot of programmers > are > > lazy when it comes to resources. Although for some resources are cleaned > up > > occasionally by the garbage collector, most are not and unless the system > is > > under heavy load the problem doesn't show itself until it's in the live > > environment. For this reason I do feel that the ARM proposal would > alleviate > > this as long as the programmers know that the new construct exists. > > > > Now I do feel that Locks are a form of resource but one that is actively > > short lived. Although it seems simple to just write them manually with a > try > > finally block you'll be surprised how easy it is for someone to miss the > > finally block or refactor it out without noticing. In a large system this > > can be costly (my gaming background coming in here). > > > > Over the last few years I've ended up wasting so much time debugging a > > complex system to locate a deadlock just to find that someone has > forgotten > > to release a lock. It is this reason why I think the ARM proposal should > > support Lock's as a separate use-case. > > > > The main issues with Disposable and Lock that I can see are: > > > > 1: Lock is an interface and cannot extend Disposable as that would break > > existing code. Also implementing Disposable in the Lock implementations > > would not work if you use try( Lock ) as javac would not see it as being > > Disposable. > > > > 2: Normal resources are already open/active before the try so with > > Disposable the try(Disposable) would simply call Disposable.close() at > the > > end. With Locks they are not active until lock() is called so try(Lock) > > would have to call Lock.lock() before the method body and then > Lock.unlock() > > at the end. > > > > As I said in an earlier email I implement this pattern in JDK1.6 by > having a > > set of annotations which with a processor inject the try...finally block > > around a method thats locked (yes I know annotation processors shouldn't > do > > this but it's removed the problem completely). Having the ARM proposal > would > > not just obsolete the hack but make it more flexible (as the hack only > works > > at the method level). > > > > As for any other use-cases that don't work with the current proposal > other > > than Lock, I can't think of any at the moment. > > > > > >> > >> --Reinier Zwitserloot > >> > >> > >> On Mar 8, 2009, at 09:03, Peter Mount wrote: > >> > >> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson > >> > wrote: > >> > > >> >> I am aware Lock is an interface. You wouldn't actually change the > >> >> Lock interface, you would change the classes. Just as they retrofit > >> >> Iterable everywhere. That's why I put "class Lock" there; perhaps it > >> >> would have been clearer if it said "class MyLock". > >> > > >> > > >> > What about when someone just references the lock as Lock rather than > >> > the > >> > implementing class? Javac won't be able to determine that the lock > >> > implements Disposable so in that case it will fail.. > >> > > >> > > >> > > >> > > >> >> > >> >> > >> >> Jeremy > >> >> > >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne > >> >> wrote: > >> >>> Jeremy Manson wrote: > >> >>>> The "right" fix, if we want to support this pattern, is to allow > >> >>>> the > >> >>>> try resource statement to accept expressions that return > >> >>>> Disposables, > >> >>>> and to retrofit the relevant lock APIs with disposables and lock > >> >>>> methods that return this: > >> >>>> > >> >>>> class Lock implements Disposable { > >> >>>> public Lock dlock() { > >> >>>> return this; > >> >>>> } > >> >>>> @Override public void dispose() { > >> >>>> unlock(); > >> >>>> } > >> >>>> } > >> >>>> > >> >>> Lock is an interface. No changes are possible. > >> >>> > >> >>> Stephen > >> >>> > >> >>> > >> >>> > >> >> > >> >> > >> > > >> > > >> > -- > >> > Peter Mount > >> > e: peter at retep.org.uk > >> > w: http://retep.org > >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > >> > > >> > >> > >> > > > > > > -- > > Peter Mount > > e: peter at retep.org.uk > > w: http://retep.org > > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > > > > > > From Joe.Darcy at Sun.COM Fri Mar 13 09:30:14 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Fri, 13 Mar 2009 09:30:14 -0700 Subject: Add more methods to array In-Reply-To: References: Message-ID: <49BA8A16.3060702@sun.com> ??????? ???????? wrote: > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Alexey Kuznetsov > > OVERVIEW > More useful methods for array object. > > [snip] > DETAILS > SPECIFICATION: > ? > Any proposal without a specification is not a proposal. -Joe From neal at gafter.com Fri Mar 13 09:54:45 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 13 Mar 2009 09:54:45 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> Message-ID: <15e8b9d20903130954m7c32d5bbv349e26f938d17110@mail.gmail.com> I agree that one might want to avoid this construct in performance critical code, and I also agree that it probably doesn't make sense to add a construct that addresses locks in particular (but only locks). I think Jeremy was right when he suggested that locks are being discussed as a proxy for a category of resources that are not well handled by the proposal in its current form. On Fri, Mar 13, 2009 at 9:26 AM, Joshua Bloch wrote: > Matthias, > > Hi. This would work, but I'd have concerns about the performance. Locks have > to be really fast. ?If we want to solve the locking case (and I'm not so > sure we do), I believe that we should do so with another construct. ?I made > a "Preproposal" for such a construct, but no one showed any enthusiasm. > > ? ? ? ? ?Josh > > On Fri, Mar 13, 2009 at 2:47 AM, Matthias Ernst wrote: > >> On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount wrote: >> > On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot < >> reinier at zwitserloot.com >> >> wrote: >> > >> >> We're veering waaay offtopic here; the ARM proposal does not address >> >> locks. Period. Would everyone be happy if this was added in the 'major >> >> disadvantages' section? >> > >> > >> > Yes this is becoming more offtopic but hopefully my comments have brought >> up >> > two points: >> > >> > 1: Although Locks are a form of resource, the ARM proposal as is cannot >> > support them >> > 2: Someone will abuse it to support Lock's at some point with potentially >> > disastrous consequences. >> >> What would be the problem with: >> >> package j.u.c: >> abstract class AbstractLock implements Lock { >> ?private final AutoCloseable locked = new AutoCloseable() { >> ? ?public void close() { AbstractLock.this.unlock(); } >> ?} >> >> >> ?public AutoCloseable locked() { >> ? ?lock(); >> ? ?return locked; >> ?} >> } >> >> Have the j.u.c locks inherit from AbstractLock. >> >> Add in class LockSupport: >> ?public static AutoCloseable locked(final Lock lock) { >> ? ?return (lock instanceof AbstractLock) ? >> ((AbstractLock)lock).locked() : new AutoCloseable() { >> ? ? ?public void close() { lock.unlock(); } >> ? ?}; >> ?} >> >> Use: >> >> import static LockSupport.locked; >> >> try(locked(guard)) { >> >> } >> >> >> Matthias >> >> > >> > >> >> >> >> If locks are truly deemed crucial, or the consensus is that, >> >> eventhough evidently ARM-as-is can't do locks, people will try anyway >> >> and the resulting confusion must be avoided, I suggest that the ARM >> >> proposal is updated to do the right thing when an expression of type >> >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else >> >> proposed this before and I can't see any downside to this. It would be >> >> bad if, for every release, a bunch more types get special uniquely >> >> defined semantics in relation to the ARM expression, but that seems >> >> very unlikely. Nobody else has named a use-case that doesn't work in >> >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. >> > >> > >> > Yes I did yesterday. >> > >> > The one thing I've learned from experience is that a lot of programmers >> are >> > lazy when it comes to resources. Although for some resources are cleaned >> up >> > occasionally by the garbage collector, most are not and unless the system >> is >> > under heavy load the problem doesn't show itself until it's in the live >> > environment. For this reason I do feel that the ARM proposal would >> alleviate >> > this as long as the programmers know that the new construct exists. >> > >> > Now I do feel that Locks are a form of resource but one that is actively >> > short lived. Although it seems simple to just write them manually with a >> try >> > finally block you'll be surprised how easy it is for someone to miss the >> > finally block or refactor it out without noticing. In a large system this >> > can be costly (my gaming background coming in here). >> > >> > Over the last few years I've ended up wasting so much time debugging a >> > complex system to locate a deadlock just to find that someone has >> forgotten >> > to release a lock. It is this reason why I think the ARM proposal should >> > support Lock's as a separate use-case. >> > >> > The main issues with Disposable and Lock that I can see are: >> > >> > 1: Lock is an interface and cannot extend Disposable as that would break >> > existing code. Also implementing Disposable in the Lock implementations >> > would not work if you use try( Lock ) as javac would not see it as being >> > Disposable. >> > >> > 2: Normal resources are already open/active before the try so with >> > Disposable the try(Disposable) would simply call Disposable.close() at >> the >> > end. With Locks they are not active until lock() is called so try(Lock) >> > would have to call Lock.lock() before the method body and then >> Lock.unlock() >> > at the end. >> > >> > As I said in an earlier email I implement this pattern in JDK1.6 by >> having a >> > set of annotations which with a processor inject the try...finally block >> > around a method thats locked (yes I know annotation processors shouldn't >> do >> > this but it's removed the problem completely). Having the ARM proposal >> would >> > not just obsolete the hack but make it more flexible (as the hack only >> works >> > at the method level). >> > >> > As for any other use-cases that don't work with the current proposal >> other >> > than Lock, I can't think of any at the moment. >> > >> > >> >> >> >> ?--Reinier Zwitserloot >> >> >> >> >> >> On Mar 8, 2009, at 09:03, Peter Mount wrote: >> >> >> >> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson >> >> > wrote: >> >> > >> >> >> I am aware Lock is an interface. ?You wouldn't actually change the >> >> >> Lock interface, you would change the classes. ?Just as they retrofit >> >> >> Iterable everywhere. ?That's why I put "class Lock" there; perhaps it >> >> >> would have been clearer if it said "class MyLock". >> >> > >> >> > >> >> > What about when someone just references the lock as Lock rather than >> >> > the >> >> > implementing class? Javac won't be able to determine that the lock >> >> > implements Disposable so in that case it will fail.. >> >> > >> >> > >> >> > >> >> > >> >> >> >> >> >> >> >> >> Jeremy >> >> >> >> >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne >> >> >> wrote: >> >> >>> Jeremy Manson wrote: >> >> >>>> The "right" fix, if we want to support this pattern, is to allow >> >> >>>> the >> >> >>>> try resource statement to accept expressions that return >> >> >>>> Disposables, >> >> >>>> and to retrofit the relevant lock APIs with disposables and lock >> >> >>>> methods that return this: >> >> >>>> >> >> >>>> class Lock implements Disposable { >> >> >>>> ?public Lock dlock() { >> >> >>>> ? ?return this; >> >> >>>> ?} >> >> >>>> ?@Override public void dispose() { >> >> >>>> ? ?unlock(); >> >> >>>> ?} >> >> >>>> } >> >> >>>> >> >> >>> Lock is an interface. No changes are possible. >> >> >>> >> >> >>> Stephen >> >> >>> >> >> >>> >> >> >>> >> >> >> >> >> >> >> >> > >> >> > >> >> > -- >> >> > Peter Mount >> >> > e: peter at retep.org.uk >> >> > w: http://retep.org >> >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> >> > >> >> >> >> >> >> >> > >> > >> > -- >> > Peter Mount >> > e: peter at retep.org.uk >> > w: http://retep.org >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> > >> > >> >> > > From edward.ribeiro at gmail.com Fri Mar 13 09:57:52 2009 From: edward.ribeiro at gmail.com (Edward Ribeiro) Date: Fri, 13 Mar 2009 13:57:52 -0300 Subject: Implementations Message-ID: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> Hi, Just out of curiosity, is any of these proposals already implemented so that we can play with it? I am appreciating the discussions, but a proof of concept would be really helpful. Cheers, Ed From belingueres at gmail.com Fri Mar 13 10:06:53 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Fri, 13 Mar 2009 15:06:53 -0200 Subject: Extended arrays declaration and access syntax with use of enumerated types In-Reply-To: References: Message-ID: ALTERNATIVES none? You could use a Map implementation, or even a SortedMap implementation if you need to keep an order between the keys. Regards, Gabriel 2009/3/13, ??????? ???????? : > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Alexey Kuznetsov > > OVERVIEW > Extend arrays declaration and access syntax with use of enumerated types > > FEATURE SUMMARY: > Self-explaining syntax for declaring and accessing arrays. > See examples. > > MAJOR ADVANTAGE: > 1) The code would be more typesafe. > 2) The code would be more compact and self-explained > > MAJOR BENEFIT: > More checks at compile time. > > MAJOR DISADVANTAGE: > Associated costs in documentation, tutorials and overall language size. > > ALTERNATIVES: > None. > > EXAMPLES > SIMPLE EXAMPLE: > String[] strs = new String[boolean]; > strs[false] = "some str_1"; > strs[true] = "some str_2"; > boolean someFlag = true; > System.out.println(strs[b]); > > ADVANCED EXAMPLE: > > public enum MyEnum > { > one, two, three; > } > Integer[] ints = new Integer[MyEnum]; > ints[MyEnum.one] = 1; > ints[MyEnum.two] = 2; > ints[MyEnum.three] = 3; > System.out.println(ints[MyEnum.one]); > > DETAILS > SPECIFICATION: > ? > > COMPILATION: > As today. > > TESTING: > ? > > LIBRARY SUPPORT: > None. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > A trivial textual substitution can be used to translate old code to the new syntax. > > COMPATIBILITY > > BREAKING CHANGES: > None. > > EXISTING PROGRAMS: > No impact. > > REFERENCES > > EXISTING BUGS: > None. > > URL FOR PROTOTYPE (optional): > None. > > From peter at retep.org.uk Fri Mar 13 10:08:53 2009 From: peter at retep.org.uk (Peter Mount) Date: Fri, 13 Mar 2009 17:08:53 +0000 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> Message-ID: <85bf933e0903131008l60a7648s72723a5fd91fcfce@mail.gmail.com> On Fri, Mar 13, 2009 at 4:26 PM, Joshua Bloch wrote: > Matthias, > > Hi. This would work, but I'd have concerns about the performance. Locks > have to be really fast. If we want to solve the locking case (and I'm not > so sure we do), I believe that we should do so with another construct. I > made a "Preproposal" for such a construct, but no one showed any enthusiasm. I think there was some enthusiasm but Tim Peierls response about three days ago sort of killed the discussion a bit. Peter > > Josh > > > On Fri, Mar 13, 2009 at 2:47 AM, Matthias Ernst wrote: > >> On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount wrote: >> > On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot < >> reinier at zwitserloot.com >> >> wrote: >> > >> >> We're veering waaay offtopic here; the ARM proposal does not address >> >> locks. Period. Would everyone be happy if this was added in the 'major >> >> disadvantages' section? >> > >> > >> > Yes this is becoming more offtopic but hopefully my comments have >> brought up >> > two points: >> > >> > 1: Although Locks are a form of resource, the ARM proposal as is cannot >> > support them >> > 2: Someone will abuse it to support Lock's at some point with >> potentially >> > disastrous consequences. >> >> What would be the problem with: >> >> package j.u.c: >> abstract class AbstractLock implements Lock { >> private final AutoCloseable locked = new AutoCloseable() { >> public void close() { AbstractLock.this.unlock(); } >> } >> >> >> public AutoCloseable locked() { >> lock(); >> return locked; >> } >> } >> >> Have the j.u.c locks inherit from AbstractLock. >> >> Add in class LockSupport: >> public static AutoCloseable locked(final Lock lock) { >> return (lock instanceof AbstractLock) ? >> ((AbstractLock)lock).locked() : new AutoCloseable() { >> public void close() { lock.unlock(); } >> }; >> } >> >> Use: >> >> import static LockSupport.locked; >> >> try(locked(guard)) { >> >> } >> >> >> Matthias >> >> > >> > >> >> >> >> If locks are truly deemed crucial, or the consensus is that, >> >> eventhough evidently ARM-as-is can't do locks, people will try anyway >> >> and the resulting confusion must be avoided, I suggest that the ARM >> >> proposal is updated to do the right thing when an expression of type >> >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else >> >> proposed this before and I can't see any downside to this. It would be >> >> bad if, for every release, a bunch more types get special uniquely >> >> defined semantics in relation to the ARM expression, but that seems >> >> very unlikely. Nobody else has named a use-case that doesn't work in >> >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. >> > >> > >> > Yes I did yesterday. >> > >> > The one thing I've learned from experience is that a lot of programmers >> are >> > lazy when it comes to resources. Although for some resources are cleaned >> up >> > occasionally by the garbage collector, most are not and unless the >> system is >> > under heavy load the problem doesn't show itself until it's in the live >> > environment. For this reason I do feel that the ARM proposal would >> alleviate >> > this as long as the programmers know that the new construct exists. >> > >> > Now I do feel that Locks are a form of resource but one that is actively >> > short lived. Although it seems simple to just write them manually with a >> try >> > finally block you'll be surprised how easy it is for someone to miss the >> > finally block or refactor it out without noticing. In a large system >> this >> > can be costly (my gaming background coming in here). >> > >> > Over the last few years I've ended up wasting so much time debugging a >> > complex system to locate a deadlock just to find that someone has >> forgotten >> > to release a lock. It is this reason why I think the ARM proposal should >> > support Lock's as a separate use-case. >> > >> > The main issues with Disposable and Lock that I can see are: >> > >> > 1: Lock is an interface and cannot extend Disposable as that would break >> > existing code. Also implementing Disposable in the Lock implementations >> > would not work if you use try( Lock ) as javac would not see it as being >> > Disposable. >> > >> > 2: Normal resources are already open/active before the try so with >> > Disposable the try(Disposable) would simply call Disposable.close() at >> the >> > end. With Locks they are not active until lock() is called so try(Lock) >> > would have to call Lock.lock() before the method body and then >> Lock.unlock() >> > at the end. >> > >> > As I said in an earlier email I implement this pattern in JDK1.6 by >> having a >> > set of annotations which with a processor inject the try...finally block >> > around a method thats locked (yes I know annotation processors shouldn't >> do >> > this but it's removed the problem completely). Having the ARM proposal >> would >> > not just obsolete the hack but make it more flexible (as the hack only >> works >> > at the method level). >> > >> > As for any other use-cases that don't work with the current proposal >> other >> > than Lock, I can't think of any at the moment. >> > >> > >> >> >> >> --Reinier Zwitserloot >> >> >> >> >> >> On Mar 8, 2009, at 09:03, Peter Mount wrote: >> >> >> >> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson >> >> > wrote: >> >> > >> >> >> I am aware Lock is an interface. You wouldn't actually change the >> >> >> Lock interface, you would change the classes. Just as they retrofit >> >> >> Iterable everywhere. That's why I put "class Lock" there; perhaps >> it >> >> >> would have been clearer if it said "class MyLock". >> >> > >> >> > >> >> > What about when someone just references the lock as Lock rather than >> >> > the >> >> > implementing class? Javac won't be able to determine that the lock >> >> > implements Disposable so in that case it will fail.. >> >> > >> >> > >> >> > >> >> > >> >> >> >> >> >> >> >> >> Jeremy >> >> >> >> >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne >> >> >> wrote: >> >> >>> Jeremy Manson wrote: >> >> >>>> The "right" fix, if we want to support this pattern, is to allow >> >> >>>> the >> >> >>>> try resource statement to accept expressions that return >> >> >>>> Disposables, >> >> >>>> and to retrofit the relevant lock APIs with disposables and lock >> >> >>>> methods that return this: >> >> >>>> >> >> >>>> class Lock implements Disposable { >> >> >>>> public Lock dlock() { >> >> >>>> return this; >> >> >>>> } >> >> >>>> @Override public void dispose() { >> >> >>>> unlock(); >> >> >>>> } >> >> >>>> } >> >> >>>> >> >> >>> Lock is an interface. No changes are possible. >> >> >>> >> >> >>> Stephen >> >> >>> >> >> >>> >> >> >>> >> >> >> >> >> >> >> >> > >> >> > >> >> > -- >> >> > Peter Mount >> >> > e: peter at retep.org.uk >> >> > w: http://retep.org >> >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> >> > >> >> >> >> >> >> >> > >> > >> > -- >> > Peter Mount >> > e: peter at retep.org.uk >> > w: http://retep.org >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> > >> > >> >> > -- Peter Mount e: peter at retep.org.uk w: http://retep.org Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com From markmahieu at googlemail.com Fri Mar 13 10:15:15 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 13 Mar 2009 17:15:15 +0000 Subject: Implementations In-Reply-To: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> References: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> Message-ID: <7611BDAE-DBE5-45F8-A1C1-823A40C15612@gmail.co.uk> Mine has a prototype but I haven't finished writing up the proposal yet! I know, I know, the spec should come *before* the implementation... ;) Mark On 13 Mar 2009, at 16:57, Edward Ribeiro wrote: > Hi, > > Just out of curiosity, is any of these proposals already implemented > so that we can play with it? I am appreciating the discussions, but a > proof of concept would be really helpful. > > Cheers, > Ed > From scolebourne at joda.org Fri Mar 13 10:51:25 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Fri, 13 Mar 2009 17:51:25 +0000 Subject: Implementations In-Reply-To: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> References: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> Message-ID: <4b4f45e00903131051g1d815c65t819a808275caf309@mail.gmail.com> There are a number of implementations of various changes (both submitted and not, and with various degrees of success) at Kijaro - http://kijaro.dev.java.net I'll grant access to anyone who wants a new branch in svn. Stephen 2009/3/13 Edward Ribeiro : > Hi, > > Just out of curiosity, is any of these proposals already implemented > so that we can play with it? I am appreciating the discussions, but a > proof of concept would be really helpful. > > Cheers, > Ed > > From neal at gafter.com Fri Mar 13 11:00:10 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 13 Mar 2009 11:00:10 -0700 Subject: Implementations In-Reply-To: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> References: <123dcca0903130957qa760e13r732283564249b3d4@mail.gmail.com> Message-ID: <15e8b9d20903131100o2939f09cl72508252212c042a@mail.gmail.com> Multicatch is implemented in the BGGA prototype (http://www.javac.info), but based on a different spec (by adding support for disjunction types). The main difference in practice is that the BGGA version does not require the catch parameter to be final. -Neal On Fri, Mar 13, 2009 at 9:57 AM, Edward Ribeiro wrote: > Hi, > > Just out of curiosity, is any of these proposals already implemented > so that we can play with it? I am appreciating the discussions, but a > proof of concept would be really helpful. > > Cheers, > Ed > > From jjb at google.com Fri Mar 13 11:05:48 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 13 Mar 2009 11:05:48 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> References: <49B576EE.40703@sun.com> <15e8b9d20903092025i1f1863c0ie0775b6610cf1f18@mail.gmail.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> Message-ID: <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> Hi Mark, On Fri, Mar 13, 2009 at 7:25 AM, Mark Mahieu wrote: > > > It may be worth persevering with the Adapter interface for a little longer > though, as it is something we can parameterize with the exception type. If > it's going to be returned by an adapter method rather than implemented > directly by the resources, perhaps the Adapter interface should extend > AutoCloseable itself: > > > interface AutoCloseableAdapter > extends AutoCloseable { > > void close() throws X; > } > > A problem with this is that parameterizing the exception type thrown by a method doesn't work very well (as I'm sure you're aware). Methods can be declared to throw multiple exceptions, but Java doesn't provide any way of expressing this disjunction of types. Therefore, users of an interface prameterized in the exception thrown by a method have to make do with the "least common ancestor" of all the unchecked exceptions thrown by the method. Usually this is java.lang.Exception, which is unacceptable. > > The main concern I have about this approach in general is that the variable > declaration might be a little too 'magical' : you appear to start out with a > resource (a Path, to continue previous themes), call a method to turn it > into something completely different, then assign that to a variable of the > type you started out with. Possibly a bit confusing, given a syntax that > uses the assignment operator anyway. > I would tend to agree with you on this. Bob Lee conjectures that we simply don't need adapters: that AutoCloseablesolves a sufficiently large fraction of the cases of interest that it's all we need. He has investigated many of the cases that aren't addressed by this interface, and finds them uncompelling. But neither Bob nor I are GUI programmers by trade. Bob suggested that I put together a freely writable Google doc that would allow all of us to collaborate on compiling a list of types for which this automatic resource management might be of interest. This document could help us assess and refine the proposal. The criteria for deciding whether a type is appropriate for automatic resource management are simple: (1) Typical use of the type must require "lexically scoped resource management." In other words, best practice dictates that the resource be disposed of in the same scope that it was created. This is true for some *but not all* types with close/dispose methods. (2) The type must be in very common use; if a type is rarely used, it barely matter whether the construct handles it. I have created a document for this purpose ( http://docs.google.com/Doc?id=ddv8ts74_1d7tz65fd), and anyone who wants can add to it. Please participate (constructively)! Thanks, Josh From jjb at google.com Fri Mar 13 11:27:58 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 13 Mar 2009 11:27:58 -0700 Subject: Proposal: Automatic Resource Management In-Reply-To: <15e8b9d20903130954m7c32d5bbv349e26f938d17110@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> <15e8b9d20903130954m7c32d5bbv349e26f938d17110@mail.gmail.com> Message-ID: <17b2302a0903131127g383e1f79s2a2963144f2f1b0e@mail.gmail.com> Hi Neal, Please take a look my recent response to Mark Mahieu. Briefly, I want to prepare a survey of types for which automatic resource management would be useful. I believe this is best done collaboratively, as all of us have expertise in different areas. I have started the document, and I welcome all contributions. I believe that this document will go a long way towards answering these questions. Josh On Fri, Mar 13, 2009 at 9:54 AM, Neal Gafter wrote: > I agree that one might want to avoid this construct in performance > critical code, and I also agree that it probably doesn't make sense to > add a construct that addresses locks in particular (but only locks). > I think Jeremy was right when he suggested that locks are being > discussed as a proxy for a category of resources that are not well > handled by the proposal in its current form. > > On Fri, Mar 13, 2009 at 9:26 AM, Joshua Bloch wrote: > > Matthias, > > > > Hi. This would work, but I'd have concerns about the performance. Locks > have > > to be really fast. If we want to solve the locking case (and I'm not so > > sure we do), I believe that we should do so with another construct. I > made > > a "Preproposal" for such a construct, but no one showed any enthusiasm. > > > > Josh > > > > On Fri, Mar 13, 2009 at 2:47 AM, Matthias Ernst > wrote: > > > >> On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount > wrote: > >> > On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot < > >> reinier at zwitserloot.com > >> >> wrote: > >> > > >> >> We're veering waaay offtopic here; the ARM proposal does not address > >> >> locks. Period. Would everyone be happy if this was added in the > 'major > >> >> disadvantages' section? > >> > > >> > > >> > Yes this is becoming more offtopic but hopefully my comments have > brought > >> up > >> > two points: > >> > > >> > 1: Although Locks are a form of resource, the ARM proposal as is > cannot > >> > support them > >> > 2: Someone will abuse it to support Lock's at some point with > potentially > >> > disastrous consequences. > >> > >> What would be the problem with: > >> > >> package j.u.c: > >> abstract class AbstractLock implements Lock { > >> private final AutoCloseable locked = new AutoCloseable() { > >> public void close() { AbstractLock.this.unlock(); } > >> } > >> > >> > >> public AutoCloseable locked() { > >> lock(); > >> return locked; > >> } > >> } > >> > >> Have the j.u.c locks inherit from AbstractLock. > >> > >> Add in class LockSupport: > >> public static AutoCloseable locked(final Lock lock) { > >> return (lock instanceof AbstractLock) ? > >> ((AbstractLock)lock).locked() : new AutoCloseable() { > >> public void close() { lock.unlock(); } > >> }; > >> } > >> > >> Use: > >> > >> import static LockSupport.locked; > >> > >> try(locked(guard)) { > >> > >> } > >> > >> > >> Matthias > >> > >> > > >> > > >> >> > >> >> If locks are truly deemed crucial, or the consensus is that, > >> >> eventhough evidently ARM-as-is can't do locks, people will try anyway > >> >> and the resulting confusion must be avoided, I suggest that the ARM > >> >> proposal is updated to do the right thing when an expression of type > >> >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone > else > >> >> proposed this before and I can't see any downside to this. It would > be > >> >> bad if, for every release, a bunch more types get special uniquely > >> >> defined semantics in relation to the ARM expression, but that seems > >> >> very unlikely. Nobody else has named a use-case that doesn't work in > >> >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. > >> > > >> > > >> > Yes I did yesterday. > >> > > >> > The one thing I've learned from experience is that a lot of > programmers > >> are > >> > lazy when it comes to resources. Although for some resources are > cleaned > >> up > >> > occasionally by the garbage collector, most are not and unless the > system > >> is > >> > under heavy load the problem doesn't show itself until it's in the > live > >> > environment. For this reason I do feel that the ARM proposal would > >> alleviate > >> > this as long as the programmers know that the new construct exists. > >> > > >> > Now I do feel that Locks are a form of resource but one that is > actively > >> > short lived. Although it seems simple to just write them manually with > a > >> try > >> > finally block you'll be surprised how easy it is for someone to miss > the > >> > finally block or refactor it out without noticing. In a large system > this > >> > can be costly (my gaming background coming in here). > >> > > >> > Over the last few years I've ended up wasting so much time debugging a > >> > complex system to locate a deadlock just to find that someone has > >> forgotten > >> > to release a lock. It is this reason why I think the ARM proposal > should > >> > support Lock's as a separate use-case. > >> > > >> > The main issues with Disposable and Lock that I can see are: > >> > > >> > 1: Lock is an interface and cannot extend Disposable as that would > break > >> > existing code. Also implementing Disposable in the Lock > implementations > >> > would not work if you use try( Lock ) as javac would not see it as > being > >> > Disposable. > >> > > >> > 2: Normal resources are already open/active before the try so with > >> > Disposable the try(Disposable) would simply call Disposable.close() at > >> the > >> > end. With Locks they are not active until lock() is called so > try(Lock) > >> > would have to call Lock.lock() before the method body and then > >> Lock.unlock() > >> > at the end. > >> > > >> > As I said in an earlier email I implement this pattern in JDK1.6 by > >> having a > >> > set of annotations which with a processor inject the try...finally > block > >> > around a method thats locked (yes I know annotation processors > shouldn't > >> do > >> > this but it's removed the problem completely). Having the ARM proposal > >> would > >> > not just obsolete the hack but make it more flexible (as the hack only > >> works > >> > at the method level). > >> > > >> > As for any other use-cases that don't work with the current proposal > >> other > >> > than Lock, I can't think of any at the moment. > >> > > >> > > >> >> > >> >> --Reinier Zwitserloot > >> >> > >> >> > >> >> On Mar 8, 2009, at 09:03, Peter Mount wrote: > >> >> > >> >> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson > >> >> > wrote: > >> >> > > >> >> >> I am aware Lock is an interface. You wouldn't actually change the > >> >> >> Lock interface, you would change the classes. Just as they > retrofit > >> >> >> Iterable everywhere. That's why I put "class Lock" there; perhaps > it > >> >> >> would have been clearer if it said "class MyLock". > >> >> > > >> >> > > >> >> > What about when someone just references the lock as Lock rather > than > >> >> > the > >> >> > implementing class? Javac won't be able to determine that the lock > >> >> > implements Disposable so in that case it will fail.. > >> >> > > >> >> > > >> >> > > >> >> > > >> >> >> > >> >> >> > >> >> >> Jeremy > >> >> >> > >> >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne > >> >> >> wrote: > >> >> >>> Jeremy Manson wrote: > >> >> >>>> The "right" fix, if we want to support this pattern, is to allow > >> >> >>>> the > >> >> >>>> try resource statement to accept expressions that return > >> >> >>>> Disposables, > >> >> >>>> and to retrofit the relevant lock APIs with disposables and lock > >> >> >>>> methods that return this: > >> >> >>>> > >> >> >>>> class Lock implements Disposable { > >> >> >>>> public Lock dlock() { > >> >> >>>> return this; > >> >> >>>> } > >> >> >>>> @Override public void dispose() { > >> >> >>>> unlock(); > >> >> >>>> } > >> >> >>>> } > >> >> >>>> > >> >> >>> Lock is an interface. No changes are possible. > >> >> >>> > >> >> >>> Stephen > >> >> >>> > >> >> >>> > >> >> >>> > >> >> >> > >> >> >> > >> >> > > >> >> > > >> >> > -- > >> >> > Peter Mount > >> >> > e: peter at retep.org.uk > >> >> > w: http://retep.org > >> >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > >> >> > > >> >> > >> >> > >> >> > >> > > >> > > >> > -- > >> > Peter Mount > >> > e: peter at retep.org.uk > >> > w: http://retep.org > >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com > >> > > >> > > >> > >> > > > > > From matthias at mernst.org Fri Mar 13 15:17:13 2009 From: matthias at mernst.org (Matthias Ernst) Date: Fri, 13 Mar 2009 23:17:13 +0100 Subject: Proposal: Automatic Resource Management In-Reply-To: <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> References: <17b2302a0902272128x4bb817ffmd2058f1174a9058b@mail.gmail.com> <49B24624.7080708@gmail.com> <1631da7d0903070951v672684ceg89fee78164256c62@mail.gmail.com> <49B2BBA9.5040500@gmail.com> <1631da7d0903072358g5af7aefag8d981bf0722c9ef0@mail.gmail.com> <85bf933e0903080003l7fd56d82u1f38df0d8d0d3fc0@mail.gmail.com> <59F10CC2-3B35-478A-87A0-C85A76001C6D@zwitserloot.com> <85bf933e0903080139g47d4d494g763b17c90937c694@mail.gmail.com> <22ec15240903130247y2df9cb06gc77eb67065968589@mail.gmail.com> <17b2302a0903130926m192b7a13rb12e8524e4b66ad6@mail.gmail.com> Message-ID: <22ec15240903131517x51c3c2dck267ac8af59075ada@mail.gmail.com> On Fri, Mar 13, 2009 at 5:26 PM, Joshua Bloch wrote: > Matthias, > > Hi. This would work, but I'd have concerns about the performance. Locks have > to be really fast. Hi Josh, I also don't think we should bend ARM backwards to make Locks work. But I actually believe the way I sketched it both avoids allocation for the builtin lock types and should allow the VM to optimize to the point that it's no more expensive than a traditional lock/try/finally/unlock sequence (ok plus 2 extra loads, AbstractLock#locked#this$0). Since it's a straightforward translation, we can try it out today. If it works, great, and I would argue to allow expressions in try and add to j.u.c accordingly. If not, this use case will not be supported. That would be fine then, too. Cheers Matthias >? If we want to solve the locking case (and I'm not so > sure we do), I believe that we should do so with another construct.? I made > a "Preproposal" for such a construct, but no one showed any enthusiasm. > > ????????? Josh > > On Fri, Mar 13, 2009 at 2:47 AM, Matthias Ernst wrote: >> >> On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount wrote: >> > On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot >> > > >> wrote: >> > >> >> We're veering waaay offtopic here; the ARM proposal does not address >> >> locks. Period. Would everyone be happy if this was added in the 'major >> >> disadvantages' section? >> > >> > >> > Yes this is becoming more offtopic but hopefully my comments have >> > brought up >> > two points: >> > >> > 1: Although Locks are a form of resource, the ARM proposal as is cannot >> > support them >> > 2: Someone will abuse it to support Lock's at some point with >> > potentially >> > disastrous consequences. >> >> What would be the problem with: >> >> package j.u.c: >> abstract class AbstractLock implements Lock { >> ?private final AutoCloseable locked = new AutoCloseable() { >> ? ?public void close() { AbstractLock.this.unlock(); } >> ?} >> >> >> ?public AutoCloseable locked() { >> ? ?lock(); >> ? ?return locked; >> ?} >> } >> >> Have the j.u.c locks inherit from AbstractLock. >> >> Add in class LockSupport: >> ?public static AutoCloseable locked(final Lock lock) { >> ? ?return (lock instanceof AbstractLock) ? >> ((AbstractLock)lock).locked() : new AutoCloseable() { >> ? ? ?public void close() { lock.unlock(); } >> ? ?}; >> ?} >> >> Use: >> >> import static LockSupport.locked; >> >> try(locked(guard)) { >> >> } >> >> >> Matthias >> >> > >> > >> >> >> >> If locks are truly deemed crucial, or the consensus is that, >> >> eventhough evidently ARM-as-is can't do locks, people will try anyway >> >> and the resulting confusion must be avoided, I suggest that the ARM >> >> proposal is updated to do the right thing when an expression of type >> >> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else >> >> proposed this before and I can't see any downside to this. It would be >> >> bad if, for every release, a bunch more types get special uniquely >> >> defined semantics in relation to the ARM expression, but that seems >> >> very unlikely. Nobody else has named a use-case that doesn't work in >> >> vanilla ARM yet seems likely to be abused, other than Lock, IIRC. >> > >> > >> > Yes I did yesterday. >> > >> > The one thing I've learned from experience is that a lot of programmers >> > are >> > lazy when it comes to resources. Although for some resources are cleaned >> > up >> > occasionally by the garbage collector, most are not and unless the >> > system is >> > under heavy load the problem doesn't show itself until it's in the live >> > environment. For this reason I do feel that the ARM proposal would >> > alleviate >> > this as long as the programmers know that the new construct exists. >> > >> > Now I do feel that Locks are a form of resource but one that is actively >> > short lived. Although it seems simple to just write them manually with a >> > try >> > finally block you'll be surprised how easy it is for someone to miss the >> > finally block or refactor it out without noticing. In a large system >> > this >> > can be costly (my gaming background coming in here). >> > >> > Over the last few years I've ended up wasting so much time debugging a >> > complex system to locate a deadlock just to find that someone has >> > forgotten >> > to release a lock. It is this reason why I think the ARM proposal should >> > support Lock's as a separate use-case. >> > >> > The main issues with Disposable and Lock that I can see are: >> > >> > 1: Lock is an interface and cannot extend Disposable as that would break >> > existing code. Also implementing Disposable in the Lock implementations >> > would not work if you use try( Lock ) as javac would not see it as being >> > Disposable. >> > >> > 2: Normal resources are already open/active before the try so with >> > Disposable the try(Disposable) would simply call Disposable.close() at >> > the >> > end. With Locks they are not active until lock() is called so try(Lock) >> > would have to call Lock.lock() before the method body and then >> > Lock.unlock() >> > at the end. >> > >> > As I said in an earlier email I implement this pattern in JDK1.6 by >> > having a >> > set of annotations which with a processor inject the try...finally block >> > around a method thats locked (yes I know annotation processors shouldn't >> > do >> > this but it's removed the problem completely). Having the ARM proposal >> > would >> > not just obsolete the hack but make it more flexible (as the hack only >> > works >> > at the method level). >> > >> > As for any other use-cases that don't work with the current proposal >> > other >> > than Lock, I can't think of any at the moment. >> > >> > >> >> >> >> ?--Reinier Zwitserloot >> >> >> >> >> >> On Mar 8, 2009, at 09:03, Peter Mount wrote: >> >> >> >> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson >> >> > wrote: >> >> > >> >> >> I am aware Lock is an interface. ?You wouldn't actually change the >> >> >> Lock interface, you would change the classes. ?Just as they retrofit >> >> >> Iterable everywhere. ?That's why I put "class Lock" there; perhaps >> >> >> it >> >> >> would have been clearer if it said "class MyLock". >> >> > >> >> > >> >> > What about when someone just references the lock as Lock rather than >> >> > the >> >> > implementing class? Javac won't be able to determine that the lock >> >> > implements Disposable so in that case it will fail.. >> >> > >> >> > >> >> > >> >> > >> >> >> >> >> >> >> >> >> Jeremy >> >> >> >> >> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne >> >> >> wrote: >> >> >>> Jeremy Manson wrote: >> >> >>>> The "right" fix, if we want to support this pattern, is to allow >> >> >>>> the >> >> >>>> try resource statement to accept expressions that return >> >> >>>> Disposables, >> >> >>>> and to retrofit the relevant lock APIs with disposables and lock >> >> >>>> methods that return this: >> >> >>>> >> >> >>>> class Lock implements Disposable { >> >> >>>> ?public Lock dlock() { >> >> >>>> ? ?return this; >> >> >>>> ?} >> >> >>>> ?@Override public void dispose() { >> >> >>>> ? ?unlock(); >> >> >>>> ?} >> >> >>>> } >> >> >>>> >> >> >>> Lock is an interface. No changes are possible. >> >> >>> >> >> >>> Stephen >> >> >>> >> >> >>> >> >> >>> >> >> >> >> >> >> >> >> > >> >> > >> >> > -- >> >> > Peter Mount >> >> > e: peter at retep.org.uk >> >> > w: http://retep.org >> >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> >> > >> >> >> >> >> >> >> > >> > >> > -- >> > Peter Mount >> > e: peter at retep.org.uk >> > w: http://retep.org >> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com >> > >> > >> > > From howard.lovatt at iee.org Sat Mar 14 02:58:02 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sat, 14 Mar 2009 20:58:02 +1100 Subject: Proposal: Block Expressions for Java Message-ID: <3dd3f56a0903140258v568d9c3bsa9c6253b9b696a32@mail.gmail.com> I am with Stephen Colebourne on this one - unfortunately against. You can achieve the same using blocks for locals, init blocks for instance fields, static init blocks for static fields, and for many super calls a call to a static method can be made. The least desirable of these is for super, a better solution is to allow statements before super. These are more powerful, for example initialising a field with an argument to the constructor (e.g. the outer pointer for an inner class). VM alreadty allows statements before the super. Sorry, but I am against this. From howard.lovatt at iee.org Sat Mar 14 05:46:52 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sat, 14 Mar 2009 23:46:52 +1100 Subject: Proposal: Block Expressions for Java Message-ID: <3dd3f56a0903140546m3aaf7367ieb258479cc926053@mail.gmail.com> Allowing expressions before super have ben requested for a while, 1997, http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093999 From schulz at e-spirit.de Sat Mar 14 06:41:42 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 14 Mar 2009 14:41:42 +0100 Subject: Extended arrays declaration and access syntax with use of enumerated types In-Reply-To: References: Message-ID: <49BBB416.3010509@e-spirit.de> Gabriel Belingueres schrieb: > You could use a Map implementation, or even a SortedMap implementation > if you need to keep an order between the keys. Or rather a LinkedHashMap ;) What happened to the "Array-Syntax for Collections" proposal btw.? Proposing some Array-like syntax for Maps would be a consequent extension to that proposal, resulting in the same syntacitc statements as presented in this proposal on arrays. To me, in an object oriented language solutions easing the use of objects reducing the usage of primitive data structures seem more desirable than the opposite. Stefan From Joe.Darcy at Sun.COM Sat Mar 14 06:55:04 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 14 Mar 2009 06:55:04 -0700 Subject: Extended arrays declaration and access syntax with use of enumerated types In-Reply-To: <49BBB416.3010509@e-spirit.de> References: <49BBB416.3010509@e-spirit.de> Message-ID: <49BBB738.4090203@sun.com> Stefan Schulz wrote: > Gabriel Belingueres schrieb: > > You could use a Map implementation, or even a SortedMap implementation > > if you need to keep an order between the keys. > > Or rather a LinkedHashMap ;) > > What happened to the "Array-Syntax for Collections" proposal btw.? > I haven't written it up yet; still two more weeks available to send it in :-) -Joe From markmahieu at googlemail.com Sat Mar 14 06:55:19 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 14 Mar 2009 13:55:19 +0000 Subject: Extended arrays declaration and access syntax with use of enumerated types In-Reply-To: <49BBB416.3010509@e-spirit.de> References: <49BBB416.3010509@e-spirit.de> Message-ID: On 14 Mar 2009, at 13:41, Stefan Schulz wrote: > > What happened to the "Array-Syntax for Collections" proposal btw.? I've been wondering that. I'm sure there are a couple of other moderately high-profile ideas that have yet to show up here, in proposal form anyway. Has everyone been assuming that someone else is writing them up? Guess I have :) Mark From reinier at zwitserloot.com Sat Mar 14 07:04:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 14 Mar 2009 15:04:46 +0100 Subject: Coin Considerations Message-ID: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> So what proposals are still fermenting in the minds of coin contributors? Inspired by the recent discussion between Joe D'Arcy and Mark Mahieu that people are possibly thinking someone else will be proposing it. Here's my list (* means: Definitely 'believe' in it, just need the time, and '-' means: Not entirely sure it can be made simple enough for coin / is a good idea in the first place): * Make catching exceptions that are never thrown a warning instead of an error + new key for @SuppressWarnings * A 'return this' mechanic which makes creating builders easier. - backticks mean identifier, regardless of string content. Allows you to make a method named 'for', or call a method named '+'. Depends on a semi-official list on how to translate illegal identifier names such as '+' to legal ones, such as '$plus'. If that doesn't exist, this gets more complicated because you'd have to write it up. - factory interfaces (an interface to describe constructors and static methods). I've got a simple way to do it, but I don't think its simple enough for coin. --Reinier Zwitserloot From scolebourne at joda.org Sat Mar 14 07:25:33 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 14 Mar 2009 14:25:33 +0000 Subject: Coin Considerations In-Reply-To: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> Message-ID: <49BBBE5D.7080106@joda.org> Reinier Zwitserloot wrote: > So what proposals are still fermenting in the minds of coin > contributors? Inspired by the recent discussion between Joe D'Arcy and > Mark Mahieu that people are possibly thinking someone else will be > proposing it. * For-each loop for Maps, based on http://www.jroller.com/scolebourne/entry/java_7_for_each_loops for (String str, Integer val : map) { } * Iteration control in For-Each loops, based on http://www.jroller.com/scolebourne/entry/java_7_for_each_loop for (String str : list : it) { it.index(); it.hasNext(); it.remove(); } Abstract enums would be extremely useful, but are probably too big - http://freddy33.blogspot.com/search/label/abstract%20enum I also thought List comprehensions might come up (not by me) - http://docs.google.com/View?docid=d4tx2hw_46fkz8x6gt > - factory interfaces (an interface to describe constructors and > static methods). I've got a simple way to do it, but I don't think > its simple enough for coin. See https://kijaro.dev.java.net/ static implements. And yes, its a great idea, but too complex for Coin. public class Foo implements static Iterable { public static Iterator iterator() {...} } Stephen From scolebourne at joda.org Sat Mar 14 07:34:43 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 14 Mar 2009 14:34:43 +0000 Subject: Array syntax for collections [was Re: Extended arrays declaration and access syntax with use of enumerated types] In-Reply-To: <49BBB738.4090203@sun.com> References: <49BBB416.3010509@e-spirit.de> <49BBB738.4090203@sun.com> Message-ID: <49BBC083.8050603@joda.org> >> What happened to the "Array-Syntax for Collections" proposal btw.? >> > I haven't written it up yet; still two more weeks available to send it > in :-) It should be noted that it wasn't very popular in any of the voting I did - http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_everyone At JavaEdge http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_javaedge, it was the least popular of the 10 options presented (and more 'this is a bad idea' than any other proposal). I quite like it personally, so it wasn't presenter bias! Stephen From markmahieu at googlemail.com Sat Mar 14 08:05:25 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 14 Mar 2009 15:05:25 +0000 Subject: Coin Considerations In-Reply-To: <49BBBE5D.7080106@joda.org> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBBE5D.7080106@joda.org> Message-ID: On 14 Mar 2009, at 14:25, Stephen Colebourne wrote: > > * For-each loop for Maps, based on > http://www.jroller.com/scolebourne/entry/java_7_for_each_loops > > for (String str, Integer val : map) { > } > > * Iteration control in For-Each loops, based on > http://www.jroller.com/scolebourne/entry/java_7_for_each_loop > > for (String str : list : it) { > it.index(); > it.hasNext(); > it.remove(); > } > I wrote versions of these with BGGA - it is surprising how useful they can be. I guess the Java 5 foreach covered 80% of cases, but the remaining 20% is still a very large number. I do feel a bit uncomfortable with the idea of supporting these in the language itself though, FWLIW. > I also thought List comprehensions might come up (not by me) - > http://docs.google.com/View?docid=d4tx2hw_46fkz8x6gt I suspect that's another one which could be implemented very differently in a language with closures. > See https://kijaro.dev.java.net/ static implements. And yes, its a > great > idea, but too complex for Coin. Pity. I don't know that it's really a good idea, but it would be an interesting one to put under the microscope. Regards, Mark From markmahieu at googlemail.com Sat Mar 14 08:13:42 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 14 Mar 2009 15:13:42 +0000 Subject: Array syntax for collections [was Re: Extended arrays declaration and access syntax with use of enumerated types] In-Reply-To: <49BBC083.8050603@joda.org> References: <49BBB416.3010509@e-spirit.de> <49BBB738.4090203@sun.com> <49BBC083.8050603@joda.org> Message-ID: <1239471C-057C-454A-9940-A84EC354D857@googlemail.com> Stephen, On 14 Mar 2009, at 14:34, Stephen Colebourne wrote: >>> What happened to the "Array-Syntax for Collections" proposal btw.? >>> >> I haven't written it up yet; still two more weeks available to >> send it >> in :-) > > It should be noted that it wasn't very popular in any of the voting > I did - > http://www.jroller.com/scolebourne/entry/ > jdk_7_language_changes_everyone > > At JavaEdge > http://www.jroller.com/scolebourne/entry/ > jdk_7_language_changes_javaedge, > it was the least popular of the 10 options presented (and more > 'this is > a bad idea' than any other proposal). I quite like it personally, > so it > wasn't presenter bias! > > Stephen That's interesting. Did you get any feeling for *why* it was disliked? I get the impression that a lot of 'mostly sugar' suggestions receive a more negative reaction at first blush. I'm pretty sure even foreach was initially greeted with a certain amount of disdain by some people. Mark From reinier at zwitserloot.com Sat Mar 14 09:15:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 14 Mar 2009 17:15:46 +0100 Subject: ACCEPTABLE?: List Comprehensions? Message-ID: <64C260CE-3CC3-43ED-914D-CB6BD77FBAB5@zwitserloot.com> Ah, list comprehensions. I forgot them on my list. They aren't closures, but you can do quite a few closure use-cases with them, and are a lot easier to understand. The draft proposal looks good (but is incomplete; it doesn't mention any JLS chapters, for example), but there's one big issue it doesn't mention: If the list comprehensions return Iterables, then the generating expression, as well as the filter expressions, are effectively 'closures' and get all the complications that stem from this. For example, you would not be able to use non-final variables in there, unless we change the rules regarding usage of non-finals in 'closures', which involves a significant change for the JVM (it has to declare that variable on the heap and not on the stack). Generating the entire list on the spot has none of those issues, and turns the entire proposal into syntactic sugar + a new utility class in the spirit of Collections and Arrays, named 'Iterables'. That's all. Joe: If a list comprehension proposal is written that involves (extensive) syntax sugar + 1 new class file and nothing else, would they have a chance? Example desugaring: public List findEvensAndAdd(List in, int valueToAdd) { List out = [x + valueToAdd for x : in if x % 2 == 0]; return out; } becomes: public List findEvensAndAdd(List in, int valueToAdd) { List $uniqueName = new ArrayList(); for ( int x : in ) { if ( !(x % 2 == 0) ) continue; $uniqueName.add(x + valueToAdd); } $uniqueName = Collections.unmodifiableList($uniqueName); List out = $uniqueName; return out; } In other words, a uniquely named list is created, the variable declaration + source list is moved straight into a foreach loop clause, then the filter statement(s) are all concatenated via if ( ! CLAUSE1 || !CLAUSE2 || !CLAUSE3 ) continue, and finally the generator expression is used to generate a value, which is added to the uniquely named list. Finally, the list is turned into an unmodifiableList to avoid having to specify exactly what happens or can't happen when you add/remove/change the list. Definitive assignment follows from this desugaring; any variable read out anywhere in the list comprehension (in any of the 3 places where they can occur; generator, sources, filters) are presumed to be read (and thus need to be guaranteed initialized), any variable set anywhere in the list comprehension is presumed to Maybe occur - so it's enough to trigger 'final' warnings, but its not enough to guarantee initialization. The only exception is the sources list, which is like a normal statement (guaranteed to be run, exactly once). the type of the expression is List where X is the type of the generating expression. --Reinier Zwitserloot Like it? Tip it! http://tipit.to From reinier at zwitserloot.com Sat Mar 14 09:29:35 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 14 Mar 2009 17:29:35 +0100 Subject: ACCEPTABLE? factory interfaces? In-Reply-To: <49BBBE5D.7080106@joda.org> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBBE5D.7080106@joda.org> Message-ID: <73E4A030-5F06-452E-8779-7493701EB4AE@zwitserloot.com> I really doubt it, and my plate is a little bit too full to write it up, but perhaps someone else wants to run with it. Based on the factory interface idea Stephen linked to in an earlier email at http://www.jroller.com/jadda/entry/meta_interfaces_revisited My rough sketch makes it a little easier and avoids requiring any changes to the JVM. Any class literal is autoboxed into an object assignable to the meta interface type when used in a place where the meta interface type is valid but the class literal's type is not. This autoboxing process calls a predefined library (kind of like how java's primitives to objects autoboxing calls Integer.valueOf and friends), which will return a singleton (only GCed if both the class literal is GCed and the proxy singleton is GCable) that has normal (non-static) methods, which are just proxies to the actual static methods. The bigger issues that need to be addressed by such a proposal include (list is complete as far as I can tell): - Should interfaces be explicit in whether they are meant as a factory-interface or not? There's no reason for them to be technically, and there are certain cases where you'd want to be able to interchangably use a class'es static methods or an actual object's instance methods, but it might be confusing. My suggestion: Yes, make them explicit.... but how? New keyword seems almost unavoidable. - How do you specify that your class factory-implements something? A new keyword? Or a new type of interface so that the compiler knows when it sees this special type of interface on the 'implements' list that its about a factory-interface? My suggestion: Again, be explicit, reuse the newly created keyword. - How do you handle constructors? My suggestion: Make the identifier 'constructor' have special meaning. Disallows using an actual static method named 'constructor', though. A fun little exercise to show what you can do with this: //First generics arg is automatically translated to implementing class. public factory interface Numeric { T zero(); T seq(T in); } public class Integer factory implements Numeric { public static Integer zero() { return 0; } public static Integer seq(Integer in) { return in+1; } } public class NumberUtils { public static T one(Numeric numericClass) { return numericClass.seq(numericClass.zero()); } } public class Example { public static void main(String[] args) { assert 1 == NumberUtils.one(Integer.class); //sugar in above line: autobox Integer class object to Numeric wrapper } } eh, still much too complicated for coin, I think. --Reinier Zwitserloot On Mar 14, 2009, at 15:25, Stephen Colebourne wrote: > Reinier Zwitserloot wrote: >> So what proposals are still fermenting in the minds of coin >> contributors? Inspired by the recent discussion between Joe D'Arcy >> and >> Mark Mahieu that people are possibly thinking someone else will be >> proposing it. > > * For-each loop for Maps, based on > http://www.jroller.com/scolebourne/entry/java_7_for_each_loops > > for (String str, Integer val : map) { > } > > * Iteration control in For-Each loops, based on > http://www.jroller.com/scolebourne/entry/java_7_for_each_loop > > for (String str : list : it) { > it.index(); > it.hasNext(); > it.remove(); > } > > > Abstract enums would be extremely useful, but are probably too big - > http://freddy33.blogspot.com/search/label/abstract%20enum > > I also thought List comprehensions might come up (not by me) - > http://docs.google.com/View?docid=d4tx2hw_46fkz8x6gt > > >> - factory interfaces (an interface to describe constructors and >> static methods). I've got a simple way to do it, but I don't think >> its simple enough for coin. > > See https://kijaro.dev.java.net/ static implements. And yes, its a > great > idea, but too complex for Coin. > > public class Foo implements static Iterable { > public static Iterator iterator() {...} > } > > Stephen > From schulz at e-spirit.de Sat Mar 14 09:30:59 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 14 Mar 2009 17:30:59 +0100 Subject: Coin Considerations In-Reply-To: <49BBBE5D.7080106@joda.org> References: <49BBBE5D.7080106@joda.org> Message-ID: <49BBDBC3.2010800@e-spirit.de> Stephen Colebourne schrieb: > Reinier Zwitserloot wrote: > > - factory interfaces (an interface to describe constructors and > > static methods). I've got a simple way to do it, but I don't think > > its simple enough for coin. I'd be interested in the "simple way". Is there anything for reading? :) > See https://kijaro.dev.java.net/ static implements. And yes, its a great > idea, but too complex for Coin. I must admit that I didn't get very far with the prototype, not having the time to dwelve deep into the compiler. It further requires some additional information to be put into class files, hence, it might easily be out of scope for Coin. (In the prototype, I made use of the attributes section of a class description to not have to change the class file format. It would at least require a change in the VM specification wrt. the new attribute, I guess. And there are lots of issues to solve wrt. Generics in static interfaces, some of which I named in my blog.) Stefan From schulz at e-spirit.de Sat Mar 14 09:36:02 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 14 Mar 2009 17:36:02 +0100 Subject: ACCEPTABLE? factory interfaces? In-Reply-To: <73E4A030-5F06-452E-8779-7493701EB4AE@zwitserloot.com> References: <73E4A030-5F06-452E-8779-7493701EB4AE@zwitserloot.com> Message-ID: <49BBDCF2.6050809@e-spirit.de> Reinier Zwitserloot schrieb: > Based on the factory interface idea Stephen linked to in an earlier > email at http://www.jroller.com/jadda/entry/meta_interfaces_revisited Pity, only the "revisited" post is referenced ;) Your rough scheme reads quite like the first pseudo-prototype I did, which based on the Proxy-Class and explicit wrapping (no changes to JVM or compiler): http://www.jroller.com/jadda/entry/meta_interfaces_contracting_via_proxy Stefan From develop4lasu at gmail.com Sat Mar 14 10:02:59 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 14 Mar 2009 18:02:59 +0100 Subject: Delegation proposal Message-ID: <28bca0ff0903141002i1aa0b222u863acebf6f3ee478@mail.gmail.com> *AUTHOR: **Lasu aka Marek Kozie?* *OVERVIEW* FEATURE SUMMARY: This change allow to delegate methods, interfaces and classes. MAJOR ADVANTAGE: It would be a first step for programmers to have something instead of inheritance, allowing to write better code. MAJOR BENEFITS: Java looks incomplete without something so base as delegating. Others are: Code more immune for changes(if interface changes, there will be not so much to change, or I would say, changes will be on the right place, but not on all projects) Decreasing costs of code modification. Explicit defining MethodModifiers MAJOR DISADVANTAGE: Changes cost. ALTERNATIVES: It's nothing that cannot be implemented in a simple way, but this change does not increase delegation complex, unreadability, and costs of support with each method. *EXAMPLES* SIMPLE EXAMPLE: public abstract class ClassA implements InterfaceA { InterfaceA ia = ...; public delegate InterfaceA{ return ia; } } ADVANCED EXAMPLE: public abstract class ClassA implements InterfaceA { ClassSome cs = ... ; // ClassSome implements InterfaceA, InterfaceB, InterfaceC Some some = ... ; // have the same methods from InterfaceA and InterfaceC but do not implements them public delegate ClassSome exclude Object,InterfaceB{ if (cs==null) return some; return cs; } } *DETAILS* SPECIFICATION: DelegationDeclaration: DelegationHeader DelegationBody DelegationHeader: DelegationModifiersopt delegate MethodSets Excludeopt Throwsopt DelegationDeclarator DelegationModifiers: DelegationModifier DelegationModifiers DelegationModifier DelegationModifier: one of Annotation public protected private abstract static final synchronized Exclude: exclude MethodSets MethodSets: MethodSet MethodSets, MethodSet MethodSet: one of ClassOrInterfaceType InterfaceMemberDeclaration DelegationBody: same with: MethodBody except ReturnStatement ReturnStatement: return* Expression return work in different way in delegation than in method. For each method with ResultType(Type) it's interpreted: return (Expression).MethodIdentifier(ActualParameters); For each method with ResultType(void) it's interpreted: (Expression).MethodIdentifier(ActualParameters); return; *COMPILATION*: Delegation is deployed to all methods that occur in 'delegate MethodSets' and do not occur in Excludeopt. All methods have modifiers: DelegationModifiersopt Declared exception in Throwsopt are added to each method ExceptionTypeList. TESTING: Normal way. LIBRARY SUPPORT: No REFLECTIVE APIS: No changed. OTHER CHANGES: None. MIGRATION: No need. COMPATIBILITY All working programs will still work. New byte code is compatible with old one. *REFERENCES* Delegation proposal: http://lasu2string.blogspot.com/2009/03/delegation-proposal.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Dalibor.Topic at Sun.COM Sat Mar 14 10:05:01 2009 From: Dalibor.Topic at Sun.COM (Dalibor Topic) Date: Sat, 14 Mar 2009 18:05:01 +0100 Subject: Coin Considerations In-Reply-To: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> Message-ID: <49BBE3BD.30109@sun.com> Reinier Zwitserloot wrote: > So what proposals are still fermenting in the minds of coin > contributors? Inspired by the recent discussion between Joe D'Arcy and > Mark Mahieu that people are possibly thinking someone else will be > proposing it. I have one thing in the back of my mind - a @StoredSource annotation to store the corresponding source code as a class file attribute. cheers, dalibor topic -- ******************************************************************* Dalibor Topic Tel: (+49 40) 23 646 738 Java F/OSS Ambassador AIM: robiladonaim Sun Microsystems GmbH Mobile: (+49 177) 2664 192 Nagelsweg 55 http://openjdk.java.net D-20097 Hamburg mailto:Dalibor.Topic at sun.com Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten Amtsgericht M?nchen: HRB 161028 Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer Vorsitzender des Aufsichtsrates: Martin H?ring From reinier at zwitserloot.com Sat Mar 14 10:16:00 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 14 Mar 2009 18:16:00 +0100 Subject: Coin Considerations In-Reply-To: <49BBE3BD.30109@sun.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> Message-ID: I like that idea. So, you mean the entire source code, all of it, as one annotation (vs. a path)? - If that's what you had in mind, I'm in favour of it. Though - isn't that a change in javac, and not in the JLS? --Reinier Zwitserloot On Mar 14, 2009, at 18:05, Dalibor Topic wrote: > Reinier Zwitserloot wrote: >> So what proposals are still fermenting in the minds of coin >> contributors? Inspired by the recent discussion between Joe D'Arcy >> and >> Mark Mahieu that people are possibly thinking someone else will be >> proposing it. > > I have one thing in the back of my mind - a @StoredSource annotation > to store the corresponding source code as a class file attribute. > > cheers, > dalibor topic > -- > ******************************************************************* > Dalibor Topic Tel: (+49 40) 23 646 738 > Java F/OSS Ambassador AIM: robiladonaim > Sun Microsystems GmbH Mobile: (+49 177) 2664 192 > Nagelsweg 55 http://openjdk.java.net > D-20097 Hamburg mailto:Dalibor.Topic at sun.com > Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten > Amtsgericht M?nchen: HRB 161028 > Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer > Vorsitzender des Aufsichtsrates: Martin H?ring > > From scolebourne at joda.org Sat Mar 14 10:20:26 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 14 Mar 2009 17:20:26 +0000 Subject: Array syntax for collections [was Re: Extended arrays declaration and access syntax with use of enumerated types] In-Reply-To: <1239471C-057C-454A-9940-A84EC354D857@googlemail.com> References: <49BBB416.3010509@e-spirit.de> <49BBB738.4090203@sun.com> <49BBC083.8050603@joda.org> <1239471C-057C-454A-9940-A84EC354D857@googlemail.com> Message-ID: <49BBE75A.4080108@joda.org> Mark Mahieu wrote: > On 14 Mar 2009, at 14:34, Stephen Colebourne wrote: >> At JavaEdge >> http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_javaedge, >> it was the least popular of the 10 options presented (and more 'this is >> a bad idea' than any other proposal). I quite like it personally, so it >> wasn't presenter bias! > > That's interesting. Did you get any feeling for *why* it was disliked? Not really. The closest I got was a sense that Java should be WYSISYG, and list[0] hides the .get(0) (and possible NPE). I wasn't convinced, but equally I don't find this as compelling as ARM, NPE handling and extending for-each. As a result I personally voted them at the bottom - number 10 of 10, matching the general view. Stephen From Dalibor.Topic at Sun.COM Sat Mar 14 10:47:08 2009 From: Dalibor.Topic at Sun.COM (Dalibor Topic) Date: Sat, 14 Mar 2009 18:47:08 +0100 Subject: Coin Considerations In-Reply-To: References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> Message-ID: <49BBED9C.7000901@sun.com> Reinier Zwitserloot wrote: > I like that idea. So, you mean the entire source code, all of it, as > one annotation (vs. a path)? Yeah. Supplying the sources behind the line information referenced in other portions of debug info, basically. Dumping the entire source code for a file rather then subsets has the advantage that correct licensing, javadoc and attribution information could trivially travel along with the generated binary class file. I picked StoredSource rather then OpenSource, as the latter would have a pretty specific meaning, whereas I guess the proprietary software devs could make efficient use of such a feature, too. - If that's what you had in mind, I'm in > favour of it. Though - isn't that a change in javac, and not in the JLS? I'd see is as an addition to the predefined annotations, so it would require adding its spec to ?9.6.1, at least. It's more of a small productivity booster for those 'where is the source for this apparently semi-random snapshot JAR on my classpath that I'm getting this weird exception from' moments, then a real change of the language. On the con side, it may require some fiddling with JVMTI & friends to expose the stored source code in a standard way to IDEs and debugging tools. So I'm not really sure if it fits into the Coin domain, but since you asked I figured I'd come out with the half-baked idea. If the idea sounds useful, I'll play with it a bit further - but feel free to run with it yourself. cheers, dalibor topic -- ******************************************************************* Dalibor Topic Tel: (+49 40) 23 646 738 Java F/OSS Ambassador AIM: robiladonaim Sun Microsystems GmbH Mobile: (+49 177) 2664 192 Nagelsweg 55 http://openjdk.java.net D-20097 Hamburg mailto:Dalibor.Topic at sun.com Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten Amtsgericht M?nchen: HRB 161028 Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer Vorsitzender des Aufsichtsrates: Martin H?ring From neal at gafter.com Sat Mar 14 11:48:58 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 11:48:58 -0700 Subject: Coin Considerations In-Reply-To: <49BBED9C.7000901@sun.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> <49BBED9C.7000901@sun.com> Message-ID: <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> On Sat, Mar 14, 2009 at 10:47 AM, Dalibor Topic wrote: > Dumping the entire source code > for a file rather then subsets has the advantage that correct licensing, > javadoc and attribution information could trivially travel along with > the generated binary class file. Dalibor- There is currently no way to place an annotation on a "source file". You could only annotate the individual classes found within it. In that case, I would think it surprising to find that the annotation contains source for all the classes, imports, and comments in the same source file. -Neal From develop4lasu at gmail.com Sat Mar 14 13:24:27 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 14 Mar 2009 21:24:27 +0100 Subject: Consider operator proposal Message-ID: <28bca0ff0903141324m776aa49cg6f47275fa6e23502@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: Consider operator extends language with full value support and assign value to name and return it. MAJOR ADVANTAGE: It introduces natural division in variables and values. It makes language to be more natural for human and generics easier to use. MAJOR BENEFIT(s): If we need to get a value, we can do that quite simple (without splitting expression or duplicating code). Decrease number of potential bugs (value cannot be assigned). It can help in splitting code to proper parts; nowdays, we need to declare variable regardless we need it or not (or make it final). Decrease size of unnecessary code. Method can be itself multi-thread with this, but it's far future. MAJOR DISADVANTAGE: Possibility to be unclear at start. ALTERNATIVES: Some time 'final' variables can be used, but it's more like for-each, life is better with it. EXAMPLES SIMPLE EXAMPLE: public static void standard(Resource> resource) { Comparator>> resourceComparator = (standard? Resource.baseComparator : Resource.extdComparator); if (resourceComparator.compare(resource,this.last)==0) return; // duplicate ... } public static void consider(Resource> resource) { (standard? Resource.baseComparator : Resource.extdComparator) :: resourceComparator; if (resourceComparator.compare(resource,this.last)==0) return; // duplicate ... } public static void standard_2(ArrayList>> resources){ for (Resource> resource: resources){ System.out.println(resource); } } public static void consider_2(ArrayList>> resources){ for (::resource:resources){ System.out.println(resource); } } ADVANCED EXAMPLE: public void validLastElementState(ArrayList list){ if (list.get(list.size()::size-1)::data.reportStare().getState()!=validState){ throw new IllegalStateException(Data.class.getSimpleName()+"("+data+") of "+size+" elements is in wrong "+State.class.getSimpleName()); } ... other operations ... } > Would be compiled to: public void validLastElementState(ArrayList list){ { list.size()::size; list.get(size-1)::data if (data.reportStare().getState()!=validState){ throw new IllegalStateException( Data.class.getSimpleName()+"("+data+") of "+size+" elements is in wrong "+State.class.getSimpleName()); } } ... other operations ... } DETAILS SPECIFICATION: Value :: name Assign left side value to given name and return it. JLS 14.14.2: http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.14.2 EnhancedForStatement: for ( VarDeclaration : Expression) Statement VarDeclaration: al least one of VariableDeclaration ValueDeclaration VariableDeclaration VariableModifiersopt Type Identifier ValueDeclaration :: ValueName COMPILATION: While value is same as final variable compiling is not big problem. TESTING: Same as final variable. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: No need. COMPATIBILITY Compiled code can be normally executed. REFERENCES Consider operator proposal: http://lasu2string.blogspot.com/2009/03/consider-operator-proposal.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Sat Mar 14 13:32:56 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 13:32:56 -0700 Subject: Method Bodies in Interfaces -- Why Not? In-Reply-To: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> Message-ID: <15e8b9d20903141332r4f9cd5d0o3d5e086244d48b43@mail.gmail.com> I think adding extension methods as C# does is both simpler and more powerful than adding method bodies to an interface. See http://www.javac.info/ExtensionMethods.html for a very brief glossy. I do not plan to submit a proposal for this. On Tue, Mar 10, 2009 at 4:38 PM, David Walend wrote: > A lot of us spend energy dealing with the fact that we can not add > methods to interfaces. We can't add methods to interfaces because > everything that implements those interfaces would break. We could get > around that by letting interface-defined methods have method bodies. > The resulting problem is that the compiler would not be able to choose > between or order method bodies with the same signature. (As I > understand it, that's why interfaces can't have method bodies.) > > It's modestly rare for classes to inherit two interfaces that define > methods with the same signature in the wild. What happens if the JLS > were to relax the constraint? > > I imagine a few options: > > With multiple inheritance, if different implemented interfaces define > bodies for methods with the same signature then: > > 1) Give the developer a compile error or > 2) Inherit neither method body and force the developer to implement > something himself or > 3) Inherit neither method body, force the developer to implement > something himself, and give him some way to access to all the inherited > implementations. > > That would let us out of some of our more painful contortions. What > are the holes in that idea? > > Thanks, > > Dave > david at walend.net > > > From neal at gafter.com Sat Mar 14 13:52:19 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 13:52:19 -0700 Subject: Method Bodies in Interfaces -- Why Not? In-Reply-To: <15e8b9d20903141332r4f9cd5d0o3d5e086244d48b43@mail.gmail.com> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> <15e8b9d20903141332r4f9cd5d0o3d5e086244d48b43@mail.gmail.com> Message-ID: <15e8b9d20903141352r50068614mc5310c196771c9d2@mail.gmail.com> On Sat, Mar 14, 2009 at 1:32 PM, Neal Gafter wrote: > I think adding extension methods as C# does is both simpler and more > powerful than adding method bodies to an interface. ?See > http://www.javac.info/ExtensionMethods.html for a very brief glossy. > I do not plan to submit a proposal for this. To keep the discussion in one place, I've included it below: Add support for Extension Methods. Once an API has been published, you can't add methods to it without breaking backward compatibility. That's because implementations of the old version of the interface don't provide an implementation of any new methods. You can use abstract classes instead of interfaces, and only add concrete methods in the future. Unfortunately, that limits you to single inheritance. One way API designers work around this limitation is to add new functionality to an interface by writing static utility functions. For example, java.util.Collections.sort acts as an extension of java.util.List. But such methods are less convenient to use, and code written using them is more difficult to read. Extension methods enable programmers to provide additional methods that clients of an interface can elect use as if they are members of the interface. Todd Millstein's Expanders are the most full-featured version of this feature. The simplest version of this feature that I advocate would be to enable statically-imported methods to be used as if members of their first argument type. For example: import static java.util.Collections.sort; ... List list = ...; list.sort(); One of the biggest advantages of extension methods is that they enable more flexible extension of the language moving forward. For example, suppose a new Automated Resource Management statement were defined in terms of invoking an acquire() method, and then later invoking a release() method on the result of the earlier acquire(). Clearly existing APIs such as Closeable do not implement this protocol, but by providing static factory methods they could be made to act as if they do. Such a statement could then be easily retrofitted onto other resource APIs, such as java.util.concurrent.locks.Lock (an interface), simply by providing extension methods. This retrofitting introduces no breaking changes, since the underlying APIs are not changed. From develop4lasu at gmail.com Sat Mar 14 14:04:26 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 14 Mar 2009 22:04:26 +0100 Subject: Method Bodies in Interfaces -- Why Not? In-Reply-To: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> References: <963FE781-B11B-49B6-9171-FFC4A0BC34FF@walend.net> Message-ID: <28bca0ff0903141404p1dbd832ei197f381d37c3ae72@mail.gmail.com> To be hones I was thinking about it some time ago. But it has some great disadvantage: After you will add the new method to interface people may found hard to trace bugs in their code (this method can exists in code already). Soon I translate proposal that will be quite easy and allow that. Be patient. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From fw at deneb.enyo.de Sat Mar 14 16:20:11 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 15 Mar 2009 00:20:11 +0100 Subject: Coin Considerations In-Reply-To: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> (Reinier Zwitserloot's message of "Sat, 14 Mar 2009 15:04:46 +0100") References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> Message-ID: <873adfzo7o.fsf@mid.deneb.enyo.de> * Reinier Zwitserloot: > Here's my list (* means: Definitely 'believe' in it, just need the > time, and '-' means: Not entirely sure it can be made simple enough > for coin / is a good idea in the first place): I would like to see: o transient modifier on local variables Basically, { transient SomeClass foo = getFoo(); doSomething(foo); } is translated to: { transient SomeClass foo = getFoo(); try { doSomething(foo); } finally { if (foo != null) { foo.cleanup(); } } } were SomeClass#cleanup() is the single method in class SomeClass which carries a @Cleanup annotation. The "!= null" part is there to make it possible to signal to the cleanup handler that the object has changed ownership. Assignment to the variable does not trigger cleanup, cleanup only happens at scope exit. Annotation-controlled overlading is used instead of an interface because the existing cleanup routines have a myriad of different names and declare different checked exceptions, too. If there are multiple @Cleanup methods for a type, a warning should be issued if this happens through inheritance (old code which needs to be ported), or an error if there are multiple such methods declared in the same type (erroneous new code). In both cases, if such a type is used in a transient local variable declaration, the declaration is rejected. Syntactically, this extensions blends well with type inference for local variables. However, similar to other forms of compile-time overloading, removing type declarations will change invoked methods in a few corner cases. The choice of the transient keyword means that the same syntax cannot be used for generating cleanup methods for classes. It is not clear to me how to generate code for such classes in the presence of inheritance and exceptions, so I don't think this is a significant problem. (This problem does not arise in the local variables case because there is a clear nesting of scopes.) My hope is that such an extension eventually leads to code which has got fewer resource leaks, but is as succinct and as easy to read as code which (improperly) relies on garbage collection. o new-style for loops with non-Iterator iterators. Basically, allow interfaces besides Iterable and Iterator, guided by annotations (a more complicated variant of the approach for "transient"). The use case are iterators which may throw IOException (and other checked exceptions, of course). This is likely a waste if Java gets something which allows you to define new control flow constructs (and even syntactically lightweight anonymous classes might be good enough). o "class Foo extends ?" syntax for code injection through JSR 269 Right now, you have to use a class name instead of "?" which you shouldn't use anywhere else due to concerns for circularity. Not being able to name that class increases robustness. The compiler would automatically generate a suitable type name in the same package as the class that contains the "?". This would also enable code injection for nested types. o injection of automatically generated superinterface using JSR 269 IIRC, there is a bug which prevents this from working. I don't know if this is deliberate. The syntax extension for classes might help here, too. o static methods in interface types This is for injecting code using a superinterface generated in a JSR 269 scenario. Static member classes already work today (if you fix the bug mentioned in the previous item.) o compiler warnings for crass mismatches between syntax and indentation (if this is too hard to implement efficiently, a backport of the -Xlint:braces warning from Netbeans) A mode which rejects tab characters in the source code might be useful, too. My larger wish list includes: - non-nullable reference types - tuples and structural record types - algebraic data types - type classes and type families (or reified generics with partial specialization) - non-hashable/comparable/synchronizable reference types (perhaps via type classes) Okay, this list is not to be taken completely seriously. But I think some of the stuff is indeed useful (the last point would allow a clean implementation of fixnums, for instance). > - factory interfaces (an interface to describe constructors and > static methods). I've got a simple way to do it, but I don't think its > simple enough for coin. Method handles will cover many use cases, I think. From neal at gafter.com Sat Mar 14 16:39:01 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 16:39:01 -0700 Subject: Coin Considerations In-Reply-To: <873adfzo7o.fsf@mid.deneb.enyo.de> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <873adfzo7o.fsf@mid.deneb.enyo.de> Message-ID: <15e8b9d20903141639u223011bcp38fee79a33d26b1d@mail.gmail.com> Florian- As an alternative formulation of resource management, I like that this proposal doesn't mix up the new construct with an already existing control construct. I have two issues with this alternative formulation of ARM blocks. First, it allows reassigning the variable referencing the resource. That means you might end up closing a different resource than the one you opened. The other issue is its dependence on annotations as a way to avoid adding modifiers. Annotations are supposed to be just that: annotations of the code. They should not modify the behavior of language primitives. Regards, Neal On Sat, Mar 14, 2009 at 4:20 PM, Florian Weimer wrote: > * Reinier Zwitserloot: > >> Here's my list (* means: Definitely 'believe' in it, just need the >> time, and '-' means: Not entirely sure it can be made simple enough >> for coin / is a good idea in the first place): > > I would like to see: > > ?o transient modifier on local variables > > ? ?Basically, > > ? ? ? { > ? ? ? ? transient SomeClass foo = getFoo(); > ? ? ? ? doSomething(foo); > ? ? ? } > > ? is translated to: > > ? ? ? { > ? ? ? ? transient SomeClass foo = getFoo(); > ? ? ? ? try { > ? ? ? ? ? doSomething(foo); > ? ? ? ? } finally { > ? ? ? ? ? if (foo != null) { > ? ? ? ? ? ? foo.cleanup(); > ? ? ? ? ? } > ? ? ? ? } > ? ? ? } > > ? ?were SomeClass#cleanup() is the single method in class SomeClass > ? ?which carries a @Cleanup annotation. > > ? ?The "!= null" part is there to make it possible to signal to the > ? ?cleanup handler that the object has changed ownership. ?Assignment > ? ?to the variable does not trigger cleanup, cleanup only happens at > ? ?scope exit. > > ? ?Annotation-controlled overlading is used instead of an interface > ? ?because the existing cleanup routines have a myriad of different > ? ?names and declare different checked exceptions, too. ?If there are > ? ?multiple @Cleanup methods for a type, a warning should be issued > ? ?if this happens through inheritance (old code which needs to be > ? ?ported), or an error if there are multiple such methods declared > ? ?in the same type (erroneous new code). ?In both cases, if such a > ? ?type is used in a transient local variable declaration, the > ? ?declaration is rejected. > > ? ?Syntactically, this extensions blends well with type inference for > ? ?local variables. ?However, similar to other forms of compile-time > ? ?overloading, removing type declarations will change invoked > ? ?methods in a few corner cases. > > ? ?The choice of the transient keyword means that the same syntax > ? ?cannot be used for generating cleanup methods for classes. ?It is > ? ?not clear to me how to generate code for such classes in the > ? ?presence of inheritance and exceptions, so I don't think this is a > ? ?significant problem. (This problem does not arise in the local > ? ?variables case because there is a clear nesting of scopes.) > > ? ?My hope is that such an extension eventually leads to code which > ? ?has got fewer resource leaks, but is as succinct and as easy to > ? ?read as code which (improperly) relies on garbage collection. From markmahieu at googlemail.com Sat Mar 14 16:39:22 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 14 Mar 2009 23:39:22 +0000 Subject: Coin Considerations In-Reply-To: <873adfzo7o.fsf@mid.deneb.enyo.de> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <873adfzo7o.fsf@mid.deneb.enyo.de> Message-ID: Hi Florian, On 14 Mar 2009, at 23:20, Florian Weimer wrote: > The "!= null" part is there to make it possible to signal to the > cleanup handler that the object has changed ownership. Assignment > to the variable does not trigger cleanup, cleanup only happens at > scope exit. I toyed with this idea a while back when I was messing around with the predecessor to Josh Bloch's current ARM proposal (presumably you've seen that?). I didn't think it pulled its weight to be honest, in the context of ARM anyway. > Annotation-controlled overlading is used instead of an interface > because the existing cleanup routines have a myriad of different > names and declare different checked exceptions, too. If there are > multiple @Cleanup methods for a type, a warning should be issued > if this happens through inheritance (old code which needs to be > ported), or an error if there are multiple such methods declared > in the same type (erroneous new code). In both cases, if such a > type is used in a transient local variable declaration, the > declaration is rejected. For better or worse, using annotations for these purposes is off limits. Regards, Mark From howard.lovatt at iee.org Sat Mar 14 18:41:37 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 15 Mar 2009 12:41:37 +1100 Subject: Proposal: Improved Wildcard Syntax for Java Message-ID: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> Neal Gafter has proposed replacing the current wildcard syntax with in and out instead of extends and super; an alternative to the current extends/super and Neal's proposal would be to deprecate the current wildcards and to change to the behaviour to that of arrays (covariant only). In particular to change the wildcard syntax to SomeClass for variables, arguments, or fields, class AClass for classes, and for methods where T is compulsory when declaring classes or methods but not used when declaring variables etc. (i.e. exactly like method arguments). This new syntax is similar in behaviour to the current syntax SomeClass (the difference is that the new does not issue a warning for covariant assignment). This proposal deprecates the concepts of SomeClass, SomeClass, and SomeClass in the current syntax. Generics are made covariant so that List lo = new ArrayList() is OK and does not issue a warning (like arrays). If "lo" form the previous example has an object added to it, lo.add( new Object() ), then if this produces an error or not is dependant on the class in question (in the case or ArrayList it wouldn't). See http://www.artima.com/weblogs/viewpost.jsp?thread=222021 for more detail. At the same time I propose cleaning up other pain points with generics, in particular: 1. Deprecate raw declarations, new ArrayList() becomes a deprecated warning - you need to say new ArrayList(). 2a. Deprecate self references, you get a deprecated warning for class Type>, you wouldn't use generics in this case. 2b. It follows that T> is an error in the new syntax, see next point for how you would do this. 3. Deprecate the ability to specify multiple bounds, e.g. instead of static > T max(Collection) you write static T max(Collection) (note Comparable would not be parameterised with the new syntax since you would almost always want Comparable). 4. Allow arrays of parameterised types, List[] lsa = new ArrayList[10] is OK (you may get a runtime exception though if you misuse the feature). Examples of use of proposed new syntax are: boolean isAnnotationPresent( Class annotationClass ); // was: boolean isAnnotationPresent( Class annotationClass ); static createList( Collection coll ); // was: static createList( Collection coll ); static void sort( List list ); // was: static > void sort( List list ); static Enum valueOf( Class enum, String name ); // was: static > T valueOf( Class enum, String name ); The disadvantage of this proposal is that you can now get the equivalent of ArrayStoreExceptions, the reason that this is acceptable is that ArrayStoreExceptions are rare (I have never had one). For compatibility the existing syntax would still be allowed, but would issue a deprecated warning. The reason that I am proposing deprecating wildcards is that they are not worth the trouble (they have a poor cost/benifit ratio - less is more). I know the language pedants will hate this proposal, but I think the vast majority of Java users would welcome this change. This proposal has some overlap with the proposal to infer generic types in that they both concern generic declarations, but are otherwise orthogonal. The collections library, in particular methods like sort (see above) and interfaces like Comparable, and enum class would need updating to the new syntax and this new library would have to be supplied as a module so that old code could use the old library (nt 100% compatible). So I am proposing eventually removing something from the language (actually replacing) - is removing a feature a first on coin-dev? From develop4lasu at gmail.com Sat Mar 14 19:02:01 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 15 Mar 2009 03:02:01 +0100 Subject: Glue classes proposal (beta) Message-ID: <28bca0ff0903141902o2a52c6f3mebfabf60dcc359ea@mail.gmail.com> Notice that it's beta specification: it's not described in full details, half validated (translation), and it's provided for you to pre-analyse. I still need some time to provide syntax which fully supports generics. Multi-glue classes are under consideration as well, but this may occur to be to complex to handle by any earth living programmer. OVERVIEW FEATURE SUMMARY: Glue classes allow to link utils direct with objects. MAJOR ADVANTAGE: Forgotten functionality can be not such big deal now. MAJOR BENEFIT(s): + New functions can be easy localised (critically important while introduce new peoples into project). + Security: glue class do not see anything protected. + Light binding new functions with existing classes. + Number of used classes reduction. + Allow to assign methods and functions(static methods) to arrays, classes, interfaces, ? + It's proof against same method occurs in class and delegator as well like in two delegators. + Allow to link gained(.jar) logic with new one, witch is impossible before final developer implements his classes. + Allow to project compact interfaces and do not worry about additional logic. MAJOR DISADVANTAGE: - Do not know any ;) sorry. ALTERNATIVES: Utils classes. EXAMPLES SIMPLE EXAMPLE: public class base glue { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); public String format(This this) { synchronized (sdf) { return sdf.format(this); } } private static final Date applicationStart = new Date(); public static Date applicationStart() { return applicationStart; } } base: logic name, should start with lowercase because it's representing logic not class. glue : logic will glue to all classes extending Date. .format(This this): method that will be 'visible' for declared objects. This: Object type representing this.getClass() this: equivalent with given bound (? extends Date). Usage: import java.util.Date; import pl.some.utils.base; // imported to allow ..format() execution public class Test { public static void test_0(Date date) { System.out.println(date..format()); //simple usage } public static void test_1(Date date) { System.out.println(date..base.format()); //used when we have more logics with same methods } public static void test_2(Date date) { System.out.println(date..pl.some.utils.base.format()); // full declaration } public static void test_3() { System.out.println(Date..applicationStart()..format()); // mixed case } } ADVANCED EXAMPLE: Will come... DETAILS SPECIFICATION: JLS 8.8: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8ClassDeclaration: NormalClassDeclaration GlueClassDeclaration EnumDeclaration GlueClassDeclaration ClassModifiersopt class Identifier glue GlueClassBody ActualTypeArgument (JLS 4.5.1) represent objects for witch glue works: , , , ... COMPILATION: Everything we need is already in JDK, we just need little trick to bind static method in compilation time with existing classes. TESTING: Like simple static methods. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: None. COMPATIBILITY New jars are fully compatible. Code is only backward compatible. REFERENCES Glue classes proposal beta: http://lasu2string.blogspot.com/2009/03/glue-classes-proposal.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sat Mar 14 19:18:28 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 15 Mar 2009 03:18:28 +0100 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903092013p1dec9c1cj1ce98d8076c9377e@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <17b2302a0903092013p1dec9c1cj1ce98d8076c9377e@mail.gmail.com> Message-ID: <28bca0ff0903141918p1388451es1f3505451991716e@mail.gmail.com> 2009/3/10 Joshua Bloch > Roel, > There were several reasons. The main reason was that we wanted the > for-each > loop to be side-effect free. Had we allowed Iterators, two consecutive > for-each statements on the same Iterator would have been legal, but would > have had very different semantics from two consecutive for-each statements > over the same Iterable. The former would have traversed the collection > once, while the latter traversed it twice. We thought this might lead to > bugs. Also it allowed us to avoid the issue of what to do if the object to > be iterated over implemented both Iterable and Iterator. There were people > on the expert group who argued to allow Iterator, but in the end it was > decided we decided that it was best not to support it. > > Regards, > > Josh > > > Thanks. When you give the reason it's much easier to find some logic answer. After some thoughts: We could introduce *while-each* loop ;) just for iterators, while now I agree with you that for-each loop should be iterator free. Is that my imagination or now time the problem are proportions in comfort and complexity in language? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From howard.lovatt at iee.org Sat Mar 14 19:19:26 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 15 Mar 2009 13:19:26 +1100 Subject: String literals in Java 7: version 1.2 Message-ID: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> The things I miss in Java strings are: 1. Embedding expressions, e.g. in JavaFX you can write "The answer is {answer ? "Yes" : "No"}". In the example the part inside the {} is evaluated and replaced by its value, if that value isn't a string then it is converted to a string automatically. 2. Easy internationalisation, e.g. in JavaFX you can write ##"Favourites" and the compiler internationalises your code and creates a properties file which you then edit for the different locales ("Favourites" = "Favorites") I am not saying that your other extensions to Java Strings are not good suggestions, just that I miss these more. It would also be nice to be similar to JavaFX, since the two are likely to be used together. From Dalibor.Topic at Sun.COM Sat Mar 14 19:43:19 2009 From: Dalibor.Topic at Sun.COM (Dalibor Topic) Date: Sun, 15 Mar 2009 03:43:19 +0100 Subject: Coin Considerations In-Reply-To: <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> <49BBED9C.7000901@sun.com> <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> Message-ID: <49BC6B47.1000007@sun.com> Neal Gafter wrote: > On Sat, Mar 14, 2009 at 10:47 AM, Dalibor Topic wrote: >> Dumping the entire source code >> for a file rather then subsets has the advantage that correct licensing, >> javadoc and attribution information could trivially travel along with >> the generated binary class file. > > Dalibor- > > There is currently no way to place an annotation on a "source file". > You could only annotate the individual classes found within it. In > that case, I would think it surprising to find that the annotation > contains source for all the classes, imports, and comments in the same > source file. Thanks, Neal - that's a very good point. Would Package be a more useful target for it? cheers, dalibor topic -- ******************************************************************* Dalibor Topic Tel: (+49 40) 23 646 738 Java F/OSS Ambassador AIM: robiladonaim Sun Microsystems GmbH Mobile: (+49 177) 2664 192 Nagelsweg 55 http://openjdk.java.net D-20097 Hamburg mailto:Dalibor.Topic at sun.com Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten Amtsgericht M?nchen: HRB 161028 Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer Vorsitzender des Aufsichtsrates: Martin H?ring From develop4lasu at gmail.com Sat Mar 14 19:44:19 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 15 Mar 2009 03:44:19 +0100 Subject: Array syntax for collections [was Re: Extended arrays declaration and access syntax with use of enumerated types] In-Reply-To: <1239471C-057C-454A-9940-A84EC354D857@googlemail.com> References: <49BBB416.3010509@e-spirit.de> <49BBB738.4090203@sun.com> <49BBC083.8050603@joda.org> <1239471C-057C-454A-9940-A84EC354D857@googlemail.com> Message-ID: <28bca0ff0903141944u5c6d984eif55398e5a78a78e9@mail.gmail.com> 2009/3/14 Mark Mahieu > Stephen, > ... > That's interesting. Did you get any feeling for *why* it was disliked? > > I get the impression that a lot of 'mostly sugar' suggestions receive > a more negative reaction at first blush. I'm pretty sure even > foreach was initially greeted with a certain amount of disdain by > some people. > > Mark > > > @Mark I'll tell you my reason: I barely use List or Map because they are to weak. So while I have my own implementation which is able to handle both List and Map I would be unable to use this syntax. Some interesting solution would be introducing interface: interface Array { T get(int index); // T get(T element); // array[ element ]; T set(int index,T element); // boolean add(T element); // array[]=element; } ... replaceable with [], but I doubt about it. What's more I almost do not use indexes. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From howard.lovatt at iee.org Sat Mar 14 19:55:01 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 15 Mar 2009 13:55:01 +1100 Subject: Feedback and comments on ARM proposal - resend Message-ID: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> Neal Gafter said: > The destructor model does not require allocating objects on the stack. > A language change along these lines analogous to this ARM proposal > would provide a new modifier on a local variable, and treat the code > from the declaration point to the point where the variable goes out of > scope much the same way as the ARM proposal treats the try block. Instead of writing: try ( Resource r = new Resource() ) { r.doSomething(); } You would write: final Resource r = new Resource(); r.doSomething(); This is so much more Java like than the block construct, why not do this instead of the block construct (note it would be an error not to declare the resource final). r.dispose() is called at the end of the enclosing block, provided that r is not null, when r goes out of scope, which is probably what you want anyway (you can insert an existing {} block if you have to control lifetime). Also, why not make the dispose method exception free, realistically what can a user of an API do if dispose throws an exception? Neal also suggested that for each loops should understand Disposable, this is a good suggestion as looping is common with rources and it also fits well with his other suggestion above. From neal at gafter.com Sat Mar 14 20:47:09 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 20:47:09 -0700 Subject: Coin Considerations In-Reply-To: <49BC6B47.1000007@sun.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> <49BBED9C.7000901@sun.com> <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> <49BC6B47.1000007@sun.com> Message-ID: <15e8b9d20903142047vc3944e0v125235892ddd148@mail.gmail.com> On Sat, Mar 14, 2009 at 7:43 PM, Dalibor Topic wrote: >> There is currently no way to place an annotation on a "source file". >> You could only annotate the individual classes found within it. ?In >> that case, I would think it surprising to find that the annotation >> contains source for all the classes, imports, and comments in the same >> source file. > > Thanks, Neal - that's a very good point. Would Package be a more useful > target for it? Currently an annotation on the package declaration is only allowed in one source file (package-info.java). From neal at gafter.com Sat Mar 14 20:58:37 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 20:58:37 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> References: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> Message-ID: <15e8b9d20903142058r8c64243gc6fa1692911fa921@mail.gmail.com> My main concern is that this sounds like a significant change to the type system, and therefore almost certainly out of scope for project Coin. I have no idea how you would specify or implement the proposed compile-time diagnostics (such as an error on lo.add(new Object())) or runtime type tests (such as the "equivalent of ArrayStoreExceptions"). The link with "more details" actually has fewer details than this email. I don't see how you plan to make the change backward compatible. Without something resembling a specification, it's hard to evaluate further. On Sat, Mar 14, 2009 at 6:41 PM, Howard Lovatt wrote: > Neal Gafter has proposed replacing the current wildcard syntax with in > and out instead of extends and super; an alternative to the current > extends/super and Neal's proposal would be to deprecate the current > wildcards and to change to the behaviour to that of arrays (covariant > only). In particular to change the wildcard syntax to > SomeClass for variables, arguments, or fields, class > AClass for classes, and for methods > where T is compulsory when declaring classes or methods but not used > when declaring variables etc. (i.e. exactly like method arguments). > This new syntax is similar in behaviour to the current syntax > SomeClass (the difference is that the new > does not issue a warning for covariant assignment). > > This proposal deprecates the concepts of SomeClass SomeOtherClass>, SomeClass, and SomeClass in the > current syntax. Generics are made covariant so that List lo = > new ArrayList() is OK and does not issue a warning (like > arrays). If "lo" form the previous example has an object added to it, > lo.add( new Object() ), then if this produces an error or not is > dependant on the class in question (in the case or ArrayList it > wouldn't). See http://www.artima.com/weblogs/viewpost.jsp?thread=222021 > for more detail. > > At the same time I propose cleaning up other pain points with > generics, in particular: > > 1. Deprecate raw declarations, new ArrayList() becomes a deprecated > warning - you need to say new ArrayList(). > > 2a. Deprecate self references, you get a deprecated warning for class > Type>, you wouldn't use generics in this case. > > 2b. It follows that T> is an error in the new syntax, see > next point for how you would do this. > > 3. Deprecate the ability to specify multiple bounds, e.g. instead of > static > T max(Collection extends T>) you write static T max(Collection) (note > Comparable would not be parameterised with the new syntax since you > would almost always want Comparable). > > 4. Allow arrays of parameterised types, List[] lsa = new > ArrayList[10] is OK (you may get a runtime exception though if > you misuse the feature). > > Examples of use of proposed new syntax are: > > boolean isAnnotationPresent( Class annotationClass ); // > was: boolean isAnnotationPresent( Class > annotationClass ); > > static createList( Collection coll ); // was: static > createList( Collection coll ); > > static void sort( List list ); // was: static extends Comparable> void sort( List list ); > > static Enum valueOf( Class enum, String name ); // was: static > > T valueOf( Class enum, String name ); > > The disadvantage of this proposal is that you can now get the > equivalent of ArrayStoreExceptions, the reason that this is acceptable > is that ArrayStoreExceptions are rare (I have never had one). For > compatibility the existing syntax would still be allowed, but would > issue a deprecated warning. The reason that I am proposing deprecating > wildcards is that they are not worth the trouble (they have a poor > cost/benifit ratio - less is more). I know the language pedants will > hate this proposal, but I think the vast majority of Java users would > welcome this change. > > This proposal has some overlap with the proposal to infer generic > types in that they both concern generic declarations, but are > otherwise orthogonal. The collections library, in particular methods > like sort (see above) and interfaces like Comparable, and enum class > would need updating to the new syntax and this new library would have > to be supplied as a module so that old code could use the old library > (nt 100% compatible). > > So I am proposing eventually removing something from the language > (actually replacing) - is removing a feature a first on coin-dev? > > From neal at gafter.com Sat Mar 14 21:04:48 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 21:04:48 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> Message-ID: <15e8b9d20903142104t30aff61cpd354a7c863f0df8b@mail.gmail.com> On Sat, Mar 14, 2009 at 7:55 PM, Howard Lovatt wrote: > Instead of writing: > > try ( Resource r = new Resource() ) { > ?r.doSomething(); > } > > You would write: > > final Resource r = new Resource(); > r.doSomething(); I think this requires something like a new modifier on the local variable declaration. Without a distinguished syntax, I don't see how to distinguish this from a normal local variable declaration. > This is so much more Java like than the block construct, why not do > this instead of the block construct (note it would be an error not to > declare the resource final). r.dispose() is called at the end of the > enclosing block, provided that r is not null, when r goes out of > scope, which is probably what you want anyway (you can insert an > existing {} block if you have to control lifetime). Also, why not make > the dispose method exception free, realistically what can a user of an > API do if dispose throws an exception? If it's not final, what happens when the variable is reassigned? Without allowing checked exceptions on the resource release, I don't see how to retrofit this onto the primary use-case, Closeable. > Neal also suggested that for each loops should understand Disposable, > this is a good suggestion as looping is common with rources and it > also fits well with his other suggestion above. > > From howard.lovatt at iee.org Sat Mar 14 21:13:46 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 15 Mar 2009 15:13:46 +1100 Subject: Use "default" keyword for default visibility Message-ID: <3dd3f56a0903142113we599148y13e012855d900c28@mail.gmail.com> Early versions of Java had package private (I think) for this. It would make the code clearer in that everything would have a keyword. package could be used, since this is the scope of the default. From jjb at google.com Sat Mar 14 22:28:15 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 14 Mar 2009 22:28:15 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <28bca0ff0903141918p1388451es1f3505451991716e@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903091624t7e4d5be7n7cb9d3eab1effa6@mail.gmail.com> <17b2302a0903092013p1dec9c1cj1ce98d8076c9377e@mail.gmail.com> <28bca0ff0903141918p1388451es1f3505451991716e@mail.gmail.com> Message-ID: <17b2302a0903142228i25d8cc6bhe4a65e4c42a601d2@mail.gmail.com> Marek, On Sat, Mar 14, 2009 at 7:18 PM, Marek Kozie? wrote: > 2009/3/10 Joshua Bloch > > When you give the reason it's much easier to find some logic answer. > > After some thoughts: > We could introduce *while-each* loop ;) just for iterators, while now I > agree with you that for-each loop should be iterator free. > > Is that my imagination or now time the problem are proportions in comfort > and complexity in language? > It's not your imagination. This is a key issue in evolving a language. It's absolutely fundamental. Josh From jjb at google.com Sat Mar 14 22:31:17 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 14 Mar 2009 22:31:17 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> Message-ID: <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> On Sat, Mar 14, 2009 at 7:55 PM, Howard Lovatt wrote: > > Instead of writing: > > try ( Resource r = new Resource() ) { > r.doSomething(); > } > > You would write: > > final Resource r = new Resource(); > r.doSomething(); > > This is so much more Java like than the block construct There is room for disagreement here. We discussed this extensively at Google when I drafted the proposal, and we ended up eschewing a declaration-based approach because there was general agreement that it was much less Java-like to imbue the closing bracket with such "magical powers." Josh From jeremy.manson at gmail.com Sat Mar 14 22:56:02 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 14 Mar 2009 22:56:02 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> Message-ID: <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> It is probably worth pointing out that the flip side of this in our discussions was that variables are also block-scoped, so there was wiggle room for people who believed that this whole issue was secretly a scoping issue for variables and didn't have anything at all to do with blocks of code. Jeremy On Sat, Mar 14, 2009 at 10:31 PM, Joshua Bloch wrote: > On Sat, Mar 14, 2009 at 7:55 PM, Howard Lovatt wrote: > >> >> Instead of writing: >> >> try ( Resource r = new Resource() ) { >> ?r.doSomething(); >> } >> >> You would write: >> >> final Resource r = new Resource(); >> r.doSomething(); >> >> This is so much more Java like than the block construct > > > There is room for disagreement here. ?We discussed this extensively at > Google when I drafted the proposal, and we ended up eschewing a > declaration-based approach because there was general agreement that it was > much less Java-like to imbue the closing bracket with such "magical powers." > > ? ? ? ? Josh > > From jjb at google.com Sat Mar 14 23:08:40 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 14 Mar 2009 23:08:40 -0700 Subject: Use "default" keyword for default visibility In-Reply-To: <3dd3f56a0903142113we599148y13e012855d900c28@mail.gmail.com> References: <3dd3f56a0903142113we599148y13e012855d900c28@mail.gmail.com> Message-ID: <17b2302a0903142308o330c9942hc866052d05ebdbe4@mail.gmail.com> Howard, Are you sure? The only other modifier I remember was "private protected," which was quite different from package private. I believe that it was always the default access mode. I thought I coined the term "package private" for Effective Java (though it's likely that others came up with it independently and earlier). Josh On Sat, Mar 14, 2009 at 9:13 PM, Howard Lovatt wrote: > Early versions of Java had package private (I think) for this. It > would make the code clearer in that everything would have a keyword. > package could be used, since this is the scope of the default. > > From neal at gafter.com Sat Mar 14 23:29:26 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 14 Mar 2009 23:29:26 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> Message-ID: <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> On Sat, Mar 14, 2009 at 10:56 PM, Jeremy Manson wrote: > It is probably worth pointing out that the flip side of this in our > discussions was that variables are also block-scoped, so there was > wiggle room for people who believed that this whole issue was secretly > a scoping issue for variables and didn't have anything at all to do > with blocks of code. ? Agreed, though there is one context in which it is possible to jump into the scope of a local variable declaration without "executing" the declaration: the switch statement. From Dalibor.Topic at Sun.COM Sun Mar 15 01:18:20 2009 From: Dalibor.Topic at Sun.COM (Dalibor Topic) Date: Sun, 15 Mar 2009 09:18:20 +0100 Subject: Coin Considerations In-Reply-To: <15e8b9d20903142047vc3944e0v125235892ddd148@mail.gmail.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> <49BBED9C.7000901@sun.com> <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> <49BC6B47.1000007@sun.com> <15e8b9d20903142047vc3944e0v125235892ddd148@mail.gmail.com> Message-ID: <49BCB9CC.1020204@sun.com> Neal Gafter wrote: > On Sat, Mar 14, 2009 at 7:43 PM, Dalibor Topic wrote: >>> There is currently no way to place an annotation on a "source file". >>> You could only annotate the individual classes found within it. In >>> that case, I would think it surprising to find that the annotation >>> contains source for all the classes, imports, and comments in the same >>> source file. >> Thanks, Neal - that's a very good point. Would Package be a more useful >> target for it? > > Currently an annotation on the package declaration is only allowed in > one source file (package-info.java). Extending annotations to be allowed in more places pretty much kills the idea of this being a simple change, so - withdrawn. cheers, dalibor topic -- ******************************************************************* Dalibor Topic Tel: (+49 40) 23 646 738 Java F/OSS Ambassador AIM: robiladonaim Sun Microsystems GmbH Mobile: (+49 177) 2664 192 Nagelsweg 55 http://openjdk.java.net D-20097 Hamburg mailto:Dalibor.Topic at sun.com Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten Amtsgericht M?nchen: HRB 161028 Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer Vorsitzender des Aufsichtsrates: Martin H?ring From reinier at zwitserloot.com Sun Mar 15 02:12:26 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 15 Mar 2009 10:12:26 +0100 Subject: Coin Considerations In-Reply-To: <49BC6B47.1000007@sun.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> <49BBED9C.7000901@sun.com> <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> <49BC6B47.1000007@sun.com> Message-ID: <031AB425-4CE6-4E24-ABDC-2B629C31FA52@zwitserloot.com> No, you can do this within project coin, I think: If there's one top-level member, or there are many, but only one is public (there can't be more than one public), that's the one that gets the real annotation. Any spin-off classes (e.g. a $1 or whatnot, or a top-level package-private) get a @SourceRef annotation, which contains a class literal that does contain the full source (the public top- level member). That covers virtually all source files. For the remaining files, which would pretty much boil down to a bunch of package private classes bundled up into one source file (a situation eclipse couldn't even handle until eclipse 3.0, which should go a ways to indicate how rare that is), Pick one: just toss the full source on each and every file, -or-, pick a random one (probably: 'the first member in the compilationunit') and put @SourceRef on all the other ones. It's sufficiently rare that I doubt it matters. For files that have no source members at all, there are no class files either (package-info.java, module-info.java do have significance but don't produce class files AFAIK, any other .java file with 0 members in it is by definition empty, other than comments, and wouldn't do anything at all), so no @Source or @SourceRef needed. --Reinier Zwitserloot On Mar 15, 2009, at 03:43, Dalibor Topic wrote: > Neal Gafter wrote: >> On Sat, Mar 14, 2009 at 10:47 AM, Dalibor Topic > > wrote: >>> Dumping the entire source code >>> for a file rather then subsets has the advantage that correct >>> licensing, >>> javadoc and attribution information could trivially travel along >>> with >>> the generated binary class file. >> >> Dalibor- >> >> There is currently no way to place an annotation on a "source file". >> You could only annotate the individual classes found within it. In >> that case, I would think it surprising to find that the annotation >> contains source for all the classes, imports, and comments in the >> same >> source file. > > Thanks, Neal - that's a very good point. Would Package be a more > useful > target for it? > > cheers, > dalibor topic > > -- > ******************************************************************* > Dalibor Topic Tel: (+49 40) 23 646 738 > Java F/OSS Ambassador AIM: robiladonaim > Sun Microsystems GmbH Mobile: (+49 177) 2664 192 > Nagelsweg 55 http://openjdk.java.net > D-20097 Hamburg mailto:Dalibor.Topic at sun.com > Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten > Amtsgericht M?nchen: HRB 161028 > Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer > Vorsitzender des Aufsichtsrates: Martin H?ring > > > From reinier at zwitserloot.com Sun Mar 15 02:20:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 15 Mar 2009 10:20:06 +0100 Subject: Coin Considerations In-Reply-To: <873adfzo7o.fsf@mid.deneb.enyo.de> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <873adfzo7o.fsf@mid.deneb.enyo.de> Message-ID: Static Methods in Interfaces has already been submitted. (by me and Roel Spilker, near the start of Project Coin). javac should most definitely not whine about tabs, because the One True Indentation Style uses tabs. If anything, it should whine if you don't use the OTIS, but most of the java sources are in the crazy 'indents are 4 spaces, but replace any 8 spaces with a tab' mode. That's one of those warnings everyone's going to turn off. A warning for indentation that makes no sense might be more useful, but there are still many exceptions to this, such as giving a long string in the source file (code smell, but it happens) no indentation whatsoever to make more of it readable / require less line breaks to keep it all within 80 characters. The summary: indentation style is something that keeps evolving, and has no concensus. That's exactly the kind of thing that should NOT be hardcoded into the language. If such style checking is important, javac needs a pluggable interface for style checking, which all the IDEs can than standardize upon. That's not a bad idea at all. It could ship with a few standard checkers out of the box, which you can then add to and remove from to your heart's content. NB: OTIS is to use tabs for indentation, and spaces for spacing. The central rule for OTIS is: Any tab symbol may appear ONLY after either A) a newline, or B) a tab symbol. One of the side-effects is that you can mess with your editor's tab stop setting as much as you want, it won't break the indentation. It'll merely change it to something that is convenient for your eyeballs/monitor combination, one of the advantages of the OTIS. If you want to line things out in a source file (e.g. put a multi-line string's second opener right below the first), then tab to the usual indent, and use spaces from there for lining it up. This makes semantic sense; the tabs are indent, the spaces are spacing. Just like the names suggest. --Reinier Zwitserloot On Mar 15, 2009, at 00:20, Florian Weimer wrote: > * Reinier Zwitserloot: > >> Here's my list (* means: Definitely 'believe' in it, just need the >> time, and '-' means: Not entirely sure it can be made simple enough >> for coin / is a good idea in the first place): > > I would like to see: > > o transient modifier on local variables > > Basically, > > { > transient SomeClass foo = getFoo(); > doSomething(foo); > } > > is translated to: > > { > transient SomeClass foo = getFoo(); > try { > doSomething(foo); > } finally { > if (foo != null) { > foo.cleanup(); > } > } > } > > were SomeClass#cleanup() is the single method in class SomeClass > which carries a @Cleanup annotation. > > The "!= null" part is there to make it possible to signal to the > cleanup handler that the object has changed ownership. Assignment > to the variable does not trigger cleanup, cleanup only happens at > scope exit. > > Annotation-controlled overlading is used instead of an interface > because the existing cleanup routines have a myriad of different > names and declare different checked exceptions, too. If there are > multiple @Cleanup methods for a type, a warning should be issued > if this happens through inheritance (old code which needs to be > ported), or an error if there are multiple such methods declared > in the same type (erroneous new code). In both cases, if such a > type is used in a transient local variable declaration, the > declaration is rejected. > > Syntactically, this extensions blends well with type inference for > local variables. However, similar to other forms of compile-time > overloading, removing type declarations will change invoked > methods in a few corner cases. > > The choice of the transient keyword means that the same syntax > cannot be used for generating cleanup methods for classes. It is > not clear to me how to generate code for such classes in the > presence of inheritance and exceptions, so I don't think this is a > significant problem. (This problem does not arise in the local > variables case because there is a clear nesting of scopes.) > > My hope is that such an extension eventually leads to code which > has got fewer resource leaks, but is as succinct and as easy to > read as code which (improperly) relies on garbage collection. > > o new-style for loops with non-Iterator iterators. > > Basically, allow interfaces besides Iterable and Iterator, guided > by annotations (a more complicated variant of the approach for > "transient"). The use case are iterators which may throw > IOException (and other checked exceptions, of course). > > This is likely a waste if Java gets something which allows you to > define new control flow constructs (and even syntactically > lightweight anonymous classes might be good enough). > > o "class Foo extends ?" syntax for code injection through JSR 269 > > Right now, you have to use a class name instead of "?" which you > shouldn't use anywhere else due to concerns for circularity. Not > being able to name that class increases robustness. The compiler > would automatically generate a suitable type name in the same > package as the class that contains the "?". This would also > enable code injection for nested types. > > o injection of automatically generated superinterface using JSR 269 > > IIRC, there is a bug which prevents this from working. I don't > know if this is deliberate. The syntax extension for classes > might help here, too. > > o static methods in interface types > > This is for injecting code using a superinterface generated in a > JSR 269 scenario. Static member classes already work today (if > you fix the bug mentioned in the previous item.) > > o compiler warnings for crass mismatches between syntax and > indentation (if this is too hard to implement efficiently, a > backport of the -Xlint:braces warning from Netbeans) > > A mode which rejects tab characters in the source code might be > useful, too. > > My larger wish list includes: > > - non-nullable reference types > - tuples and structural record types > - algebraic data types > - type classes and type families > (or reified generics with partial specialization) > - non-hashable/comparable/synchronizable reference types > (perhaps via type classes) > > Okay, this list is not to be taken completely seriously. But I think > some of the stuff is indeed useful (the last point would allow a clean > implementation of fixnums, for instance). > >> - factory interfaces (an interface to describe constructors and >> static methods). I've got a simple way to do it, but I don't think >> its >> simple enough for coin. > > Method handles will cover many use cases, I think. > From reinier at zwitserloot.com Sun Mar 15 02:29:44 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 15 Mar 2009 10:29:44 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> Message-ID: <3C3ACF70-51AF-4F5F-AE67-578A90DFC6BA@zwitserloot.com> Howard, On Mar 15, 2009, at 03:55, Howard Lovatt wrote: > Also, why not make the dispose method exception free, > realistically what can a user of an API do if dispose throws an > exception? > Realistically, what can a user of an API do if 'write' throws an exception? Your argument does not hold water unless this is an argument for eschewing checked exceptions altogether. --Reinier Zwitserloot From howard.lovatt at iee.org Sun Mar 15 03:20:59 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 15 Mar 2009 21:20:59 +1100 Subject: 'This' type Message-ID: <3dd3f56a0903150320g7e8c7294j8c34448567f41a72@mail.gmail.com> I am not sure I completely follow the proposal, but if the proposal is something like self types in Eiffel or Scala then they can have problems. In the Eiffel book, I think it is ed. 3 that has self types, they are introduced in a Skier example. The example is organising a High School Ski Trip and you don't want the boys sharing with the girls, so you want the roommate() method to have type this (self in Eiffel), so that Boy's roommmate returns a Boy and Girl's roommate() returns a Girl. Something like: interface Skier { This roommate(); void setRoommate(This roomie); ... } class Boy implements Skier { Boy roommate() ... } class Girls implements Skier { Girl roommate() ... } Now they introduce the concept of a Ranked skier and have classes RankedBoy and RankedGirl, something like this: interface Ranked { int ranking(); } class RankedBoy extends Boy implements Ranking { RankedBoy roommate() ... } ... The problem is that now only RankedBoys can share with RankedBoys; which was not the intention in the example and is an extremely difficult to find bug. This shows that even *expert* programmers can make mistakes with self types. Therefore self types seem to solve some problems, but introduce others. From develop4lasu at gmail.com Sun Mar 15 03:57:43 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 15 Mar 2009 11:57:43 +0100 Subject: 'This' type In-Reply-To: <3dd3f56a0903150320g7e8c7294j8c34448567f41a72@mail.gmail.com> References: <3dd3f56a0903150320g7e8c7294j8c34448567f41a72@mail.gmail.com> Message-ID: <28bca0ff0903150357g1f8261c8s325194604a6b7df5@mail.gmail.com> 2009/3/15 Howard Lovatt > I am not sure I completely follow the proposal, but if the proposal is > something like self types in Eiffel or Scala then they can have > problems. In the Eiffel book, I think it is ed. 3 that has self types, > they are introduced in a Skier example. The example is organising a > High School Ski Trip and you don't want the boys sharing with the > girls, so you want the roommate() method to have type this (self in > Eiffel), so that Boy's roommmate returns a Boy and Girl's roommate() > returns a Girl. Something like: > > interface Skier { This roommate(); void setRoommate(This roomie); ... } > > class Boy implements Skier { Boy roommate() ... } > > class Girls implements Skier { Girl roommate() ... } > > Now they introduce the concept of a Ranked skier and have classes > RankedBoy and RankedGirl, something like this: > > interface Ranked { int ranking(); } > > class RankedBoy extends Boy implements Ranking { RankedBoy roommate() ... } > > ... > > The problem is that now only RankedBoys can share with RankedBoys; > which was not the intention in the example and is an extremely > difficult to find bug. This shows that even *expert* programmers can > make mistakes with self types. Therefore self types seem to solve some > problems, but introduce others. > > After some time, I found the same about this. 'This' type need lots analyze and it should be split into: 'This' type : - work with inheritance - can be used in generics - but allowed only for return type (would add relation to generics) - it would be great mistake to allow 'This' as input parameter other than 'Self' type : - used as replacement current class. I'll try to finish other specification that will allow return 'this' and will do interfere with potential added 'This' type. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From howard.lovatt at iee.org Sun Mar 15 04:30:33 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 15 Mar 2009 22:30:33 +1100 Subject: PRE-PROPOSAL: Source and Encoding keyword Message-ID: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> Since I proposed a source keyword a while back, http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6519124, I am obviously biased in favour of this proposal. I think the place for source is in the file, since the compiler deals with files. The advantage of a source statement is that it positions Java for the future: 1. There are many proposals around that would benefit from more syntax changes than is currently possible. The obvious current one is module, instead of burdening every tool with a new parsing technology - just make module a keyword. Remember exotic names are already in coin, therefore you can still call old code that uses module as an identifier. 2. Many proposals for the language jump through hoops it trying to avoid new keywords (I'm talking about you BGGA). These proposals end up looking nothing like Java as a consequence. Java uses unabbreviated keywords, e.g. extends instead of :, this is part of the character of Java. You need a source statement to enable new keywords and hence enable future extensions that don't appear alien. 3. When there is a reliable library dating scheme (maybe as part of the modules), then the compiler could enforce this also (this would be true for both -source and source in the file). Reliable library management is something separate, but one in place source will be able to use it. The argument that the JLS doesn't spell out what the current -source flag does, but would have to if source were added to Java is a bit weak. The -source flag exists, it is documented, that documentation could be moved into JLS. If the documentation is not up to JLS standard then at some point, not necessarily now, it will need improving. Remember that this is nothing new, other than putting it into the file. -source already exists, it already has some documentation (people including compiler writers seem largely happy with its documentation). My motivation for the source keyword came form network protocols (and similar) that have a version number. This has proved a very successful way of maintaining backward compatibility and still adding new features, the same would be true for a programming language. Since there is not much time for coin there is little that this change would add to 6, other than making module a true keyword, but the big picture is the future changes are much more manageable (it is a future proofing strategy - part of a grand plan). From neal at gafter.com Sun Mar 15 08:07:09 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 15 Mar 2009 08:07:09 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> References: <49B576EE.40703@sun.com> <63b4e4050903100836t58aa6e61i2c267b265e749618@mail.gmail.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> Message-ID: <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> On Fri, Mar 13, 2009 at 11:05 AM, Joshua Bloch wrote: >?I have created a document for this purpose ( > http://docs.google.com/Doc?id=ddv8ts74_1d7tz65fd), and anyone who wants can > add to it. ?Please participate (constructively)! I'm confused about how this document is to be used. On the one hand, the preface appears to set conventions about notes that can be used in the discussion to classify use cases. On the other hand, you (Josh) appear to have moved some use cases below a line whose title disagrees with the annotations, along with a command not to move any of them. I'm fine with consistently using annotations (which most of the discussion does) or consistently using sections, but mixing the two isn't working out so well. From jjb at google.com Sun Mar 15 10:14:10 2009 From: jjb at google.com (Joshua Bloch) Date: Sun, 15 Mar 2009 10:14:10 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> References: <49B576EE.40703@sun.com> <15e8b9d20903100918i4777fbd7je7131e4bbff5ddd2@mail.gmail.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> Message-ID: <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> Neal, Sorry if I wasn't clear. The proposed construct is aimed at types with a single termination method that must be called when the program will never use the resource again. The purpose of the document is to enumerate the many existing types that fit this usage pattern, so that we can assess the applicability of the construct to these types, and tune it if necessary. If a type doesn't fit this usage pattern but you think it belongs in the document, it should be placed below the line. The java.util.concurrent.locks.Lock type doesn't fit the pattern because it is reused after it is "terminated" (unlocked). The java.util.Iterator&AutoDisposable type doesn't fit the pattern because it isn't found in any existing Java APIs. Regards, Josh P.S. The notations [1] and [2] were designed to identify types that appear to obey the above usage pattern but aren't important for other reasons. On Sun, Mar 15, 2009 at 8:07 AM, Neal Gafter wrote: > On Fri, Mar 13, 2009 at 11:05 AM, Joshua Bloch wrote: > > I have created a document for this purpose ( > > http://docs.google.com/Doc?id=ddv8ts74_1d7tz65fd), and anyone who wants > can > > add to it. Please participate (constructively)! > > I'm confused about how this document is to be used. On the one hand, > the preface appears to set conventions about notes that can be used in > the discussion to classify use cases. On the other hand, you (Josh) > appear to have moved some use cases below a line whose title disagrees > with the annotations, along with a command not to move any of them. > I'm fine with consistently using annotations (which most of the > discussion does) or consistently using sections, but mixing the two > isn't working out so well. > From neal at gafter.com Sun Mar 15 10:45:46 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 15 Mar 2009 10:45:46 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> References: <49B576EE.40703@sun.com> <63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> Message-ID: <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> On Sun, Mar 15, 2009 at 10:14 AM, Joshua Bloch wrote: > Neal, > Sorry if I wasn't clear.??The proposed construct is aimed at?types with a > single termination method that must be called when the program will never > use the resource again. ?The purpose of the document is to enumerate the > many existing types that fit this usage pattern, so that we can assess the > applicability of the construct to these types, and tune it if necessary. > If a type doesn't fit this usage pattern but you think it belongs in the > document, it should be placed below the line. The > ?java.util.concurrent.locks.Lock type doesn't fit the pattern because it is > reused after it is "terminated" (unlocked). The > java.util.Iterator&AutoDisposable type doesn't fit the pattern because it > isn't found in any existing Java APIs. > ?? ?Regards, > ?? ?Josh > P.S. The notations [1] and [2] were designed to identify types that appear > to obey the above usage pattern but aren't important for other reasons. It sounds like this may be conflating the solution with the problem. I think what you're saying is that the proposal is restricting itself to the RAII pattern for resources - where there is some value that is a stand-in for the resource being held. In virtually all cases the true resource itself requiring mediation - O/S file handles, physical memory, etc - can and often is reused, and the intent of resource management is to mediate the reuse of the resource. Streams, for example, need to be closed so that O/S resources such as file handles can be reused. FileLock represents exclusive access to a file, and is implemented using an RAII pattern, but the resource (the file) certainly can be used again by the program. And so on. Locks are indeed resources where assistance in mediation is helpful, they just don't happen to be implemented using the RAII pattern. Locks do, however, satisfy the definitions in the document. [1] Best practice demands that the resource typically has a "lexically scoped lifetime" (i.e., its close/dispose method should be called when execution exits the scope in which they were acquired).; and [2] The type is widely used in practice. (Roughly speaking, at least thousands of programmers use it on a daily basis.). This definition is more useful than the criteria in your mail, above, as it allows us to more accurately measure the proposal's applicability. Use cases should not be excluded from consideration simply because they aren't well supported by the proposal. If you have comments on the various use cases, it is probably best to place them below the use cases for consistency. I've already noted that Locks are not implemented using the RAII pattern. Any type that extends Iterator&AutoDisposable certainly does satisfy either definition of a resource, though it should (and is) annotated with a [2] to indicate that the type AutoDisposable doesn't exist yet and therefore isn't yet used. I've also noted that in the description. But that's not how it is described by the title bar you placed above it. From schulz at e-spirit.de Sun Mar 15 12:15:00 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 15 Mar 2009 20:15:00 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> References: <49B576EE.40703@sun.com><63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com><17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com><3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com><17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com><961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com><17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com><15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com><17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> Message-ID: <49BD53B4.7040909@e-spirit.de> Howard mentioned it before, embedding expressions might be a nice thing to have in Java. The simplest thing is to embed variables to print their value. The proposal is not at the same level as Multi-line Strings, as it does not result in a construction of a String Literal but rather offers a "short cut" for building complex Strings. To at least have a basis for discussion, I set up a proposal that IMO could fit in the scope of COIN. Stefan Proposal: Embedded Expressions for String Statements AUTHOR(S): Stefan Schulz VERSION: 1.0 Initial version. Formatted version: http://docs.google.com/Doc?id=ddhp95vd_11dv7rmrcp OVERVIEW FEATURE SUMMARY: Often, textual output is constructed of a mix of plain text and values resolving from expressions. An escape sequence allows embedding such expressions into a string. If the result of the expression is no String, it will be converted to one. MAJOR ADVANTAGE: Improves readability and eases String construction. MAJOR BENEFIT: Reduces the cluttering in writing textual output. MAJOR DISADVANTAGE: May encourage to write one-liners with many expressions inside a String construction. ALTERNATIVES: Write strings the old way by using concatenations or using builders. EXAMPLES SIMPLE EXAMPLE: String name = "Dave"; System.out.println("Hello, \{name}!"); ADVANCED EXAMPLE: Object product = produce(); log("We \{product == null ? "failed" : "produced \{product}"}!"); DETAILS SPECIFICATION: The new escape sequence \{ will be handled at compile time by transforming the string statement into a concatenation of Strings. Neither can the statement be understood as a String literal nor is it an escape sequence in the sense of representing a single character literal. Therefore, the transformation has to be done prior to any other escape sequence handling. Changes are required in the JLS ?3.10.5 "String Literals" and 3.10.6 "Escape Sequences for Character and String Literals". Although the new escape sequence does not form a part of a String literal, it must be stated that it's a legit escape sequence with the consequence of making the string sequence become a statement rather than a literal. A new chapter is to be introduced on embedding expressions in string sequences, which closely relates to ?15.18.1 "String Concatenation Operator +". The syntax would be as follows: EmbeddedExpressionStatement: " StringCharactersAndExpression StringCharactersOpt " StringCharactersAndExpression StringCharactersOpt EmbeddedExpression StringCharactersAndExpressionOpt EmbeddedExpression \ { Expression } Note: The sequence "\{exp}" is deliberately chosen as it resembles the way other languages provide a similar ability, e.g., JavaFX ("{exp}"), PHP, Python and Groovy ("${exp}"). COMPILATION: In general, the statement will be transformed into a concatenation of literals and expressions. In the following, the String Concatenation Operator is being used, but maybe replaced by a StringBuilder solution. The latter might be easy to do, as the transformation happens before literal processing. Transformed simple example: String name = "Dave"; System.out.println("Hello, " + name + "!"); Transformed complex example: Object product = produceSomething(); log("We " + (product == null ? "failed" : "produced " + product) + "!"); TESTING: The transformation has to be tested to resolve to the expected old style way of concatenating Strings. The cases should cover simple variable references (null, primitive, String, and Object) as well as simple and nested expressions (including nested expressions with Strings having embedded expressions). LIBRARY SUPPORT: None. REFLECTIVE APIS: None. OTHER CHANGES: None. MIGRATION: Replace existing old style concatenation by applying the new escape sequence. COMPATIBILITY BREAKING CHANGES: None. The escape sequence \{ would prior have caused a compiler error. EXISTING PROGRAMS: No changes. REFERENCES EXISTING BUGS: (Although it is to be assumed there are existing bugs/rfes, the search did not pop up results for the keywords used. So this remains to be done.) URL FOR PROTOTYPE (optional): None of yet. From jeremy.manson at gmail.com Sun Mar 15 12:57:55 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 15 Mar 2009 12:57:55 -0700 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <49BD53B4.7040909@e-spirit.de> References: <49B576EE.40703@sun.com> <17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> <49BD53B4.7040909@e-spirit.de> Message-ID: <1631da7d0903151257o28404da5va1cb1da4d90c484c@mail.gmail.com> Hi Stefan, I'm sure this is obvious to everyone who isn't me, but I'm not sure what the big win is here. Basically, it looks to me as if you save a very small number of keystrokes: String name = "Dave"; Old: System.out.println("Hello, " + name + "!"); New: System.out.println("Hello, \{name}!"); ADVANCED EXAMPLE: Object product = produce(); Old: log("We " + (product == null ? "failed" : "produced " + product) + "!"); New: log("We \{product == null ? "failed" : "produced \{product}"}!"); Again, I'm sure there is a motivation here, but I'm not exactly sure what it is? Jeremy On Sun, Mar 15, 2009 at 12:15 PM, Stefan Schulz wrote: > Howard mentioned it before, embedding expressions might be a nice thing > to have in Java. The simplest thing is to embed variables to print their > value. > The proposal is not at the same level as Multi-line Strings, as it does > not result in a construction of a String Literal but rather offers a > "short cut" for building complex Strings. > To at least have a basis for discussion, I set up a proposal that IMO > could fit in the scope of COIN. > > Stefan > > > Proposal: Embedded Expressions for String Statements > > AUTHOR(S): > > Stefan Schulz > > VERSION: > > 1.0 ? ?Initial version. > > Formatted version: > http://docs.google.com/Doc?id=ddhp95vd_11dv7rmrcp > > > OVERVIEW > > FEATURE SUMMARY: > > Often, textual output is constructed of a mix of plain text and values > resolving from expressions. An escape sequence allows embedding such > expressions into a string. If the result of the expression is no String, > it will be converted to one. > > MAJOR ADVANTAGE: > > Improves readability and eases String construction. > > MAJOR BENEFIT: > > Reduces the cluttering in writing textual output. > > MAJOR DISADVANTAGE: > > May encourage to write one-liners with many expressions inside a String > construction. > > ALTERNATIVES: > > Write strings the old way by using concatenations or using builders. > > > EXAMPLES > > SIMPLE EXAMPLE: > ? String name = "Dave"; > ? System.out.println("Hello, \{name}!"); > > ADVANCED EXAMPLE: > ? Object product = produce(); > ? log("We \{product == null ? "failed" : "produced \{product}"}!"); > > > DETAILS > > SPECIFICATION: > > The new escape sequence \{ will be handled at compile time by > transforming the string statement into a concatenation of Strings. > Neither can the statement be understood as a String literal nor is it an > escape sequence in the sense of representing a single character literal. > Therefore, the transformation has to be done prior to any other escape > sequence handling. > > Changes are required in the JLS ?3.10.5 "String Literals" and 3.10.6 > "Escape Sequences for Character and String Literals". Although the new > escape sequence does not form a part of a String literal, it must be > stated that it's a legit escape sequence with the consequence of making > the string sequence become a statement rather than a literal. > > A new chapter is to be introduced on embedding expressions in string > sequences, which closely relates to ?15.18.1 "String Concatenation > Operator +". The syntax would be as follows: > > EmbeddedExpressionStatement: > ? " StringCharactersAndExpression StringCharactersOpt " > > StringCharactersAndExpression > ? StringCharactersOpt EmbeddedExpression StringCharactersAndExpressionOpt > > EmbeddedExpression > ? \ { Expression } > > Note: The sequence "\{exp}" is deliberately chosen as it resembles the > way other languages provide a similar ability, e.g., JavaFX ("{exp}"), > PHP, Python and Groovy ("${exp}"). > > COMPILATION: > > In general, the statement will be transformed into a concatenation of > literals and expressions. In the following, the String Concatenation > Operator is being used, but maybe replaced by a StringBuilder solution. > The latter might be easy to do, as the transformation happens before > literal processing. > > Transformed simple example: > ? String name = "Dave"; > ? System.out.println("Hello, " + name + "!"); > > Transformed complex example: > ? Object product = produceSomething(); > ? log("We " + (product == null ? "failed" : "produced " + product) + "!"); > > TESTING: > > The transformation has to be tested to resolve to the expected old style > way of concatenating Strings. The cases should cover simple variable > references (null, primitive, String, and Object) as well as simple and > nested expressions (including nested expressions with Strings having > embedded expressions). > > LIBRARY SUPPORT: > > None. > > REFLECTIVE APIS: > > None. > > OTHER CHANGES: > > None. > > MIGRATION: > > Replace existing old style concatenation by applying the new escape > sequence. > > > COMPATIBILITY > > BREAKING CHANGES: > > None. The escape sequence \{ would prior have caused a compiler error. > > EXISTING PROGRAMS: > > No changes. > > > REFERENCES > > EXISTING BUGS: > > (Although it is to be assumed there are existing bugs/rfes, the search > did not pop up results for the keywords used. So this remains to be done.) > > URL FOR PROTOTYPE (optional): > > None of yet. > > > From talden at gmail.com Sun Mar 15 13:12:40 2009 From: talden at gmail.com (Talden) Date: Mon, 16 Mar 2009 09:12:40 +1300 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> Message-ID: <738d207f0903151312g49c70f3cp980875aa2a8a094a@mail.gmail.com> > 2. Many proposals for the language jump through hoops it trying to > avoid new keywords (I'm talking about you BGGA). These proposals end > up looking nothing like Java as a consequence. Java uses unabbreviated > keywords, e.g. extends instead of :, this is part of the character of > Java. You need a source statement to enable new keywords and hence > enable future extensions that don't appear alien. You have to be careful not to characterise that aversion to abbreviation as an absolute. 'enum' instead of 'enumeration' for example. Of course we also don't say MULTIPLY x BY 2 GIVING x We instead say x *= 2; but then we wouldn't want to reinvent the overly verbose wheel. I agree though that there is a challenge to make Java language extensions feel like language growth rather than mutation but I would still hope the aim is to enhance function and maintain readability - I'm less worried about 'style' given that this language is a tool and not some fashion item. I'm also just not sure it's as objectively black and white as you make out nor am I sure that everything java is a good thing (such as the verbosity of some constructs). I for one wouldn't mind adding keywords if they clearly and surely improve readability. Altering programs that are broken by such changes are generally fairly easily corrected with tools to help -- and unless we choose poorly, it's unlikely a new keyword will have the impact that introducing assert did. Assert was so heavy used in testing frameworks, pervasively used across the market and across each source-base - not every word is so heavily used as identifiers in code. I look forward to seeing more proposals, there are some (in part and sometimes in full) that sound quite reasonable and I can see myself finding a use for them. -- Talden From neal at gafter.com Sun Mar 15 13:23:16 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 15 Mar 2009 13:23:16 -0700 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <1631da7d0903151257o28404da5va1cb1da4d90c484c@mail.gmail.com> References: <49B576EE.40703@sun.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> <49BD53B4.7040909@e-spirit.de> <1631da7d0903151257o28404da5va1cb1da4d90c484c@mail.gmail.com> Message-ID: <15e8b9d20903151323j2a873e44h6c7802452756fc75@mail.gmail.com> By properly nesting the embedded expressions, it helps address precedence puzzlers such as this System.out.println("2 + 2 is " + 2+2); Which declares that 2+2 is 22. On Sun, Mar 15, 2009 at 12:57 PM, Jeremy Manson wrote: > Hi Stefan, > > I'm sure this is obvious to everyone who isn't me, but I'm not sure > what the big win is here. ?Basically, it looks to me as if you save a > very small number of keystrokes: > > ?String name = "Dave"; > Old: > ?System.out.println("Hello, " + name + "!"); > New: > ?System.out.println("Hello, \{name}!"); > > ADVANCED EXAMPLE: > ?Object product = produce(); > Old: > ?log("We " + (product == null ? "failed" : "produced " + product) + "!"); > New: > ?log("We \{product == null ? "failed" : "produced \{product}"}!"); > > Again, I'm sure there is a motivation here, but I'm not exactly sure what it is? > > Jeremy > > On Sun, Mar 15, 2009 at 12:15 PM, Stefan Schulz wrote: >> Howard mentioned it before, embedding expressions might be a nice thing >> to have in Java. The simplest thing is to embed variables to print their >> value. >> The proposal is not at the same level as Multi-line Strings, as it does >> not result in a construction of a String Literal but rather offers a >> "short cut" for building complex Strings. >> To at least have a basis for discussion, I set up a proposal that IMO >> could fit in the scope of COIN. >> >> Stefan >> >> >> Proposal: Embedded Expressions for String Statements >> >> AUTHOR(S): >> >> Stefan Schulz >> >> VERSION: >> >> 1.0 ? ?Initial version. >> >> Formatted version: >> http://docs.google.com/Doc?id=ddhp95vd_11dv7rmrcp >> >> >> OVERVIEW >> >> FEATURE SUMMARY: >> >> Often, textual output is constructed of a mix of plain text and values >> resolving from expressions. An escape sequence allows embedding such >> expressions into a string. If the result of the expression is no String, >> it will be converted to one. >> >> MAJOR ADVANTAGE: >> >> Improves readability and eases String construction. >> >> MAJOR BENEFIT: >> >> Reduces the cluttering in writing textual output. >> >> MAJOR DISADVANTAGE: >> >> May encourage to write one-liners with many expressions inside a String >> construction. >> >> ALTERNATIVES: >> >> Write strings the old way by using concatenations or using builders. >> >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> ? String name = "Dave"; >> ? System.out.println("Hello, \{name}!"); >> >> ADVANCED EXAMPLE: >> ? Object product = produce(); >> ? log("We \{product == null ? "failed" : "produced \{product}"}!"); >> >> >> DETAILS >> >> SPECIFICATION: >> >> The new escape sequence \{ will be handled at compile time by >> transforming the string statement into a concatenation of Strings. >> Neither can the statement be understood as a String literal nor is it an >> escape sequence in the sense of representing a single character literal. >> Therefore, the transformation has to be done prior to any other escape >> sequence handling. >> >> Changes are required in the JLS ?3.10.5 "String Literals" and 3.10.6 >> "Escape Sequences for Character and String Literals". Although the new >> escape sequence does not form a part of a String literal, it must be >> stated that it's a legit escape sequence with the consequence of making >> the string sequence become a statement rather than a literal. >> >> A new chapter is to be introduced on embedding expressions in string >> sequences, which closely relates to ?15.18.1 "String Concatenation >> Operator +". The syntax would be as follows: >> >> EmbeddedExpressionStatement: >> ? " StringCharactersAndExpression StringCharactersOpt " >> >> StringCharactersAndExpression >> ? StringCharactersOpt EmbeddedExpression StringCharactersAndExpressionOpt >> >> EmbeddedExpression >> ? \ { Expression } >> >> Note: The sequence "\{exp}" is deliberately chosen as it resembles the >> way other languages provide a similar ability, e.g., JavaFX ("{exp}"), >> PHP, Python and Groovy ("${exp}"). >> >> COMPILATION: >> >> In general, the statement will be transformed into a concatenation of >> literals and expressions. In the following, the String Concatenation >> Operator is being used, but maybe replaced by a StringBuilder solution. >> The latter might be easy to do, as the transformation happens before >> literal processing. >> >> Transformed simple example: >> ? String name = "Dave"; >> ? System.out.println("Hello, " + name + "!"); >> >> Transformed complex example: >> ? Object product = produceSomething(); >> ? log("We " + (product == null ? "failed" : "produced " + product) + "!"); >> >> TESTING: >> >> The transformation has to be tested to resolve to the expected old style >> way of concatenating Strings. The cases should cover simple variable >> references (null, primitive, String, and Object) as well as simple and >> nested expressions (including nested expressions with Strings having >> embedded expressions). >> >> LIBRARY SUPPORT: >> >> None. >> >> REFLECTIVE APIS: >> >> None. >> >> OTHER CHANGES: >> >> None. >> >> MIGRATION: >> >> Replace existing old style concatenation by applying the new escape >> sequence. >> >> >> COMPATIBILITY >> >> BREAKING CHANGES: >> >> None. The escape sequence \{ would prior have caused a compiler error. >> >> EXISTING PROGRAMS: >> >> No changes. >> >> >> REFERENCES >> >> EXISTING BUGS: >> >> (Although it is to be assumed there are existing bugs/rfes, the search >> did not pop up results for the keywords used. So this remains to be done.) >> >> URL FOR PROTOTYPE (optional): >> >> None of yet. >> >> >> > > From jeremy.manson at gmail.com Sun Mar 15 13:46:33 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 15 Mar 2009 13:46:33 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> Message-ID: <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> I think there are a few problems with this: 1) If you are doing this so you can ensure that the old code will remain able to run on old versions of Java, this really is only half a solution, unless you include the APIs. If a "source" keyword is introduced for this purpose, it has to be introduced at the same time as versioned APIs, otherwise it is useless. 2) If you are doing this so that you can evolve the language by introducing new keywords and maintain backwards compatibility with old code, then you have a problem, because these old APIs are going to be allowed to export the new keywords as public members. If we add a new keyword "foo", and we use -source 5 so that we can have a public method "foo", you won't be able to use that API with -source 7 code. 3) None of the code you care about maintaining compatibility with is going to have the "source" annotation on it, which means that if you don't have the source keyword, you are going to have to assume that the source is Java 6. Does this mean that Java 7 code now *requires* a source annotation to tell you it is Java 7? Or do we have to go back and put "source 6" on all of the files that won't compile? If we are doing that anyway, can't we just change the code so that it compiles? 4) Do we have *really* compelling language changes that actually require new keywords (that aren't context sensitive, like "module")? 5) Is it easy to specify what the differences are in each source revision? When we add this to the JLS, what does it say, exactly, about what the number after the "source" keyword means? I'm not objecting to versioning in principle, but I think there are enough unanswered questions that this proposal is probably beyond the scope of "small changes". Jeremy On Sun, Mar 15, 2009 at 4:30 AM, Howard Lovatt wrote: > 3. When there is a reliable library dating scheme (maybe as part of > the modules), then the compiler could enforce this also (this would be > true for both -source and source in the file). Reliable library > management is something separate, but one in place source will be able > to use it. You can't really have one without the other. The APIs are just as much a part of Java as the language. If you release Java 7 and have people use -source 6, but allow them to use, say, java.util.concurrent.LinkedTransferQueue in the same code, then there is really no rea Jeremy From jeremy.manson at gmail.com Sun Mar 15 14:06:17 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 15 Mar 2009 14:06:17 -0700 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <15e8b9d20903151323j2a873e44h6c7802452756fc75@mail.gmail.com> References: <49B576EE.40703@sun.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> <49BD53B4.7040909@e-spirit.de> <1631da7d0903151257o28404da5va1cb1da4d90c484c@mail.gmail.com> <15e8b9d20903151323j2a873e44h6c7802452756fc75@mail.gmail.com> Message-ID: <1631da7d0903151406q4542df0du61e5a631c549c04e@mail.gmail.com> Fair enough. I guess I'm too used to that; I just put parentheses everywhere. On the flip side, I'm not a big fan of \{ as a delimiter. It seems to me that there should be a way to unify the general desire for better String handling (escaped Strings, multi-line Strings, embedded expressions). Can we colonize the ` (back-tick) character and start Strings over again from scratch? Jeremy On Sun, Mar 15, 2009 at 1:23 PM, Neal Gafter wrote: > By properly nesting the embedded expressions, it helps address > precedence puzzlers such as this > > System.out.println("2 + 2 is " + > ? ? ? ?2+2); > > Which declares that 2+2 is 22. > > On Sun, Mar 15, 2009 at 12:57 PM, Jeremy Manson wrote: >> Hi Stefan, >> >> I'm sure this is obvious to everyone who isn't me, but I'm not sure >> what the big win is here. ?Basically, it looks to me as if you save a >> very small number of keystrokes: >> >> ?String name = "Dave"; >> Old: >> ?System.out.println("Hello, " + name + "!"); >> New: >> ?System.out.println("Hello, \{name}!"); >> >> ADVANCED EXAMPLE: >> ?Object product = produce(); >> Old: >> ?log("We " + (product == null ? "failed" : "produced " + product) + "!"); >> New: >> ?log("We \{product == null ? "failed" : "produced \{product}"}!"); >> >> Again, I'm sure there is a motivation here, but I'm not exactly sure what it is? >> >> Jeremy >> >> On Sun, Mar 15, 2009 at 12:15 PM, Stefan Schulz wrote: >>> Howard mentioned it before, embedding expressions might be a nice thing >>> to have in Java. The simplest thing is to embed variables to print their >>> value. >>> The proposal is not at the same level as Multi-line Strings, as it does >>> not result in a construction of a String Literal but rather offers a >>> "short cut" for building complex Strings. >>> To at least have a basis for discussion, I set up a proposal that IMO >>> could fit in the scope of COIN. >>> >>> Stefan >>> >>> >>> Proposal: Embedded Expressions for String Statements >>> >>> AUTHOR(S): >>> >>> Stefan Schulz >>> >>> VERSION: >>> >>> 1.0 ? ?Initial version. >>> >>> Formatted version: >>> http://docs.google.com/Doc?id=ddhp95vd_11dv7rmrcp >>> >>> >>> OVERVIEW >>> >>> FEATURE SUMMARY: >>> >>> Often, textual output is constructed of a mix of plain text and values >>> resolving from expressions. An escape sequence allows embedding such >>> expressions into a string. If the result of the expression is no String, >>> it will be converted to one. >>> >>> MAJOR ADVANTAGE: >>> >>> Improves readability and eases String construction. >>> >>> MAJOR BENEFIT: >>> >>> Reduces the cluttering in writing textual output. >>> >>> MAJOR DISADVANTAGE: >>> >>> May encourage to write one-liners with many expressions inside a String >>> construction. >>> >>> ALTERNATIVES: >>> >>> Write strings the old way by using concatenations or using builders. >>> >>> >>> EXAMPLES >>> >>> SIMPLE EXAMPLE: >>> ? String name = "Dave"; >>> ? System.out.println("Hello, \{name}!"); >>> >>> ADVANCED EXAMPLE: >>> ? Object product = produce(); >>> ? log("We \{product == null ? "failed" : "produced \{product}"}!"); >>> >>> >>> DETAILS >>> >>> SPECIFICATION: >>> >>> The new escape sequence \{ will be handled at compile time by >>> transforming the string statement into a concatenation of Strings. >>> Neither can the statement be understood as a String literal nor is it an >>> escape sequence in the sense of representing a single character literal. >>> Therefore, the transformation has to be done prior to any other escape >>> sequence handling. >>> >>> Changes are required in the JLS ?3.10.5 "String Literals" and 3.10.6 >>> "Escape Sequences for Character and String Literals". Although the new >>> escape sequence does not form a part of a String literal, it must be >>> stated that it's a legit escape sequence with the consequence of making >>> the string sequence become a statement rather than a literal. >>> >>> A new chapter is to be introduced on embedding expressions in string >>> sequences, which closely relates to ?15.18.1 "String Concatenation >>> Operator +". The syntax would be as follows: >>> >>> EmbeddedExpressionStatement: >>> ? " StringCharactersAndExpression StringCharactersOpt " >>> >>> StringCharactersAndExpression >>> ? StringCharactersOpt EmbeddedExpression StringCharactersAndExpressionOpt >>> >>> EmbeddedExpression >>> ? \ { Expression } >>> >>> Note: The sequence "\{exp}" is deliberately chosen as it resembles the >>> way other languages provide a similar ability, e.g., JavaFX ("{exp}"), >>> PHP, Python and Groovy ("${exp}"). >>> >>> COMPILATION: >>> >>> In general, the statement will be transformed into a concatenation of >>> literals and expressions. In the following, the String Concatenation >>> Operator is being used, but maybe replaced by a StringBuilder solution. >>> The latter might be easy to do, as the transformation happens before >>> literal processing. >>> >>> Transformed simple example: >>> ? String name = "Dave"; >>> ? System.out.println("Hello, " + name + "!"); >>> >>> Transformed complex example: >>> ? Object product = produceSomething(); >>> ? log("We " + (product == null ? "failed" : "produced " + product) + "!"); >>> >>> TESTING: >>> >>> The transformation has to be tested to resolve to the expected old style >>> way of concatenating Strings. The cases should cover simple variable >>> references (null, primitive, String, and Object) as well as simple and >>> nested expressions (including nested expressions with Strings having >>> embedded expressions). >>> >>> LIBRARY SUPPORT: >>> >>> None. >>> >>> REFLECTIVE APIS: >>> >>> None. >>> >>> OTHER CHANGES: >>> >>> None. >>> >>> MIGRATION: >>> >>> Replace existing old style concatenation by applying the new escape >>> sequence. >>> >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: >>> >>> None. The escape sequence \{ would prior have caused a compiler error. >>> >>> EXISTING PROGRAMS: >>> >>> No changes. >>> >>> >>> REFERENCES >>> >>> EXISTING BUGS: >>> >>> (Although it is to be assumed there are existing bugs/rfes, the search >>> did not pop up results for the keywords used. So this remains to be done.) >>> >>> URL FOR PROTOTYPE (optional): >>> >>> None of yet. >>> >>> >>> >> >> > From reinier at zwitserloot.com Sun Mar 15 14:31:22 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 15 Mar 2009 22:31:22 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> Message-ID: <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> 1) the 'source' keyword has absolutely nothing to do with running old *CLASS* files on newer VMs. Again, this is exactly like the -source parameter to javac. It does not have magical 'make old stuff work on newer VM' powers. That's not what its for. Ergo, that's not what the 'source' keyword is for either. 2) One proposal that is in Joe's shortlist back when he announced project coin is a simple way to enforce 'this is an identifier', for example by including it in backticks. This doesn't -have- to go in at the same time as the source keyword (after all, even with the source keyword, which is trivially context sensitive, java7 will not introduce any new keywords. It's just opening the door to do so in the future. context: top of file only, otherwise its an identifier). Solve this problem. 3) Well, java7 source is source-compatible with java6, but if a future version adds a new keyword or makes another breaking change, then the 'source' keyword is mandatory. Just like the -source 1.4 parameter was mandatory when you wanted to use asserts in javac 1.4. What's the problem with this? 4) There are tons of compelling language changes that are made far more compelling by breaking source compatibility. None of these compelling features are on the table for java7, but there's absolutely no reason for any language change to be an 'all-or-nothing' proposal. Introduce the source keyword now, so that java programmers are familiar with it and have already seeded their files with 'source 7;' - then use the freedom that comes from this in java8 and beyond. 5) The JLS would say nothing at all about it. A separate document lists javac versions and matching versions of the JLS. If this documentation doesn't exist, as Howard said: Then that's a bug in the documentation, because the -source parameter (which is 100% analogous to the source keyword) MUST be documented; it does not have an -X in front of it. The only thing the JLS needs to say about the source keyword is how it works, and what the string is supposed to represent (target javac version). No more needs to be said. A compatible javac is not forced to support compiling older sources. It will merely be forced to not compile any source version that it can't compile, with an appropriate error message. If a compiler wants to go above and beyond (like sun's own javac, and eclipse's ecj, and just about every other compiler out there) and compile it anyway, according to the JLS as it was for that javac version, that's great, but its not a requirement. Here's the golden rule in regards to the source proposal: It's already a part of java, via javac -source. Just about every problem mentioned so far is either not a problem, or if it is, should be filed as a bug, because it also applies to javac -source. As I've already told Joe D'Arcy: If nobody else thinks this will improve java, especially for future expansion in java 8 and beyond, then I'm certainly not going to go through the trouble of writing out a full proposal. I find other proposals more worthy of cheerleading for. So far the overwhelming negative attitude on this forum means it's not going to happen. Unless someone else (Howard?) wants to run with it, of course. Consider this post a final effort to convince the coin-dev list :) --Reinier Zwitserloot On Mar 15, 2009, at 21:46, Jeremy Manson wrote: > I think there are a few problems with this: > > 1) If you are doing this so you can ensure that the old code will > remain able to run on old versions of Java, this really is only half a > solution, unless you include the APIs. If a "source" keyword is > introduced for this purpose, it has to be introduced at the same time > as versioned APIs, otherwise it is useless. > > 2) If you are doing this so that you can evolve the language by > introducing new keywords and maintain backwards compatibility with old > code, then you have a problem, because these old APIs are going to be > allowed to export the new keywords as public members. If we add a new > keyword "foo", and we use -source 5 so that we can have a public > method "foo", you won't be able to use that API with -source 7 code. > > 3) None of the code you care about maintaining compatibility with is > going to have the "source" annotation on it, which means that if you > don't have the source keyword, you are going to have to assume that > the source is Java 6. Does this mean that Java 7 code now *requires* > a source annotation to tell you it is Java 7? Or do we have to go > back and put "source 6" on all of the files that won't compile? If we > are doing that anyway, can't we just change the code so that it > compiles? > > 4) Do we have *really* compelling language changes that actually > require new keywords (that aren't context sensitive, like "module")? > > 5) Is it easy to specify what the differences are in each source > revision? When we add this to the JLS, what does it say, exactly, > about what the number after the "source" keyword means? > > I'm not objecting to versioning in principle, but I think there are > enough unanswered questions that this proposal is probably beyond the > scope of "small changes". > > Jeremy > > On Sun, Mar 15, 2009 at 4:30 AM, Howard Lovatt > wrote: >> 3. When there is a reliable library dating scheme (maybe as part of >> the modules), then the compiler could enforce this also (this would >> be >> true for both -source and source in the file). Reliable library >> management is something separate, but one in place source will be >> able >> to use it. > > You can't really have one without the other. The APIs are just as > much a part of Java as the language. If you release Java 7 and have > people use -source 6, but allow them to use, say, > java.util.concurrent.LinkedTransferQueue in the same code, then there > is really no rea > > Jeremy > From develop4lasu at gmail.com Sun Mar 15 14:34:27 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 15 Mar 2009 22:34:27 +0100 Subject: Return 'this' proposal Message-ID: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? GENESIS It's a simplified 'This' type problem, which seems to be too much complicated as for now and need more analyses. Construction is designed not to interact with possibility that 'This' type will be introduced. OVERVIEW FEATURE SUMMARY: It allows the method to return 'this' object. MAJOR ADVANTAGE: Simplification of return this; statement. 'void' can be easy replaced with 'this'. MAJOR BENEFIT(s):It would prevent NFP, in a described situation, and make some 'builder' like interfaces look really clear and simple. MAJOR DISADVANTAGE: It's a change in language. Depending on the way that it would be compiled to byte-code, it determine compatibility(here may lie some problem that I do not know about). ALTERNATIVES: Self-bounded generics. EXAMPLES SIMPLE/ADVANCED EXAMPLE: public class Builder { public this add (char c){...} public this add (String c){ if (c==null){ ... return; // this will be returned } ... } public static void test(Builder builder) { builder.add('.').add("test()").add(':'); } } DETAILS SPECIFICATION: JLS 8.4: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4 ResultType: Type void this A method declaration either specifies the type of value that the method returns, uses the keyword void to indicate that the method does not return a value, or uses the keyword this to indicate that the method return the reference to called object. Keyword this cannot occurs if method is static. JLS 14.17: http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.17 ReturnStatement: return Expressionopt ; A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value (?8.4), or in the body of a method that is declared, using the keyword this , to return this reference (?8...),or in the body of a constructor (?8.8). COMPILATION: Returned 'void' should be replaced with 'this', no more no less. TESTING: Normal way. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: I wander what object should represent 'this' return type in: Method.getReturnType(); (this.getObject() ?) MIGRATION: None. COMPATIBILITY Backward: full. REFERENCES Bug: 6479372: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 http://java.net/cs/user/view/cs_msg/37432 Return 'this' proposal : http://lasu2string.blogspot.com/2009/03/return-this-proposal.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Sun Mar 15 14:52:18 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 15 Mar 2009 22:52:18 +0100 Subject: Return 'this' proposal In-Reply-To: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> Message-ID: Marek, the interesting/complicated part of a return this proposal is the actual return type (in the classfile) of the method. Should it be 'void'? Should it be the type of the class? But, in that case, every method that has a return type of 'this' needs to be dummy-overridden in every subclass just to set the return type correctly. You've covered none of this in your proposal. --Reinier Zwitserloot On Mar 15, 2009, at 22:34, Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? > > GENESIS > > It's a simplified 'This' type problem, which seems to be too much > complicated as for now and need more analyses. Construction is > designed not > to interact with possibility that 'This' type will be introduced. > OVERVIEW > > FEATURE SUMMARY: > It allows the method to return 'this' object. > > MAJOR ADVANTAGE: > Simplification of return this; statement. > 'void' can be easy replaced with 'this'. > > MAJOR BENEFIT(s):It would prevent NFP, in a described situation, and > make > some 'builder' like interfaces look really clear and simple. > > MAJOR DISADVANTAGE: > It's a change in language. Depending on the way that it would be > compiled to > byte-code, it determine compatibility(here may lie some problem that > I do > not know about). > > ALTERNATIVES: > Self-bounded generics. > > > EXAMPLES > > SIMPLE/ADVANCED EXAMPLE: > public class Builder > { > > public this add (char c){...} > > public this add (String c){ > if (c==null){ > ... > return; // this will be returned > } > ... > } > > public static void test(Builder builder) { > builder.add('.').add("test()").add(':'); > } > > } > DETAILS > > SPECIFICATION: > JLS 8.4: > http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4 > > ResultType: > Type > void > this > > A method declaration either specifies the type of value that the > method > returns, uses the keyword void to indicate that the method does not > return a > value, or uses the keyword this to indicate that the method return the > reference to called object. > > Keyword this cannot occurs if method is static. > > > JLS 14.17: > http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.17 > > ReturnStatement: > return Expressionopt ; > > A return statement with no Expression must be contained in the body > of a > method that is declared, using the keyword void, not to return any > value > (?8.4), or in the body of a method that is declared, using the > keyword this > , to return this reference (?8...),or in the body of a constructor > (?8.8). > > COMPILATION: > Returned 'void' should be replaced with 'this', no more no less. > > TESTING: > Normal way. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > > I wander what object should represent 'this' return type in: > Method.getReturnType(); (this.getObject() ?) > > MIGRATION: > None. > > COMPATIBILITY > Backward: full. > > REFERENCES > Bug: 6479372: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 > http://java.net/cs/user/view/cs_msg/37432 > Return 'this' proposal : > http://lasu2string.blogspot.com/2009/03/return-this-proposal.html > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From scolebourne at joda.org Sun Mar 15 15:03:05 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sun, 15 Mar 2009 22:03:05 +0000 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <49BD53B4.7040909@e-spirit.de> References: <49B576EE.40703@sun.com><63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com><17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com><3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com><17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com><961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com><17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com><15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com><17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> <49BD53B4.7040909@e-spirit.de> Message-ID: <49BD7B19.6000209@joda.org> Stefan Schulz wrote: > SIMPLE EXAMPLE: > String name = "Dave"; > System.out.println("Hello, \{name}!"); It shoud be noted that Groovy uses "Hello, ${name}!" and Fan uses "Hello, $name!" For Java, I'd always thought of going down the route of: $"Hello, ${name}!" ie. a $ prefix to the string. I know why the \{ notation is used, I ust think that staying in line with other close relative languages is important too. Jeremy Manson wrote: > I'm sure this is obvious to everyone who isn't me, but I'm not sure > what the big win is here. Basically, it looks to me as if you save a > very small number of keystrokes: IMO, its a lot more readable. Stephen From schulz at e-spirit.de Sun Mar 15 15:05:53 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 15 Mar 2009 23:05:53 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <1631da7d0903151406q4542df0du61e5a631c549c04e@mail.gmail.com> References: <1631da7d0903151406q4542df0du61e5a631c549c04e@mail.gmail.com> Message-ID: <49BD7BC1.3090403@e-spirit.de> I'm sorry the examples were a bit uninspired, it was a first cast to get it discussed. Maybe, the example given by Neal fits much better to make the (admittedly) small benefits of the change a bit more clear. Moreover, I think, especially multi-line Strings would benefit from embedding expressions (but of course, neither depends on the other). Jeremy Manson schrieb: > On the flip side, I'm not a big fan of \{ as a delimiter. It seems to > me that there should be a way to unify the general desire for better > String handling (escaped Strings, multi-line Strings, embedded > expressions). Can we colonize the ` (back-tick) character and start > Strings over again from scratch? I was just about to propose using the backtick for escape-free Strings, but then again, it might be possible to use the same (or a similar) notation for expressions as for escape sequences. In other languages, I could find no unifying solution but seperate ones for the String features, like choosable quoting characters (leading by %, e.g. %/some string/) and multi-line definition (introduced by "\ followed by a new-line). The question is, if a unifying proposal will be possible that still fits as a small change into Coin. So I'd rather first like to see all the proposals or features in a small specification and then maybe join them into one bigger proposal. Stefan From schulz at e-spirit.de Sun Mar 15 15:18:48 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 15 Mar 2009 23:18:48 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <49BD7B19.6000209@joda.org> References: <49B576EE.40703@sun.com><63b4e4050903100933y44d18eadga0f6901c71645f5e@mail.gmail.com><17b2302a0903101451p4150266eh492890cd4fd7e7f5@mail.gmail.com><3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com><17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com><961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com><17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com><15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com><17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com><49BD53B4.7040909@e-spirit.de> <49BD7B19.6000209@joda.org> Message-ID: <49BD7EC8.2040205@e-spirit.de> Stephen Colebourne schrieb: > Stefan Schulz wrote: > > SIMPLE EXAMPLE: > > String name = "Dave"; > > System.out.println("Hello, \{name}!"); > > It shoud be noted that Groovy uses > > "Hello, ${name}!" > > and Fan uses > > "Hello, $name!" Right, I mentioned some related languages having this feature in the proposal (Fan is not one of them, yet). The $-notation is quite common, but I did not want to introduce yet another notation for the String itself (e.g. $") that switches the meaning of a String with a single character upfront. After all, the proposal is not that much about the notation but the feature, so that's up for revisions. If one goes for distinguishing new Strings that provide this (and/or other) features from old style, I'd rather go the full line like using a backtick (backquote) or similar. Stefan From vilya.harvey at gmail.com Sun Mar 15 15:27:08 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Sun, 15 Mar 2009 22:27:08 +0000 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <1631da7d0903151257o28404da5va1cb1da4d90c484c@mail.gmail.com> References: <49B576EE.40703@sun.com> <3BE719A0-8335-4D32-8451-40E6B5527067@googlemail.com> <17b2302a0903122113l64889cf3mdb294928f59acd64@mail.gmail.com> <961BF063-E9AB-46E0-AC74-D376516AD0AE@googlemail.com> <17b2302a0903131105u31d31dc9h5d43e1954c31cbfc@mail.gmail.com> <15e8b9d20903150807l64fad648r87942db66f00d458@mail.gmail.com> <17b2302a0903151014n37696f52u93192ee3528bf458@mail.gmail.com> <15e8b9d20903151045n10567ab5td79685698453cd91@mail.gmail.com> <49BD53B4.7040909@e-spirit.de> <1631da7d0903151257o28404da5va1cb1da4d90c484c@mail.gmail.com> Message-ID: <6aef848f0903151527h786acdfbwd298816a9635617e@mail.gmail.com> 2009/3/15 Jeremy Manson > Hi Stefan, > > I'm sure this is obvious to everyone who isn't me, but I'm not sure > what the big win is here. Basically, it looks to me as if you save a > very small number of keystrokes: > The big win is readability, in my opinion. If you have variables or expression intermingled with your string, it's harder to tell what the result will be. In particular it's harder to tell which columns things will be starting or ending on, so aligning things nicely across multiple lines is harder. That said, I don't think this should be part of the language. There's already the MessageFormat class, which covers a lot of the use cases. It's not perfect by any means, but as it's not embedded in the language syntax there's nothing to prevent you writing a replacement. Also (maybe) of note: Python had this feature for a long time but it's been *removed* from the latest version of the language (3.0). Vil. From markmahieu at googlemail.com Sun Mar 15 15:49:42 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sun, 15 Mar 2009 22:49:42 +0000 Subject: Use "default" keyword for default visibility In-Reply-To: <17b2302a0903142308o330c9942hc866052d05ebdbe4@mail.gmail.com> References: <3dd3f56a0903142113we599148y13e012855d900c28@mail.gmail.com> <17b2302a0903142308o330c9942hc866052d05ebdbe4@mail.gmail.com> Message-ID: My first edition copy of Java in a Nutshell says that there were public, protected, private protected, private and the default, all with distinct visibility rules. Mark 2009/3/15 Joshua Bloch > Howard, > Are you sure? The only other modifier I remember was "private protected," > which was quite different from package private. I believe that it was > always the default access mode. I thought I coined the term "package > private" for Effective Java (though it's likely that others came up with it > independently and earlier). > > Josh > > On Sat, Mar 14, 2009 at 9:13 PM, Howard Lovatt >wrote: > > > Early versions of Java had package private (I think) for this. It > > would make the code clearer in that everything would have a keyword. > > package could be used, since this is the scope of the default. > > > > > > From develop4lasu at gmail.com Sun Mar 15 15:49:51 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 15 Mar 2009 23:49:51 +0100 Subject: Return 'this' proposal In-Reply-To: References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> Message-ID: <28bca0ff0903151549k76959f84m96d4ce2216bf3e26@mail.gmail.com> 2009/3/15 Reinier Zwitserloot > Marek, > > the interesting/complicated part of a return this proposal is the actual > return type (in the classfile) of the method. Should it be 'void'? Should it > be the type of the class? But, in that case, every method that has a return > type of 'this' needs to be dummy-overridden in every subclass just to set > the return type correctly. > > You've covered none of this in your proposal. > > --Reinier Zwitserloot > > Actual return type is current object type, but it could be extracted to other type. I know that overriding is required, truly this solution is not refactor friendly, but interpret it is much more easy than 'This' type. What more 'This' as type would be allowed to some "special" generics only, what could prevent programmers from using it. So notice that: - When Generic change and will be not able to handle This type than model will need to be changed. When need change void to this, we need only change returned type in all methods. This two proposals are on completely different levels: 'This': Generics & inheritance & return type & return type interaction 'this': return type Hope you get what do I mean. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Sun Mar 15 16:54:33 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 15 Mar 2009 16:54:33 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> Message-ID: <15e8b9d20903151654k4f484179p9421c2aa90cd1bb7@mail.gmail.com> On Sun, Mar 15, 2009 at 2:31 PM, Reinier Zwitserloot wrote: > Here's the golden rule in regards to the source proposal: > > It's already a part of java, via javac -source. Just about every > problem mentioned so far is either not a problem, or if it is, should > be filed as a bug, because it also applies to javac -source. javac's command line is not part of the Java programming language. The proposed construct would be. Therefore, the proposed construct would have to be described precisely in the JLS, including every effect it would have on every other language feature. In addition, since it would now be part of the language, the specification would have to describe precisely what happens when you combine translation units with different source settings in every possible combination for every language construct affected. I don't see how that could possibly be done without a major overhaul of the language specification. From neal at gafter.com Sun Mar 15 16:57:53 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 15 Mar 2009 16:57:53 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <15e8b9d20903151654k4f484179p9421c2aa90cd1bb7@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <15e8b9d20903151654k4f484179p9421c2aa90cd1bb7@mail.gmail.com> Message-ID: <15e8b9d20903151657s6242fc53u701ddb3985248ac8@mail.gmail.com> On Sun, Mar 15, 2009 at 4:54 PM, Neal Gafter wrote: > On Sun, Mar 15, 2009 at 2:31 PM, Reinier Zwitserloot > wrote: >> Here's the golden rule in regards to the source proposal: >> >> It's already a part of java, via javac -source. Just about every >> problem mentioned so far is either not a problem, or if it is, should >> be filed as a bug, because it also applies to javac -source. > > javac's command line is not part of the Java programming language. > The proposed construct would be. ?Therefore, the proposed construct > would have to be described precisely in the JLS, including every > effect it would have on every other language feature. ?In addition, > since it would now be part of the language, the specification would > have to describe precisely what happens when you combine translation > units with different source settings in every possible combination for > every language construct affected. ?I don't see how that could > possibly be done without a major overhaul of the language > specification. I should add that the Java programming language is part of the Java SE platform specification. The javac command line is NOT part of the Java SE platform specification. That's why the JCP-defined spec doesn't have to specify these things today, but would have to if it were to become part of the language. From jeremy.manson at gmail.com Sun Mar 15 16:58:01 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 15 Mar 2009 16:58:01 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> Message-ID: <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> Reinier, I wrote out a long response to each of your points, but I realized that perhaps what it boiled down to was something I said in my previous message: "I'm not objecting to versioning in principle, but I think there are enough unanswered questions that this proposal is probably beyond the scope of "small changes"." You are saying that if I have a problem with something, it is the -source flag. You are absolutely right: I have problems with the -source flag. Those problems should be sorted out before we include it in the language. Each solution to each of these problems makes this change larger: 1) API / Classfile compatibility 2) Backticks for identifiers 3) A need for thorough documentation for each potential version we support. (You seem to be suggesting that this would be implementation-dependent, but that's unlike everything else in the language. Java is historically opposed to things that are implementation-dependent. Part of the selling point of Java is that code written for / compiled on a version of Java 7 will work with / compile on all compliant Java 7 implementations.). 4) Is "source" really necessary at the top of the file (you seem to be agreeing that it is), and if so, is that what we actually want? I also think it would be worthwhile finding out how this proposal gels with the module system they are introducing. Fundamentally, it seems to me to be a large problem to solve, and I think the right answer is to start a proper JSR and make sure you get it right. It is, of course, by no means important to Project Coin that I (as one person) happen to think that this change is (or should be) too large. But I suspect that I'm not the only one. Jeremy From reinier at zwitserloot.com Sun Mar 15 17:45:57 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 16 Mar 2009 01:45:57 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> Message-ID: <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> Neal: As I've mentioned at least twice on coin-dev already, the JLS only needs to specify how the 'source' keyword sets the 'source' property of the CompilationUnit that contains the source keyword. As far as the JLS is concerned, this is a string value that has no further meaning. It's a bit like a comment in this sense. To be crystal clear: ** The JLS will NOT specify what is supposed to happen when you write "source 1.1;" in a JLSv3 view of the source file! ** The effect of a source property in a CompilationUnit will however be specified in the documentation for java compilers. Jeremy: 1) No, -source does not show up in the class file at all, so obviously it wouldn't for a source keyword, either. Therefore the API / Classfile compatibility issue is 0. 2) No, backticks aren't neccessary for the source keyword to work. java7 is not going to be source incompatible with java6 and does not add new keywords (well, module, but it'll be context sensitive). Compatibility issue: 0. It would certainly help make it easier to make breaking changes in java 7, if at that time a proposal comes along that makes sense but would be better with a few breaking changes. 3) There is no need for much *JLS* documentation at all. CompilationUnits get a 'source' property, which is a string value. That's where it ends as far as the JLS is concerned. It has no meaning within the JLS. Just a string, that's all. The documentation for javac has quite a bit to say about this, but that's nothing new: The -source parameter has the exact same function and is already documented. This documentation needs a very minor update. 4) "source 1.7;" is really neccessary at the top of the file. It is crucial meta-data without which you cannot make any sense of a java CompilationUnit. Is 'assert' a keyword or an identifier? What about strictfp? Are inner classes legal? Is @Override on an interface- inherited method legal, or an error? Should lack of generics result in a warning, or should any generics actually be indicated as a compile- time error? You don't, of course, -have- to put it there, but its suggested, and I expect IDEs and style checkers will start warning when its missing. This is somewhat akin to package statements. Those are -really- neccessary as well. a CompilationUnit's target package isn't a command line parameter for the same (good) reason. This metadata is not dependent on a compile run, it is solely dependent on the source file itself, and should therefore be inside it. --Reinier Zwitserloot On Mar 16, 2009, at 00:58, Jeremy Manson wrote: > Reinier, > > I wrote out a long response to each of your points, but I realized > that perhaps what it boiled down to was something I said in my > previous message: "I'm not objecting to versioning in principle, but I > think there are enough unanswered questions that this proposal is > probably beyond the scope of "small changes"." > > You are saying that if I have a problem with something, it is the > -source flag. You are absolutely right: I have problems with the > -source flag. Those problems should be sorted out before we include > it in the language. Each solution to each of these problems makes > this change larger: > > 1) API / Classfile compatibility > > 2) Backticks for identifiers > > 3) A need for thorough documentation for each potential version we > support. (You seem to be suggesting that this would be > implementation-dependent, but that's unlike everything else in the > language. Java is historically opposed to things that are > implementation-dependent. Part of the selling point of Java is that > code written for / compiled on a version of Java 7 will work with / > compile on all compliant Java 7 implementations.). > > 4) Is "source" really necessary at the top of the file (you seem to be > agreeing that it is), and if so, is that what we actually want? > > I also think it would be worthwhile finding out how this proposal gels > with the module system they are introducing. > > Fundamentally, it seems to me to be a large problem to solve, and I > think the right answer is to start a proper JSR and make sure you get > it right. > > It is, of course, by no means important to Project Coin that I (as one > person) happen to think that this change is (or should be) too large. > But I suspect that I'm not the only one. > > Jeremy From neal at gafter.com Sun Mar 15 18:11:38 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 15 Mar 2009 18:11:38 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> Message-ID: <15e8b9d20903151811x10bccc11jf6f6a25162e43015@mail.gmail.com> On Sun, Mar 15, 2009 at 5:45 PM, Reinier Zwitserloot wrote: > As I've mentioned at least twice on coin-dev already, the JLS only needs to > specify how the 'source' keyword sets the 'source' property of the > CompilationUnit that contains the source keyword. As far as the JLS is > concerned, this is a string value that has no further meaning. It's a bit > like a comment in this sense. To be crystal clear: ** The JLS will NOT > specify what is supposed to happen when you write "source 1.1;" in a JLSv3 > view of the source file! ** That's fine, as long as the compiler obeys the language specification (recognizing ALL keywords in the spec, etc) in order to obey the platform specification. In which case I don't see what the purpose of placing this thing in the source file was in the first place. From markmahieu at googlemail.com Sun Mar 15 18:23:11 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 16 Mar 2009 01:23:11 +0000 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> Message-ID: Alex Buckley's slides on the modules JSR ( http://blogs.sun.com/abuckley/resource/Devoxx2008-ModularityInJava.pdf) show examples of specifying a required module version, including things like "java.core @ 1.7". Presumably things like java.lang and javax.lang.model will sit somewhere in this versioned module system, so wouldn't that be a more suitable way to approach this? I mean, why add yet another place to specify the version? Mark 2009/3/16 Reinier Zwitserloot > > > As I've mentioned at least twice on coin-dev already, the JLS only > needs to specify how the 'source' keyword sets the 'source' property > of the CompilationUnit that contains the source keyword. As far as the > JLS is concerned, this is a string value that has no further meaning. > It's a bit like a comment in this sense. To be crystal clear: ** The > JLS will NOT specify what is supposed to happen when you write "source > 1.1;" in a JLSv3 view of the source file! ** > From jeremy.manson at gmail.com Sun Mar 15 19:02:28 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 15 Mar 2009 19:02:28 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> Message-ID: <1631da7d0903151902w34737a5ev8ce9a3528464a73e@mail.gmail.com> Reinier, Fundamentally, I think we are in disagreement that the source keyword that you are suggesting provides any useful semantics. I haven't seen your proposal (I can't find the message where you posted it?), but here is one of your motivations from your pre-proposal: > Leaving half your sourcebase in v1.6 and the > other half in v1.7 is pretty much impossible today, it's all-or- > nothing. Having a "source" statement that is spec'd to do nothing other than set a property in the CompilationUnit doesn't actually address this, in the ways in which I said it didn't before: 1) My API / Classfile comment was not about changes to classfiles, it was about the fact that your proposal doesn't address the fact that different APIs are available to different Java versions. "source 7;" isn't going to stop the code I write from using some new API introduced in Java 8, just as "-source 5" as a parameter to javac doesn't stop me from using ConcurrentSkipListMap. I know your proposal isn't intended to address this, but I think any proposal that provides versioning needs to address this, because you aren't keeping half your codebase in Java 6 in any meaningful way if that code can use Java 7 APIs. 2) I know that your proposal isn't intended to address the problem that the backticks were intended to solve, but I think that any proposal that provides versioning needs to address this, because it is difficult to keep half of your codebase in Java 7 if you can't call out to some APIs that your Java 6 code provides because their names clash wit keywords. 3) All that javac says about -source is that it provides source compatibility with the specified release. However, there are releases it doesn't support (anymore), and there are targets that can't be generated from specific source versions. You need, at the very least, to define what sources are guaranteed to be supported. You can't leave half your codebase in Java 6 if no compiler supports Java 6. You seem to be willing to leave these things up in the air, which I think is easier when it is an option to the javac program, where this is offered as a convenience, but not fine for a language specification, when the source code needs to be portable to any Java 7 compliant compiler. At any rate, Joe already stepped in and said that the proposal as it stood was too complicated for Project Coin: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000298.html Jeremy On Sun, Mar 15, 2009 at 5:45 PM, Reinier Zwitserloot wrote: > Neal: > > As I've mentioned at least twice on coin-dev already, the JLS only needs to > specify how the 'source' keyword sets the 'source' property of the > CompilationUnit that contains the source keyword. As far as the JLS is > concerned, this is a string value that has no further meaning. It's a bit > like a comment in this sense. To be crystal clear: ** The JLS will NOT > specify what is supposed to happen when you write "source 1.1;" in a JLSv3 > view of the source file! ** > > The effect of a source property in a CompilationUnit will however be > specified in the documentation for java compilers. > > Jeremy: > > 1) No, -source does not show up in the class file at all, so obviously it > wouldn't for a source keyword, either. Therefore the API / Classfile > compatibility issue is 0. > > 2) No, backticks aren't neccessary for the source keyword to work. java7 is > not going to be source incompatible with java6 and does not add new keywords > (well, module, but it'll be context sensitive). Compatibility issue: 0. It > would certainly help make it easier to make breaking changes in java 7, if > at that time a proposal comes along that makes sense but would be better > with a few breaking changes. > > 3) There is no need for much *JLS* documentation at all. CompilationUnits > get a 'source' property, which is a string value. That's where it ends as > far as the JLS is concerned. It has no meaning within the JLS. Just a > string, that's all. The documentation for javac has quite a bit to say about > this, but that's nothing new: The -source parameter has the exact same > function and is already documented. This documentation needs a very minor > update. > > 4) ?"source 1.7;" is really neccessary at the top of the file. It is crucial > meta-data without which you cannot make any sense of a java CompilationUnit. > Is 'assert' a keyword or an identifier? What about strictfp? Are inner > classes legal? Is @Override on an interface-inherited method legal, or an > error? Should lack of generics result in a warning, or should any generics > actually be indicated as a compile-time error? You don't, of course, -have- > to put it there, but its suggested, and I expect IDEs and style checkers > will start warning when its missing. This is somewhat akin to package > statements. Those are -really- neccessary as well. a CompilationUnit's > target package isn't a command line parameter for the same (good) reason. > This metadata is not dependent on a compile run, it is solely dependent on > the source file itself, and should therefore be inside it. > > ?--Reinier Zwitserloot > > > > On Mar 16, 2009, at 00:58, Jeremy Manson wrote: > >> Reinier, >> >> I wrote out a long response to each of your points, but I realized >> that perhaps what it boiled down to was something I said in my >> previous message: "I'm not objecting to versioning in principle, but I >> think there are enough unanswered questions that this proposal is >> probably beyond the scope of "small changes"." >> >> You are saying that if I have a problem with something, it is the >> -source flag. ?You are absolutely right: I have problems with the >> -source flag. ?Those problems should be sorted out before we include >> it in the language. ?Each solution to each of these problems makes >> this change larger: >> >> 1) API / Classfile compatibility >> >> 2) Backticks for identifiers >> >> 3) A need for thorough documentation for each potential version we >> support. ?(You seem to be suggesting that this would be >> implementation-dependent, but that's unlike everything else in the >> language. ?Java is historically opposed to things that are >> implementation-dependent. ?Part of the selling point of Java is that >> code written for / compiled on a version of Java 7 will work with / >> compile on all compliant Java 7 implementations.). >> >> 4) Is "source" really necessary at the top of the file (you seem to be >> agreeing that it is), and if so, is that what we actually want? >> >> I also think it would be worthwhile finding out how this proposal gels >> with the module system they are introducing. >> >> Fundamentally, it seems to me to be a large problem to solve, and I >> think the right answer is to start a proper JSR and make sure you get >> it right. >> >> It is, of course, by no means important to Project Coin that I (as one >> person) happen to think that this change is (or should be) too large. >> But I suspect that I'm not the only one. >> >> Jeremy > > From reinier at zwitserloot.com Sun Mar 15 19:14:42 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 16 Mar 2009 03:14:42 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> Message-ID: Well, source language compatibility isn't the same thing as a library dependency. Specifically: java.core would refer to the runtime library. source would refer to the JLS interpretation used to compile the file. These are rather unrelated. The java.core dependency is something that the JVM needs to sort out. The 'source' keyword isn't even in the class file; the JVM wouldn't even know what it means. Consider the differences between the -source and the -target options for javac for another example of the difference. It might be a nice idea to allow javac to peek at the module-info file to look for a source compatibility level as well, but I can't add it to a proposal without a rigid spec on jigsaw and the modules JSR. It might be possible to dress up the 'source' keyword functionality as a library dependency in the modules JSR syntax, but wouldn't that just add more confusion? --Reinier Zwitserloot On Mar 16, 2009, at 02:23, Mark Mahieu wrote: > Alex Buckley's slides on the modules JSR (http://blogs.sun.com/abuckley/resource/Devoxx2008-ModularityInJava.pdf > ) show examples of specifying a required module version, including > things like "java.core @ 1.7". Presumably things like java.lang and > javax.lang.model will sit somewhere in this versioned module system, > so wouldn't that be a more suitable way to approach this? > > I mean, why add yet another place to specify the version? > > Mark > > > 2009/3/16 Reinier Zwitserloot > > As I've mentioned at least twice on coin-dev already, the JLS only > needs to specify how the 'source' keyword sets the 'source' property > of the CompilationUnit that contains the source keyword. As far as the > JLS is concerned, this is a string value that has no further meaning. > It's a bit like a comment in this sense. To be crystal clear: ** The > JLS will NOT specify what is supposed to happen when you write "source > 1.1;" in a JLSv3 view of the source file! ** > From reinier at zwitserloot.com Sun Mar 15 19:28:35 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 16 Mar 2009 03:28:35 +0100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <1631da7d0903151902w34737a5ev8ce9a3528464a73e@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> <1631da7d0903151902w34737a5ev8ce9a3528464a73e@mail.gmail.com> Message-ID: <4A4664E7-440E-4C89-B2CC-78B81391BB83@zwitserloot.com> There is no proposal, Jeremy. I made a pre-proposal on the assumption it would sail right through. It didn't, and that was that, until Howard Lovatt re-opened the discussion in support of the proposal. Having a "source" statement that is spec'd to do nothing other than set the CompilationUnit's source property *DOES* resolve the issue of having half your codebase in v1.6 and half in v1.7. Because half is in v1.7, this is -obviously- only going to run in a JVM v1.7 or above - this has been true in java for years and I don't see how this could possibly change for v1.7 given that the class file format is changing and the module system will be added. A JVM v1.7 - will- be able to run both: - class files compiled with javac 1.6, *and* - class files compiled with javac 1.7 with -target 1.7 and -source 1.6 on the command line (or after this proposal, source 1.6 in the file). The only issue someone might have in the middle of porting old code is that the 1.6 code is being compiled as if it is 1.7 code. To highlight how annoying that can be: When java went from 1.4 to 1.5, old code would produce an enormous list of generics warnings. Effectively you had to disable ALL of them until you finished porting all your java code to 1.5; there was no practical way to get a list of genuine generics warnings for your post-porting code. *THAT* problem is what the 'source' keyword would address. If we had it back then, javac would know NOT to generate those generics warnings for all source files marked source 1.4. The notion that 'source 7;' isn't going to stop you from writing code using Java8 APIs is true, but that's what the module system is for, *NOT* the -source system. I fundamentally think its a mistake to attempt to marry these two ideas together. For example, just now I'm hacking om some HTML parsing using htmlparser, which was written for java 1.4. One of the interfaces I need to implement passes my code a (non-generified) Vector object. Instead of dealing with the warnings, I decided to just configure eclipse to set the entire project to source compatibility 1.4. Nevertheless, I stil want to use String.replace("foo", "bar"), which is a String method that exists only in java6+. There is no problem, because I'll be running my code, and the htmlparser library, on a JVM6. Imagining for a moment that both the source keyword exist, and the module system, I'd have to bundle htmlparser into its own module, and set my module bundle to be dependent on jvm.core=6+, and have a source compatibility of java 1.4, lest it rains generics warnings. Once we have both the source and the module system, it becomes trivial to create java files that will actually compile AND run on old versions of the JDK/JVM: If both your source keyword AND your java.core dependency are on java 1.X or below, then your code should compile and run on a JDK/JVM 1.X or above. Whether the JDK itself offers a command line option or other mechanism to enforce this, or whether tool providers such as ant make handy shortcuts for this isn't relevant: Someone can run with it, surely. However, a 'source' keyword would help quite a bit, lest we get the reference situation: You only use library calls from java1.4 and below, but you are using foreach loops and generics, so a JDK v1.4 won't compile your code, and if you compile it with a JDK1.6, the class files won't run on a JVM1.4. There is, again, no need for the backticks, because there will be 0 new keywords in java7 (excluding context sensitive keywords). *IF* java 8 includes a proposal that does have new keywords, then it would automatically also require a backtick proposal. But it's not 2012 yet. javac (the compiler itself) will support -source 1.6, if history is any indication. I think making that commitment at this point in time is a no-brainer. There is no need for a compiler to neccessarily do the best possible option when a "source 1.6;" is encountered. If that version of javac no longer has the capability to parse v1.6 code, then it can gracefully exit with an appropriate error message, instead of a weird batch of parsing mismatches that leaves the person attempting to dust off some 10 year old code none the wiser. --Reinier Zwitserloot On Mar 16, 2009, at 03:02, Jeremy Manson wrote: > Reinier, > > Fundamentally, I think we are in disagreement that the source keyword > that you are suggesting provides any useful semantics. I haven't seen > your proposal (I can't find the message where you posted it?), but > here is one of your motivations from your pre-proposal: > >> Leaving half your sourcebase in v1.6 and the >> other half in v1.7 is pretty much impossible today, it's all-or- >> nothing. > > Having a "source" statement that is spec'd to do nothing other than > set a property in the CompilationUnit doesn't actually address this, > in the ways in which I said it didn't before: > > 1) My API / Classfile comment was not about changes to classfiles, it > was about the fact that your proposal doesn't address the fact that > different APIs are available to different Java versions. "source 7;" > isn't going to stop the code I write from using some new API > introduced in Java 8, just as "-source 5" as a parameter to javac > doesn't stop me from using ConcurrentSkipListMap. I know your > proposal isn't intended to address this, but I think any proposal that > provides versioning needs to address this, because you aren't keeping > half your codebase in Java 6 in any meaningful way if that code can > use Java 7 APIs. > > 2) I know that your proposal isn't intended to address the problem > that the backticks were intended to solve, but I think that any > proposal that provides versioning needs to address this, because it is > difficult to keep half of your codebase in Java 7 if you can't call > out to some APIs that your Java 6 code provides because their names > clash wit keywords. > > 3) All that javac says about -source is that it provides source > compatibility with the specified release. However, there are releases > it doesn't support (anymore), and there are targets that can't be > generated from specific source versions. You need, at the very least, > to define what sources are guaranteed to be supported. You can't > leave half your codebase in Java 6 if no compiler supports Java 6. > > You seem to be willing to leave these things up in the air, which I > think is easier when it is an option to the javac program, where this > is offered as a convenience, but not fine for a language > specification, when the source code needs to be portable to any Java 7 > compliant compiler. > > At any rate, Joe already stepped in and said that the proposal as it > stood was too complicated for Project Coin: > > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000298.html > > Jeremy > > On Sun, Mar 15, 2009 at 5:45 PM, Reinier Zwitserloot > wrote: >> Neal: >> >> As I've mentioned at least twice on coin-dev already, the JLS only >> needs to >> specify how the 'source' keyword sets the 'source' property of the >> CompilationUnit that contains the source keyword. As far as the JLS >> is >> concerned, this is a string value that has no further meaning. It's >> a bit >> like a comment in this sense. To be crystal clear: ** The JLS will >> NOT >> specify what is supposed to happen when you write "source 1.1;" in >> a JLSv3 >> view of the source file! ** >> >> The effect of a source property in a CompilationUnit will however be >> specified in the documentation for java compilers. >> >> Jeremy: >> >> 1) No, -source does not show up in the class file at all, so >> obviously it >> wouldn't for a source keyword, either. Therefore the API / Classfile >> compatibility issue is 0. > > > >> >> 2) No, backticks aren't neccessary for the source keyword to work. >> java7 is >> not going to be source incompatible with java6 and does not add new >> keywords >> (well, module, but it'll be context sensitive). Compatibility >> issue: 0. It >> would certainly help make it easier to make breaking changes in >> java 7, if >> at that time a proposal comes along that makes sense but would be >> better >> with a few breaking changes. > > >> >> 3) There is no need for much *JLS* documentation at all. >> CompilationUnits >> get a 'source' property, which is a string value. That's where it >> ends as >> far as the JLS is concerned. It has no meaning within the JLS. Just a >> string, that's all. The documentation for javac has quite a bit to >> say about >> this, but that's nothing new: The -source parameter has the exact >> same >> function and is already documented. This documentation needs a very >> minor >> update. >> >> 4) "source 1.7;" is really neccessary at the top of the file. It >> is crucial >> meta-data without which you cannot make any sense of a java >> CompilationUnit. >> Is 'assert' a keyword or an identifier? What about strictfp? Are >> inner >> classes legal? Is @Override on an interface-inherited method legal, >> or an >> error? Should lack of generics result in a warning, or should any >> generics >> actually be indicated as a compile-time error? You don't, of >> course, -have- >> to put it there, but its suggested, and I expect IDEs and style >> checkers >> will start warning when its missing. This is somewhat akin to package >> statements. Those are -really- neccessary as well. a >> CompilationUnit's >> target package isn't a command line parameter for the same (good) >> reason. >> This metadata is not dependent on a compile run, it is solely >> dependent on >> the source file itself, and should therefore be inside it. >> >> --Reinier Zwitserloot >> >> >> >> On Mar 16, 2009, at 00:58, Jeremy Manson wrote: >> >>> Reinier, >>> >>> I wrote out a long response to each of your points, but I realized >>> that perhaps what it boiled down to was something I said in my >>> previous message: "I'm not objecting to versioning in principle, >>> but I >>> think there are enough unanswered questions that this proposal is >>> probably beyond the scope of "small changes"." >>> >>> You are saying that if I have a problem with something, it is the >>> -source flag. You are absolutely right: I have problems with the >>> -source flag. Those problems should be sorted out before we include >>> it in the language. Each solution to each of these problems makes >>> this change larger: >>> >>> 1) API / Classfile compatibility >>> >>> 2) Backticks for identifiers >>> >>> 3) A need for thorough documentation for each potential version we >>> support. (You seem to be suggesting that this would be >>> implementation-dependent, but that's unlike everything else in the >>> language. Java is historically opposed to things that are >>> implementation-dependent. Part of the selling point of Java is that >>> code written for / compiled on a version of Java 7 will work with / >>> compile on all compliant Java 7 implementations.). >>> >>> 4) Is "source" really necessary at the top of the file (you seem >>> to be >>> agreeing that it is), and if so, is that what we actually want? >>> >>> I also think it would be worthwhile finding out how this proposal >>> gels >>> with the module system they are introducing. >>> >>> Fundamentally, it seems to me to be a large problem to solve, and I >>> think the right answer is to start a proper JSR and make sure you >>> get >>> it right. >>> >>> It is, of course, by no means important to Project Coin that I (as >>> one >>> person) happen to think that this change is (or should be) too >>> large. >>> But I suspect that I'm not the only one. >>> >>> Jeremy >> >> From brucechapman at paradise.net.nz Mon Mar 16 02:05:25 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Mon, 16 Mar 2009 22:05:25 +1300 Subject: Coin Considerations In-Reply-To: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> Message-ID: <49BE1655.3030604@paradise.net.nz> Reinier Zwitserloot wrote: > So what proposals are still fermenting in the minds of coin > contributors? Inspired by the recent discussion between Joe D'Arcy and > Mark Mahieu that people are possibly thinking someone else will be > proposing it. > > > Here's my list byte size integral literals either via autosizing hex literals 0hNNNN (type is smallest type that can hold the value - would probably also include binaries 0bNNNNN) or alternatively via a new integer literal suffix (would include shorts as well). A zero fill (unsigned) widening conversion (but can't call it that cause we lose sign) / operator probably "(+)" to morph bytes into integers without sign extension. A special language escape operator which will always generate a compiler error. Reasons too complex to explain in one sentence. - no implementation required. Maybe: Type literals (for annotations) depending on where the field / method literals discussion goes - might be too big for coin. Bruce From vilya.harvey at gmail.com Mon Mar 16 03:37:40 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Mon, 16 Mar 2009 10:37:40 +0000 Subject: Coin Considerations In-Reply-To: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> Message-ID: <6aef848f0903160337l48901c19q3428a84c3cde90d1@mail.gmail.com> 2009/3/14 Reinier Zwitserloot > So what proposals are still fermenting in the minds of coin > contributors? Inspired by the recent discussion between Joe D'Arcy and > Mark Mahieu that people are possibly thinking someone else will be > proposing it. I had a few things in mind, mostly to do with lists, some of which people have already mentioned: - list comprehensions. - either list literals or autoboxing/unboxing conversions between arrays and lists (I haven't really thought this one through yet; I suspect there would be a lot of issues in deciding when to apply the boxing). - array style access for lists, maps and strings. - negative array indexes should count from the back of the array (e.g. a[-1] == a[a.length - 1]). - slice syntax a la python for arrays, lists and strings. I'll happily write any of these up, if anyone thinks there'd be enough interest. Vil. From reinier at zwitserloot.com Mon Mar 16 06:22:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 16 Mar 2009 14:22:06 +0100 Subject: Coin Considerations In-Reply-To: <6aef848f0903160337l48901c19q3428a84c3cde90d1@mail.gmail.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <6aef848f0903160337l48901c19q3428a84c3cde90d1@mail.gmail.com> Message-ID: Of all those items, list comprehensions and list literals rank -far- higher on my 'general utility' meter than any of the other ones, but almost all of them seem doable with a minimum of JLS munging. list comprehensions, /IF/ they produce a complete list and not a lazily evaluating iterable, is just syntax sugar. If they do apply lazy evaluation, it inherits most of the problems closure proposals try to deal with. Serious doubts about suitability for Project Coin in the latter case. Suggestion: [] makes complete lists, there's always the opportunity to introduce a slightly alternative syntax in the future when/if closures show up in java8 and those issues have already been solved - then an iterable based list comprehension is just syntax sugared into something involving closures for the generator and filter expressions. List literals are equally complicated; the complication lies in correctly parsing a new construct, such as 'stuff in between array brackets that does not appear after an expression (because that would be array index lookup)' - presuming for a moment that list comprehensions use [] as well. array style access for lists, maps, and strings: I believe Joe D'Arcy posted it as a suggestion at the announcement of coin-dev. Support from the community has been tepid at best, but in combination with comprehensions and slices, I'd be in favour. Much more difficult for maps (right now brackets-after-expression wants an integer inside the brackets. You'd be changing this for maps to be a K instead). Proposal without bracket access for maps would still sound good to me. I don't use list.get(X) very often, though... negative array indices should count backwards: Utterly impossible for arrays. Would break backwards compatibility (foo[-1] should produce an ArrayIOOBException, people will be relying on that). The notion that many things in java return -1 to indicate 'not found' (such as String.indexOf) makes this idea a bit more complicated than it might seem at first glance, and the idea you could only apply it to Lists, not arrays, would be an unfortunate inconsistency. I say: skip this one. slices: What type of list should roll out? A generic immutable List, regardless of what you sliced on? If so, trivial syntax sugar: Add a library that produces a sliced list given as input a list and 2 numbers, then rewrite all slices to a call to this library. Also offers a sneaky way to get the last item in a list without -1 syntax: list[-1:0][0]. Alternative outputs: A bound view (which just remembers start index and size, and continues to call .get(X+offset) into the original list), which would mean removing an item in the original list removes it from the sliced list. Such a bound view could support being mutable, but that would introduce even more weirdness: Removing an item from the original does not shrink the bound view, but removing it via the bound vie DOES shrink the bound view. Meh. I strongly suggest making slicelists immutable copies to avoid this mess. autoboxing arrays to lists and vice versa: Because they share part of their inheritance tree (specifically: java.lang.Object), that would get very confusing, very fast. There's also the issue of covariance: Can you autobox an ArrayList[] to a List>? Again, type issues. I doubt this one is worth it. --Reinier Zwitserloot On Mar 16, 2009, at 11:37, Vilya Harvey wrote: > 2009/3/14 Reinier Zwitserloot > So what proposals are still fermenting in the minds of coin > contributors? Inspired by the recent discussion between Joe D'Arcy and > Mark Mahieu that people are possibly thinking someone else will be > proposing it. > > I had a few things in mind, mostly to do with lists, some of which > people have already mentioned: > list comprehensions. > either list literals or autoboxing/unboxing conversions between > arrays and lists (I haven't really thought this one through yet; I > suspect there would be a lot of issues in deciding when to apply the > boxing). > array style access for lists, maps and strings. > negative array indexes should count from the back of the array (e.g. > a[-1] == a[a.length - 1]). > slice syntax a la python for arrays, lists and strings. > I'll happily write any of these up, if anyone thinks there'd be > enough interest. > > Vil. From kuaw26 at mail.ru Mon Mar 16 08:27:11 2009 From: kuaw26 at mail.ru (=?windows-1251?Q?=C0=EB=E5=EA=F1=E5=E9_=CA=F3=E7=ED=E5=F6=EE=E2?=) Date: Mon, 16 Mar 2009 22:27:11 +0700 Subject: =?windows-1251?Q?Question=3A_is_this_sutits_for_Project_Coin=3F?= Message-ID: Hello all! Question: is this sutits for Project Coin? 1) Add caseSensitive flag for all sutable methods from java.lang.String indexOf(String s, boolean caseSensitive) startsWith(String prefix, boolean caseSensitive) ... and so on... 2) Add constructor with var args for classes that implement java.util.Collection public Vector(E... items) public ArrayList(E... items) public HashSet(E... items) ... and so on ... Alexey Kuznetsov kuaw26 at mail.ru From markmahieu at googlemail.com Mon Mar 16 08:31:03 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 16 Mar 2009 15:31:03 +0000 Subject: Question: is this sutits for Project Coin? In-Reply-To: References: Message-ID: Those proposals would be library changes, so no they're not suitable for Coin. Mark 2009/3/16 ??????? ???????? > Hello all! > > Question: is this sutits for Project Coin? > > 1) Add caseSensitive flag for all sutable methods from java.lang.String > indexOf(String s, boolean caseSensitive) > startsWith(String prefix, boolean caseSensitive) > ... and so on... > > 2) Add constructor with var args for classes that implement > java.util.Collection > public Vector(E... items) > public ArrayList(E... items) > public HashSet(E... items) > ... and so on ... > > Alexey Kuznetsov > kuaw26 at mail.ru > > From r.spilker at gmail.com Mon Mar 16 08:34:47 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Mon, 16 Mar 2009 16:34:47 +0100 Subject: Question: is this sutits for Project Coin? In-Reply-To: References: Message-ID: Apart from that, I'd recommend String.indexOfIgnoreCase and String.startWithIgnoreCase to be consistent with String.equalsIgnoreCase. 2009/3/16 Mark Mahieu > Those proposals would be library changes, so no they're not suitable for > Coin. > Mark > > > 2009/3/16 ??????? ???????? > > > Hello all! > > > > Question: is this sutits for Project Coin? > > > > 1) Add caseSensitive flag for all sutable methods from java.lang.String > > indexOf(String s, boolean caseSensitive) > > startsWith(String prefix, boolean caseSensitive) > > ... and so on... > > > > 2) Add constructor with var args for classes that implement > > java.util.Collection > > public Vector(E... items) > > public ArrayList(E... items) > > public HashSet(E... items) > > ... and so on ... > > > > Alexey Kuznetsov > > kuaw26 at mail.ru > > > > > > From fw at deneb.enyo.de Mon Mar 16 09:31:46 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Mon, 16 Mar 2009 17:31:46 +0100 Subject: Question: is this sutits for Project Coin? In-Reply-To: (=?utf-8?B?ItCQ0LvQtdC60YHQtdC5CdCa0YPQt9C90LXRhtC+0LIiJ3M=?= message of "Mon, 16 Mar 2009 22:27:11 +0700") References: Message-ID: <87mybl2zv1.fsf@mid.deneb.enyo.de> * ??????? ????????: > Question: is this sutits for Project Coin? > > 1) Add caseSensitive flag for all sutable methods from java.lang.String > indexOf(String s, boolean caseSensitive) > startsWith(String prefix, boolean caseSensitive) > ... and so on... Case sensitivity is locale-dependent (the canonical example is Turkish, where 'i' and 'I' are distinct even when case is ignored), and this API proposal doesn't reflect that. From openjdk at jazillian.com Mon Mar 16 08:30:43 2009 From: openjdk at jazillian.com (Andy Tripp) Date: Mon, 16 Mar 2009 11:30:43 -0400 Subject: Proposal: Enhanced String constructs for Java Message-ID: <49BE70A3.5040303@jazillian.com> Felix, One major disadvantage you didn't mention is the addition of keywords. This could be either a huge show-stopper issue or a complete non-issue, depending on the reputation of the proposal submitter. You should either mention this disadvantage, or simply say that you don't think it seems to be an issue, like this: http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000033.html Andy ;) From i30817 at gmail.com Mon Mar 16 10:18:08 2009 From: i30817 at gmail.com (Paulo Levi) Date: Mon, 16 Mar 2009 17:18:08 +0000 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> References: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> Message-ID: <212322090903161018h2ee7bd56yb24dc0304f80c0af@mail.gmail.com> I would love list comprehensions, but only if they were amenable to using all kinds of statements there (methods) and many comprehension statements in one list. List input .... List out = [x + valueToAdd for x : input if x % 2 == 0; x + valueToAdd + 2 for x : input]; Possibly this could be compressed for the same list (as here) to: List out = [x + valueToAdd if x % 2 == 0, x + valueToAdd + 2 for x : in]; With only one iteration needed. Would LOVE this. From i30817 at gmail.com Mon Mar 16 10:16:30 2009 From: i30817 at gmail.com (Paulo Levi) Date: Mon, 16 Mar 2009 17:16:30 +0000 Subject: ACCEPTABLE?: List Comprehensions? Message-ID: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> I would love list comprehensions, but only if they were amenable to using all kinds of statements there (methods) and many comprehension statements in one list. List input .... List out = [x + valueToAdd for x : input if x % 2 == 0; x + valueToAdd + 2 for x : input]; Possibly this could be compressed for the same list (as here) to: List out = [x + valueToAdd if x % 2 == 0, x + valueToAdd + 2 for x : in]; With only one iteration needed. Would LOVE this. From neal at gafter.com Mon Mar 16 11:03:28 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 16 Mar 2009 11:03:28 -0700 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> References: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> Message-ID: <15e8b9d20903161103v436fa0e6i81c3270cbf8fd64c@mail.gmail.com> This is sort of a half-way to C#'s LINQ (language integrated native query), which has proven remarkably successful. It's been integrated into Scala as well. I think that bucket of changes is worth considering, but certainly not in the scope of project Coin. On Mon, Mar 16, 2009 at 10:16 AM, Paulo Levi wrote: > I would love list comprehensions, but only if they were amenable to using > all kinds of statements there ?(methods) and many comprehension statements > in one list. > > List input .... > List out = [x + valueToAdd for x : input if x % 2 == 0; x + > valueToAdd + 2 for x : input]; > Possibly this could be compressed for the same list (as here) to: > List out = [x + valueToAdd if x % 2 == 0, x + valueToAdd + 2 for x > : in]; > With only one iteration needed. > > Would LOVE this. > > From reinier at zwitserloot.com Mon Mar 16 11:06:21 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 16 Mar 2009 19:06:21 +0100 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <212322090903161018h2ee7bd56yb24dc0304f80c0af@mail.gmail.com> References: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> <212322090903161018h2ee7bd56yb24dc0304f80c0af@mail.gmail.com> Message-ID: <4BD19F64-DB02-4B05-99B5-9AE9F98F182C@zwitserloot.com> Paulo, why do you feel such an edge case is crucial? Adding syntax for this makes the concept far more confusing (for the same reason perl's cartoon swearing is confusing: No guidance by keywords, lots of different forms that are all legal but slightly different). Also, java does not support tuples, which is what that list comprehension you posted would output in other languages, IIRC. The generator expression, as well as the filter expression(s), are just that: Expressions. Method calls are expressions, so they'd of course be legal. Here's a syntax proposal for list comprehensions. I can spin a proposal around this, but this would be the meat and potatoes: '[' GeneratorExpression ComprehensionSources ']' GeneratorExpression: Any expression, of any type. The type of the entire list comprehension (which is an expression) is a List, where T is the inferred type of the generatorexpression. Forcing a type is done in the usual way (with a cast). ComprehensionSources: ComprehensionSource ComprehensionSources(opt) ComprehensionSource: ';' 'for' VarDeclaration ':' SourceExpression SourceFilter(opt) VarDeclaration: Variable Declaration's scope restricted to only the SourceFilter belonging to this ComprehensionSource, all SourceFilter expressions of any ComprehensionSources to the right of this one, and the GeneratorExpression. Scope ends with the list comprehension. SourceExpression: Either an Iterable or an array of T; 100% analogous to the legal expressions on the RHS of foreach blocks. SourceFilter: 'if' FilterExpression. FilterExpression: Any expression that results in a 'boolean' value. Evaluated for each iteration; iteration is not run through the generator expression if the FilterExpression returns true. If the SourceFilter is not specified, assume it reads "if true". (i.e. don't discard any iterations). Multiple ComprehensionSources are treated like nested for loops, with the last ComprehensionSource serving as the innermost loop. Therefore, the following list comprehension: [ a + b + c ; for int a : intList if a > 5 ; for int b : new int[] {1, 2, 3, 4, 5} ; for c : intList if a + c == 10] gets translated to: { List list = new ArrayList(); //from type of generator expression. for ( int a : intList ) { //copy/paste from ComprehensionSource if ( !(a > 5) ) continue; //copy paste from filter expression for ( int b : new int[] { 1, 2, 3, 4, 5} ) { for ( int c : intList ) { if ( !(a + c == 10) ) continue; list.add(a + b + c); //generator expression } } } list } Where you'll have to imagine for a moment that the above block is an expression that returns 'list' as its value. Paulo, could you elaborate on the exact meaning of what you wanted? Can you do it with the above syntax? --Reinier Zwitserloot On Mar 16, 2009, at 18:18, Paulo Levi wrote: > I would love list comprehensions, but only if they were amenable to > using > all kinds of statements there (methods) and many comprehension > statements > in one list. > > List input .... > List out = [x + valueToAdd for x : input if x % 2 == 0; x + > valueToAdd + 2 for x : input]; > Possibly this could be compressed for the same list (as here) to: > List out = [x + valueToAdd if x % 2 == 0, x + valueToAdd + > 2 for x > : in]; > With only one iteration needed. > > Would LOVE this. > From Dalibor.Topic at Sun.COM Mon Mar 16 12:55:54 2009 From: Dalibor.Topic at Sun.COM (Dalibor Topic) Date: Mon, 16 Mar 2009 12:55:54 -0700 Subject: Coin Considerations In-Reply-To: <031AB425-4CE6-4E24-ABDC-2B629C31FA52@zwitserloot.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> <49BBED9C.7000901@sun.com> <15e8b9d20903141148x2bb203et4891c54b348dd7b9@mail.gmail.com> <49BC6B47.1000007@sun.com> <031AB425-4CE6-4E24-ABDC-2B629C31FA52@zwitserloot.com> Message-ID: <49BEAECA.4080807@sun.com> Reinier Zwitserloot wrote: > No, you can do this within project coin, I think: > > If there's one top-level member, or there are many, but only one is > public (there can't be more than one public), that's the one that gets > the real annotation. Any spin-off classes (e.g. a $1 or whatnot, or a > top-level package-private) get a @SourceRef annotation, which contains > a class literal that does contain the full source (the public top- > level member). > > That covers virtually all source files. Yeah, but that would now require two annotations instead of one, making it a bit more complex. Thinking a but further about the idea, I don't think I would really want to have to tell my compiler one or more times in each source file that I want its contents stored. I'd much rather pass a flag to it to do it for all compilation units at once. That would turn the idea from a small language change proposal, into a small javac patch proposal. cheers, dalibor topic -- ******************************************************************* Dalibor Topic Tel: (+49 40) 23 646 738 Java F/OSS Ambassador AIM: robiladonaim Sun Microsystems GmbH Mobile: (+49 177) 2664 192 Nagelsweg 55 http://openjdk.java.net D-20097 Hamburg mailto:Dalibor.Topic at sun.com Sitz der Gesellschaft: Sonnenallee 1, D-85551 Kirchheim-Heimstetten Amtsgericht M?nchen: HRB 161028 Gesch?ftsf?hrer: Thomas Schr?der, Wolfgang Engels, Dr. Roland B?mer Vorsitzender des Aufsichtsrates: Martin H?ring From crazybob at crazybob.org Mon Mar 16 13:00:05 2009 From: crazybob at crazybob.org (Bob Lee) Date: Mon, 16 Mar 2009 13:00:05 -0700 Subject: Coin Considerations In-Reply-To: <49BBE3BD.30109@sun.com> References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <49BBE3BD.30109@sun.com> Message-ID: On Sat, Mar 14, 2009 at 10:05 AM, Dalibor Topic wrote: > I have one thing in the back of my mind - a @StoredSource annotation > to store the corresponding source code as a class file attribute. FWIW, just jarring the source files up with your .class files would probably be simpler, more flexible, and more efficient. Bob From reinier at zwitserloot.com Mon Mar 16 12:57:29 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 16 Mar 2009 20:57:29 +0100 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <212322090903161147y73ab9c3t4b698f1e11d33c8f@mail.gmail.com> References: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> <212322090903161018h2ee7bd56yb24dc0304f80c0af@mail.gmail.com> <4BD19F64-DB02-4B05-99B5-9AE9F98F182C@zwitserloot.com> <212322090903161147y73ab9c3t4b698f1e11d33c8f@mail.gmail.com> Message-ID: How do the if statements bind if you have multiple generator expressions with multiple sources? This seems to make an already complicated proposal even harder to read. --Reinier Zwitserloot On Mar 16, 2009, at 19:47, Paulo Levi wrote: > > Something like this: > List out = [x + valueToAdd if x % 2 == 0; x + valueToAdd + > 2; for x : in]; > > { > List list = new ArrayList(); //from type of > generator expression. > for ( int x : in ) { //copy/paste from ComprehensionSource > if ( x % 2 == 0 ){ //1? filter expression > list.add(x + valueToAdd); //1? generator expression > } > list.add(x+valueToAdd+2); > } > } > > Nested loops would get used if using "," instead of ";". From i30817 at gmail.com Mon Mar 16 13:48:12 2009 From: i30817 at gmail.com (Paulo Levi) Date: Mon, 16 Mar 2009 20:48:12 +0000 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: References: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> <212322090903161018h2ee7bd56yb24dc0304f80c0af@mail.gmail.com> <4BD19F64-DB02-4B05-99B5-9AE9F98F182C@zwitserloot.com> <212322090903161147y73ab9c3t4b698f1e11d33c8f@mail.gmail.com> Message-ID: <212322090903161348y61ef7b57yfbdb3c87a93f7914@mail.gmail.com> I dunno. The major line reduction win is in the nested fors example, but most of the fors i make with a list output are not nested. I would just like that this proposal also adapts to the simple zip or multi-map usage. Lets see if i understand it: Simple copy: List out = [x for x : in] Simple map: List out = [x+valueToAdd for x : in] Multi-map : List out = [x+valueToAdd, x+3 for x : in] (output list.size = in.size * 2) List out = [x+valueToAdd if x % 2 == 0, x+3 if x % 2 != 0 for x : in] Zip: List out = [x+valueToAdd, y+3 for x : in, y : in2] List out = [x+valueToAdd if x % 2 == 0, y+3 if x % 2 == 0 for x : in, y : in2] Nested fors (only 1 condiction allowed): [ a + b + c, if a > 5 && c < 2, for a : intList1, for b : intList, for c : intList] The nested for is the most bizarre and unusual example of all. I see why you put the condition after the for, but i think that is a little less readable. If you see the nested fors example you see i'm contracting myself, viz ";" and ",". I leave the field to the experts, but please make the main usecase the easiest. From reinier at zwitserloot.com Mon Mar 16 17:54:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 17 Mar 2009 01:54:06 +0100 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <212322090903161348y61ef7b57yfbdb3c87a93f7914@mail.gmail.com> References: <212322090903161016r1b2c0cdcl57e7417a09094f7a@mail.gmail.com> <212322090903161018h2ee7bd56yb24dc0304f80c0af@mail.gmail.com> <4BD19F64-DB02-4B05-99B5-9AE9F98F182C@zwitserloot.com> <212322090903161147y73ab9c3t4b698f1e11d33c8f@mail.gmail.com> <212322090903161348y61ef7b57yfbdb3c87a93f7914@mail.gmail.com> Message-ID: <620C3092-DCB3-4A7E-A0F0-227ED793A6FF@zwitserloot.com> Paulo, Scala and Python both have list comprehensions. They both implement them according to my sketch: 1 generator expression, filters AFTER the source, and multiple sources allowed. They don't allow multiple generator expressions and they don't allow you to put ifs on the generators (you put them on the sources). Exactly like the syntax I sketched in an earlier mail to coin-dev. It seems clear then that the main use-case appears to be nested fors (multiple source expressions), and not turning a list of 3 elements into something with more than that. See: http://docs.python.org/tutorial/datastructures.html#list-comprehensions http://www.scala-lang.org/node/111 The only saving grace here is that in both scala and python, you can take a List and turn them into a List by unpacking the tuples, fairly easily. This is slightly more complicated in java, but not terribly so *IF* we have list literals: public static List compress(List> input) { //implementation obvious } compress([ [a, a] for int a : intList]); //turns [1, 2, 3] into [1, 1, 2, 2, 3, 3]. I don't suggest adding it to this proposal. Just highlighting that, if certain people really are stumped without this feature, they can solve it with minimal effort and 1 static import, which is a lot better than nothing at all. I say: err on the side of caution. If the above idiom becomes well-used, we can always add a syntax for multiple generator expressions at some later point in time. --Reinier Zwitserloot On Mar 16, 2009, at 21:48, Paulo Levi wrote: > I dunno. > The major line reduction win is in the nested fors example, but most > of the fors i make with a list output are not nested. I would just > like that this proposal also adapts to the simple zip or multi-map > usage. > > Lets see if i understand it: > Simple copy: > List out = [x for x : in] > Simple map: > List out = [x+valueToAdd for x : in] > Multi-map : > List out = [x+valueToAdd, x+3 for x : in] (output list.size > = in.size * 2) > List out = [x+valueToAdd if x % 2 == 0, x+3 if x % 2 != 0 > for x : in] > Zip: > List out = [x+valueToAdd, y+3 for x : in, y : in2] > List out = [x+valueToAdd if x % 2 == 0, y+3 if x % 2 == 0 > for x : in, y : in2] > Nested fors (only 1 condiction allowed): > [ a + b + c, if a > 5 && c < 2, for a : intList1, for b : intList, > for c : intList] > > The nested for is the most bizarre and unusual example of all. > I see why you put the condition after the for, but i think that is a > little less readable. > If you see the nested fors example you see i'm contracting myself, > viz ";" and ",". > I leave the field to the experts, but please make the main usecase > the easiest. From david at walend.net Mon Mar 16 19:37:22 2009 From: david at walend.net (David Walend) Date: Mon, 16 Mar 2009 22:37:22 -0400 Subject: Proposal: Access to Generic Type Parameters at Compile-Time Message-ID: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> I've been hesitating to submit this proposal because I have seen so few other people push generics as hard as I do. However, the discussion around method and field literals -- and adding type parameters to Field and Method -- may make it more relevant than I first thought. My test for reflection APIs is using the API to convert between a class in memory and bytes in a stream. One common corner case is converting Map. I often create a simple class for the chore. If Field becomes parameterized, I'll be using Field> in that class, and will perhaps be creating specialized classes for different Keys and Values. If the Key or Value types take parameters, the generics will be three layers deep. Type parameters on methods that return types with their own type parameters invites developers to wade into the depths of layered generics. This proposal addresses one of the associated pain points. I've attempted to write a spec section which I hope is clear. I'm not sure it's wrong. What do you think? Dave David Walend david at walend.net --- Access to Generic Type Parameters at Compile-Time AUTHOR: David Walend OVERVIEW FEATURE SUMMARY: This feature allows a developer to gain dot access to the type parameters of type parameters in classes and interfaces, similar to accessing encapsulated fields in the class, but only in source code. For example, given Digraph, one could declare Subgraph extends Digraph. MAJOR ADVANTAGE: This change will simplify the use of layered generics and opens the door to richer general purpose code. MAJOR BENEFIT: This change transfers the rote work of resolving specified types from the developer to the compiler. Given the mechanical nature of the task, that is where the work belongs. MAJOR DISADVANTAGE: Generics in Java are already complex; the Java Generics FAQ is very large. This change will make it slightly longer, and require developers to learn one more (relatively intuitive) detail. ALTERNATIVES: 1) Do nothing. 2) Full reification, if done well, would provide similar compile-time language-level access beyond the type specifiers. (This option is one of the case examples of things too large for project coin.) 3) Diminish generics' prominent position in Java by removing the compile-time warnings. 4) Remove generics from Java. EXAMPLES: My examples are directed graph examples from the JDiraph project on java.net. The semiring (advanced) example was inspired by Cormen, Leiserson and Rivest, 26.4. I show what the code looks like in JDK5 first, then with the access to generic type parameters proposed. --- SIMPLE EXAMPLE: Given interface Digraph, define Paths through the Digraph, a Digraph representing a probalistic transitions in the dialog, and an instance of Path that represents a conversation. JDK5 Syntax -- three type specifiers, one of which requires the developer to match the first two by hand: interface Path> extends Digraph { Node getHead(); ... } To use it: class DialogGraph extends Digraph {...} //If the developer gets one of these type specifiers wrong, //it won't compile //But the right answers already exist in DialogGraph Path conversation = ... With access to the encapsulated type parameters -- The developer's class has one type parameter and the developer repeats none of the work that the compiler must do: interface Path extends Digraph { ThruGraph.Node getHead(); ... } To use it: class DialogGraph extends Digraph {...} //Path requires only one type specifier. //The compiler determines that Nodes are Phrases //and Edges are Doubles. Path conversation = ... ADVANCED EXAMPLE: Semirings and Digraph Minimization Algorithms. For a problem domain defined by a Digraph, a Semiring defines a solution domain and a set of four operators: identity, annihilator, extension and summary. The solution domain is a Digraph with the original nodes, but edges that label (summarize) relevant subgraphs of the original digraph. The full solution is an overlay of the original digraph. One Semiring can be used to determine the digraph's connectivity. Other Semirings may find shortest path, least path, most probable path or other labels involving traversing the graph. These graph minimization algorithms, like Floyd-Warshall, Dijkstra or A*, are defined in terms of the operators in the Semiring. The same graph minimization code can be reused with different semirings. JDK5 Syntax -- Each layer of the problem domain is exposed. The type parameter list is monstrous. Getting the type specifiers right is daunting and the resulting code assaults the eyes. interface Semiring, LabelDigraph extends OverlayDigraph> { void summary(Node from, Node through, Node to, LabelDigraph labelDigraph); ... } public class FloydWarshall, LabelDigraph extends OverlayDigraph, SRing extends Semiring> {...} To use it: public class LeastPathSemiring> implements Semiring > { public void summary(Node from,Node through,Node to,NextStepDigraph labelDigraph) {...} ... } LeastPathSemiring shortestLabelsSemiring = new LeastPathSemiring(new TestPathMeter()); FloydWarshall, LeastPathSemiring> floydWarshall = new FloydWarshall, LeastPathSemiring>(); With access to the encapsulated type parameters -- Only the outermost layer of the problem domain is exposed. The type parameter list collapses to a single parameter. The compiler does the work to get the type specifiers correct. The code becomes much more readable. interface Semiring { void summary(LabelDigraph.Node from, LabelDigraph.Node through, LabelDigraph.Node to, LabelDigraph labelDigraph); ... } public class FloydWarshall {...} To use it: public class LeastPathSemiring implements Semiring> { public void summary(BaseDigraph.Node from, BaseDigraph.Node through, BaseDigraph.Node to, NextStepDigraph labelDigraph) {...} ... } LeastPathSemiring shortestLabelsSemiring = new LeastPathSemiring(new TestPathMeter()); FloydWarshall> floydWarshall = new FloydWarshall>(); DETAILS SPECIFICATION: A new 4.5.2.1 can hold the changes. Sections 5.1.10, 6.4.1, 6.8.7, 8.1.2, 8.4.4, 8.8.4 and 9.1.2 may all need to be touched, but seem fine to my inexpert eye. 4.5.2.1 Members and Constructors of Referenced Parameterized Types From Parameterized Types Let C be a class or interface declaration with formal type parameters A1 extends P1,...,An extends Pn. Let P1..Pn be class or interface declarations, each of which may have its own formal type parameters B11..B1p, ... Bn1..Bnp. Let C be an invocation of C, where Ti are types (not wildcards) with parameters Ti, and Uj are types (not wildcards). Let m be a member or constructor declaration in C, whose type as declared is A.B. Then the type of m (see 8.2 and 8.8.6) in the type C with Ti is U[A1.B1 := T1.U1, ..., An.Bp := Tn.Up]. Let m be a member or constructor declaration in D, where D is a class extended by C or an interface implemented by C. Let D be the supertype of C that corresponds to D. Then the type of m in C is the type of m in D. (Same paragraph as found in 4.5.2.) If any of the type arguments to a parameterized type are wildcards, the type of its members and constructors is undefined. COMPILATION: This change requires no changes to bytecodes. Erasure will work as it does now. The type specification resolver within the compiler will need to map named types to the contained type parameters instead of just checking the developer's work. TESTING: This change will require additions to the suite of generics cases to test. Feel free to pull test cases from JDigraph. LIBRARY SUPPORT: Existing libraries may remain unchanged or take advantage of this new feature. Widely implemented interfaces and extended classes that can not change existing APIs still can not change existing type parameter lists to take advantage of this feature. REFLECTIVE APIS: No change. OTHER CHANGES: Some new examples will be needed in the docs. The generics FAQ will grow a bit. MIGRATION: Widely implemented interfaces and extended classes with complex type specifiers can not change their type parameters. Those interfaces and classes could be subclassed with adapters. However, few people have taken advantage of this part of generics' expressive power to date. Few examples of layered generics exist. COMPATIBILITY BREAKING CHANGES: Adding this access is an an additive change. Nothing will break. EXISTING PROGRAMS: I'll be able to simplify the semiring package in JDigraph. See comments in MIGRATION. Existing programs will need no changes. REFERENCES EXISTING BUGS: http://bugs.sun.com/view_bug.do?bug_id=6448707 http://weblogs.java.net/blog/dwalend/archive/2006/05/tilting_at_the_1.html is probably the best blog. JDigraph is at https://jdigraph.dev.java.net . From markmahieu at googlemail.com Tue Mar 17 09:22:18 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 17 Mar 2009 16:22:18 +0000 Subject: Proposal: Access to Generic Type Parameters at Compile-Time In-Reply-To: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> References: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> Message-ID: <3BA402DB-7828-42EF-A443-0A7A4ECEE052@googlemail.com> Hi David, On 17 Mar 2009, at 02:37, David Walend wrote: > > interface Path > extends Digraph > { > ThruGraph.Node getHead(); > ... > } So, if I were the author of Digraph and I decided to rename its type parameters (to N and E for example), your Path interface would no longer compile? Mark From Joe.Darcy at Sun.COM Tue Mar 17 13:34:47 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 13:34:47 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> References: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> Message-ID: <49C00967.3000905@sun.com> Howard Lovatt wrote: > Neal Gafter has proposed replacing the current wildcard syntax with in > and out instead of extends and super; an alternative to the current > extends/super and Neal's proposal would be to deprecate the current > wildcards and to change to the behaviour to that of arrays (covariant > only). In particular to change the wildcard syntax to > SomeClass for variables, arguments, or fields, class > AClass for classes, and for methods > where T is compulsory when declaring classes or methods but not used > when declaring variables etc. (i.e. exactly like method arguments). > This new syntax is similar in behaviour to the current syntax > SomeClass (the difference is that the new > does not issue a warning for covariant assignment). > > This proposal deprecates the concepts of SomeClass SomeOtherClass>, SomeClass, and SomeClass in the > current syntax. Generics are made covariant so that List lo = > new ArrayList() is OK and does not issue a warning (like > arrays). If "lo" form the previous example has an object added to it, > lo.add( new Object() ), then if this produces an error or not is > dependant on the class in question (in the case or ArrayList it > wouldn't). See http://www.artima.com/weblogs/viewpost.jsp?thread=222021 > for more detail. > > At the same time I propose cleaning up other pain points with > generics, in particular: > > 1. Deprecate raw declarations, new ArrayList() becomes a deprecated > warning - you need to say new ArrayList(). > That could be a fine lint option. You could also write an annotation processor that used the javac tree API to generated such warnings/errors today. > 2a. Deprecate self references, you get a deprecated warning for class > Type>, you wouldn't use generics in this case. > F-bounds are part of Java's generics. > 2b. It follows that T> is an error in the new syntax, see > next point for how you would do this. > > 3. Deprecate the ability to specify multiple bounds, e.g. instead of > static > T max(Collection extends T>) you write static T max(Collection) (note > Comparable would not be parameterised with the new syntax since you > would almost always want Comparable). > There are reasons why multiple bounds are supported. > 4. Allow arrays of parameterised types, List[] lsa = new > ArrayList[10] is OK (you may get a runtime exception though if > you misuse the feature). > Arrays and generics don't play well together; ignoring the impedance mismatch doesn't make the problem go away. > Examples of use of proposed new syntax are: > > boolean isAnnotationPresent( Class annotationClass ); // > was: boolean isAnnotationPresent( Class > annotationClass ); > > static createList( Collection coll ); // was: static > createList( Collection coll ); > > static void sort( List list ); // was: static extends Comparable> void sort( List list ); > > static Enum valueOf( Class enum, String name ); // was: static > > T valueOf( Class enum, String name ); > > The disadvantage of this proposal is that you can now get the > equivalent of ArrayStoreExceptions, the reason that this is acceptable > is that ArrayStoreExceptions are rare (I have never had one). For > compatibility the existing syntax would still be allowed, but would > issue a deprecated warning. The reason that I am proposing deprecating > wildcards is that they are not worth the trouble (they have a poor > cost/benifit ratio - less is more). I know the language pedants will > hate this proposal, but I think the vast majority of Java users would > welcome this change. > > This proposal has some overlap with the proposal to infer generic > types in that they both concern generic declarations, but are > otherwise orthogonal. The collections library, in particular methods > like sort (see above) and interfaces like Comparable, and enum class > would need updating to the new syntax and this new library would have > to be supplied as a module so that old code could use the old library > (nt 100% compatible). > If you want a proposal formally considered, you must fill out a proposal form: http://openjdk.java.net/projects/coin/#proposal_form > So I am proposing eventually removing something from the language > (actually replacing) - is removing a feature a first on coin-dev? > However, the proposal form explicitly disallows removing features "The proposal must not remove existing features of the language...". -Joe From Joe.Darcy at Sun.COM Tue Mar 17 13:36:40 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 13:36:40 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <15e8b9d20902280903h32967535l8f6e4f6580fdd93d@mail.gmail.com> References: <15e8b9d20902280903h32967535l8f6e4f6580fdd93d@mail.gmail.com> Message-ID: <49C009D8.7040208@sun.com> Hello. While the existing "? extends" and "? super" syntax is certainly a bit obtuse (but better than "+" and "-"!), I don't find introducing redundant ways of declaring those semantics attractive at this point. -Joe Neal Gafter wrote: > Improved Wildcard Syntax for Java > http://docs.google.com/Doc?id=ddb3zt39_79g2mtpccz > > AUTHOR(S): > > Neal Gafter > > OVERVIEW > > The current syntax for Java's wildcards is confusing enough that > mneumonics are required to read code. We suggest adding an > alternative syntax that is much more readable, and then migrating code > to the more readable syntax over time. > > FEATURE SUMMARY: > > [Note: since this is an additional syntax for a feature already in the > language, most existing tutorial material can be used.] > > A covariant wildcard generic argument can be written either "? extends > Y" or "out Y". > > A contravariant wildcard generic argument can be written either "? > super Y" or "in Y". > > MAJOR ADVANTAGE: > > While the existing syntax is mneumonic from the point of view of > describing its effect on the type system, it is not mneumonic in its > use. The new syntax is self-mneumonic for users. > > MAJOR BENEFIT: > > Jave code that uses wildcards is more readable, as are diagnostics > involving them. > > MAJOR DISADVANTAGE: > > Two ways of doing the same thing, though we hope code will migrate > over time toward the new more readable syntax. > > ALTERNATIVES: > > None. > > EXAMPLES > > SIMPLE EXAMPLE: > > interface Collection { > boolean addAll(Collection c); > ... > } > > ADVANCED EXAMPLE: > > class Collections { > public static > void sort(List list) {...} > public static void sort(List list, Comparator c) {...} > int binarySearch(List> list, T key) {...} > public static void fill(List list, T obj) {...} > public static void copy(List dest, List src) { > ... > } > > DETAILS > > SPECIFICATION: > > "in" and "out" are added as context-sensitive keywords with precisely > the same meaning of "? super" and "? extends". As context-sensitive > keywords, they continue to be usable as identifiers in all contexts. > > COMPILATION: > > As today. > > TESTING: > > As today, though a bit of additional work to ensure that the context > sensitive keyword is handled properly by the compiler. Specifically, > that they continue to be fully usable as identifiers in other > contexts. > > LIBRARY SUPPORT: > > None. > > REFLECTIVE APIS: > > None. > > OTHER CHANGES: > > None. > > MIGRATION: > > A trivial textual substitution can be used to translate old code to > the new syntax. > > COMPATIBILITY > > BREAKING CHANGES: > > None. > > EXISTING PROGRAMS: > > No impact. > > REFERENCES > > EXISTING BUGS: > > None > > URL FOR PROTOTYPE (optional): > > None > > From lapsus63 at gmail.com Tue Mar 17 13:25:25 2009 From: lapsus63 at gmail.com (Olivier Chorier) Date: Tue, 17 Mar 2009 21:25:25 +0100 Subject: PROPOSAL : Specify nullable argument Message-ID: Example : public void getListOfProducts(Company owner, !String facultativeName) { .... } The '!' should prevent the developper that the argument is able to be null. Invoking getListOfProducts(null, "name") could throw a compilation error/warning. Or maybe better : public void getListOfProducts(!Company owner, String facultativeName) { .... } Here, the '!' indicates a mandatory argument (not null). However, I don't know if the '!' marker could be the most appropriate. From neal at gafter.com Tue Mar 17 13:41:45 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 17 Mar 2009 13:41:45 -0700 Subject: PROPOSAL : Specify nullable argument In-Reply-To: References: Message-ID: <15e8b9d20903171341u17a6d056rbc0e2f726e778471@mail.gmail.com> Did you intend this to be a complete proposal? Do you like this better than @NonNull, which will probably be included in Java 7 under jsr 305? On Tue, Mar 17, 2009 at 1:25 PM, Olivier Chorier wrote: > Example : > > public void getListOfProducts(Company owner, !String facultativeName) > { > .... > } > > The '!' should prevent the developper that the argument is able to be null. > Invoking getListOfProducts(null, "name") could throw a compilation > error/warning. > > Or maybe better : > > public void getListOfProducts(!Company owner, String facultativeName) > { > .... > } > > Here, the '!' indicates a mandatory argument (not null). > > > However, I don't know if the '!' marker could be the most appropriate. > > From Joe.Darcy at Sun.COM Tue Mar 17 14:07:08 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 14:07:08 -0700 Subject: Return 'this' proposal In-Reply-To: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> Message-ID: <49C010FC.8050306@sun.com> This 'this' proposal remains vague and imprecise. Including this type/self type in a language is a continuing area of study; for example, see the recent paper "Matching ThisType to Subtyping," Chieri Saito and Atsushi Igarashi, Kyoto University, Japan, ACM SAC 2009. There are open bugs requesting this capability. For example typing "site:bugs.sun.com this type" into a popular search engine quickly yields, amongst other hits, 6479372 Add self types (type of 'this' aka ThisClass) to the language This bug discusses the size of the type system impact of this change, a magnitude far too large for Project Coin. There is no need to submit further refinements of this idea; any proposal along the lines of adding a this type will be out of scope for Project Coin. -Joe Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? > > GENESIS > > It's a simplified 'This' type problem, which seems to be too much > complicated as for now and need more analyses. Construction is designed not > to interact with possibility that 'This' type will be introduced. > OVERVIEW > > FEATURE SUMMARY: > It allows the method to return 'this' object. > > MAJOR ADVANTAGE: > Simplification of return this; statement. > 'void' can be easy replaced with 'this'. > > MAJOR BENEFIT(s):It would prevent NFP, in a described situation, and make > some 'builder' like interfaces look really clear and simple. > > MAJOR DISADVANTAGE: > It's a change in language. Depending on the way that it would be compiled to > byte-code, it determine compatibility(here may lie some problem that I do > not know about). > > ALTERNATIVES: > Self-bounded generics. > > > EXAMPLES > > SIMPLE/ADVANCED EXAMPLE: > public class Builder > { > > public this add (char c){...} > > public this add (String c){ > if (c==null){ > ... > return; // this will be returned > } > ... > } > > public static void test(Builder builder) { > builder.add('.').add("test()").add(':'); > } > > } > DETAILS > > SPECIFICATION: > JLS 8.4: > http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4 > > ResultType: > Type > void > this > > A method declaration either specifies the type of value that the method > returns, uses the keyword void to indicate that the method does not return a > value, or uses the keyword this to indicate that the method return the > reference to called object. > > Keyword this cannot occurs if method is static. > > > JLS 14.17: > http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.17 > > ReturnStatement: > return Expressionopt ; > > A return statement with no Expression must be contained in the body of a > method that is declared, using the keyword void, not to return any value > (?8.4), or in the body of a method that is declared, using the keyword this > , to return this reference (?8...),or in the body of a constructor (?8.8). > > COMPILATION: > Returned 'void' should be replaced with 'this', no more no less. > > TESTING: > Normal way. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > > I wander what object should represent 'this' return type in: > Method.getReturnType(); (this.getObject() ?) > > MIGRATION: > None. > > COMPATIBILITY > Backward: full. > > REFERENCES > Bug: 6479372: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 > http://java.net/cs/user/view/cs_msg/37432 > Return 'this' proposal : > http://lasu2string.blogspot.com/2009/03/return-this-proposal.html > > From Joe.Darcy at Sun.COM Tue Mar 17 14:44:10 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 14:44:10 -0700 Subject: PROPOSAL: Multiple switch expressions and case ranges In-Reply-To: <30992e5d0903061344w1cbf4285i143291cae930bdeb@mail.gmail.com> References: <30992e5d0903051416o446a9363kc7ac403510c3f6b7@mail.gmail.com> <30992e5d0903061344w1cbf4285i143291cae930bdeb@mail.gmail.com> Message-ID: <49C019AA.4090904@sun.com> Greetings. While pattern matching is common in functional languages, my assessment is that the effort / reward ratio of this change for Java programs is not favorable for inclusion in the platform. -Joe Pinku Surana wrote: > Updated: Added relevant bug id. Added support for sequences within > ranges. More info on how to compile this feature. > > Maybe this should be split into two proposals? (1) case ranges and (2) > multiple switch expressions. > > > AUTHOR(S): Pinku Surana > > OVERVIEW > > FEATURE SUMMARY: > > Extend the switch statement to support multiple switch expressions and case > ranges. > > MAJOR ADVANTAGE: > > It is syntactic sugar that makes it easier to write/read complex > logic. This is one small aspect of the vastly more powerful match or > case expression in functional languages. > > MAJOR BENEFIT: > > Better readability for complex cases, and potentially better > performance relative to if statements. > > MAJOR DISADVANTAGE: > > Requires changes to compiler. > > ALTERNATIVES: > > It can currently be implemented with if statements. > > EXAMPLES > > Show us the code! > > SIMPLE EXAMPLE: Show the simplest possible program utilizing the new > feature. > > switch (c) { > case ['a'..'z']: return "lower case" ; > case ['A'..'Z']: return "upper case" ; > default: return "something else" ; > } > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > switch (suit, value) { > case [SPADE,CLUB], [2..10] : return "black low-value card" ; > case [HEART,DIAMOND], [2..10] : return "red low-value card" ; > case _, [11..14] : return "face card" ; > } > > 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. > > * The lexer will need to support underscore ('_') and ".." > * The parser rules for switch statements must be changed. > > SwitchStatement: > switch (Expression [, Expression]*) SwitchBlock > > SwitchLabel: > case CaseExpression [, CaseExpression]* : > default : > > CaseExpression: > _ > ConstantExpression > EnumConstantName > [ CaseRanges ] > > CaseRanges > CaseRange > CaseRanges , CaseRange > > CaseRange > ConstantExpression > EnumConstantName > ConstantExpression .. ConstantExpression > EnumConstantName .. EnumConstantName > > * Semantic rules: > - The number of CaseExpressions must equal the number of expressions in > the SwitchStatement > - The underscore ('_') means "don't care" > - In [ c1 .. c2], c1 should be less than c2 > - The types of the constants/enums must match the type of the expression > in the same position > - If the range of constants/enums overlap between case arms, then raise an > error. > > COMPILATION: > > The implementation for these two features is similar to that of switch > in any optimizing compiler. There are two popular implementations for > switch: jump tables (JT) and branching search (BS). This high-level > switch statement must be "lowered" to a combination of JT and BS, > either implementing them manually and/or using the switch bytecode where > appropriate. > > First, case ranges are a simple extension because it gives the > compiler an easily recognizable dense region of constants. If that > range is small enough (ask the JIT guys), then use the switch bytecode > so the JIT will generate an efficient JT. If the range is large and > the JIT would have done BS anyway, implement the range checks using > standard BS techniques. These techniques have been around for over 30 > years. > > Second, multiple switch expressions are a bit more complicated, but > the implementation has existed in pattern matcher compilers for > functional languages for over 20 years. In fact, this will be much > simpler because it only supports constants. Basically, the compiler > builds a decision tree where the case constant/ranges are at the > leaves. Then it merges redundant checks and generates BS code and/or > uses the switch bytecode to get the JIT to implement a JT. > > > TESTING: How can the feature be tested? > > Normal compiler testing. > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > > None > > 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. > > The package com.sun.source.tree will need to return a list of switch > expressions and case constants. Also, new expression nodes must be > added for ranges and for the "don't care" underscore. > > 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. > > Don't think so. > > MIGRATION: Sketch how a code base could be converted, manually or > automatically, to use the new feature. > > I think this would be difficult because the logic would be obscured in if > statements. > > COMPATIBILITY > > BREAKING CHANGES: Are any previously valid programs now invalid? If so, list > one. > > None. > > 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? > > Should be backwards compatible. > > REFERENCES > > EXISTING BUGS: Please include a list of any existing Sun bug ids related to > this proposal. > > 4269827 > I couldn't find any RFEs for multiple switch expressions. > > URL FOR PROTOTYPE (optional): > > If there's interest, I can cook up a prototype with Polyglot. > > From develop4lasu at gmail.com Tue Mar 17 15:09:30 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 17 Mar 2009 23:09:30 +0100 Subject: Return 'this' proposal In-Reply-To: <49C010FC.8050306@sun.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> Message-ID: <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> 2009/3/17 Joseph D. Darcy > This 'this' proposal remains vague and imprecise. > > Including this type/self type in a language is a continuing area of study; > for example, see the recent paper > > "Matching ThisType to Subtyping," Chieri Saito and Atsushi Igarashi, Kyoto > University, Japan, ACM SAC 2009. > > There are open bugs requesting this capability. For example typing "site: > bugs.sun.com this type" into a popular search engine quickly yields, > amongst other hits, > > 6479372 Add self types (type of 'this' aka ThisClass) to the language > > This bug discusses the size of the type system impact of this change, a > magnitude far too large for Project Coin. > > There is no need to submit further refinements of this idea; any proposal > along the lines of adding a this type will be out of scope for Project Coin. > > -Joe > > > I'll check it, but I'm afraid that introducing 'This' type will be impossible for Java and for all other languages with Inheritance, or I would say it's possible but conditions would be huge. return 'this': - Idea is quite simple: you use object from left side of dot as returned from method, it's the same quite idea with converting void -> this, but allowed only when it's written directly. - Byte-code for that is other story and I'm not sure how much limitation this contains. Maybe you cold while what problems you see (that could help)? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Tue Mar 17 15:12:14 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 15:12:14 -0700 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903121002g57b48225yc83d3c26cf099e38@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903111411h1669ba4blcbc9ca239b7cd494@mail.gmail.com> <108fcdeb0903120932o1f689f65ob4df40322393b8ec@mail.gmail.com> <6aef848f0903121002g57b48225yc83d3c26cf099e38@mail.gmail.com> Message-ID: <49C0203E.1090206@sun.com> Vilya Harvey wrote: > 2009/3/12 Kevin Bourrillion > > >> On Wed, Mar 11, 2009 at 2:11 PM, Neal Gafter wrote: >> >> Vilya- >> >>> I suspect that if you narrowed the scope of this proposal to just enum >>> types, it would have a much better chance of getting accepted for project >>> Coin. >>> >> To the general proposal, I believe the problem of conflicting meanings of >> <=, >= and == make it a non-starter. >> >> > > I tried implementing the change & it was remarkably simple - without having > looked at any of the openjdk code before, it took me just one evening; hats > off to the compiler designers! However even the first bit of example code I > wrote to test it with looked a bit strange: > > String a, b; > ... > if (a < b) > System.out.println("a < b"); > else if (a > b) > System.out.println("a > b"); > else if (a == b) > System.out.println("a == b"); > else > System.out.println("a.compareTo(b) == 0")'; > > It seems really odd that the else clause is actually reachable, but of > course it is. I suspect that would catch a lot of people out. > > So given that experience and having read everyone's comments, I've come to > the conclusion that the proposal would only make sense if it was part of a > larger plan that included changing the meaning of == and !=. That would be > such a breaking change that I doubt it will ever happen, much less in the > jdk7 time frame, so I'm withdrawing the proposal. > > Thanks a lot to all of you who provided me with feedback! > > Vil. > If support for using relational operators on declared types were to be added, I agree that leveraging implementations of the Comparable interface would be the right approach. However, I also agree that the "==" and "!=" semantics issue is sufficiently large to block the proposal as a coin. A few other numerical wrinkles, as Neal noted earlier in the thread floating-point comparison does *not* define a total ordering of values because NaN is neither, less than, greater than, nor equal to any floating-point value, including itself. Therefore, if a and b above were double or float, the last else clause would actually be reachable too whereas the final else clause would not actually be reachable if a and b had integral types. Some classes can have a natural ordering that is inconsistent with equals, such as the BigDecimal. In BigDecimal, the same numerical value can have multiple representation, such as 100 * 10^0 versus 10 * 10^1 versus 1 * 10^2. These are all "the same" under (compareTo == 0) but are *not* .equals with each other, making replacement of == with (compareTo == 0) conceptually problematic for another reason than object equality. As an aside, I've considered whether it would be worthwhile to include an "@NaturalOrderingInconsistentWithEquals" annotation in the platform to flag the classes that have this quirk. Such an annotation could be used to various checkers to find potentially problematic uses of such classes in sets and maps. -Joe From Joe.Darcy at Sun.COM Tue Mar 17 15:27:19 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 15:27:19 -0700 Subject: PROPOSAL: Static Methods in Interfaces In-Reply-To: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> References: <3B8E7669-6E97-4591-A672-A26BB3F925D3@zwitserloot.com> Message-ID: <49C023C7.1070501@sun.com> Hello. A few comments. I generally find the helper class pattern to be an adequate workaround to this problem. Reinier Zwitserloot wrote: > Apparently the previous version's attachment didn't come through > properly, so here's an inline HTML version. > > Static Methods in Interfaces > > VERSION > > This is version 1.0. > The latest version can be found at http://tinyurl.com/static-methods-in-interfaces > AUTHOR(S): > > Reinier Zwitserloot > Roel Spilker > OVERVIEW > > FEATURE SUMMARY: > > Static methods are now allowed in interfaces. The static method is > defined with a method body in the interface and it exists in the > namespace of the interface; it does not imply that implementing > classes must implement the method. This feature is especially useful > for utility methods that belong with a given interface. For example, > many methods in java.util.Collections are specific for a particular > interface, such as sort (java.util.List) and unmodifiableMap > (java.util.Map). > [snip] > ALTERNATIVES: > > The usual solution to this problem right now is to offer a separate > utility class (a class that is not instantiable and contains only > static methods) that contain the utility methods, along with a > reference in the javadoc of the interface to this utility class. For > example, java.util.Collections is the utility class that goes with > Map, List, Set and other Java Collections API interfaces. The use case > of default / common implementations is currently handled by having an > implementing class with a constructor. For example, a new class called > java.io.ExtensionFileFilter could be made that takes a String and > implements FileFilter. The sugar employed by this proposal is itself > also an alternative: Creating a member type class that contains the > static methods (With just a backwards and migration compatible API > addition, you could make List.Utils.of(items) work in java 1.6 > notation (The Utils class is an inner member type to the interface, > which is legal, and as it is a class, may contain static methods. > Adding extension methods would be alternative to address the same problem. [snip] > > LIBRARY SUPPORT: > > No library support is needed. However, it would be advisable to update > various interfaces in the core java APIs with useful static utility > methods. Some examples: > > java.util.List/Map/Set: All methods in java.util.Collections should > also be made available on the appropriate java collections API > interface. > java.io.Closeable: should contain a utility method > 'closeAndIgnoreException' (arguably better suited on InputStream > instead). > java.util.List/Set: Should contain an 'of' method that makes > unmodifiable lists and sets via varargs. > java.io.FileFilter: Should contain an 'ofExtension(String)' method > that creates a FileFilter for the provided extension. > > REFLECTIVE APIS: > > Currently, synthetic members are not treated specially by the > reflection API. Therefore, this proposal does not require any > reflective API changes. However, if transparency of the static method > in interfaces proposal is required for the reflection API, the > following 4 changes need to be made: > > There are 3 methods in java.lang.Class which need minor changes: > getMethod(), getDeclaredMethods(), and getMethods(). These method > finders will need to presume all static methods in a member type > called $Methods are considered part of the type itself, and thus need > to be returned as well, if the class object represents an interface. > Because getDeclaredMethods() doesn't return methods in supertypes, and > getMethod()/getMethods() only return accessible members of supertypes, > none of these methods need to look in $Methods inner types of > supertypes. These methods just need to look in the actual interface > represented by the class object for a $Methods. > > There is one method in java.lang.Method that needs a minor change: the > getDeclaringClass() method needs to return the Class object > representing the interface, and not the $Methodssynthetic class, when > invoked on a static method of an interface. > Similar questions would have to be answered for various methods in the javax.lang.model.* API. > OTHER CHANGES: > > No changes required. > Javadoc output comes to mind. > MIGRATION: > > No migration is needed. However, any java projects that currently > employ utility classes (defined as having a private constructor that > is not called anywhere in scope) which either return interface types, > or take as first parameter an interface type, or both, where all > previously mentioned interfaces are in the same package, are likely > candidates for moving or copying to the relevant interface. Thus, IDEs > can offer refactor advice to perform this task automatically and to > find likely candidates. Such a refactor tool would for example > identify all methods injava.util.Collections. > > COMPATIBILITY > > BREAKING CHANGES: > > Existing source that already uses an inner type named $Methods in an > interface will change semantics when this proposal is implemented, > primarily when queried via reflection. Between the vanishingly small > odds of both a $Methods already existing and its methods being queried > by the reflection API, and the general rule that $ should only be used > in type names by compilers, the potential breaking change is hardly > worth mentioning. > > EXISTING PROGRAMS: > > Existing programs are not affected by this change, other than as > described above in the 'breaking changes' section. > > REFERENCES > > EXISTING BUGS: > > None. > Searching for "site:bugs.sun.com static method interface" in a popular search engine yields many relevant bugs. -Joe From Joe.Darcy at Sun.COM Tue Mar 17 15:46:13 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 15:46:13 -0700 Subject: PROPOSAL: Simplified Varargs Method Invocation (Round II) In-Reply-To: References: Message-ID: <49C02835.8070209@sun.com> Bob Lee wrote: > Simplified Varargs Method Invocation > > AUTHOR: Bob Lee > > OVERVIEW > > FEATURE SUMMARY: When a programmer tries to invoke a varargs (variable > arity) method with a non-reifiable varargs type, the compiler currently > generates an "unsafe operation" warning. This proposal moves the warning > from the call site to the method declaration. > The general contract when adding generics was "if your entire program compiles without unchecked warnings, you won't get heap pollution at runtime," heap pollution being where "a variable of parameterized type refers to an object that is not of that parameterized type" (JLSv3 4.12.2.1). While warning at the declaration site is fine for a lint-style warning, the use sites merit warnings too because of heap pollution. Generics and arrays (including varags) simply do not play well together! -Joe From Joe.Darcy at Sun.COM Tue Mar 17 15:48:26 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 15:48:26 -0700 Subject: Return 'this' proposal In-Reply-To: <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> Message-ID: <49C028BA.4090609@sun.com> Marek Kozie? wrote: > 2009/3/17 Joseph D. Darcy > > > This 'this' proposal remains vague and imprecise. > > Including this type/self type in a language is a continuing area > of study; for example, see the recent paper > > "Matching ThisType to Subtyping," Chieri Saito and Atsushi > Igarashi, Kyoto University, Japan, ACM SAC 2009. > > There are open bugs requesting this capability. For example typing > "site:bugs.sun.com this type" into a popular > search engine quickly yields, amongst other hits, > > 6479372 Add self types (type of 'this' aka ThisClass) to the language > > This bug discusses the size of the type system impact of this > change, a magnitude far too large for Project Coin. > > There is no need to submit further refinements of this idea; any > proposal along the lines of adding a this type will be out of > scope for Project Coin. > > -Joe > > > I'll check it, but I'm afraid that introducing 'This' type will be > impossible for Java and for all other languages with Inheritance, or I > would say it's possible but conditions would be huge. > > return 'this': > - Idea is quite simple: you use object from left side of dot as > returned from method, it's the same quite idea with converting void -> > this, but allowed only when it's written directly. > - Byte-code for that is other story and I'm not sure how much > limitation this contains. > > > Maybe you cold while what problems you see (that could help)? > As the author and submitter of a proposal, it is your responsibility to research, understand, and explain the consequences and implications of your proposal. -Joe From Joe.Darcy at Sun.COM Tue Mar 17 15:51:50 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 15:51:50 -0700 Subject: Question: is this sutits for Project Coin? In-Reply-To: References: Message-ID: <49C02986.90201@sun.com> Mark Mahieu wrote: > Those proposals would be library changes, so no they're not suitable for > Coin. > Correct; in the near future there will be separate processes for proposing and making small API changes in JDK 7: http://mail.openjdk.java.net/pipermail/jdk7-dev/2009-February/000411.html -Joe > Mark > > > 2009/3/16 ??????? ???????? > > >> Hello all! >> >> Question: is this sutits for Project Coin? >> >> 1) Add caseSensitive flag for all sutable methods from java.lang.String >> indexOf(String s, boolean caseSensitive) >> startsWith(String prefix, boolean caseSensitive) >> ... and so on... >> >> 2) Add constructor with var args for classes that implement >> java.util.Collection >> public Vector(E... items) >> public ArrayList(E... items) >> public HashSet(E... items) >> ... and so on ... >> >> Alexey Kuznetsov >> kuaw26 at mail.ru >> >> >> > > From crazybob at crazybob.org Tue Mar 17 15:52:45 2009 From: crazybob at crazybob.org (Bob Lee) Date: Tue, 17 Mar 2009 15:52:45 -0700 Subject: PROPOSAL: Simplified Varargs Method Invocation (Round II) In-Reply-To: <49C02835.8070209@sun.com> References: <49C02835.8070209@sun.com> Message-ID: On Tue, Mar 17, 2009 at 3:46 PM, Joseph D. Darcy wrote: > While warning at the declaration site is fine for a lint-style warning, the > use sites merit warnings too because of heap pollution. > Joe, to my knowledge, this proposal does not allow for heap pollution without issuing a warning. Do you see a hole somewhere? Thanks, Bob From howard.lovatt at iee.org Tue Mar 17 15:59:03 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 09:59:03 +1100 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <15e8b9d20903142058r8c64243gc6fa1692911fa921@mail.gmail.com> References: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> <15e8b9d20903142058r8c64243gc6fa1692911fa921@mail.gmail.com> Message-ID: <3dd3f56a0903171559s7bea7c05yb69631d0d9e4a18a@mail.gmail.com> 2009/3/15 Neal Gafter : > My main concern is that this sounds like a significant change to the > type system, and therefore almost certainly out of scope for project > Coin. There is only one change to the type system; which is to allow covariant assignment, e.g. List lo = new ArrayList(). This isn't a drastic change, arrays already do this. The other changes are some new syntax to replace with and the existing wildcard syntax issues a deprecated warning. This is not a big change. > I have no idea how you would specify or implement the proposed > compile-time diagnostics (such as an error on lo.add(new Object())) There is no intention to do this, the proposal says exactly the opposite. Assuming that List lo = new ArrayList() then the proposal suggests that lo.add( new Object() ) should be allowed by the type system. > or > runtime type tests (such as the "equivalent of ArrayStoreExceptions"). Nothing to do here. The class either generates an exception upon write or it doesn't, just like pre-generics. For example if the underlying store in ArrayList is Object[], as it currently is, then no error on write. However if the underlying store was from a type factory passed into the constructor, e.g.: class List16 extends AbstractList { private Object[] values; List16(final Class clazz) { values = (Object[]) Array.newInstance(clazz, 16); } public E get(final int index) { return (E) values[index]; } public E set(final int index, final E value) { final E temp = (E) values[index]; values[index] = value; return temp; } public int size() { return values.length; } } final List l16 = new List16(String.class); l16.set(0, new Object()); // throws ArrayStoreException Then you will get an ArrayStoreException, because the underlying array is correctly typed. > ?The link with "more details" actually has fewer details than this > email. ?I don't see how you plan to make the change backward > compatible. ?Without something resembling a specification, it's hard > to evaluate further. Nothing is removed, the old syntax still works as before (except you get a deprecated warning when you use it), hence it is backward compatible. Howard. > > On Sat, Mar 14, 2009 at 6:41 PM, Howard Lovatt wrote: >> Neal Gafter has proposed replacing the current wildcard syntax with in >> and out instead of extends and super; an alternative to the current >> extends/super and Neal's proposal would be to deprecate the current >> wildcards and to change to the behaviour to that of arrays (covariant >> only). In particular to change the wildcard syntax to >> SomeClass for variables, arguments, or fields, class >> AClass for classes, and for methods >> where T is compulsory when declaring classes or methods but not used >> when declaring variables etc. (i.e. exactly like method arguments). >> This new syntax is similar in behaviour to the current syntax >> SomeClass (the difference is that the new >> does not issue a warning for covariant assignment). >> >> This proposal deprecates the concepts of SomeClass> SomeOtherClass>, SomeClass, and SomeClass in the >> current syntax. Generics are made covariant so that List lo = >> new ArrayList() is OK and does not issue a warning (like >> arrays). If "lo" form the previous example has an object added to it, >> lo.add( new Object() ), then if this produces an error or not is >> dependant on the class in question (in the case or ArrayList it >> wouldn't). See http://www.artima.com/weblogs/viewpost.jsp?thread=222021 >> for more detail. >> >> At the same time I propose cleaning up other pain points with >> generics, in particular: >> >> 1. Deprecate raw declarations, new ArrayList() becomes a deprecated >> warning - you need to say new ArrayList(). >> >> 2a. Deprecate self references, you get a deprecated warning for class >> Type>, you wouldn't use generics in this case. >> >> 2b. It follows that T> is an error in the new syntax, see >> next point for how you would do this. >> >> 3. Deprecate the ability to specify multiple bounds, e.g. instead of >> static > T max(Collection> extends T>) you write static T max(Collection) (note >> Comparable would not be parameterised with the new syntax since you >> would almost always want Comparable). >> >> 4. Allow arrays of parameterised types, List[] lsa = new >> ArrayList[10] is OK (you may get a runtime exception though if >> you misuse the feature). >> >> Examples of use of proposed new syntax are: >> >> boolean isAnnotationPresent( Class annotationClass ); // >> was: boolean isAnnotationPresent( Class >> annotationClass ); >> >> static createList( Collection coll ); // was: static >> createList( Collection coll ); >> >> static void sort( List list ); // was: static > extends Comparable> void sort( List list ); >> >> static Enum valueOf( Class enum, String name ); // was: static >> > T valueOf( Class enum, String name ); >> >> The disadvantage of this proposal is that you can now get the >> equivalent of ArrayStoreExceptions, the reason that this is acceptable >> is that ArrayStoreExceptions are rare (I have never had one). For >> compatibility the existing syntax would still be allowed, but would >> issue a deprecated warning. The reason that I am proposing deprecating >> wildcards is that they are not worth the trouble (they have a poor >> cost/benifit ratio - less is more). I know the language pedants will >> hate this proposal, but I think the vast majority of Java users would >> welcome this change. >> >> This proposal has some overlap with the proposal to infer generic >> types in that they both concern generic declarations, but are >> otherwise orthogonal. The collections library, in particular methods >> like sort (see above) and interfaces like Comparable, and enum class >> would need updating to the new syntax and this new library would have >> to be supplied as a module so that old code could use the old library >> (nt 100% compatible). >> >> So I am proposing eventually removing something from the language >> (actually replacing) - is removing a feature a first on coin-dev? >> >> > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From Joe.Darcy at Sun.COM Tue Mar 17 16:02:58 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 16:02:58 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <3dd3f56a0903171559s7bea7c05yb69631d0d9e4a18a@mail.gmail.com> References: <3dd3f56a0903141841g7b9ab134of5139d5a818621a0@mail.gmail.com> <15e8b9d20903142058r8c64243gc6fa1692911fa921@mail.gmail.com> <3dd3f56a0903171559s7bea7c05yb69631d0d9e4a18a@mail.gmail.com> Message-ID: <49C02C22.7010104@sun.com> Howard Lovatt wrote: > 2009/3/15 Neal Gafter : > >> My main concern is that this sounds like a significant change to the >> type system, and therefore almost certainly out of scope for project >> Coin. >> > > There is only one change to the type system; which is to allow > covariant assignment, e.g. List lo = new ArrayList(). > This isn't a drastic change, arrays already do this. This is in general *not* type safe. Arrays allow one to do this because array types are reified and there is a store-check at runtime when writing into an array. Since generics in Java are implemented via erasure, this implementation strategy is not possible for Lists and Sets, etc. -Joe From markmahieu at googlemail.com Tue Mar 17 16:02:54 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 17 Mar 2009 23:02:54 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <49C0203E.1090206@sun.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> <15e8b9d20903111411h1669ba4blcbc9ca239b7cd494@mail.gmail.com> <108fcdeb0903120932o1f689f65ob4df40322393b8ec@mail.gmail.com> <6aef848f0903121002g57b48225yc83d3c26cf099e38@mail.gmail.com> <49C0203E.1090206@sun.com> Message-ID: <047BEA00-0E3B-4429-91D0-16355EDB3F16@googlemail.com> On 17 Mar 2009, at 22:12, Joseph D. Darcy wrote: > In BigDecimal, the > same numerical value can have multiple representation, such as 100 * > 10^0 versus 10 * 10^1 versus 1 * 10^2. These are all "the same" under > (compareTo == 0) but are *not* .equals with each other, making > replacement of == with (compareTo == 0) conceptually problematic for > another reason than object equality. 10, 10.0, 10.00 not being equals() is the one that I keep seeing people get caught out by. Mark From howard.lovatt at iee.org Tue Mar 17 16:29:25 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 10:29:25 +1100 Subject: Proposal: Improved Wildcard Syntax for Java Message-ID: <3dd3f56a0903171629s528fcf91habde1bbac53ffc75@mail.gmail.com> Hi Joe, Emails overlapped, you sent me one whilst I was replying to you, hence second email. 2009/3/18 Joseph D. Darcy wrote: [snip] >> There is only one change to the type system; which is to allow >> covariant assignment, e.g. List lo = new ArrayList(). >> This isn't a drastic change, arrays already do this. > > This is in general *not* type safe. Arrays allow one to do this because > array types are reified and there is a store-check at runtime when writing > into an array. Since generics in Java are implemented via erasure, this > implementation strategy is not possible for Lists and Sets, etc. In the example I sent to Neal I showed how you can write a List that generates an ArrayStoreException, that still uses erasure, by using a factory (java.lang.reflect.Array.newInstance( ... )) to generate a correctly typed array. The underlying array generates the ArrayStoreException. Therefore it is possible to have generic covariant assignment, erasure, and runtime type safety simultaneously. Trying to catch this error, incorrect use of an aliased generic, in the type system isn't worth the trouble, arrays have a more useful behaviour. Note this proposed change will also remove the impedance mismatch between arrays and collections. From reinier at zwitserloot.com Tue Mar 17 17:00:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 01:00:07 +0100 Subject: PROPOSAL: Simplified Varargs Method Invocation (Round II) In-Reply-To: <49C02835.8070209@sun.com> References: <49C02835.8070209@sun.com> Message-ID: Joe, I'm a bit unclear about what is/isn't acceptable for coin. There's only one way for Simplified Varargs Method to result in heap corruption WITHOUT triggering at least 1 warning. That's the following case: varargs-accepting-method is compiled with javac5 or javac6, and code that calls that method is compiled with javac7. __however__, that situation has happened before! It is perfectly legal (no warnings, no errors) to write a method that takes a List (no generics) and adds a string to this list, if you compile it with javac4 (or javac5/6 with -source 1.4 -target 1.4). it is also perfectly legal (no warnings, no errors) to write a method that creates a List and then calls the method from the previously produced class file. You now have a string in a List, and 0 warnings. Oops. Entirely analogous to this proposal's situation, just across a different version boundary (1.6/1.7 instead of 1.4/1.5). So, given that precedent, allowed for coin, or not? I'd be very happy if this got fixed, because, frankly, varargs are almost useless in the current state. A fun trick to make printf work, not much more than that. I can't make a library that is **guaranteed** to produce warnings in client code, eventhough there is 0 chance anything could possibly go wrong. I work around it now by supplying each method in quadruplicate just to avoid the warnings: public void foo(T one) {} public void foo(T one, T two) {} public void foo(T one, T two, T three) {} public void foo(T one, T two, T three, T... rest) {} it's a valid workaround, but as far as workarounds go, this one is ridiculous. Not to mention it wreaks havoc on the javadoc and auto- complete. --Reinier Zwitserloot On Mar 17, 2009, at 23:46, Joseph D. Darcy wrote: > Bob Lee wrote: >> Simplified Varargs Method Invocation >> >> AUTHOR: Bob Lee >> >> OVERVIEW >> >> FEATURE SUMMARY: When a programmer tries to invoke a varargs >> (variable >> arity) method with a non-reifiable varargs type, the compiler >> currently >> generates an "unsafe operation" warning. This proposal moves the >> warning >> from the call site to the method declaration. >> > > The general contract when adding generics was "if your entire program > compiles without unchecked warnings, you won't get heap pollution at > runtime," heap pollution being where "a variable of parameterized type > refers to an object that is not of that parameterized type" (JLSv3 > 4.12.2.1). > > While warning at the declaration site is fine for a lint-style > warning, > the use sites merit warnings too because of heap pollution. > > Generics and arrays (including varags) simply do not play well > together! > > -Joe > > From reinier at zwitserloot.com Tue Mar 17 17:07:10 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 01:07:10 +0100 Subject: Return 'this' proposal In-Reply-To: <49C028BA.4090609@sun.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> Message-ID: Joe, What's the coin viability for a proposal that does NOT change the type system, but just introduces syntax sugar that translates: expression.setBar().setBaz(); to: TypeOfExpression $unique = expression; $unique.setBar(); $unique.setBaz(); where the setBar() method has a void return type, but has also been ktited out with a flag that indicates its legal for call sites to do the syntax sugar transformation above? The way this would work is very similar to varargs: The method with the 'varargs flag' really doesn't do anything special other than have a flag. It's the callers that do all the work. There are backwards compatibility issues, because most of the code that wants to 'return this' currently does not return void, it instead returns its own type, but I have one strategy for dealing with that issue that is simple and doesn't introduce any new keywords - basically, you get to add the flag to any method, and any callers will check if the type of the expression is tighter than the return type. If so, then the type of the returned value of the call is similarly tightened. In trade, setting the flag requires the java code to always "return this" for all return statements; anything else is an instant compiler error. The flag is set by adding 'this' as a keyword to the method's modifier section. This modifier is strictly inherited. So: public abstract class MyBuilder { public this MyBuilder setFoo(int foo) { return this; } } --Reinier Zwitserloot On Mar 17, 2009, at 23:48, Joseph D. Darcy wrote: > Marek Kozie? wrote: >> 2009/3/17 Joseph D. Darcy > >> >> >> This 'this' proposal remains vague and imprecise. >> >> Including this type/self type in a language is a continuing area >> of study; for example, see the recent paper >> >> "Matching ThisType to Subtyping," Chieri Saito and Atsushi >> Igarashi, Kyoto University, Japan, ACM SAC 2009. >> >> There are open bugs requesting this capability. For example typing >> "site:bugs.sun.com this type" into a popular >> search engine quickly yields, amongst other hits, >> >> 6479372 Add self types (type of 'this' aka ThisClass) to the >> language >> >> This bug discusses the size of the type system impact of this >> change, a magnitude far too large for Project Coin. >> >> There is no need to submit further refinements of this idea; any >> proposal along the lines of adding a this type will be out of >> scope for Project Coin. >> >> -Joe >> >> >> I'll check it, but I'm afraid that introducing 'This' type will be >> impossible for Java and for all other languages with Inheritance, >> or I >> would say it's possible but conditions would be huge. >> >> return 'this': >> - Idea is quite simple: you use object from left side of dot as >> returned from method, it's the same quite idea with converting void >> -> >> this, but allowed only when it's written directly. >> - Byte-code for that is other story and I'm not sure how much >> limitation this contains. >> >> >> Maybe you cold while what problems you see (that could help)? >> > > As the author and submitter of a proposal, it is your responsibility > to > research, understand, and explain the consequences and implications of > your proposal. > > -Joe > > From reinier at zwitserloot.com Tue Mar 17 17:27:33 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 01:27:33 +0100 Subject: PROPOSAL : Specify nullable argument In-Reply-To: <15e8b9d20903171341u17a6d056rbc0e2f726e778471@mail.gmail.com> References: <15e8b9d20903171341u17a6d056rbc0e2f726e778471@mail.gmail.com> Message-ID: <8E238A0B-E25A-415E-A5AB-D7110FBE689C@zwitserloot.com> Adding non-nullity to the type system would be a great boon, IMO, but its far more complicated than just having a @NonNull annotation. I've written up a proposal a while ago here: http://www.zwitserloot.com/2008/10/23/non-null-in-static-languages/ Suffice to say it gets very complicated because you need 4 nullity states (Never-Allows-Null, Definitely-Allows-Null, Might-Allow-Null, Legacy (like raw generics, for interop with old code), *AND* you need a separate process to promote or demote generics (So that you can say: Eventhough this is a Map that maps NonNull String to NonNull String, if you call get() on this, you get a @Nullable String back, because null will flow out if I can't find the key. In other words, the 'V' generics parameter needs to be demoted to @Nullable V somehow). Read the blog entry for a more elaborate explanation with examples. I'd love something like that in java, but the proposal as it stands needs a source 1.7; keyword (because having no modifier is taken as 'never null', which is obviously not backwards compatible), and is very complicated, so: Definitely not project coin material. Incidentally, I think jsr305 is fundamentally broken. It doesn't have the states needed to convey nullity info; it needs at least 2 annotations, probably 3 to be able to differentiate between code that simply didn't specify anything, and code that did, instead of the one annotation that jsr305 gives. --Reinier Zwitserloot On Mar 17, 2009, at 21:41, Neal Gafter wrote: > Did you intend this to be a complete proposal? > > Do you like this better than @NonNull, which will probably be included > in Java 7 under jsr 305? > > On Tue, Mar 17, 2009 at 1:25 PM, Olivier Chorier > wrote: >> Example : >> >> public void getListOfProducts(Company owner, !String facultativeName) >> { >> .... >> } >> >> The '!' should prevent the developper that the argument is able to >> be null. >> Invoking getListOfProducts(null, "name") could throw a compilation >> error/warning. >> >> Or maybe better : >> >> public void getListOfProducts(!Company owner, String facultativeName) >> { >> .... >> } >> >> Here, the '!' indicates a mandatory argument (not null). >> >> >> However, I don't know if the '!' marker could be the most >> appropriate. >> >> > From howard.lovatt at iee.org Tue Mar 17 17:54:56 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 11:54:56 +1100 Subject: Proposal: Improved Wildcard Syntax for Java Message-ID: <3dd3f56a0903171754h7845bc78waa3aca1c2401b704@mail.gmail.com> Hi Joe, Thanks for the response, answers in text. 2009/3/18 Joseph D. Darcy wrote: [snip] >> 1. Deprecate raw declarations, new ArrayList() becomes a deprecated >> warning - you need to say new ArrayList(). > That could be a fine lint option. You could also write an annotation > processor that used the javac tree API to generated such warnings/errors > today. Yes you could - but I think it would be better in the language so that every implementation gets this useful behaviour. >> 2a. Deprecate self references, you get a deprecated warning for class >> Type>, you wouldn't use generics in this case. > F-bounds are part of Java's generics. Yes. But I am suggesting that we deprecate it because no one likes it. The complication and confusion that it brings outweighs its benefit. Less is more. [snip] >> 3. Deprecate the ability to specify multiple bounds, e.g. instead of >> static > T max(Collection> extends T>) you write static T max(Collection) (note >> Comparable would not be parameterised with the new syntax since you >> would almost always want Comparable). > There are reasons why multiple bounds are supported. Yes. Again not worth the trouble - don't use generics in these backward compatibility cases. Typically you want Object - just use Object, no generics. Same argument as deprecating F-bounds, less is more. [snip] > If you want a proposal formally considered, you must fill out a proposal > form: > http://openjdk.java.net/projects/coin/#proposal_form Happy to do this if there is some support, not much point spending the time if it is just going to be rejected outright. By some support I don't mean a guarantee that it will make it into 7, but I do mean that people who have a vote in this process (you, who else?) think it is worth considering and within scope for coin. >> So I am proposing eventually removing something from the language >> (actually replacing) - is removing a feature a first on coin-dev? > However, the proposal form explicitly disallows removing features "The > proposal must not remove existing features of the language...". That was more a flippant comment at the end of the email, I am proposing deprecating features (warning issued) - not removing them. Cheers, Howard. From Jonathan.Gibbons at Sun.COM Tue Mar 17 18:31:34 2009 From: Jonathan.Gibbons at Sun.COM (Jonathan Gibbons) Date: Tue, 17 Mar 2009 18:31:34 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <3dd3f56a0903171754h7845bc78waa3aca1c2401b704@mail.gmail.com> References: <3dd3f56a0903171754h7845bc78waa3aca1c2401b704@mail.gmail.com> Message-ID: <49C04EF6.9060801@sun.com> With respect to (1), see -Xlint:raw. -- Jon Howard Lovatt wrote: > Hi Joe, > > Thanks for the response, answers in text. > > 2009/3/18 Joseph D. Darcy wrote: > > [snip] > > > > >>> 1. Deprecate raw declarations, new ArrayList() becomes a deprecated >>> warning - you need to say new ArrayList(). >>> > > > > > That could be a fine lint option. You could also write an annotation > > processor that used the javac tree API to generated such warnings/errors > > today. > > > > Yes you could - but I think it would be better in the language so that > every implementation gets this useful behaviour. > > > > >>> 2a. Deprecate self references, you get a deprecated warning for class >>> Type>, you wouldn't use generics in this case. >>> > > > > >> F-bounds are part of Java's generics. >> > > > > Yes. But I am suggesting that we deprecate it because no one likes it. > The complication and confusion that it brings outweighs its benefit. > Less is more. > > [snip] > > > > >>> 3. Deprecate the ability to specify multiple bounds, e.g. instead of >>> static > T max(Collection>> extends T>) you write static T max(Collection) (note >>> Comparable would not be parameterised with the new syntax since you >>> would almost always want Comparable). >>> > > > > > There are reasons why multiple bounds are supported. > > > > Yes. Again not worth the trouble - don't use generics in these > backward compatibility cases. Typically you want Object - just use > Object, no generics. Same argument as deprecating F-bounds, less is > more. > > [snip] > > > > >> If you want a proposal formally considered, you must fill out a proposal >> form: >> http://openjdk.java.net/projects/coin/#proposal_form >> > > > > Happy to do this if there is some support, not much point spending the > time if it is just going to be rejected outright. By some support I > don't mean a guarantee that it will make it into 7, but I do mean that > people who have a vote in this process (you, who else?) think it is > worth considering and within scope for coin. > > > > >>> So I am proposing eventually removing something from the language >>> (actually replacing) - is removing a feature a first on coin-dev? >>> > > > > > However, the proposal form explicitly disallows removing features "The > > proposal must not remove existing features of the language...". > > > > That was more a flippant comment at the end of the email, I am > proposing deprecating features (warning issued) - not removing them. > > Cheers, > > Howard. > > From reinier at zwitserloot.com Tue Mar 17 18:59:38 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 02:59:38 +0100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) Message-ID: Includes Joe D'Arcy's suggestions. An easier to read copy with markup is available at: http://tinyurl.com/static-methods-in-interfaces The text below is identical aside from the formatting: PROPOSAL: Static Methods in Interfaces VERSION This is version 1.1. The latest version can be found at http://tinyurl.com/static-methods-in-interfaces Changes from v1.0 to v1.1: Added links to bug reports on bugs.sun.com, expanded on alternatives, simplified reflective APIs, added note on javadoc. (via Joe D'Arcy). AUTHOR(S): Reinier Zwitserloot Roel Spilker OVERVIEW *FEATURE SUMMARY:* Static methods are now allowed in interfaces. The static method is defined with a method body in the interface and it exists in the namespace of the interface; it does not imply that implementing classes must implement the method. This feature is especially useful for utility methods that belong with a given interface. For example, many methods in java.util.Collections are specific for a particular interface, such as sort (java.util.List) and unmodifiableMap (java.util.Map). MAJOR ADVANTAGE: Allows maintaining code that 'goes together' in a single file, and helps auto-complete dialogs come up with more relevant operations on any given object. Also improves syntax by using a more specific term (e.g. List) instead of a usually somewhat generic grab bag utility class (e.g. Collections). Also allows interfaces to contain pseudo-constructor, for common tasks and default implementations (e.g. java.io.FileFilter could contain a method to create a new one based on a file extension). This proposal will also offer an easy solution to the current deplorable situation that you need to call on 2 separate utility classes, one of which has no relation to List whatsoever, just to create an immutable List: Collections.unmodifiableList(Arrays.asList(items)) can be replaced with the much more elegant List.of(items) MAJOR BENEFIT: Java (the language) is very strictly namespaced; the default package is discouraged and java does not allow dynamically adding or changing methods at runtime (so called monkey patching). Java also does not support mixins nor multiple inheritance. Therefore, the platform currently lacks a way to meaningfully offer utility methods for interfaces. Instead, kludges such as java.util.Collections exist as a vehicle for these support methods. Furthermore, static methods in interfaces are currently illegal (see JLS Chapter 9.4 ) so this proposed change does not complicate the language very much. MAJOR DISADVANTAGE: Confusion about the notion that static methods in java in java are not 'virtual' (they are not inherited and cannot be overridden) may cause a programmer to erroneously think a static method in an interface implies it is something an implementing class must implement. However, the mandatory method body should help avoid confusion. Slightly more complex language specification. No opportunity to use the static keyword in interfaces for some sort of /factory interface/ concept (an interface for constructors and static methods). The proposed implementation is also somewhat inconsistent in rare cases compared to static methods in classes. While this inconsistency is a disadvantage, the authors do not believe there's a way to avoid this inconsistency without creating more serious disadvantages ALTERNATIVES: The usual solution to this problem right now is to offer a separate utility class (a class that is not instantiable and contains only static methods) that contain the utility methods, along with a reference in the /javadoc/ of the interface to this utility class. For example, java.util.Collections is the utility class that goes with Map, List, Set and other Java Collections API interfaces. The use case of default / common implementations is currently handled by having an implementing class with a constructor. For example, a new class called java.io.ExtensionFileFilter could be made that takes a String and implements FileFilter. The sugar employed by this proposal is itself also an alternative: Creating a member type class that contains the static methods (With just a backwards and migration compatible API addition, you could make List.Utils.of(items) work in java 1.6 notation (The Utils class is an inner member type to the interface, which is legal, and as it is a class, may contain static methods. Another language change that can serve as an alternative is extension methods (the ability to lexically 'monkey patch' methods onto types, such as "import static java.util.Collections.sort into java.util.List;" EXAMPLES SIMPLE EXAMPLE: public interface Foo { public static void printHello() { System.out.println("Hello, World!"); } } Foo.printHello(); //Prints 'Hello, World! ADVANCED EXAMPLE: package java.util; public interface List extends Collection { int size(); // List's other instance methods public static List of(final T... items) { return new AbstractList() { public T get(int index) { return items[index]; } public int size() { return items.length; } }; } } List list = List.of("foo", "bar"); assert list.get(0).equals("foo"); assert list.size() == 2; DETAILS SPECIFICATION: Java Language Specification changes: JLS Chapter 9.1.4 : original: InterfaceMemberDeclaration: ConstantDeclaration AbstractMethodDeclaration ClassDeclaration InterfaceDeclaration ; replacement: InterfaceMemberDeclaration: ConstantDeclaration AbstractMethodDeclaration StaticMethodDeclaration ClassDeclaration InterfaceDeclaration ; JLS Chapter 9.4 : original: Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block. replacement: Every non-static method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block. original: Note that a method declarated in an interface must not be declared static, or a compile-time error occurs, because static methods cannot be abstract. replacement: None - this line is removed from the JLS. JLS Chapter 9.5 and 9.6 are bumped to 9.6 and 9.7, respectively, and a new 9.5 is added: ------------------------------------------------------------------------ 9.5 Static Method Declarations StaticMethodDeclaration: StaticMethodModifiers TypeParameters_opt ResultType MethodDeclarator Throws(opt) ; StaticMethodModifiers: static MethodModifiers static static MethodModifiers The MethodModifiers are described in 8.4.3 , The access modifier |public| is discussed in 6.6 . A compile-time error occurs if the same modifier appears more than once in an static method declaration. The static keyword is mandatory. Static method declarations in interfaces are either public or private; protected and package private are not allowed. If no access modifier is specified, the static method is implicitly public, to be consistent with the notion that everything else in an interface, be it a field, an abstract method, or a member type, is implicitly public. Private static methods are allowed to accommodate helper methods. Other than being limited to public and private access, a static interface method is identical to a method declaration in a class (8.4) . During compilation, all static methods are stored in a synthetic inner class called $Methods, which is generated with a private constructor. If that class already exists in the source file, a compile-time error occurs. ------------------------------------------------------------------------ JLS Chapter 15.12.1 : The specification of method invocation forms that invoke static methods are updated to refer to 'class or interface' instead of just 'class', and the following line: If /TypeName/ is the name of an interface rather than a class, then a compile-time error occurs, because this form can invoke only |static| methods and interfaces have no |static| methods. is replaced with: If /TypeName/ is the name of an interface rather than a class, then the call is presumed to be for a static method in a synthetic member class of the interface, called $Methods. If the method exists, the class to be searched is denoted by /TypeName.$Methods/ where /$Methods/ is a static inner class of the interface /TypeName/, literally called "$Methods". COMPILATION: Any interface with static methods is sugared by creating a member class called $Methods which will contain the static methods. The generated $Methods class should also have a private constructor, as they aren't supposed to be instantiable. If the $Methods inner class has been explicitly created in the source file, any static methods in the interface are considered a compile-time error (if the class is present in the source file, the assumption is that the programmer wants to keep manual control of the static methods). For method invocations, currently, an invocation of the form InterfaceName.method(), will result in an immediate compile error. The compiler will instead need to search the $Methods class (if any exists) for the method, and rewrite the call to InterfaceName.$Methods.method() if the method does exist in the $Methods inner class. The method is not inherited by any member types. So, the second 'hello()' call in the following example would result in a compile time error (method not found): public interface Foo { public static void hello() { System.out.println("Hello, World!"); } } public class Bar implements Foo {} Foo.hello(); //works Bar.hello(); //does not work This is an unfortunate inconsistency (if Foo was a class, Bar.hello() would work just fine), but there is no way to adequately recreate this inheritance system with syntax sugar. Even with a more thorough solution (that involves changing the JVM), allowing inheritance of the methods would mean allowing diamond relations (where 1 class implements 2 interfaces, that each have the same static method signature with different implementations. Which one is chosen?). This is principally the reason why this proposal suggests not letting the method be inherited. However, if inheritance is deemed important, the alternate solution is to fix the JVM Specification chapter 2.13 in similar ways as the JLS, and make static methods legal in interfaces. The Type.method() invocation would then require a much broader search and should give up with a compile-time error if a diamond relation is found, listing the conflicting implementations and asking the programmer to choose one. As this proposal breaks the norm on inheritance already, the following syntax is not allowed either, which for static methods in classes *is* currently legal but flagged as a warning in all popular IDEs and code style checkers: Character c = 'f'; c.isWhiteSpace(' '); //if Character was an interface, this would not be legal. TESTING: This new feature can be tested by applying the existing tests for static method calls to static methods in interfaces. Compilation and class file parsing needs to be expanded to apply tests to read method bodies in interfaces as well as classes. "Finding" the static method inside the $Methods inner class during compilation needs to be tested, which is straight forward. The changes described below to the reflective APIs also need testing, which is also straight forward. LIBRARY SUPPORT: No library support is needed. However, it would be advisable to update various interfaces in the core java APIs with useful static utility methods. Some examples: * java.util.List/Map/Set: All methods in java.util.Collections should also be made available on the appropriate java collections API interface. * java.io.Closeable: should contain a utility method 'closeAndIgnoreException' (arguably better suited on InputStream instead). * java.util.List/Set: Should contain an 'of' method that makes unmodifiable lists and sets via varargs. * java.io.FileFilter: Should contain an 'ofExtension(String)' method that creates a FileFilter for the provided extension. REFLECTIVE APIS: Currently, synthetic members are not treated specially by the reflection API. Therefore, this proposal does not require any reflective API changes. Attempting to use reflection to access these methods requires you to access them via the generated $Methods member. Asking for such a method's parent class would return the $Methods class, not the interface. OTHER CHANGES: The javadoc tool will need a minor change: It will need to produce a new section on static methods for interfaces, if they exist. (Unlike reflection, javadoc should abstract away the inner $Methods class). Fortunately, this code already exists for printing static methods in normal classes. MIGRATION: No migration is needed. However, any java projects that currently employ utility classes (defined as having a private constructor that is not called anywhere in scope) which either return interface types, or take as first parameter an interface type, or both, where all previously mentioned interfaces are in the same package, are likely candidates for moving or copying to the relevant interface. Thus, IDEs can offer refactor advice to perform this task automatically and to find likely candidates. Such a refactor tool would for example identify all methods in java.util.Collections. COMPATIBILITY BREAKING CHANGES: Existing source that already uses an inner type named $Methods in an interface will change semantics when this proposal is implemented, primarily when queried via reflection. Between the vanishingly small odds of both a $Methods already existing and its methods being queried by the reflection API, and the general rule that $ should only be used in type names by compilers, the potential breaking change is hardly worth mentioning. EXISTING PROGRAMS: Existing programs are not affected by this change, other than as described above in the 'breaking changes' section. REFERENCES EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093687 (Main RFE) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4291381 (Duplicate) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4491759 (Duplicate) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4306573 (Duplicate) URL FOR PROTOTYPE (optional): None. From neal at gafter.com Tue Mar 17 19:05:55 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 17 Mar 2009 19:05:55 -0700 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: References: Message-ID: <15e8b9d20903171905v4315c4ecm74ae1a056429491a@mail.gmail.com> Experience with extension methods have shown them to be a powerful and more flexible alternative to this. I believe extension methods are also simpler. If there is enough interest I could write it up. On Tue, Mar 17, 2009 at 6:59 PM, Reinier Zwitserloot wrote: > Includes Joe D'Arcy's suggestions. An easier to read copy with markup > is available at: > > ? ? http://tinyurl.com/static-methods-in-interfaces > > > The text below is identical aside from the formatting: > > > ? PROPOSAL: Static Methods in Interfaces > > > ? ? VERSION > > ? ? This is version 1.1. > ? ? The latest version can be found at > ? ? http://tinyurl.com/static-methods-in-interfaces > > > ? ? Changes from v1.0 to v1.1: Added links to bug reports on > ? ? bugs.sun.com, expanded on alternatives, simplified reflective APIs, > ? ? added note on javadoc. (via Joe D'Arcy). > > > ? ? AUTHOR(S): > > ? ? Reinier Zwitserloot > ? ? Roel Spilker > > > ? ? OVERVIEW > > ? ? *FEATURE SUMMARY:* > > > ? ? ? ? Static methods are now allowed in interfaces. The static method > ? ? ? ? is defined with a method body in the interface and it exists in > ? ? ? ? the namespace of the interface; it does not imply that > ? ? ? ? implementing classes must implement the method. This feature is > ? ? ? ? especially useful for utility methods that belong with a given > ? ? ? ? interface. For example, many methods in java.util.Collections > ? ? ? ? are specific for a particular interface, such as sort > ? ? ? ? (java.util.List) and unmodifiableMap (java.util.Map). > > > ? ? ? ? MAJOR ADVANTAGE: > > ? ? ? ? Allows maintaining code that 'goes together' in a single file, > ? ? ? ? and helps auto-complete dialogs come up with more relevant > ? ? ? ? operations on any given object. Also improves syntax by using a > ? ? ? ? more specific term (e.g. List) instead of a usually somewhat > ? ? ? ? generic grab bag utility class (e.g. Collections). Also allows > ? ? ? ? interfaces to contain pseudo-constructor, for common tasks and > ? ? ? ? default implementations (e.g. java.io.FileFilter could > contain a > ? ? ? ? method to create a new one based on a file extension). This > ? ? ? ? proposal will also offer an easy solution to the current > ? ? ? ? deplorable situation that you need to call on 2 separate > utility > ? ? ? ? classes, one of which has no relation to List whatsoever, just > ? ? ? ? to create an immutable List: > ? ? ? ? Collections.unmodifiableList(Arrays.asList(items)) can be > ? ? ? ? replaced with the much more elegant List.of(items) > > > ? ? ? ? MAJOR BENEFIT: > > ? ? ? ? Java (the language) is very strictly namespaced; the default > ? ? ? ? package is discouraged and java does not allow dynamically > ? ? ? ? adding or changing methods at runtime (so called monkey > ? ? ? ? patching). Java also does not support mixins nor multiple > ? ? ? ? inheritance. Therefore, the platform currently lacks a way to > ? ? ? ? meaningfully offer utility methods for interfaces. Instead, > ? ? ? ? kludges such as java.util.Collections exist as a vehicle for > ? ? ? ? these support methods. Furthermore, static methods in > interfaces > ? ? ? ? are currently illegal (see JLS Chapter 9.4 > ? ? ? ? ?>) > ? ? ? ? so this proposed change does not complicate the language very > much. > > > ? ? ? ? MAJOR DISADVANTAGE: > > ? ? ? ? Confusion about the notion that static methods in java in java > ? ? ? ? are not 'virtual' (they are not inherited and cannot be > ? ? ? ? overridden) may cause a programmer to erroneously think a > static > ? ? ? ? method in an interface implies it is something an implementing > ? ? ? ? class must implement. However, the mandatory method body should > ? ? ? ? help avoid confusion. Slightly more complex language > ? ? ? ? specification. No opportunity to use the static keyword in > ? ? ? ? interfaces for some sort of /factory interface/ concept (an > ? ? ? ? interface for constructors and static methods). The proposed > ? ? ? ? implementation is also somewhat inconsistent in rare cases > ? ? ? ? compared to static methods in classes. While this inconsistency > ? ? ? ? is a disadvantage, the authors do not believe there's a way to > ? ? ? ? avoid this inconsistency without creating more serious > disadvantages > > ? ? ? ? ALTERNATIVES: > > ? ? ? ? The usual solution to this problem right now is to offer a > ? ? ? ? separate utility class (a class that is not instantiable and > ? ? ? ? contains only static methods) that contain the utility methods, > ? ? ? ? along with a reference in the /javadoc/ of the interface to > this > ? ? ? ? utility class. For example, java.util.Collections is the > utility > ? ? ? ? class that goes with Map, List, Set and other Java Collections > ? ? ? ? API interfaces. The use case of default / common > implementations > ? ? ? ? is currently handled by having an implementing class with a > ? ? ? ? constructor. For example, a new class called > ? ? ? ? java.io.ExtensionFileFilter could be made that takes a String > ? ? ? ? and implements FileFilter. The sugar employed by this proposal > ? ? ? ? is itself also an alternative: Creating a member type class > that > ? ? ? ? contains the static methods (With just a backwards and > migration > ? ? ? ? compatible API addition, you could make List.Utils.of(items) > ? ? ? ? work in java 1.6 notation (The Utils class is an inner member > ? ? ? ? type to the interface, which is legal, and as it is a class, > may > ? ? ? ? contain static methods. > > ? ? ? ? Another language change that can serve as an alternative is > ? ? ? ? extension methods (the ability to lexically 'monkey patch' > ? ? ? ? methods onto types, such as "import static > ? ? ? ? java.util.Collections.sort into java.util.List;" > > > ? ? EXAMPLES > > > ? ? ?SIMPLE EXAMPLE: > > ? ? ? ? public interface Foo { > ? ? ? ? ? ? public static void printHello() { > ? ? ? ? ? ? ? ? System.out.println("Hello, World!"); > ? ? ? ? ? ? } > ? ? ? ? } > > ? ? ? ? Foo.printHello(); ?//Prints 'Hello, World! > > > ? ? ? ADVANCED EXAMPLE: > > ? ? ? ? package java.util; > > ? ? ? ? public interface List extends Collection { > ? ? ? ? ? ? int size(); > ? ? ? ? ? ? // List's other instance methods > > ? ? ? ? ? ? public static List of(final T... items) { > ? ? ? ? ? ? ? ? return new AbstractList() { > ? ? ? ? ? ? ? ? ? ? public T get(int index) { > ? ? ? ? ? ? ? ? ? ? ? ? return items[index]; > ? ? ? ? ? ? ? ? ? ? } > > ? ? ? ? ? ? ? ? ? ? public int size() { > ? ? ? ? ? ? ? ? ? ? ? ? return items.length; > ? ? ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? ? ? }; > ? ? ? ? ? ? } > ? ? ? ? } > > ? ? ? ? List list = List.of("foo", "bar"); > ? ? ? ? assert list.get(0).equals("foo"); > ? ? ? ? assert list.size() == 2; > > > ? ? DETAILS > > ? ? ?SPECIFICATION: > > ? ? ? ? Java Language Specification changes: > > ? ? ? ? JLS Chapter 9.1.4 > ? ? ? ? ?>: > ? ? ? ? original: > > ? ? ? ? InterfaceMemberDeclaration: > ? ? ? ? ? ? ? ?ConstantDeclaration > ? ? ? ? ? ? ? ?AbstractMethodDeclaration > ? ? ? ? ? ? ? ?ClassDeclaration > ? ? ? ? ? ? ? ?InterfaceDeclaration > ? ? ? ? ? ? ? ?; > > ? ? ? ? replacement: > > ? ? ? ? InterfaceMemberDeclaration: > ? ? ? ? ? ? ? ?ConstantDeclaration > ? ? ? ? ? ? ? ?AbstractMethodDeclaration > ? ? ? ? ? ? ? ?StaticMethodDeclaration > ? ? ? ? ? ? ? ?ClassDeclaration > ? ? ? ? ? ? ? ?InterfaceDeclaration > ? ? ? ? ? ? ? ?; > > > ? ? ? ? JLS Chapter 9.4 > ? ? ? ? ?>: > ? ? ? ? original: > > ? ? ? ? ? ? Every method declaration in the body of an interface is > ? ? ? ? ? ? implicitly abstract, so its body is always represented by a > ? ? ? ? ? ? semicolon, not a block. > > ? ? ? ? replacement: > > ? ? ? ? ? ? Every non-static method declaration in the body of an > ? ? ? ? ? ? interface is implicitly abstract, so its body is always > ? ? ? ? ? ? represented by a semicolon, not a block. > > ? ? ? ? original: > > ? ? ? ? ? ? Note that a method declarated in an interface must not be > ? ? ? ? ? ? declared static, or a compile-time error occurs, because > ? ? ? ? ? ? static methods cannot be abstract. > > ? ? ? ? replacement: > > ? ? ? ? ? ? None - this line is removed from the JLS. > > > ? ? ? ? JLS Chapter 9.5 > ? ? ? ? ?> and > ? ? ? ? 9.6 > ? ? ? ? ?> > ? ? ? ? are bumped to 9.6 and 9.7, respectively, and a new 9.5 is > added: > > ------------------------------------------------------------------------ > > > ? ? ? ? ? ? 9.5 Static Method Declarations > > ? ? ? ? ? ? StaticMethodDeclaration: > ? ? ? ? ? ? ?StaticMethodModifiers TypeParameters_opt ?ResultType > ? ? ? ? ? ? MethodDeclarator Throws(opt) ?; > > ? ? ? ? ? ? StaticMethodModifiers: > ? ? ? ? ? ? ?static > ? ? ? ? ? ? ?MethodModifiers static > ? ? ? ? ? ? ?static MethodModifiers > > ? ? ? ? The MethodModifiers are described in 8.4.3 > ? ? ? ? ?>, > ? ? ? ? The access modifier |public| is discussed in 6.6 > ? ? ? ? ?>. > ? ? ? ? A compile-time error occurs if the same modifier appears more > ? ? ? ? than once in an static method declaration. The static keyword > is > ? ? ? ? mandatory. > > > ? ? ? ? ? ? Static method declarations in interfaces are either public > ? ? ? ? ? ? or private; protected and package private are not allowed. > ? ? ? ? ? ? If no access modifier is specified, the static method is > ? ? ? ? ? ? implicitly public, to be consistent with the notion that > ? ? ? ? ? ? everything else in an interface, be it a field, an abstract > ? ? ? ? ? ? method, or a member type, is implicitly public. Private > ? ? ? ? ? ? static methods are allowed to accommodate helper > ? ? ? ? ? ? methods. Other than being limited to public and private > ? ? ? ? ? ? access, a static interface method is identical to a method > ? ? ? ? ? ? declaration in a class (8.4) > ? ? ? ? ? ? ?>. > ? ? ? ? ? ? During compilation, all static methods are stored in a > ? ? ? ? ? ? synthetic inner class called $Methods, which is generated > ? ? ? ? ? ? with a private constructor. If that class already exists in > ? ? ? ? ? ? the source file, a compile-time error occurs. > > > ------------------------------------------------------------------------ > > ? ? ? ? JLS Chapter 15.12.1 > ? ? ? ? ?>: > > ? ? ? ? The specification of method invocation forms that invoke static > ? ? ? ? methods are updated to refer to 'class or interface' instead of > ? ? ? ? just 'class', and the following line: > > ? ? ? ? ? ? If /TypeName/ is the name of an interface rather than a > ? ? ? ? ? ? class, then a compile-time error occurs, because this form > ? ? ? ? ? ? can invoke only |static| methods and interfaces have > ? ? ? ? ? ? no |static| methods. > > > ? ? ? ? is replaced with: > > ? ? ? ? ? ? If /TypeName/ is the name of an interface rather than a > ? ? ? ? ? ? class, then the call is presumed to be for a static method > ? ? ? ? ? ? in a synthetic member class of the interface, called > ? ? ? ? ? ? $Methods. If the method exists, the class to be searched is > ? ? ? ? ? ? denoted by /TypeName.$Methods/ where /$Methods/ is a static > ? ? ? ? ? ? inner class of the interface /TypeName/, literally called > ? ? ? ? ? ? "$Methods". > > > ? ? COMPILATION: > > ? ? ? ? Any interface with static methods is sugared by creating a > ? ? ? ? member class called $Methods which will contain the static > ? ? ? ? methods. The generated $Methods class should also have a > private > ? ? ? ? constructor, as they aren't supposed to be instantiable. If the > ? ? ? ? $Methods inner class has been explicitly created in the source > ? ? ? ? file, any static methods in the interface are considered a > ? ? ? ? compile-time error (if the class is present in the source file, > ? ? ? ? the assumption is that the programmer wants to keep manual > ? ? ? ? control of the static methods). For method invocations, > ? ? ? ? currently, an invocation of the form InterfaceName.method(), > ? ? ? ? will result in an immediate compile error. The compiler will > ? ? ? ? instead need to search the $Methods class (if any exists) for > ? ? ? ? the method, and rewrite the call to > ? ? ? ? InterfaceName.$Methods.method() if the method does exist in the > ? ? ? ? $Methods inner class. > > ? ? ? ? The method is not inherited by any member types. So, the second > ? ? ? ? 'hello()' call in the following example would result in a > ? ? ? ? compile time error (method not found): > > ? ? ? ? ? ? public interface Foo { > ? ? ? ? ? ? ? ? public static void hello() { > ? ? ? ? ? ? ? ? ? ? System.out.println("Hello, World!"); > ? ? ? ? ? ? ? ? } > ? ? ? ? ? ? } > > ? ? ? ? ? ? public class Bar implements Foo {} > > ? ? ? ? ? ? Foo.hello(); //works > ? ? ? ? ? ? Bar.hello(); //does not work > > > ? ? ? ? This is an unfortunate inconsistency (if Foo was a class, > ? ? ? ? Bar.hello() would work just fine), but there is no way to > ? ? ? ? adequately recreate this inheritance system with syntax sugar. > ? ? ? ? Even with a more thorough solution (that involves changing the > ? ? ? ? JVM), allowing inheritance of the methods would mean allowing > ? ? ? ? diamond relations (where 1 class implements 2 interfaces, that > ? ? ? ? each have the same static method signature with different > ? ? ? ? implementations. Which one is chosen?). This is principally the > ? ? ? ? reason why this proposal suggests not letting the method be > ? ? ? ? inherited. However, if inheritance is deemed important, the > ? ? ? ? alternate solution is to fix the JVM Specification chapter 2.13 > ? ? ? ? ?> in > ? ? ? ? similar ways as the JLS, and make static methods legal in > ? ? ? ? interfaces. The Type.method() invocation would then require a > ? ? ? ? much broader search and should give up with a compile-time > error > ? ? ? ? if a diamond relation is found, listing the conflicting > ? ? ? ? implementations and asking the programmer to choose one. > > ? ? ? ? As this proposal breaks the norm on inheritance already, the > ? ? ? ? following syntax is not allowed either, which for static > methods > ? ? ? ? in classes *is* currently legal but flagged as a warning in all > ? ? ? ? popular IDEs and code style checkers: > > ? ? ? ? ? ? Character c = 'f'; > ? ? ? ? ? ? c.isWhiteSpace(' '); //if Character was an interface, this > ? ? ? ? ? ? would not be legal. > > > > ? ? TESTING: > > ? ? ? ? This new feature can be tested by applying the existing tests > ? ? ? ? for static method calls to static methods in interfaces. > ? ? ? ? Compilation and class file parsing needs to be expanded to > apply > ? ? ? ? tests to read method bodies in interfaces as well as classes. > ? ? ? ? "Finding" the static method inside the $Methods inner class > ? ? ? ? during compilation needs to be tested, which is straight > ? ? ? ? forward. The changes described below to the reflective APIs > also > ? ? ? ? need testing, which is also straight forward. > > > ? ? LIBRARY SUPPORT: > > ? ? ? ? No library support is needed. However, it would be advisable to > ? ? ? ? update various interfaces in the core java APIs with useful > ? ? ? ? static utility methods. Some examples: > > ? ? ? ? ? ? * java.util.List/Map/Set: All methods in > ? ? ? ? ? ? ? java.util.Collections should also be made available on > the > ? ? ? ? ? ? ? appropriate java collections API interface. > ? ? ? ? ? ? * java.io.Closeable: should contain a utility method > ? ? ? ? ? ? ? 'closeAndIgnoreException' (arguably better suited on > ? ? ? ? ? ? ? InputStream instead). > ? ? ? ? ? ? * java.util.List/Set: Should contain an 'of' method that > ? ? ? ? ? ? ? makes unmodifiable lists and sets via varargs. > ? ? ? ? ? ? * java.io.FileFilter: Should contain an > ? ? ? ? ? ? ? 'ofExtension(String)' method that creates a FileFilter > for > ? ? ? ? ? ? ? the provided extension. > > > ? ? REFLECTIVE APIS: > > ? ? ? ? Currently, synthetic members are not treated specially by the > ? ? ? ? reflection API. Therefore, this proposal does not require any > ? ? ? ? reflective API changes. Attempting to use reflection to access > ? ? ? ? these methods requires you to access them via the generated > ? ? ? ? $Methods member. Asking for such a method's parent class would > ? ? ? ? return the $Methods class, not the interface. > > > ? ? OTHER CHANGES: > > ? ? ? ? The javadoc tool will need a minor change: It will need to > ? ? ? ? produce a new section on static methods for interfaces, if they > ? ? ? ? exist. (Unlike reflection, javadoc should abstract away the > ? ? ? ? inner $Methods class). Fortunately, this code already exists > for > ? ? ? ? printing static methods in normal classes. > > > ? ? MIGRATION: > > ? ? ? ? No migration is needed. However, any java projects that > ? ? ? ? currently employ utility classes (defined as having a private > ? ? ? ? constructor that is not called anywhere in scope) which either > ? ? ? ? return interface types, or take as first parameter an interface > ? ? ? ? type, or both, where all previously mentioned interfaces are in > ? ? ? ? the same package, are likely candidates for moving or copying > to > ? ? ? ? the relevant interface. Thus, IDEs can offer refactor advice to > ? ? ? ? perform this task automatically and to find likely candidates. > ? ? ? ? Such a refactor tool would for example identify all methods in > ? ? ? ? java.util.Collections. > > > ? ? COMPATIBILITY > > ? ? BREAKING CHANGES: > > ? ? ? ? Existing source that already uses an inner type named $Methods > ? ? ? ? in an interface will change semantics when this proposal is > ? ? ? ? implemented, primarily when queried via reflection. Between the > ? ? ? ? vanishingly small odds of both a $Methods already existing and > ? ? ? ? its methods being queried by the reflection API, and the > general > ? ? ? ? rule that $ should only be used in type names by compilers, the > ? ? ? ? potential breaking change is hardly worth mentioning. > > > ? ? EXISTING PROGRAMS: > > ? ? ? ? Existing programs are not affected by this change, other than > as > ? ? ? ? described above in the 'breaking changes' section. > > > ? ? REFERENCES > > ? ? EXISTING BUGS: > > ? ? ? ? http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093687 > (Main RFE) > ? ? ? ? http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4291381 > ? ? ? ? (Duplicate) > ? ? ? ? http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4491759 > ? ? ? ? (Duplicate) > ? ? ? ? http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4306573 > ? ? ? ? (Duplicate) > > > ? ? URL FOR PROTOTYPE (optional): > > ? ? ? ? None. > > > > > From david at walend.net Tue Mar 17 19:35:56 2009 From: david at walend.net (David Walend) Date: Tue, 17 Mar 2009 22:35:56 -0400 Subject: Proposal: Access to Generic Type Parameters at Compile-Time In-Reply-To: <3BA402DB-7828-42EF-A443-0A7A4ECEE052@googlemail.com> References: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> <3BA402DB-7828-42EF-A443-0A7A4ECEE052@googlemail.com> Message-ID: <34BE7C25-01CA-4D83-BB66-139C86BF79D5@walend.net> Hi Mark, On Mar 17, 2009, at 12:22 PM, Mark Mahieu wrote: > Hi David, > > On 17 Mar 2009, at 02:37, David Walend wrote: >> >> interface Path >> extends Digraph >> { >> ThruGraph.Node getHead(); >> ... >> } > > So, if I were the author of Digraph and I decided to rename its type > parameters (to N and E for example), your Path interface would no > longer compile? That's correct. Changing the name of a type parameter would have the same potential impact as renaming other public/protected/default- accessible parts of the class, like an inner class, a static method or a static member field. Changing an extends or super clause risks breaking something. Adding or removing type parameters almost always breaks downstream code that uses the class. The name of the type parameter is (I think) the only thing you can safely change in the parameter list currently. I think this problem would come up far less often than breaking the interface by adding an extends or super clause to an existing parameter. Is it a big enough problem to add to the disadvantages list? Thanks, Dave David Walend david at walend.net From jeremy.manson at gmail.com Tue Mar 17 19:48:19 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 17 Mar 2009 19:48:19 -0700 Subject: Return 'this' proposal In-Reply-To: References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> Message-ID: <1631da7d0903171948k4a7275bdw42a36d2a726d88f2@mail.gmail.com> Hey Reinier, I'm unclear on how that doesn't change the type system. That is, you've described an implementation technique that doesn't require a change to bytecode (which is nice), but doesn't it still change Java-the-language's type system? Jeremy On Tue, Mar 17, 2009 at 5:07 PM, Reinier Zwitserloot wrote: > Joe, > > What's the coin viability for a proposal that does NOT change the type > system, but just introduces syntax sugar that translates: > > expression.setBar().setBaz(); > > to: > > TypeOfExpression $unique = expression; > $unique.setBar(); > $unique.setBaz(); > > > where the setBar() method has a void return type, but has also been > ktited out with a flag that indicates its legal for call sites to do > the syntax sugar transformation above? The way this would work is very > similar to varargs: The method with the 'varargs flag' really doesn't > do anything special other than have a flag. It's the callers that do > all the work. > > > There are backwards compatibility issues, because most of the code > that wants to 'return this' currently does not return void, it instead > returns its own type, but I have one strategy for dealing with that > issue that is simple and doesn't introduce any new keywords - > basically, you get to add the flag to any method, and any callers will > check if the type of the expression is tighter than the return type. > If so, then the type of the returned value of the call is similarly > tightened. In trade, setting the flag requires the java code to always > "return this" for all return statements; anything else is an instant > compiler error. The flag is set by adding 'this' as a keyword to the > method's modifier section. This modifier is strictly inherited. So: > > public abstract class MyBuilder { > ? ? public this MyBuilder setFoo(int foo) { > ? ? ? ? return this; > ? ? } > } > > > > ?--Reinier Zwitserloot > > > > On Mar 17, 2009, at 23:48, Joseph D. Darcy wrote: > >> Marek Kozie? wrote: >>> 2009/3/17 Joseph D. Darcy >> >> >>> >>> ? ?This 'this' proposal remains vague and imprecise. >>> >>> ? ?Including this type/self type in a language is a continuing area >>> ? ?of study; for example, see the recent paper >>> >>> ? ?"Matching ThisType to Subtyping," Chieri Saito and Atsushi >>> ? ?Igarashi, Kyoto University, Japan, ACM SAC 2009. >>> >>> ? ?There are open bugs requesting this capability. For example typing >>> ? ?"site:bugs.sun.com this type" into a popular >>> ? ?search engine quickly yields, amongst other hits, >>> >>> ? ?6479372 Add self types (type of 'this' aka ThisClass) to the >>> language >>> >>> ? ?This bug discusses the size of the type system impact of this >>> ? ?change, a magnitude far too large for Project Coin. >>> >>> ? ?There is no need to submit further refinements of this idea; any >>> ? ?proposal along the lines of adding a this type will be out of >>> ? ?scope for Project Coin. >>> >>> ? ?-Joe >>> >>> >>> I'll check it, but I'm afraid that introducing 'This' type will be >>> impossible for Java and for all other languages with Inheritance, >>> or I >>> would say it's possible but conditions would be huge. >>> >>> return 'this': >>> - Idea is quite simple: you use object from left side of dot as >>> returned from method, it's the same quite idea with converting void >>> -> >>> this, but allowed only when it's written directly. >>> - Byte-code for that is other story and I'm not sure how much >>> limitation this contains. >>> >>> >>> Maybe you cold while what problems you see (that could help)? >>> >> >> As the author and submitter of a proposal, it is your responsibility >> to >> research, understand, and explain the consequences and implications of >> your proposal. >> >> -Joe >> >> > > > From jeremy.manson at gmail.com Tue Mar 17 19:49:52 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 17 Mar 2009 19:49:52 -0700 Subject: PROPOSAL : Specify nullable argument In-Reply-To: <8E238A0B-E25A-415E-A5AB-D7110FBE689C@zwitserloot.com> References: <15e8b9d20903171341u17a6d056rbc0e2f726e778471@mail.gmail.com> <8E238A0B-E25A-415E-A5AB-D7110FBE689C@zwitserloot.com> Message-ID: <1631da7d0903171949u65b794dfx6e105dab03619a49@mail.gmail.com> I don't know what the current state of the 305 proposal is, but Bill has been talking about at least three annotations in informal conversations. Jeremy On Tue, Mar 17, 2009 at 5:27 PM, Reinier Zwitserloot wrote: > Adding non-nullity to the type system would be a great boon, IMO, but > its far more complicated than just having a @NonNull annotation. > > I've written up a proposal a while ago here: http://www.zwitserloot.com/2008/10/23/non-null-in-static-languages/ > > Suffice to say it gets very complicated because you need 4 nullity > states (Never-Allows-Null, Definitely-Allows-Null, Might-Allow-Null, > Legacy (like raw generics, for interop with old code), *AND* you need > a separate process to promote or demote generics (So that you can say: > Eventhough this is a Map that maps NonNull String to NonNull String, > if you call get() on this, you get a @Nullable String back, because > null will flow out if I can't find the key. In other words, the 'V' > generics parameter needs to be demoted to @Nullable V somehow). > > Read the blog entry for a more elaborate explanation with examples. > > I'd love something like that in java, but the proposal as it stands > needs a source 1.7; keyword (because having no modifier is taken as > 'never null', which is obviously not backwards compatible), and is > very complicated, so: Definitely not project coin material. > > Incidentally, I think jsr305 is fundamentally broken. It doesn't have > the states needed to convey nullity info; it needs at least 2 > annotations, probably 3 to be able to differentiate between code that > simply didn't specify anything, and code that did, instead of the one > annotation that jsr305 gives. > > ?--Reinier Zwitserloot > > > > On Mar 17, 2009, at 21:41, Neal Gafter wrote: > >> Did you intend this to be a complete proposal? >> >> Do you like this better than @NonNull, which will probably be included >> in Java 7 under jsr 305? >> >> On Tue, Mar 17, 2009 at 1:25 PM, Olivier Chorier >> wrote: >>> Example : >>> >>> public void getListOfProducts(Company owner, !String facultativeName) >>> { >>> .... >>> } >>> >>> The '!' should prevent the developper that the argument is able to >>> be null. >>> Invoking getListOfProducts(null, "name") could throw a compilation >>> error/warning. >>> >>> Or maybe better : >>> >>> public void getListOfProducts(!Company owner, String facultativeName) >>> { >>> .... >>> } >>> >>> Here, the '!' indicates a mandatory argument (not null). >>> >>> >>> However, I don't know if the '!' marker could be the most >>> appropriate. >>> >>> >> > > > From reinier at zwitserloot.com Tue Mar 17 19:57:31 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 03:57:31 +0100 Subject: Return 'this' proposal In-Reply-To: <1631da7d0903171948k4a7275bdw42a36d2a726d88f2@mail.gmail.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> <1631da7d0903171948k4a7275bdw42a36d2a726d88f2@mail.gmail.com> Message-ID: <5E94921F-D350-4DFA-8C29-2493BC9A186A@zwitserloot.com> I don't think so. This: (foo.setBar()).setBaz(); does not translate to: Take whatever type rolls out of the setBar() call, and call the 'setBaz()' method on that type. It instead translates to: run foo.setBar(). Then run foo.setBaz(). The type returned by the setBar() method *IS* void. This is just syntax sugar. --Reinier Zwitserloot On Mar 18, 2009, at 03:48, Jeremy Manson wrote: > Hey Reinier, > > I'm unclear on how that doesn't change the type system. That is, > you've described an implementation technique that doesn't require a > change to bytecode (which is nice), but doesn't it still change > Java-the-language's type system? > > Jeremy > > On Tue, Mar 17, 2009 at 5:07 PM, Reinier Zwitserloot > wrote: >> Joe, >> >> What's the coin viability for a proposal that does NOT change the >> type >> system, but just introduces syntax sugar that translates: >> >> expression.setBar().setBaz(); >> >> to: >> >> TypeOfExpression $unique = expression; >> $unique.setBar(); >> $unique.setBaz(); >> >> >> where the setBar() method has a void return type, but has also been >> ktited out with a flag that indicates its legal for call sites to do >> the syntax sugar transformation above? The way this would work is >> very >> similar to varargs: The method with the 'varargs flag' really doesn't >> do anything special other than have a flag. It's the callers that do >> all the work. >> >> >> There are backwards compatibility issues, because most of the code >> that wants to 'return this' currently does not return void, it >> instead >> returns its own type, but I have one strategy for dealing with that >> issue that is simple and doesn't introduce any new keywords - >> basically, you get to add the flag to any method, and any callers >> will >> check if the type of the expression is tighter than the return type. >> If so, then the type of the returned value of the call is similarly >> tightened. In trade, setting the flag requires the java code to >> always >> "return this" for all return statements; anything else is an instant >> compiler error. The flag is set by adding 'this' as a keyword to the >> method's modifier section. This modifier is strictly inherited. So: >> >> public abstract class MyBuilder { >> public this MyBuilder setFoo(int foo) { >> return this; >> } >> } >> >> >> >> --Reinier Zwitserloot >> >> >> >> On Mar 17, 2009, at 23:48, Joseph D. Darcy wrote: >> >>> Marek Kozie? wrote: >>>> 2009/3/17 Joseph D. Darcy >>>>> >>>> >>>> This 'this' proposal remains vague and imprecise. >>>> >>>> Including this type/self type in a language is a continuing area >>>> of study; for example, see the recent paper >>>> >>>> "Matching ThisType to Subtyping," Chieri Saito and Atsushi >>>> Igarashi, Kyoto University, Japan, ACM SAC 2009. >>>> >>>> There are open bugs requesting this capability. For example >>>> typing >>>> "site:bugs.sun.com this type" into a >>>> popular >>>> search engine quickly yields, amongst other hits, >>>> >>>> 6479372 Add self types (type of 'this' aka ThisClass) to the >>>> language >>>> >>>> This bug discusses the size of the type system impact of this >>>> change, a magnitude far too large for Project Coin. >>>> >>>> There is no need to submit further refinements of this idea; any >>>> proposal along the lines of adding a this type will be out of >>>> scope for Project Coin. >>>> >>>> -Joe >>>> >>>> >>>> I'll check it, but I'm afraid that introducing 'This' type will be >>>> impossible for Java and for all other languages with Inheritance, >>>> or I >>>> would say it's possible but conditions would be huge. >>>> >>>> return 'this': >>>> - Idea is quite simple: you use object from left side of dot as >>>> returned from method, it's the same quite idea with converting void >>>> -> >>>> this, but allowed only when it's written directly. >>>> - Byte-code for that is other story and I'm not sure how much >>>> limitation this contains. >>>> >>>> >>>> Maybe you cold while what problems you see (that could help)? >>>> >>> >>> As the author and submitter of a proposal, it is your responsibility >>> to >>> research, understand, and explain the consequences and >>> implications of >>> your proposal. >>> >>> -Joe >>> >>> >> >> >> From reinier at zwitserloot.com Tue Mar 17 19:58:06 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 03:58:06 +0100 Subject: PROPOSAL : Specify nullable argument In-Reply-To: <1631da7d0903171949u65b794dfx6e105dab03619a49@mail.gmail.com> References: <15e8b9d20903171341u17a6d056rbc0e2f726e778471@mail.gmail.com> <8E238A0B-E25A-415E-A5AB-D7110FBE689C@zwitserloot.com> <1631da7d0903171949u65b794dfx6e105dab03619a49@mail.gmail.com> Message-ID: <8CF2E34E-98BB-4B16-B362-D56459CBAC15@zwitserloot.com> That sounds like great news. I'll do some more research. --Reinier Zwitserloot On Mar 18, 2009, at 03:49, Jeremy Manson wrote: > I don't know what the current state of the 305 proposal is, but Bill > has been talking about at least three annotations in informal > conversations. > > Jeremy > > On Tue, Mar 17, 2009 at 5:27 PM, Reinier Zwitserloot > wrote: >> Adding non-nullity to the type system would be a great boon, IMO, but >> its far more complicated than just having a @NonNull annotation. >> >> I've written up a proposal a while ago here: http://www.zwitserloot.com/2008/10/23/non-null-in-static-languages/ >> >> Suffice to say it gets very complicated because you need 4 nullity >> states (Never-Allows-Null, Definitely-Allows-Null, Might-Allow-Null, >> Legacy (like raw generics, for interop with old code), *AND* you need >> a separate process to promote or demote generics (So that you can >> say: >> Eventhough this is a Map that maps NonNull String to NonNull String, >> if you call get() on this, you get a @Nullable String back, because >> null will flow out if I can't find the key. In other words, the 'V' >> generics parameter needs to be demoted to @Nullable V somehow). >> >> Read the blog entry for a more elaborate explanation with examples. >> >> I'd love something like that in java, but the proposal as it stands >> needs a source 1.7; keyword (because having no modifier is taken as >> 'never null', which is obviously not backwards compatible), and is >> very complicated, so: Definitely not project coin material. >> >> Incidentally, I think jsr305 is fundamentally broken. It doesn't have >> the states needed to convey nullity info; it needs at least 2 >> annotations, probably 3 to be able to differentiate between code that >> simply didn't specify anything, and code that did, instead of the one >> annotation that jsr305 gives. >> >> --Reinier Zwitserloot >> >> >> >> On Mar 17, 2009, at 21:41, Neal Gafter wrote: >> >>> Did you intend this to be a complete proposal? >>> >>> Do you like this better than @NonNull, which will probably be >>> included >>> in Java 7 under jsr 305? >>> >>> On Tue, Mar 17, 2009 at 1:25 PM, Olivier Chorier >>> wrote: >>>> Example : >>>> >>>> public void getListOfProducts(Company owner, !String >>>> facultativeName) >>>> { >>>> .... >>>> } >>>> >>>> The '!' should prevent the developper that the argument is able to >>>> be null. >>>> Invoking getListOfProducts(null, "name") could throw a compilation >>>> error/warning. >>>> >>>> Or maybe better : >>>> >>>> public void getListOfProducts(!Company owner, String >>>> facultativeName) >>>> { >>>> .... >>>> } >>>> >>>> Here, the '!' indicates a mandatory argument (not null). >>>> >>>> >>>> However, I don't know if the '!' marker could be the most >>>> appropriate. >>>> >>>> >>> >> >> >> From howard.lovatt at iee.org Tue Mar 17 21:50:15 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 15:50:15 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> Message-ID: <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> Hi All, 2009/3/15 Neal Gafter : [snip] > Agreed, though there is one context in which it is possible to jump > into the scope of a local variable declaration without "executing" the > declaration: the switch statement. I thought this was only in C/C++ and Java had plugged this hole - I guess I am wrong - do you have an example. Cheers, Howard. From howard.lovatt at iee.org Tue Mar 17 22:00:57 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 16:00:57 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3C3ACF70-51AF-4F5F-AE67-578A90DFC6BA@zwitserloot.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <3C3ACF70-51AF-4F5F-AE67-578A90DFC6BA@zwitserloot.com> Message-ID: <3dd3f56a0903172200g1f62ee18wb6b1066014e91c41@mail.gmail.com> Hi All, 2009/3/15 Reinier Zwitserloot : [snip] >> Also, why not make the dispose method exception free, >> realistically what can a user of an API do if dispose throws an exception? >> > > Realistically, what can a user of an API do if 'write' throws an exception? > > Your argument does not hold water unless this is an argument for eschewing > checked exceptions altogether. There are cases were the user can do something with a checked exception, e.g. opening a file. In this case the user can be prompted for a different file name if the one suggested does not exist. So I think there are some cases for which checked exceptions are suitable, I have certainly used them from time to time (I don't use many though). I think one of the problems with checked exceptions is that they are over used, e.g. close file, that is why I am suggesting that the resource auto-clean-up should not throw an exception. From develop4lasu at gmail.com Tue Mar 17 22:10:01 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 06:10:01 +0100 Subject: Return 'this' proposal In-Reply-To: <49C028BA.4090609@sun.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> Message-ID: <28bca0ff0903172210u62bcf876r7b6512febcb85026@mail.gmail.com> 2009/3/17 Joseph D. Darcy > > > As the author and submitter of a proposal, it is your responsibility to > research, understand, and explain the consequences and implications of your > proposal. > > -Joe > > I can agree with you that author should do that, but in my opinion we work here to make Java better, and I do not see any reason for you to not write problems you see. But still I'll be not able to explain it, if you will not give a question, while something may be obvious for me and I forgotten to write it. For me this solution is quite compete, I described the part that is important and skipped the rest while it can be 'implemented' in few ways without any impact on solution. Only bad implementation is compile line: expression.setBar().setBaz(); to: expression.setBar(); expression.setBaz(); while: TypeOfExpression $unique = expression; $unique.setBar(); $unique.setBaz(); is ok. My favorite is: expression.setBar().setBaz(); while: setBar() : care to return 'this' -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Tue Mar 17 22:16:07 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 06:16:07 +0100 Subject: Return 'this' proposal In-Reply-To: References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> Message-ID: <28bca0ff0903172216s3aba5341vfe5d425430fe5362@mail.gmail.com> 2009/3/18 Reinier Zwitserloot > Joe, > [snip] > This modifier is strictly inherited. So: > > public abstract class MyBuilder { > public this MyBuilder setFoo(int foo) { > return this; > } > } > > > --Reinier Zwitserloot > > > It's interesting proposition. I noticed that editor corrected me in wrong way. It would prevent NFP should be: It would prevent NPE (NullPointerException). -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Tue Mar 17 22:19:55 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 22:19:55 -0700 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: References: Message-ID: <49C0847B.1050705@sun.com> Reinier Zwitserloot wrote: > Includes Joe D'Arcy's suggestions. I'm just "Joe Darcy"! -Joe From develop4lasu at gmail.com Tue Mar 17 22:24:58 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 06:24:58 +0100 Subject: Return 'this' proposal In-Reply-To: <1631da7d0903171948k4a7275bdw42a36d2a726d88f2@mail.gmail.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> <1631da7d0903171948k4a7275bdw42a36d2a726d88f2@mail.gmail.com> Message-ID: <28bca0ff0903172224l536e5b7fu4a7dc9f3e22632dd@mail.gmail.com> W dniu 18 marca 2009 03:48 u?ytkownik Jeremy Manson napisa?: > Hey Reinier, > > I'm unclear on how that doesn't change the type system. That is, > you've described an implementation technique that doesn't require a > change to bytecode (which is nice), but doesn't it still change > Java-the-language's type system? > > Jeremy > > In basics this proposal should do not impact 'type system', but still it allow to introduce 'This' type. Because 'this' is not a type, just like void. And it's very strict, while 'This' can be: reduced while inheritance (and prevented from stocking) bounded: This extend OutputStream super ? (this would cause activation on described level) used in Generics. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Tue Mar 17 22:33:37 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 06:33:37 +0100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: References: Message-ID: <28bca0ff0903172233q4712feffi4d79d205ee68140c@mail.gmail.com> @Reinier Zwitserloot Glue classes would not solve that for you? @Neal Gafter Extension Methods can be problem while inheritance. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Tue Mar 17 22:35:48 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 17 Mar 2009 22:35:48 -0700 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: <28bca0ff0903172233q4712feffi4d79d205ee68140c@mail.gmail.com> References: <28bca0ff0903172233q4712feffi4d79d205ee68140c@mail.gmail.com> Message-ID: <15e8b9d20903172235p504bc2f2xc24687c4a9408d3c@mail.gmail.com> On Tue, Mar 17, 2009 at 10:33 PM, Marek Kozie? wrote: > @Neal Gafter > > Extension Methods can be problem while inheritance. Can you please be more specific? From neal at gafter.com Tue Mar 17 22:43:40 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 17 Mar 2009 22:43:40 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> Message-ID: <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> On Tue, Mar 17, 2009 at 9:50 PM, Howard Lovatt wrote: >> Agreed, though there is one context in which it is possible to jump >> into the scope of a local variable declaration without "executing" the >> declaration: the switch statement. > > I thought this was only in C/C++ and Java had plugged this hole - I > guess I am wrong - do you have an example. Below, in the form of a puzzler. What does the program print? If you remove "final", does the answer change? import java.io.*; class T { public static void main(String[] args) { switch (args.length) { case 0: final int i = 0; // a constant variable break; case 1: i = 1; // i is not definitely assigned here, so we assign to it System.out.println(i); // i is constant, so prints 0? 1? break; } } } From develop4lasu at gmail.com Tue Mar 17 22:57:28 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 06:57:28 +0100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: <15e8b9d20903172235p504bc2f2xc24687c4a9408d3c@mail.gmail.com> References: <28bca0ff0903172233q4712feffi4d79d205ee68140c@mail.gmail.com> <15e8b9d20903172235p504bc2f2xc24687c4a9408d3c@mail.gmail.com> Message-ID: <28bca0ff0903172257v16a6ff47u1808e0b71e8e5db1@mail.gmail.com> W dniu 18 marca 2009 06:35 u?ytkownik Neal Gafter napisa?: > On Tue, Mar 17, 2009 at 10:33 PM, Marek Kozie? > wrote: > > @Neal Gafter > > > > Extension Methods can be problem while inheritance. > > Can you please be more specific? > It's good solution at start. Bad sites: 1. You need know where the methods are and then you can use it. 2. What happen if some one write same method in inherited class and you will want use extended one? 3. What happen if there will be two extension with same methods: Extension1{ void method1(...){...} void method2(...){...} } Extension2{ void method1(...){...} void method2(...){...} } ? and u want call Extension1.method1 and Extension2.method2 3. It's not clear if method is extension or it's in class for the one who read the code. I see it MS way solution: good for short projects. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Tue Mar 17 23:03:50 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 23:03:50 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <4A4664E7-440E-4C89-B2CC-78B81391BB83@zwitserloot.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> <1631da7d0903151902w34737a5ev8ce9a3528464a73e@mail.gmail.com> <4A4664E7-440E-4C89-B2CC-78B81391BB83@zwitserloot.com> Message-ID: <49C08EC6.9040904@sun.com> A few general comments here. While it would be technically possible to add some kind of metadata to a Java source file, as such as annotation with a javax.lang.model.SourceVersion member, to state its source version, I don't find this a compelling problem to solve. The issue primarily occurs when a mixed-version code base is being compiled with a single javac invocation: Patient: "Doctor, it hurts when I move my arm like this." Doctor: "Don't move your arm like that!" The major impediments to compiling under a single source version in the past were the introduction of new keywords in later versions of the language. As Alex Buckley has stated at JavaOne, we don't plan to add new keywords to the language, unless they are contextual keywords like "module" in JDK 7 which still allow the use of the reserved name for fields, methods, etc. Defining source version metadata information with no semantics doesn't strike me as useful or meaningful in terms of a language specification. How would that be tested? Mixing multiple source versions together in one compile could expose many compilation artifact details that need to be specified for cross-version interoperability. I don't think this is a worthwhile path to pursue. -Joe Reinier Zwitserloot wrote: > There is no proposal, Jeremy. I made a pre-proposal on the assumption > it would sail right through. It didn't, and that was that, until > Howard Lovatt re-opened the discussion in support of the proposal. > > > Having a "source" statement that is spec'd to do nothing other than > set the CompilationUnit's source property *DOES* resolve the issue of > having half your codebase in v1.6 and half in v1.7. > > Because half is in v1.7, this is -obviously- only going to run in a > JVM v1.7 or above - this has been true in java for years and I don't > see how this could possibly change for v1.7 given that the class file > format is changing and the module system will be added. A JVM v1.7 - > will- be able to run both: > > - class files compiled with javac 1.6, *and* > - class files compiled with javac 1.7 with -target 1.7 and -source > 1.6 on the command line (or after this proposal, source 1.6 in the > file). > > > The only issue someone might have in the middle of porting old code is > that the 1.6 code is being compiled as if it is 1.7 code. To highlight > how annoying that can be: When java went from 1.4 to 1.5, old code > would produce an enormous list of generics warnings. Effectively you > had to disable ALL of them until you finished porting all your java > code to 1.5; there was no practical way to get a list of genuine > generics warnings for your post-porting code. > > *THAT* problem is what the 'source' keyword would address. If we had > it back then, javac would know NOT to generate those generics warnings > for all source files marked source 1.4. > > > The notion that 'source 7;' isn't going to stop you from writing code > using Java8 APIs is true, but that's what the module system is for, > *NOT* the -source system. I fundamentally think its a mistake to > attempt to marry these two ideas together. For example, just now I'm > hacking om some HTML parsing using htmlparser, which was written for > java 1.4. One of the interfaces I need to implement passes my code a > (non-generified) Vector object. Instead of dealing with the warnings, > I decided to just configure eclipse to set the entire project to > source compatibility 1.4. Nevertheless, I stil want to use > String.replace("foo", "bar"), which is a String method that exists > only in java6+. There is no problem, because I'll be running my code, > and the htmlparser library, on a JVM6. > > Imagining for a moment that both the source keyword exist, and the > module system, I'd have to bundle htmlparser into its own module, and > set my module bundle to be dependent on jvm.core=6+, and have a source > compatibility of java 1.4, lest it rains generics warnings. > > > Once we have both the source and the module system, it becomes trivial > to create java files that will actually compile AND run on old > versions of the JDK/JVM: If both your source keyword AND your > java.core dependency are on java 1.X or below, then your code should > compile and run on a JDK/JVM 1.X or above. Whether the JDK itself > offers a command line option or other mechanism to enforce this, or > whether tool providers such as ant make handy shortcuts for this isn't > relevant: Someone can run with it, surely. However, a 'source' keyword > would help quite a bit, lest we get the reference situation: > > You only use library calls from java1.4 and below, but you are using > foreach loops and generics, so a JDK v1.4 won't compile your code, and > if you compile it with a JDK1.6, the class files won't run on a JVM1.4. > > > > There is, again, no need for the backticks, because there will be 0 > new keywords in java7 (excluding context sensitive keywords). *IF* > java 8 includes a proposal that does have new keywords, then it would > automatically also require a backtick proposal. But it's not 2012 yet. > > javac (the compiler itself) will support -source 1.6, if history is > any indication. I think making that commitment at this point in time > is a no-brainer. > > There is no need for a compiler to neccessarily do the best possible > option when a "source 1.6;" is encountered. If that version of javac > no longer has the capability to parse v1.6 code, then it can > gracefully exit with an appropriate error message, instead of a weird > batch of parsing mismatches that leaves the person attempting to dust > off some 10 year old code none the wiser. > > --Reinier Zwitserloot > > > On Mar 16, 2009, at 03:02, Jeremy Manson wrote: > > >> Reinier, >> >> Fundamentally, I think we are in disagreement that the source keyword >> that you are suggesting provides any useful semantics. I haven't seen >> your proposal (I can't find the message where you posted it?), but >> here is one of your motivations from your pre-proposal: >> >> >>> Leaving half your sourcebase in v1.6 and the >>> other half in v1.7 is pretty much impossible today, it's all-or- >>> nothing. >>> >> Having a "source" statement that is spec'd to do nothing other than >> set a property in the CompilationUnit doesn't actually address this, >> in the ways in which I said it didn't before: >> >> 1) My API / Classfile comment was not about changes to classfiles, it >> was about the fact that your proposal doesn't address the fact that >> different APIs are available to different Java versions. "source 7;" >> isn't going to stop the code I write from using some new API >> introduced in Java 8, just as "-source 5" as a parameter to javac >> doesn't stop me from using ConcurrentSkipListMap. I know your >> proposal isn't intended to address this, but I think any proposal that >> provides versioning needs to address this, because you aren't keeping >> half your codebase in Java 6 in any meaningful way if that code can >> use Java 7 APIs. >> >> 2) I know that your proposal isn't intended to address the problem >> that the backticks were intended to solve, but I think that any >> proposal that provides versioning needs to address this, because it is >> difficult to keep half of your codebase in Java 7 if you can't call >> out to some APIs that your Java 6 code provides because their names >> clash wit keywords. >> >> 3) All that javac says about -source is that it provides source >> compatibility with the specified release. However, there are releases >> it doesn't support (anymore), and there are targets that can't be >> generated from specific source versions. You need, at the very least, >> to define what sources are guaranteed to be supported. You can't >> leave half your codebase in Java 6 if no compiler supports Java 6. >> >> You seem to be willing to leave these things up in the air, which I >> think is easier when it is an option to the javac program, where this >> is offered as a convenience, but not fine for a language >> specification, when the source code needs to be portable to any Java 7 >> compliant compiler. >> >> At any rate, Joe already stepped in and said that the proposal as it >> stood was too complicated for Project Coin: >> >> http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000298.html >> >> Jeremy >> >> On Sun, Mar 15, 2009 at 5:45 PM, Reinier Zwitserloot >> wrote: >> >>> Neal: >>> >>> As I've mentioned at least twice on coin-dev already, the JLS only >>> needs to >>> specify how the 'source' keyword sets the 'source' property of the >>> CompilationUnit that contains the source keyword. As far as the JLS >>> is >>> concerned, this is a string value that has no further meaning. It's >>> a bit >>> like a comment in this sense. To be crystal clear: ** The JLS will >>> NOT >>> specify what is supposed to happen when you write "source 1.1;" in >>> a JLSv3 >>> view of the source file! ** >>> >>> The effect of a source property in a CompilationUnit will however be >>> specified in the documentation for java compilers. >>> >>> Jeremy: >>> >>> 1) No, -source does not show up in the class file at all, so >>> obviously it >>> wouldn't for a source keyword, either. Therefore the API / Classfile >>> compatibility issue is 0. >>> >> >>> 2) No, backticks aren't neccessary for the source keyword to work. >>> java7 is >>> not going to be source incompatible with java6 and does not add new >>> keywords >>> (well, module, but it'll be context sensitive). Compatibility >>> issue: 0. It >>> would certainly help make it easier to make breaking changes in >>> java 7, if >>> at that time a proposal comes along that makes sense but would be >>> better >>> with a few breaking changes. >>> >> >>> 3) There is no need for much *JLS* documentation at all. >>> CompilationUnits >>> get a 'source' property, which is a string value. That's where it >>> ends as >>> far as the JLS is concerned. It has no meaning within the JLS. Just a >>> string, that's all. The documentation for javac has quite a bit to >>> say about >>> this, but that's nothing new: The -source parameter has the exact >>> same >>> function and is already documented. This documentation needs a very >>> minor >>> update. >>> >>> 4) "source 1.7;" is really neccessary at the top of the file. It >>> is crucial >>> meta-data without which you cannot make any sense of a java >>> CompilationUnit. >>> Is 'assert' a keyword or an identifier? What about strictfp? Are >>> inner >>> classes legal? Is @Override on an interface-inherited method legal, >>> or an >>> error? Should lack of generics result in a warning, or should any >>> generics >>> actually be indicated as a compile-time error? You don't, of >>> course, -have- >>> to put it there, but its suggested, and I expect IDEs and style >>> checkers >>> will start warning when its missing. This is somewhat akin to package >>> statements. Those are -really- neccessary as well. a >>> CompilationUnit's >>> target package isn't a command line parameter for the same (good) >>> reason. >>> This metadata is not dependent on a compile run, it is solely >>> dependent on >>> the source file itself, and should therefore be inside it. >>> >>> --Reinier Zwitserloot >>> >>> >>> >>> On Mar 16, 2009, at 00:58, Jeremy Manson wrote: >>> >>> >>>> Reinier, >>>> >>>> I wrote out a long response to each of your points, but I realized >>>> that perhaps what it boiled down to was something I said in my >>>> previous message: "I'm not objecting to versioning in principle, >>>> but I >>>> think there are enough unanswered questions that this proposal is >>>> probably beyond the scope of "small changes"." >>>> >>>> You are saying that if I have a problem with something, it is the >>>> -source flag. You are absolutely right: I have problems with the >>>> -source flag. Those problems should be sorted out before we include >>>> it in the language. Each solution to each of these problems makes >>>> this change larger: >>>> >>>> 1) API / Classfile compatibility >>>> >>>> 2) Backticks for identifiers >>>> >>>> 3) A need for thorough documentation for each potential version we >>>> support. (You seem to be suggesting that this would be >>>> implementation-dependent, but that's unlike everything else in the >>>> language. Java is historically opposed to things that are >>>> implementation-dependent. Part of the selling point of Java is that >>>> code written for / compiled on a version of Java 7 will work with / >>>> compile on all compliant Java 7 implementations.). >>>> >>>> 4) Is "source" really necessary at the top of the file (you seem >>>> to be >>>> agreeing that it is), and if so, is that what we actually want? >>>> >>>> I also think it would be worthwhile finding out how this proposal >>>> gels >>>> with the module system they are introducing. >>>> >>>> Fundamentally, it seems to me to be a large problem to solve, and I >>>> think the right answer is to start a proper JSR and make sure you >>>> get >>>> it right. >>>> >>>> It is, of course, by no means important to Project Coin that I (as >>>> one >>>> person) happen to think that this change is (or should be) too >>>> large. >>>> But I suspect that I'm not the only one. >>>> >>>> Jeremy >>>> >>> > > > From neal at gafter.com Tue Mar 17 23:14:59 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 17 Mar 2009 23:14:59 -0700 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: <28bca0ff0903172257v16a6ff47u1808e0b71e8e5db1@mail.gmail.com> References: <28bca0ff0903172233q4712feffi4d79d205ee68140c@mail.gmail.com> <15e8b9d20903172235p504bc2f2xc24687c4a9408d3c@mail.gmail.com> <28bca0ff0903172257v16a6ff47u1808e0b71e8e5db1@mail.gmail.com> Message-ID: <15e8b9d20903172314r493bb168gec9c09cc359faeb4@mail.gmail.com> On Tue, Mar 17, 2009 at 10:57 PM, Marek Kozie? wrote: > Bad sites: > 1. You need know where the methods are and then you can use it. Yes. That's a good thing, because you don't get what you don't ask for or don't want to know about. > 2. What happen if some one write same method in inherited class and you will > want use extended one? Use the old syntax (invoke the method from its static utility class). > 3. What happen if there will be two extension with same methods: > Extension1{ > void method1(...){...} > void method2(...){...} > } > > Extension2{ > void method1(...){...} > void method2(...){...} > } > > ... and u want call Extension1.method1 and Extension2.method2 Then just call them. You aren't required to use extension methods as if they are members of the type they extend. > 3. It's not clear if method is extension or it's in class for the one who > read the code. That's true; you'd have to look at the class documentation AND the imports clause. > I see it MS way solution: good for short projects. I haven't heard that experience based on the MS solution. On the contrary, I've heard that it is very helpful for large scale projects. Can you point me to any writeup of this experience? From Joe.Darcy at Sun.COM Tue Mar 17 23:15:37 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 17 Mar 2009 23:15:37 -0700 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <64C260CE-3CC3-43ED-914D-CB6BD77FBAB5@zwitserloot.com> References: <64C260CE-3CC3-43ED-914D-CB6BD77FBAB5@zwitserloot.com> Message-ID: <49C09189.9020005@sun.com> Reinier Zwitserloot wrote: > Ah, list comprehensions. I forgot them on my list. They aren't > closures, but you can do quite a few closure use-cases with them, and > are a lot easier to understand. The draft proposal looks good (but is > incomplete; it doesn't mention any JLS chapters, for example), but > there's one big issue it doesn't mention: If the list comprehensions > return Iterables, then the generating expression, as well as the > filter expressions, are effectively 'closures' and get all the > complications that stem from this. For example, you would not be able > to use non-final variables in there, unless we change the rules > regarding usage of non-finals in 'closures', which involves a > significant change for the JVM (it has to declare that variable on the > heap and not on the stack). > > Generating the entire list on the spot has none of those issues, and > turns the entire proposal into syntactic sugar + a new utility class > in the spirit of Collections and Arrays, named 'Iterables'. That's all. > > Joe: If a list comprehension proposal is written that involves > (extensive) syntax sugar + 1 new class file and nothing else, would > they have a chance? > I would be doubtful such a change would be within scope. -Joe From jeremy.manson at gmail.com Wed Mar 18 00:13:00 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Wed, 18 Mar 2009 00:13:00 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> Message-ID: <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: > ? ? ? ? ? ?i = 1; // i is not definitely assigned here, so we assign to it The compiler is traditionally not very happy when you assign a value to a final variable. :) Jeremy From markmahieu at googlemail.com Wed Mar 18 00:20:52 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 18 Mar 2009 07:20:52 +0000 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <49C08EC6.9040904@sun.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <7492781A-8D36-4872-8D42-213C3CA8534E@zwitserloot.com> <1631da7d0903151658g168e8747o7e7a7b37b8576b62@mail.gmail.com> <21D13BB0-BB21-4EE4-B97B-C5A99BA7931B@zwitserloot.com> <1631da7d0903151902w34737a5ev8ce9a3528464a73e@mail.gmail.com> <4A4664E7-440E-4C89-B2CC-78B81391BB83@zwitserloot.com> <49C08EC6.9040904@sun.com> Message-ID: 2009/3/18 Joseph D. Darcy > A few general comments here. > > While it would be technically possible to add some kind of metadata to a > Java source file, as such as annotation with a > javax.lang.model.SourceVersion member, to state its source version, I > don't find this a compelling problem to solve. The issue primarily > occurs when a mixed-version code base is being compiled with a single > javac invocation: > > Patient: "Doctor, it hurts when I move my arm like this." > Doctor: "Don't move your arm like that!" The closest I've come to this kind of problem recently was when using GWT, where some of the code is translated into another language (Javascript) at build time. GWT's current compiler attempts to comply with javac 1.5's behaviour, yet the project as a whole was at 1.6, which is just enough of a difference to cause problems as IDEs will then happily insert @Override in places that are fine with javac 1.6 but not javac 1.5. This scenario was caused by the belief that it's only necessary to worry about the libraries when mixing 1.5 and 1.6, ending up with the code to be translated mixed with the code that wasn't, which is a model GWT encourages. Wasn't serious enough to see a doctor about. > I don't think this is a worthwhile path to pursue. > I agree - at least in the type of scenario I described above, there are better ways to deal with it. Mark From jjb at google.com Wed Mar 18 00:21:40 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 18 Mar 2009 00:21:40 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> Message-ID: <17b2302a0903180021n6c2586d6s15bde1fff4917ecf@mail.gmail.com> And switch should never have supported a fallthrough (in Java). It should have bee structured like the rest of control constructs. Sigh.... Josh On Wed, Mar 18, 2009 at 12:13 AM, Jeremy Manson wrote: > On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: > > > i = 1; // i is not definitely assigned here, so we assign to > it > > The compiler is traditionally not very happy when you assign a value > to a final variable. :) > > Jeremy > From neal at gafter.com Wed Mar 18 00:24:28 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 00:24:28 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> Message-ID: <15e8b9d20903180024o62455db2o9a37e87389e8c86f@mail.gmail.com> On Wed, Mar 18, 2009 at 12:13 AM, Jeremy Manson wrote: > On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: > >> ? ? ? ? ? ?i = 1; // i is not definitely assigned here, so we assign to it > > The compiler is traditionally not very happy when you assign a value > to a final variable. :) Right... unless it's "definitely unassigned". Since we've skipped over its initialization, it's definitely unassigned, right? From markmahieu at googlemail.com Wed Mar 18 00:39:11 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 18 Mar 2009 07:39:11 +0000 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> Message-ID: For anyone who likes puzzles, I'd recommend reading the code that deals with all that DA/DU stuff in javac. I prototyped a language change in javac last year, and spent more time on understanding and subtly changing that code *just to get a better error message* than I did on anything else. All Neal's fault actually - nobody else complained about my diagnostic messages ;) Mark 2009/3/18 Jeremy Manson > On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: > > > i = 1; // i is not definitely assigned here, so we assign to > it > > The compiler is traditionally not very happy when you assign a value > to a final variable. :) > > Jeremy > > From markmahieu at googlemail.com Wed Mar 18 00:51:01 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 18 Mar 2009 07:51:01 +0000 Subject: Proposal: Access to Generic Type Parameters at Compile-Time In-Reply-To: <34BE7C25-01CA-4D83-BB66-139C86BF79D5@walend.net> References: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> <3BA402DB-7828-42EF-A443-0A7A4ECEE052@googlemail.com> <34BE7C25-01CA-4D83-BB66-139C86BF79D5@walend.net> Message-ID: I think it's worth mentioning. Incidentally, this idea touches on the same kind of issue regarding names: http://blogs.sun.com/abuckley/en_US/entry/named_parameters Mark 2009/3/18 David Walend > Hi Mark, > > > On Mar 17, 2009, at 12:22 PM, Mark Mahieu wrote: > >> Hi David, >> >> On 17 Mar 2009, at 02:37, David Walend wrote: >> >>> >>> interface Path >>> extends Digraph >>> { >>> ThruGraph.Node getHead(); >>> ... >>> } >>> >> >> So, if I were the author of Digraph and I decided to rename its type >> parameters (to N and E for example), your Path interface would no longer >> compile? >> > > That's correct. Changing the name of a type parameter would have the > same potential impact as renaming other public/protected/default-accessible > parts of the class, like an inner class, a static method or a static member > field. > > Changing an extends or super clause risks breaking something. Adding or > removing type parameters almost always breaks downstream code that uses the > class. The name of the type parameter is (I think) the only thing you can > safely change in the parameter list currently. > > I think this problem would come up far less often than breaking the > interface by adding an extends or super clause to an existing > parameter. Is it a big enough problem to add to the disadvantages list? > > Thanks, > > > Dave > > David Walend > david at walend.net > > From howard.lovatt at iee.org Wed Mar 18 01:02:25 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 19:02:25 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903142104t30aff61cpd354a7c863f0df8b@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <15e8b9d20903142104t30aff61cpd354a7c863f0df8b@mail.gmail.com> Message-ID: <3dd3f56a0903180102h613efab9k7be84d9855201f82@mail.gmail.com> Hi Neal & Joshua, I probably need to supply more info, see text below. 2009/3/15 Neal Gafter : > On Sat, Mar 14, 2009 at 7:55 PM, Howard Lovatt wrote: >> Instead of writing: >> >> try ( Resource r = new Resource() ) { >> ?r.doSomething(); >> } >> >> You would write: >> >> final Resource r = new Resource(); >> r.doSomething(); > > I think this requires something like a new modifier on the local > variable declaration. ?Without a distinguished syntax, I don't see how > to distinguish this from a normal local variable declaration. Joshua Bloch wrote: > There is room for disagreement here. We discussed this extensively at Google when I drafted the proposal, and > we ended up eschewing a declaration-based approach because there was general agreement that it was much > less Java-like to imbue the closing bracket with such "magical powers." Maybe then in response to both your points some syntax like: AutoResource ar = autoresource MyResource(); ar.doSomething(); and for other blocks, e.g. foreach loops: for ( String line : autoresource IterableFile(...) ) { ... } Is best. Note keyword autoresource and that keyword autoresource would mean allocation of a new resource and would replace new. The resource is disposed of at the end of the block it is declared in, there is no requirement for the variable to be final or even for an explicit variable. It is an error to attempt to create an AutoResource using new, you must use autoresource (this catches the mistake new MyResource() which may be common at first). As an aside to Joshua, I liken not having an explicit set of braces for resource management like automatic garbage collection, create and forget, and hence Java like. However the behaviour of auto-disposing is also C++ destructor like, so I can see other peoples point of view on this. Both approaches would be an improvement on what we currently have. My preference is not to have braces because I prefer the syntax, particularly for existing block structures like the foreach loop. Neal gafter wrote: >> This is so much more Java like than the block construct, why not do >> this instead of the block construct (note it would be an error not to >> declare the resource final). r.dispose() is called at the end of the >> enclosing block, provided that r is not null, when r goes out of >> scope, which is probably what you want anyway (you can insert an >> existing {} block if you have to control lifetime). Also, why not make >> the dispose method exception free, realistically what can a user of an >> API do if dispose throws an exception? > > If it's not final, what happens when the variable is reassigned? See comment above - have removed final requirement in response to your concern. > Without allowing checked exceptions on the resource release, I don't > see how to retrofit this onto the primary use-case, Closeable. I would propose AutoResource to be: interface AutoResource { void autoDispose(); } And the 'contract' for an AutoResource to be something that is auto opened, either when created or first used, that is to be automatically closed, that issues exceptions if the resource is used after it is closed (or that the JavaDoc notes that this resource quietly ignores usage after closure), that is tolerant, without complaint, of multiple calls to autoDispose, and that autoDispose can optionally throw an unchecked exception to report a closure problem (typically this error will be logged and the program will terminate its current operation or terminate completely). Then new interfaces and existing and new classes can extend/implement AuroResource. The purpose of picking autoDispose as the method name and autoresource as the keyword is to make name clashes unlikely. I am proposing that this should be a deliberate retrofit, not a consequence of the behaviour of an existing interface changing. That way someone needs to consciously decide they want AutoResource and are in effect saying, by implementing AutoResource, that they agree to its contract (as outlined above). What do you think? Howard. From howard.lovatt at iee.org Wed Mar 18 01:09:12 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 19:09:12 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> Message-ID: <3dd3f56a0903180109m41b2553at45726090ecb503d9@mail.gmail.com> Neal, java 6 on a Mac catches your example - it says you can't assign to a final variable. Is the Mac javac correct? Howard. 2009/3/18 Neal Gafter : > On Tue, Mar 17, 2009 at 9:50 PM, Howard Lovatt wrote: >>> Agreed, though there is one context in which it is possible to jump >>> into the scope of a local variable declaration without "executing" the >>> declaration: the switch statement. >> >> I thought this was only in C/C++ and Java had plugged this hole - I >> guess I am wrong - do you have an example. > > Below, in the form of a puzzler. ?What does the program print? ?If you > remove "final", does the answer change? > > import java.io.*; > class T { > ? ?public static void main(String[] args) { > ? ? ? ?switch (args.length) { > ? ? ? ?case 0: > ? ? ? ? ? ?final int i = 0; // a constant variable > ? ? ? ? ? ?break; > ? ? ? ?case 1: > ? ? ? ? ? ?i = 1; // i is not definitely assigned here, so we assign to it > ? ? ? ? ? ?System.out.println(i); // i is constant, so prints 0? 1? > ? ? ? ? ? ?break; > ? ? ? ?} > ? ?} > } > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From howard.lovatt at iee.org Wed Mar 18 01:11:46 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 19:11:46 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903180021n6c2586d6s15bde1fff4917ecf@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> <17b2302a0903180021n6c2586d6s15bde1fff4917ecf@mail.gmail.com> Message-ID: <3dd3f56a0903180111h50eaf126ka6c03ef9cec4369a@mail.gmail.com> Joshua, I think everyone would like this change. If we introduce a source keyword, another proposal in coin, then we could! Howard. 2009/3/18 Joshua Bloch : > And switch should never have supported a fallthrough (in Java). ?It should > have bee structured like the rest of control constructs. ?Sigh.... > ?? ? ? ? Josh > > On Wed, Mar 18, 2009 at 12:13 AM, Jeremy Manson > wrote: >> >> On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: >> >> > ? ? ? ? ? ?i = 1; // i is not definitely assigned here, so we assign to >> > it >> >> The compiler is traditionally not very happy when you assign a value >> to a final variable. :) >> >> Jeremy > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From jeremy.manson at gmail.com Wed Mar 18 01:15:49 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Wed, 18 Mar 2009 01:15:49 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903180024o62455db2o9a37e87389e8c86f@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> <15e8b9d20903180024o62455db2o9a37e87389e8c86f@mail.gmail.com> Message-ID: <1631da7d0903180115t79d9de95ndda9fba3e8bd7336@mail.gmail.com> I'm pretty sure that it is only definitely unassigned there if it is definitely unassigned after the switch expression. If you want it to compile, you have to place the declaration before the switch statement. I could be wrong about that. Another favorite: void f(boolean b) { final boolean i; if (b) { i = true; } if (!b) { i = false; } } Jeremy On Wed, Mar 18, 2009 at 12:24 AM, Neal Gafter wrote: > On Wed, Mar 18, 2009 at 12:13 AM, Jeremy Manson wrote: >> On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: >> >>> ? ? ? ? ? ?i = 1; // i is not definitely assigned here, so we assign to it >> >> The compiler is traditionally not very happy when you assign a value >> to a final variable. :) > > Right... unless it's "definitely unassigned". ?Since we've skipped > over its initialization, it's definitely unassigned, right? > From develop4lasu at gmail.com Wed Mar 18 02:04:19 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 10:04:19 +0100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: <15e8b9d20903172314r493bb168gec9c09cc359faeb4@mail.gmail.com> References: <28bca0ff0903172233q4712feffi4d79d205ee68140c@mail.gmail.com> <15e8b9d20903172235p504bc2f2xc24687c4a9408d3c@mail.gmail.com> <28bca0ff0903172257v16a6ff47u1808e0b71e8e5db1@mail.gmail.com> <15e8b9d20903172314r493bb168gec9c09cc359faeb4@mail.gmail.com> Message-ID: <28bca0ff0903180204v6c557e0aj3941a2a2c7914398@mail.gmail.com> W dniu 18 marca 2009 07:14 u?ytkownik Neal Gafter napisa?: > On Tue, Mar 17, 2009 at 10:57 PM, Marek Kozie? > wrote: > > Bad sites: > > 1. You need know where the methods are and then you can use it. > > Yes. That's a good thing, because you don't get what you don't ask > for or don't want to know about. > In my opinion it's bad. Because if u add method that will be visible for all you concentrate to do it well. But when you think 'It's only for me, I'll know what is it for.' and then happen that some one else my find this method or there will be no time to do it well. Or some one else write it because he didn't know about it. > > 2. What happen if some one write same method in inherited class and you > will > > want use extended one? > > Use the old syntax (invoke the method from its static utility class). > It's not WYSIWYG. > > 3. What happen if there will be two extension with same methods: > > Extension1{ > > void method1(...){...} > > void method2(...){...} > > } > > > > Extension2{ > > void method1(...){...} > > void method2(...){...} > > } > > > > ... and u want call Extension1.method1 and Extension2.method2 > > Then just call them. You aren't required to use extension methods as > if they are members of the type they extend. > > > 3. It's not clear if method is extension or it's in class for the one who > > read the code. > > That's true; you'd have to look at the class documentation AND the > imports clause. > > > I see it MS way solution: good for short projects. > > I haven't heard that experience based on the MS solution. On the > contrary, I've heard that it is very helpful for large scale projects. > Can you point me to any writeup of this experience? > When yuo link few projects and evolve them for few years this little problems start become annoying. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From howard.lovatt at iee.org Wed Mar 18 02:28:12 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 20:28:12 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903180115t79d9de95ndda9fba3e8bd7336@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> <15e8b9d20903180024o62455db2o9a37e87389e8c86f@mail.gmail.com> <1631da7d0903180115t79d9de95ndda9fba3e8bd7336@mail.gmail.com> Message-ID: <3dd3f56a0903180228r1cee8917x5070b34865525768@mail.gmail.com> Hi, Mac javac 6 gets this one also. Howard. 2009/3/18 Jeremy Manson : > I'm pretty sure that it is only definitely unassigned there if it is > definitely unassigned after the switch expression. ?If you want it to > compile, you have to place the declaration before the switch > statement. ?I could be wrong about that. > > Another favorite: > > void f(boolean b) { > ?final boolean i; > ?if (b) { > ? ?i = true; > ?} > ?if (!b) { > ? ?i = false; > ?} > } > > Jeremy > > On Wed, Mar 18, 2009 at 12:24 AM, Neal Gafter wrote: >> On Wed, Mar 18, 2009 at 12:13 AM, Jeremy Manson wrote: >>> On Tue, Mar 17, 2009 at 10:43 PM, Neal Gafter wrote: >>> >>>> ? ? ? ? ? ?i = 1; // i is not definitely assigned here, so we assign to it >>> >>> The compiler is traditionally not very happy when you assign a value >>> to a final variable. :) >> >> Right... unless it's "definitely unassigned". ?Since we've skipped >> over its initialization, it's definitely unassigned, right? >> > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From matthias at mernst.org Wed Mar 18 02:46:06 2009 From: matthias at mernst.org (Matthias Ernst) Date: Wed, 18 Mar 2009 10:46:06 +0100 Subject: Return 'this' proposal In-Reply-To: References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> Message-ID: <22ec15240903180246s3867be0ei3dde6be76d6772d0@mail.gmail.com> On Wed, Mar 18, 2009 at 1:07 AM, Reinier Zwitserloot wrote: > Joe, > > What's the coin viability for a proposal that does NOT change the type > system, but just introduces syntax sugar that translates: > > expression.setBar().setBaz(); > > to: > > TypeOfExpression $unique = expression; > $unique.setBar(); > $unique.setBaz(); > I very much like that. In fact I had a similar proposal up almost two years ago: http://www.mernst.org/blog/rss.xml#Cascading-First-Patch It had one big downside: it only covered void methods which was both limiting and brittle, so I didn't pursue it further. Your proposal requires modification to the callee when it should be treated as a cascadable method. I think this is pretty invasive. Instead, I've come to the conclusion that it should exclusively be a callee-side mechanism, exactly like smalltalk does it, that specifies "call again on the same receiver instead of the return value". It requires using a different syntax for a cascaded invocation which I actually like. In ST they use ";" result = Message newBuilder x: x; y: y; z: z; build. In Java, one could for example use multiple dots: Message m = Message.newBuilder() .setX(x) ...setY(y) ...setZ(z) ...build(); Or a "->" operator? It actually has a nice "and then" look to it. .setX(x) ->setY(y) ->setZ(z) ->build(); Matthias > > where the setBar() method has a void return type, but has also been > ktited out with a flag that indicates its legal for call sites to do > the syntax sugar transformation above? The way this would work is very > similar to varargs: The method with the 'varargs flag' really doesn't > do anything special other than have a flag. It's the callers that do > all the work. > > > There are backwards compatibility issues, because most of the code > that wants to 'return this' currently does not return void, it instead > returns its own type, but I have one strategy for dealing with that > issue that is simple and doesn't introduce any new keywords - > basically, you get to add the flag to any method, and any callers will > check if the type of the expression is tighter than the return type. > If so, then the type of the returned value of the call is similarly > tightened. In trade, setting the flag requires the java code to always > "return this" for all return statements; anything else is an instant > compiler error. The flag is set by adding 'this' as a keyword to the > method's modifier section. This modifier is strictly inherited. So: > > public abstract class MyBuilder { > ? ? public this MyBuilder setFoo(int foo) { > ? ? ? ? return this; > ? ? } > } > > > > ?--Reinier Zwitserloot > > > > On Mar 17, 2009, at 23:48, Joseph D. Darcy wrote: > >> Marek Kozie? wrote: >>> 2009/3/17 Joseph D. Darcy >> >> >>> >>> ? ?This 'this' proposal remains vague and imprecise. >>> >>> ? ?Including this type/self type in a language is a continuing area >>> ? ?of study; for example, see the recent paper >>> >>> ? ?"Matching ThisType to Subtyping," Chieri Saito and Atsushi >>> ? ?Igarashi, Kyoto University, Japan, ACM SAC 2009. >>> >>> ? ?There are open bugs requesting this capability. For example typing >>> ? ?"site:bugs.sun.com this type" into a popular >>> ? ?search engine quickly yields, amongst other hits, >>> >>> ? ?6479372 Add self types (type of 'this' aka ThisClass) to the >>> language >>> >>> ? ?This bug discusses the size of the type system impact of this >>> ? ?change, a magnitude far too large for Project Coin. >>> >>> ? ?There is no need to submit further refinements of this idea; any >>> ? ?proposal along the lines of adding a this type will be out of >>> ? ?scope for Project Coin. >>> >>> ? ?-Joe >>> >>> >>> I'll check it, but I'm afraid that introducing 'This' type will be >>> impossible for Java and for all other languages with Inheritance, >>> or I >>> would say it's possible but conditions would be huge. >>> >>> return 'this': >>> - Idea is quite simple: you use object from left side of dot as >>> returned from method, it's the same quite idea with converting void >>> -> >>> this, but allowed only when it's written directly. >>> - Byte-code for that is other story and I'm not sure how much >>> limitation this contains. >>> >>> >>> Maybe you cold while what problems you see (that could help)? >>> >> >> As the author and submitter of a proposal, it is your responsibility >> to >> research, understand, and explain the consequences and implications of >> your proposal. >> >> -Joe >> >> > > > From howard.lovatt at iee.org Wed Mar 18 03:10:17 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 21:10:17 +1100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> Message-ID: <3dd3f56a0903180310g59377decl384d59a78fd43a1e@mail.gmail.com> Hi, 2009/3/16 Jeremy Manson : > I think there are a few problems with this: > > 1) If you are doing this so you can ensure that the old code will > remain able to run on old versions of Java, this really is only half a > solution, unless you include the APIs. ?If a "source" keyword is > introduced for this purpose, it has to be introduced at the same time > as versioned APIs, otherwise it is useless. I don't see this, it is a separate issue tracking API versions. If the new API is compatible with the old then the old code still works with the new API and using the new compiler. The old code doesn't have a source statement and is therefore recognised as old code and therefore compiles exactly like it did with the old compiler. For the new code, which has a source statement, the compiler enables the action associated with the new constructs. > 2) If you are doing this so that you can evolve the language by > introducing new keywords and maintain backwards compatibility with old > code, then you have a problem, because these old APIs are going to be > allowed to export the new keywords as public members. ?If we add a new > keyword "foo", and we use -source 5 so that we can have a public > method "foo", you won't be able to use that API with -source 7 code. Already part of coin is exotic identifiers that allows J7 to access any valid name in the JVM. This is to support other languages that might have a different set of valid names. However the same mechanism would allow you to call an API that uses the new keyword, just like it can call an API that uses an existing keyword as a name. > 3) None of the code you care about maintaining compatibility with is > going to have the "source" annotation on it, which means that if you > don't have the source keyword, you are going to have to assume that > the source is Java 6. ?Does this mean that Java 7 code now *requires* > a source annotation to tell you it is Java 7? ?Or do we have to go > back and put "source 6" on all of the files that won't compile? ?If we > are doing that anyway, can't we just change the code so that it > compiles? If you want a new J7 feature that isn't in 6 then you have to put source Java7 (or whatever is decided) at the start of that file > 4) Do we have *really* compelling language changes that actually > require new keywords (that aren't context sensitive, like "module")? Depends what is decided for coin. The main argument is however that you are positioning for the future. For example, if we did add source then perhaps we could change switch to be block structured at some point in the future. > 5) Is it easy to specify what the differences are in each source > revision? ?When we add this to the JLS, what does it say, exactly, > about what the number after the "source" keyword means? Java has already evolved and there are multiple releases of the JLS. So one possible way to specify the changes is to say for files without a source statement see the JLS ed. 3 (I think 3 is the latest). Then you describe the new language in J7LS ed. 1 - note 7 in the title. > I'm not objecting to versioning in principle, but I think there are > enough unanswered questions that this proposal is probably beyond the > scope of "small changes". I think one of the reasons that Java is tending to stagnate a little, not badly, just a little, is that it is getting hard to introduces changes. I think source will provide a relief valve - get out of jail free. Cheers, Howard. From howard.lovatt at iee.org Wed Mar 18 03:12:46 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 21:12:46 +1100 Subject: Use "default" keyword for default visibility In-Reply-To: References: <3dd3f56a0903142113we599148y13e012855d900c28@mail.gmail.com> <17b2302a0903142308o330c9942hc866052d05ebdbe4@mail.gmail.com> Message-ID: <3dd3f56a0903180312r7582852aqbb69032c467dac8b@mail.gmail.com> You guys are probably right, it must have been private protected I was thinking of. 2009/3/16 Mark Mahieu : > My first edition copy of Java in a Nutshell says that there were public, > protected, private protected, private and the default, all with distinct > visibility rules. > Mark > > 2009/3/15 Joshua Bloch >> >> Howard, >> Are you sure? ?The only other modifier I remember was "private protected," >> which was quite different from package private. ?I believe that it was >> always the default access mode. ?I thought I coined the term "package >> private" for Effective Java (though it's likely that others came up with >> it >> independently and earlier). >> >> ? ? ? ? ?Josh >> >> On Sat, Mar 14, 2009 at 9:13 PM, Howard Lovatt >> wrote: >> >> > Early versions of Java had package private (I think) for this. It >> > would make the code clearer in that everything would have a keyword. >> > package could be used, since this is the scope of the default. >> > >> > >> > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From scolebourne at joda.org Wed Mar 18 03:51:14 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 18 Mar 2009 10:51:14 +0000 Subject: PROPOSAL : Specify nullable argument In-Reply-To: References: Message-ID: <4b4f45e00903180351l331f7da5se6447568e4641ae9@mail.gmail.com> 2009/3/17 Olivier Chorier : > Here, the '!' indicates a mandatory argument (not null). > > However, I don't know if the '!' marker could be the most appropriate. See http://docs.google.com/View?docid=dfn5297z_2kjj2fk and http://www.jroller.com/scolebourne/entry/java_7_null_safe_types So, yes, the ! is probably appropriate, although I place it after the type. Unfortunately, JSR305 is pushing Java down the annotation route for this. I personally find this verbose and broken (as the check is optional not mandatory which is misleading). That said, type system changes like String! are out of scope for Coin. Stephen From howard.lovatt at iee.org Wed Mar 18 04:04:12 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Wed, 18 Mar 2009 22:04:12 +1100 Subject: Draft proposal: allow the use of relational operators on Comparable classes Message-ID: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> You could use new operators: .<. .<=. .>. .>=. .==. The dots are meant to remind everyone that a method, comparable, is called. From develop4lasu at gmail.com Wed Mar 18 04:05:41 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 18 Mar 2009 12:05:41 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> References: <6aef848f0903100909v273b694cs3e8f465d262ceaf9@mail.gmail.com> Message-ID: <28bca0ff0903180405i449f052xbbfe696c1a03d0ef@mail.gmail.com> 2009/3/10 Vilya Harvey > I've attached a draft of a proposal to allow classes which implement the > Comparable interface to be used as operands for the relational operators. > So > for example if you had two Strings, a and b, you would be able to write > > if (a < b) { > ... > } > > instead of > > if (a.compareTo(b) < 0) { > ... > } > > and you could do the same with your own classes as well. > > Thanks in advance for any feedback, > > Vil. > > > > I'm against. Normally I use up to 4 kinds of comparators for each object. This solution is not able to handle this. I would suggest: < operation :: (operator) > :: blockWhereOperatorWork < operation :: (operator) > :: ; // work to end of this block usage: value|variable (operator) value|variable Sample (short): < comparator.compare(A,B) :: A(>)B >::{ if (someA (>) someB) {...} ... } < A.compareTo(B) :: A(>)B >::{ if (someA (>) someB) {...} else if (someC (>) someD)... } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From lapsus63 at gmail.com Wed Mar 18 04:57:31 2009 From: lapsus63 at gmail.com (Olivier Chorier) Date: Wed, 18 Mar 2009 12:57:31 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> References: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> Message-ID: I think dots are not a good solution because IDE are used to propose auto-completion with it 2009/3/18 Howard Lovatt > You could use new operators: > > .<. > .<=. > .>. > .>=. > .==. > > The dots are meant to remind everyone that a method, comparable, is called. > > From Thomas.Hawtin at Sun.COM Wed Mar 18 05:18:09 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Wed, 18 Mar 2009 12:18:09 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: References: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> Message-ID: <49C0E681.7070307@sun.com> Olivier Chorier wrote: > I think dots are not a good solution because IDE are used to propose > auto-completion with it Then IDEs could propose one of these operators. Looks like an advantage to me. Another potential issue with the language proposal is that compareTo is potentially somewhat less efficient than less general methods. For instance String.equals implementations can quickly determine that the argument is different through hash code and length. Computing compareTo could be much slower. Tom Hawtin > 2009/3/18 Howard Lovatt > >> You could use new operators: >> >> .<. >> .<=. >> .>. >> .>=. >> .==. >> >> The dots are meant to remind everyone that a method, comparable, is called. From Ruslan.Lazukov at digia.com Wed Mar 18 05:26:57 2009 From: Ruslan.Lazukov at digia.com (Ruslan) Date: Wed, 18 Mar 2009 15:26:57 +0300 Subject: Small property support. Message-ID: <49C0E891.7000901@digia.com> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Ruslan Lazukov OVERVIEW Create infrastructure for using properties in Java, but make it small change for becoming part of Java 7. I suggest to use synthetic sugar for properties in Java 7. FEATURE SUMMARY: Lack of properties in Java make developers to create a lot of solutions for solving this issue. But issue can be solved only from language level. MAJOR ADVANTAGE: Solve lack of Java property support, but this solve will be small not medium size. MAJOR BENEFIT: Improve check ability of java code. Improve readability of code. Code become less error prone. MAJOR DISADVANTAGE: Developer should understand how properties work - the same as enhanced for-each. For-each are synthetic and real code are hidden from developer. ALTERNATIVES: No; Every solution need to change language. EXAMPLES SIMPLE EXAMPLE: this code made by developer: public property int i; private void foo() { this->i = 5; int j = this->i; } will be translated by compiler to this code: private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } private void foo() { setI(5); int j = getI(); } ADVANCED EXAMPLE: code: public property String str { get { return str; } set { this.str = value; } }; transforms to this code: private String str; publiv void steStr(String value){ this.str = value; } public String getStr() { return str; } change this code (from developer side): obj2.setX(obj.getX() + obj.getY() * (obj.getZ() + obj.getName().length())); to this code (from developer side): obj->x = obj->x + obj->y * (obj->z + obj->name.length()); Every developer can easily understand is it a field pr a property. Field can be accessed by '.' (dot), and property by '->' (arrow). Examples can be read here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 DETAILS SPECIFICATION: Main problem of Java property support in Java 7 is that Sun want to create solution at one step. But also Sun do not have enough time and resources to do this for Java 7. My suggestion is to split "property" into many steps, and make some of them in Java 7. We can use documentation created for HUGE property support, and write code only in java compiler. All other stuff like changes in Reflection API - stay for next 3-5 years (for Java 8 release). HUGE property support described here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 I suggest implementation of language changes without Property object, changes in Reflection API and necessity to sit and wait 5 years for time when Java code become more readable. COMPILATION: How would the feature be compiled to class files? No additional support necessary in class files. TESTING: How can the feature be tested? The same way as for-each. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No, not for Java 7. REFLECTIVE APIS: No, not for Java 7. OTHER CHANGES: No, not for Java 7. MIGRATION: No migration needed. COMPATIBILITY BREAKING CHANGES: All existing programs remain valid. EXISTING PROGRAMS: The semantics of existing class files and legal source files and are unchanged by this feature. REFERENCES EXISTING BUGS: I think that there is a lot of bugs in Sun bug-tracking system. URL FOR PROTOTYPE (optional): Document about HUGE property that Sun presented to developers http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf, page 27. Also Sun (probably) developers create a lot of documentation how property should be supported from language level. That documents have to be used to implement this proposal fast and easy. HUGE property support described here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 WBR, Ruslan. From rssh at gradsoft.com.ua Wed Mar 18 03:53:48 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 18 Mar 2009 12:53:48 +0200 (EET) Subject: String literals in Java 7: version 1.2 In-Reply-To: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> Message-ID: <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> > The things I miss in Java strings are: > > 1. Embedding expressions, e.g. in JavaFX you can write "The answer is > {answer ? "Yes" : "No"}". In the example the part inside the {} is > evaluated and replaced by its value, if that value isn't a string then > it is converted to a string automatically. Simple case - works now. boolean x = true; String answer = (x ? "yes" : "no"); Complex case: Create special syntax for template processing inside strings - I guess this can be a library issue. We have jsr223. May be good ideaa is adding helper methods, which process string via choosed language interptreter, i.e. s.scriptEval("velocity",binding); .... but - from other side we can't receive binding between names and values automatically for now. So, will think. For me, approach is interesting, but I have more questions than answers. > > 2. Easy internationalisation, e.g. in JavaFX you can write > ##"Favourites" and the compiler internationalises your code and > creates a properties file which you then edit for the different > locales ("Favourites" = "Favorites") > I guess this can be nice small new proposal, if think about ## as not part of literal, but unary operator. Btw - interessting, why nobody fire 'simple operator overloading' proposal yet ? > I am not saying that your other extensions to Java Strings are not > good suggestions, just that I miss these more. It would also be nice > to be similar to JavaFX, since the two are likely to be used together. > > From david.goodenough at linkchoose.co.uk Wed Mar 18 06:40:50 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 18 Mar 2009 13:40:50 +0000 Subject: Small property support. In-Reply-To: <49C0E891.7000901@digia.com> References: <49C0E891.7000901@digia.com> Message-ID: <200903181340.52296.david.goodenough@linkchoose.co.uk> On Wednesday 18 March 2009, Ruslan wrote: > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Ruslan Lazukov > > OVERVIEW > Create infrastructure for using properties in Java, but make it small > change for becoming part of Java 7. > I suggest to use synthetic sugar for properties in Java 7. > > FEATURE SUMMARY: > Lack of properties in Java make developers to create a lot of solutions > for solving this issue. > But issue can be solved only from language level. > > MAJOR ADVANTAGE: > Solve lack of Java property support, but this solve will be small not > medium size. > > MAJOR BENEFIT: > Improve check ability of java code. Improve readability of code. > Code become less error prone. > > MAJOR DISADVANTAGE: > Developer should understand how properties work - the same as enhanced > for-each. > For-each are synthetic and real code are hidden from developer. > > ALTERNATIVES: > No; Every solution need to change language. > > EXAMPLES > > SIMPLE EXAMPLE: > this code made by developer: > public property int i; > > private void foo() { > this->i = 5; > int j = this->i; > } > > will be translated by compiler to this code: > private int i; > > public int getI() { > return i; > } > > public void setI(int i) { > this.i = i; > } > > private void foo() { > setI(5); > int j = getI(); > } > > > ADVANCED EXAMPLE: > code: > public property String str { > get { > return str; > } > set { > this.str = value; > } > }; > > transforms to this code: > private String str; > > publiv void steStr(String value){ > this.str = value; > } > > public String getStr() { > return str; > } > > change this code (from developer side): > obj2.setX(obj.getX() + obj.getY() * (obj.getZ() + obj.getName().length())); > > to this code (from developer side): > obj->x = obj->x + obj->y * (obj->z + obj->name.length()); > > > Every developer can easily understand is it a field pr a property. > Field can be accessed by '.' (dot), and property by '->' (arrow). > > Examples can be read here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > > > DETAILS > SPECIFICATION: > Main problem of Java property support in Java 7 is that Sun want to > create solution at one step. > But also Sun do not have enough time and resources to do this for Java 7. > > My suggestion is to split "property" into many steps, and make some of > them in Java 7. > > We can use documentation created for HUGE property support, and write > code only in java compiler. > All other stuff like changes in Reflection API - stay for next 3-5 years > (for Java 8 release). > > HUGE property support described here > http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > > I suggest implementation of language changes without Property object, > changes in Reflection API and necessity to sit > and wait 5 years for time when Java code become more readable. > > > COMPILATION: How would the feature be compiled to class files? > No additional support necessary in class files. > > TESTING: How can the feature be tested? > The same way as for-each. > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > No, not for Java 7. > > REFLECTIVE APIS: > No, not for Java 7. > > > OTHER CHANGES: > No, not for Java 7. > > MIGRATION: > No migration needed. > > > COMPATIBILITY > BREAKING CHANGES: > All existing programs remain valid. > > EXISTING PROGRAMS: > The semantics of existing class files and legal source files and are > unchanged by this feature. > > REFERENCES EXISTING BUGS: > I think that there is a lot of bugs in Sun bug-tracking system. > > URL FOR PROTOTYPE (optional): > Document about HUGE property that Sun presented to developers > http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf, > page 27. > > Also Sun (probably) developers create a lot of documentation how > property should be supported from language level. > That documents have to be used to implement this proposal fast and easy. > HUGE property support described here > http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > > > WBR, Ruslan. Ruslan, Have you read my Lightweight Property proposal. It takes a similar approach in that it splits the full Property proposal into smaller chunks, but it does not involve adding a property keyword (any field can be a property) and it does not adding get and set as parts of field declaration. Instead in concentrates on the uses of properties, in places like the Beans Binding frameworks and the JPA Criteria API. For these it is necessary to have a Property object that can be generated in an IDE or compiler checkable way and can be passed into the framework. David From Ruslan.Lazukov at digia.com Wed Mar 18 06:50:23 2009 From: Ruslan.Lazukov at digia.com (Ruslan) Date: Wed, 18 Mar 2009 16:50:23 +0300 Subject: Small property support. In-Reply-To: <200903181340.52296.david.goodenough@linkchoose.co.uk> References: <49C0E891.7000901@digia.com> <200903181340.52296.david.goodenough@linkchoose.co.uk> Message-ID: <49C0FC1F.2010002@digia.com> Hello. Yes, i have read it. But we are trying to fix different things: - You are trying to get rid of strings in "Beans Binding of JPA Criteria API" - And my point is to make property code readable and get rid of getters/setters when use Dependency Injection. HUGE property that was declined by Sun can solve both my and your problem. So i am trying to solve other issue than you even if we are speaking about same things. BR, Ruslan. David Goodenough: > On Wednesday 18 March 2009, Ruslan wrote: > >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): Ruslan Lazukov >> >> OVERVIEW >> Create infrastructure for using properties in Java, but make it small >> change for becoming part of Java 7. >> I suggest to use synthetic sugar for properties in Java 7. >> >> FEATURE SUMMARY: >> Lack of properties in Java make developers to create a lot of solutions >> for solving this issue. >> But issue can be solved only from language level. >> >> MAJOR ADVANTAGE: >> Solve lack of Java property support, but this solve will be small not >> medium size. >> >> MAJOR BENEFIT: >> Improve check ability of java code. Improve readability of code. >> Code become less error prone. >> >> MAJOR DISADVANTAGE: >> Developer should understand how properties work - the same as enhanced >> for-each. >> For-each are synthetic and real code are hidden from developer. >> >> ALTERNATIVES: >> No; Every solution need to change language. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> this code made by developer: >> public property int i; >> >> private void foo() { >> this->i = 5; >> int j = this->i; >> } >> >> will be translated by compiler to this code: >> private int i; >> >> public int getI() { >> return i; >> } >> >> public void setI(int i) { >> this.i = i; >> } >> >> private void foo() { >> setI(5); >> int j = getI(); >> } >> >> >> ADVANCED EXAMPLE: >> code: >> public property String str { >> get { >> return str; >> } >> set { >> this.str = value; >> } >> }; >> >> transforms to this code: >> private String str; >> >> publiv void steStr(String value){ >> this.str = value; >> } >> >> public String getStr() { >> return str; >> } >> >> change this code (from developer side): >> obj2.setX(obj.getX() + obj.getY() * (obj.getZ() + obj.getName().length())); >> >> to this code (from developer side): >> obj->x = obj->x + obj->y * (obj->z + obj->name.length()); >> >> >> Every developer can easily understand is it a field pr a property. >> Field can be accessed by '.' (dot), and property by '->' (arrow). >> >> Examples can be read here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 >> >> >> DETAILS >> SPECIFICATION: >> Main problem of Java property support in Java 7 is that Sun want to >> create solution at one step. >> But also Sun do not have enough time and resources to do this for Java 7. >> >> My suggestion is to split "property" into many steps, and make some of >> them in Java 7. >> >> We can use documentation created for HUGE property support, and write >> code only in java compiler. >> All other stuff like changes in Reflection API - stay for next 3-5 years >> (for Java 8 release). >> >> HUGE property support described here >> http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 >> >> I suggest implementation of language changes without Property object, >> changes in Reflection API and necessity to sit >> and wait 5 years for time when Java code become more readable. >> >> >> COMPILATION: How would the feature be compiled to class files? >> No additional support necessary in class files. >> >> TESTING: How can the feature be tested? >> The same way as for-each. >> >> LIBRARY SUPPORT: Are any supporting libraries needed for the feature? >> No, not for Java 7. >> >> REFLECTIVE APIS: >> No, not for Java 7. >> >> >> OTHER CHANGES: >> No, not for Java 7. >> >> MIGRATION: >> No migration needed. >> >> >> COMPATIBILITY >> BREAKING CHANGES: >> All existing programs remain valid. >> >> EXISTING PROGRAMS: >> The semantics of existing class files and legal source files and are >> unchanged by this feature. >> >> REFERENCES EXISTING BUGS: >> I think that there is a lot of bugs in Sun bug-tracking system. >> >> URL FOR PROTOTYPE (optional): >> Document about HUGE property that Sun presented to developers >> http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf, >> page 27. >> >> Also Sun (probably) developers create a lot of documentation how >> property should be supported from language level. >> That documents have to be used to implement this proposal fast and easy. >> HUGE property support described here >> http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 >> >> >> WBR, Ruslan. >> > > Ruslan, > > Have you read my Lightweight Property proposal. It takes a similar > approach in that it splits the full Property proposal into smaller chunks, > but it does not involve adding a property keyword (any field can be > a property) and it does not adding get and set as parts of field > declaration. > > Instead in concentrates on the uses of properties, in places like the > Beans Binding frameworks and the JPA Criteria API. For these it is > necessary to have a Property object that can be generated in an IDE > or compiler checkable way and can be passed into the framework. > > David > From rssh at gradsoft.com.ua Wed Mar 18 04:14:59 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 18 Mar 2009 13:14:59 +0200 (EET) Subject: Enhanced String literal for Java: version 1.3 with implementation. Message-ID: Good day. Here is next version with enhanced string literals for Java. Changes are: - compiler part of implementation with set of jtreg tests is added. (technically, I see, that jdk and langtools are different projects in java net, so looks, like I can't write test, which work with library, and library changes must be technically next step ?) - refined process of leading whitespace elimination, to allow less number of whitespaces in last line of multiline string, which consists only from close quotes. - Incorrect common whitespace prefix in multiline string now casue warning, not error. - Jeremy Manson removed himself from list of authors. His 'raw' strings left in proposal. - Added references to - proposal by Stephen Colebourne; - very clever proposal and library 'implementation' by by Sven Efftinge; - funny proposal by Felix Frost. - Cosmetics changes in text. Here is next version: 1.3 AUTHOR(s): Ruslan Shevchenko, Reinier Zwitserloot (if agree) OVERVIEW: FEATURE SUMMARY: new string literals in java language: * multiline string literals. * string literals without escape processing. MAJOR ADVANTAGE: Possibility more elegant to code strings from other languages, such as sql constructions or inline xml (for multiline strings) or regular expressions (for string literals without escape processing). MAJOR DISADVANTAGE Small increasing of language complexity. ALTERNATIVES: For multiline strings use operations and concatenation methods, such as: String,contact("Multiline \n", "string "); or String bigString="First line\n"+ "second line" For unescaped ('raw') stings - use escaping of ordinary java string. EXAMPLES SIMPLE EXAMPLE: Multiline string: StringBuilder sb = new StringBuilder(); sb.append("""select a from Area a, CountryCodes cc where cc.isoCode='UA' and a.owner = cc.country """); if (question.getAreaName()!=null) { sb.append("""and a.name like ? """); sqlParams.setString(++i,question.getAreaName()); } instead: StringBuilder sb = new StringBuilder(); sb.append("select a from Area a, CountryCodes cc\n"); sb.append("where cc.isoCode='UA'\n"); sb.append("and a.owner=cc.country'\n"); if (question.getAreaName()!=null) { sb.append("and a.name like ?"); sqlParams.setString(++i,question.getAreaName()); } String platformDepended="""q """.nativeLf(); is 'q\n' if run on Unix and 'q\n\r' if run on Windows. String platformIndepended="""q """; is always "q\n". String platformIndepended="""q """U.unixLf(); is the same. String platformIndepended=""" """.windowsLf(); is always '\r\n'. Unescaped String: String myParrern=''..*\.*''; instead String myParrern="\..*\\.*"; String fname=''C:\Program Files\My Program\Configuration''; instead String myParrern="C:\\Program Files\\My Program\\Configuration"; ADVANCED EXAMPLE: String empty=""" """; is empty. String foo = """ bar baz bla qux"; is equal to: String foo = "bar\n baz\n bla\nqux"; and the following: String foo = """ foo bar"""; is compiled to "foo\nbar" as compilation warning String manyQuotes="""\"""\"\"\""""; is """"" String s = """I'm long string in groovy stile wi\ th \\ at end of line"""; is: I'm long string in groovy stile with \ at end of line String s = '' I'm long string in groovy stile wi\ th \\ at end of line''; is: I'm long string in groovy stile wi\ th \\ at end of line DETAILS: Multiline strings are part of program text, which begin and ends by three double quotes. I. e. grammar in 3.10.5 of JLS can be extented as:
MultilineStringLiteral:
        """ MultilineStringCharacters/opt """

MultilineStringCharacters:
        MultilineStringCharacter
        MultilineStringCharacters  (MultilineStringCharacter but not ")
        (MultilineStringCharacters but not "") "

MultilineStringCharacter:
        InputCharacter but not \
        EscapeSequence
        LineTermination
        EolEscapeSequence

EolEscapeSequence: \LineTermination.

Unescaped strings are part of program text, which begin and ends by two single quotes.
 RowStringLiteral:
                   '' RowInputCharacters/opt ''

 RowInputCharacters:
                      ' (InputCharacter but not ')
                     |
                      (InputCharacter but not ') '
                     |
                      LineTermination
Methods for replacing line termination sequences in string to native format of host platform, and to well-known unix/windows formats must be added to standard library. COMPILATION: Handling of multiline strings: Text within """ brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. escape sequences in each line are processed exactly as in ordinary Java strings. 3. sequence \LineTermination at the end of line is erased and such line cause line be concatenated with next line in one. 4. elimination of leading whitespaces are processed in next way: - at first determinate sequence of whitespace symbols (exclude LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. let's call it 'leading whitespace sequence' - all next lines, except case, when last line consists only from multiline string close quotes (""") must start with same leading whitespace sequence. - whitespace processing erase such leading sequence from resulting lines. If line does not start with leading whitespace sequence, than compilation warning is issued 5. set of lines after erasing of leading whitespace sequence is concatenated, with LF (i. e. '\n') line-termination sequences between two neighbour lines, regardless of host system Handling of row strings: Text within '' brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. set of lines after erasing of leading whitespace sequence is concatenated, with '\n' line-termination sequences between two neighbour lines, No escape processing, no leading whitespace elimination are performed for receiving of resulting string value. new strings literals created and used in .class files exactly as ordinary strings. TESTING: add new strings literals to test-cases for all combinations of finished and unfinished escape sequences and quotes. LIBRARY SUPPORT: It would be good add to String next methods: s.platformLf() - returns string which replace all line-termination sequences in s by value of system property 'line.separator' s.unixLf() - returns string which replace all line-termination sequences in s by '\n' s.windowsLf() - returns string which replace all line-termination sequences in s by '\r\n' REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/view_bug.do?bug_id=4165111 http://bugs.sun.com/view_bug.do?bug_id=4472509 http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd by by Jacek Furmankiewicz http://blog.efftinge.de/2008/10/multi-line-string-literals-in-java.html library implementation by Sven Efftinge http://www.jroller.com/scolebourne/entry/java_7_multi_line_string - proposal by Stephen Colebourne http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000331.html - alternative joke proposal by Felix Frost IMPLEMENTATION URL: Compiler changes with set of jtreg tests available from mercurial repository at http://datacenter.gradsoft.ua/mercurial/cgi/hgwebdir.cgi/jdk7/tl/langtools/ From david.goodenough at linkchoose.co.uk Wed Mar 18 07:05:50 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 18 Mar 2009 14:05:50 +0000 Subject: Small property support. In-Reply-To: <49C0FC1F.2010002@digia.com> References: <49C0E891.7000901@digia.com> <200903181340.52296.david.goodenough@linkchoose.co.uk> <49C0FC1F.2010002@digia.com> Message-ID: <200903181405.52957.david.goodenough@linkchoose.co.uk> On Wednesday 18 March 2009, Ruslan wrote: > Hello. > > Yes, i have read it. > But we are trying to fix different things: > - You are trying to get rid of strings in "Beans Binding of JPA Criteria > API" As a matter of interest, how would I pass a property reference using your proposal? > - And my point is to make property code readable and get rid of > getters/setters when use Dependency Injection. For simple getters and setters, my proposal does actually get rid of getters and setters, in that the Property object will do the work for you using the Field get and set (and some snake oil to handle PropertyChangeSupport). David > > HUGE property that was declined by Sun can solve both my and your problem. > > So i am trying to solve other issue than you even if we are speaking > about same things. > > BR, > Ruslan. > > David Goodenough: > > On Wednesday 18 March 2009, Ruslan wrote: > >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > >> > >> AUTHOR(S): Ruslan Lazukov > >> > >> OVERVIEW > >> Create infrastructure for using properties in Java, but make it small > >> change for becoming part of Java 7. > >> I suggest to use synthetic sugar for properties in Java 7. > >> > >> FEATURE SUMMARY: > >> Lack of properties in Java make developers to create a lot of solutions > >> for solving this issue. > >> But issue can be solved only from language level. > >> > >> MAJOR ADVANTAGE: > >> Solve lack of Java property support, but this solve will be small not > >> medium size. > >> > >> MAJOR BENEFIT: > >> Improve check ability of java code. Improve readability of code. > >> Code become less error prone. > >> > >> MAJOR DISADVANTAGE: > >> Developer should understand how properties work - the same as enhanced > >> for-each. > >> For-each are synthetic and real code are hidden from developer. > >> > >> ALTERNATIVES: > >> No; Every solution need to change language. > >> > >> EXAMPLES > >> > >> SIMPLE EXAMPLE: > >> this code made by developer: > >> public property int i; > >> > >> private void foo() { > >> this->i = 5; > >> int j = this->i; > >> } > >> > >> will be translated by compiler to this code: > >> private int i; > >> > >> public int getI() { > >> return i; > >> } > >> > >> public void setI(int i) { > >> this.i = i; > >> } > >> > >> private void foo() { > >> setI(5); > >> int j = getI(); > >> } > >> > >> > >> ADVANCED EXAMPLE: > >> code: > >> public property String str { > >> get { > >> return str; > >> } > >> set { > >> this.str = value; > >> } > >> }; > >> > >> transforms to this code: > >> private String str; > >> > >> publiv void steStr(String value){ > >> this.str = value; > >> } > >> > >> public String getStr() { > >> return str; > >> } > >> > >> change this code (from developer side): > >> obj2.setX(obj.getX() + obj.getY() * (obj.getZ() + > >> obj.getName().length())); > >> > >> to this code (from developer side): > >> obj->x = obj->x + obj->y * (obj->z + obj->name.length()); > >> > >> > >> Every developer can easily understand is it a field pr a property. > >> Field can be accessed by '.' (dot), and property by '->' (arrow). > >> > >> Examples can be read here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > >> > >> > >> DETAILS > >> SPECIFICATION: > >> Main problem of Java property support in Java 7 is that Sun want to > >> create solution at one step. > >> But also Sun do not have enough time and resources to do this for Java > >> 7. > >> > >> My suggestion is to split "property" into many steps, and make some of > >> them in Java 7. > >> > >> We can use documentation created for HUGE property support, and write > >> code only in java compiler. > >> All other stuff like changes in Reflection API - stay for next 3-5 years > >> (for Java 8 release). > >> > >> HUGE property support described here > >> http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > >> > >> I suggest implementation of language changes without Property object, > >> changes in Reflection API and necessity to sit > >> and wait 5 years for time when Java code become more readable. > >> > >> > >> COMPILATION: How would the feature be compiled to class files? > >> No additional support necessary in class files. > >> > >> TESTING: How can the feature be tested? > >> The same way as for-each. > >> > >> LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > >> No, not for Java 7. > >> > >> REFLECTIVE APIS: > >> No, not for Java 7. > >> > >> > >> OTHER CHANGES: > >> No, not for Java 7. > >> > >> MIGRATION: > >> No migration needed. > >> > >> > >> COMPATIBILITY > >> BREAKING CHANGES: > >> All existing programs remain valid. > >> > >> EXISTING PROGRAMS: > >> The semantics of existing class files and legal source files and are > >> unchanged by this feature. > >> > >> REFERENCES EXISTING BUGS: > >> I think that there is a lot of bugs in Sun bug-tracking system. > >> > >> URL FOR PROTOTYPE (optional): > >> Document about HUGE property that Sun presented to developers > >> http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf, > >> page 27. > >> > >> Also Sun (probably) developers create a lot of documentation how > >> property should be supported from language level. > >> That documents have to be used to implement this proposal fast and easy. > >> HUGE property support described here > >> http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > >> > >> > >> WBR, Ruslan. > > > > Ruslan, > > > > Have you read my Lightweight Property proposal. It takes a similar > > approach in that it splits the full Property proposal into smaller > > chunks, but it does not involve adding a property keyword (any field can > > be a property) and it does not adding get and set as parts of field > > declaration. > > > > Instead in concentrates on the uses of properties, in places like the > > Beans Binding frameworks and the JPA Criteria API. For these it is > > necessary to have a Property object that can be generated in an IDE > > or compiler checkable way and can be passed into the framework. > > > > David From Ruslan.Lazukov at digia.com Wed Mar 18 07:23:54 2009 From: Ruslan.Lazukov at digia.com (Ruslan) Date: Wed, 18 Mar 2009 17:23:54 +0300 Subject: Small property support. In-Reply-To: <200903181405.52957.david.goodenough@linkchoose.co.uk> References: <49C0E891.7000901@digia.com> <200903181340.52296.david.goodenough@linkchoose.co.uk> <49C0FC1F.2010002@digia.com> <200903181405.52957.david.goodenough@linkchoose.co.uk> Message-ID: <49C103FA.909@digia.com> Hello. David Goodenough wrote: > On Wednesday 18 March 2009, Ruslan wrote: > >> Hello. >> >> Yes, i have read it. >> But we are trying to fix different things: >> - You are trying to get rid of strings in "Beans Binding of JPA Criteria >> API" >> > As a matter of interest, how would I pass a property reference using > your proposal? > My proposal have another goal. Goal is to have synthetic sugar like for-each for property. And in my case there is not property reference, so you can not pass it. Property references can be added at next release (5 years later ;) ). >> - And my point is to make property code readable and get rid of >> getters/setters when use Dependency Injection. >> > For simple getters and setters, my proposal does actually get rid of > getters and setters, in that the Property object will do the work for you > using the Field get and set (and some snake oil to handle > PropertyChangeSupport). > Yes, that is true. And my proposal are not using Property or Field. It's like macros for property get/set generation. > David > PS my goal is to avoid situation like this: private int i; public String getI() { return Integer.toString(i); } public void setI(long i) { this.i = (int)i; } What is the type of property 'i' ? private int i; public int getJ() { return i; } public void setI(int i) { this.i = i; } IS everyone see that there is not getter for 'i' - we have getter for 'j'. But compiler will not fix this error, because it is a logical error, not language. Ruslan. From david.goodenough at linkchoose.co.uk Wed Mar 18 07:46:49 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 18 Mar 2009 14:46:49 +0000 Subject: Small property support. In-Reply-To: <49C103FA.909@digia.com> References: <49C0E891.7000901@digia.com> <200903181405.52957.david.goodenough@linkchoose.co.uk> <49C103FA.909@digia.com> Message-ID: <200903181446.51430.david.goodenough@linkchoose.co.uk> On Wednesday 18 March 2009, Ruslan wrote: > Hello. > > David Goodenough wrote: > > On Wednesday 18 March 2009, Ruslan wrote: > >> Hello. > >> > >> Yes, i have read it. > >> But we are trying to fix different things: > >> - You are trying to get rid of strings in "Beans Binding of JPA Criteria > >> API" > > > > As a matter of interest, how would I pass a property reference using > > your proposal? > > My proposal have another goal. Goal is to have synthetic sugar like > for-each for property. > And in my case there is not property reference, so you can not pass it. > > Property references can be added at next release (5 years later ;) ). > > >> - And my point is to make property code readable and get rid of > >> getters/setters when use Dependency Injection. > > > > For simple getters and setters, my proposal does actually get rid of > > getters and setters, in that the Property object will do the work for you > > using the Field get and set (and some snake oil to handle > > PropertyChangeSupport). > > Yes, that is true. And my proposal are not using Property or Field. It's > like macros for property get/set generation. > > > David > > PS my goal is to avoid situation like this: > private int i; > > public String getI() { > return Integer.toString(i); > } > > public void setI(long i) { > this.i = (int)i; > } > > What is the type of property 'i' ? > > private int i; > > public int getJ() { > return i; > } > > public void setI(int i) { > this.i = i; > } > > IS everyone see that there is not getter for 'i' - we have getter for > 'j'. But compiler will not fix this error, because it is a logical > error, not language. > > > Ruslan. In my proposal all you have to do is to declare i, and I will provide you with getter and setter access to it through the Property object. So you would have:- class Foo { private int i; } ... PropertypropI = foo#i; propI.set(6); and if Foo had a PropertyChangeSupport object as a field, it would fire the correct PropertyChangeEvent as well. It is of course entirely compiler checkable. David From mbien at fh-landshut.de Wed Mar 18 07:57:05 2009 From: mbien at fh-landshut.de (Michael Bien) Date: Wed, 18 Mar 2009 15:57:05 +0100 Subject: Small property support. In-Reply-To: <49C103FA.909@digia.com> References: <49C0E891.7000901@digia.com> <200903181340.52296.david.goodenough@linkchoose.co.uk> <49C0FC1F.2010002@digia.com> <200903181405.52957.david.goodenough@linkchoose.co.uk> <49C103FA.909@digia.com> Message-ID: <49C10BC1.1000604@fh-landshut.de> I would even start smaller, should I call it tiny property support? ;) @get @set private int i; would tell the compiler to generate getter setter and property change listener methods for the field 'i'. No additonal keywords and no arrow(->) syntax required. Writing the property 'i' in the bean would cause a compiler warning, reading would be fine. Calling setters would be the preferred way to modify properties from inside or outside the bean. I know Annotations are not intended to change the meaning of a field or its behaviour. But this is rather a shortcut to the bean pattern than the usual language change proposal. I see it rather as temporary and probably even as smallest possible property feature instead of a final solution. JDK8 could add real first class properties without conflicts with this proposal (again its just the bean pattern), you could even keep the Annotations it wouldn't hurt. no changes to javadoc, compiler etc. what do you think? Should I try to file a proposal or do you already spot show stoppers? best regards, Michael Bien Ruslan wrote: > Hello. > > David Goodenough wrote: > >> On Wednesday 18 March 2009, Ruslan wrote: >> >> >>> Hello. >>> >>> Yes, i have read it. >>> But we are trying to fix different things: >>> - You are trying to get rid of strings in "Beans Binding of JPA Criteria >>> API" >>> >>> >> As a matter of interest, how would I pass a property reference using >> your proposal? >> >> > My proposal have another goal. Goal is to have synthetic sugar like > for-each for property. > And in my case there is not property reference, so you can not pass it. > > Property references can be added at next release (5 years later ;) ). > > > >>> - And my point is to make property code readable and get rid of >>> getters/setters when use Dependency Injection. >>> >>> >> For simple getters and setters, my proposal does actually get rid of >> getters and setters, in that the Property object will do the work for you >> using the Field get and set (and some snake oil to handle >> PropertyChangeSupport). >> >> > Yes, that is true. And my proposal are not using Property or Field. It's > like macros for property get/set generation. > >> David >> >> > PS my goal is to avoid situation like this: > private int i; > > public String getI() { > return Integer.toString(i); > } > > public void setI(long i) { > this.i = (int)i; > } > > What is the type of property 'i' ? > > private int i; > > public int getJ() { > return i; > } > > public void setI(int i) { > this.i = i; > } > > IS everyone see that there is not getter for 'i' - we have getter for > 'j'. But compiler will not fix this error, because it is a logical > error, not language. > > > Ruslan. > > > From neal at gafter.com Wed Mar 18 08:18:24 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 08:18:24 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903180115t79d9de95ndda9fba3e8bd7336@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <15e8b9d20903172243o6a9a4aabxc32b0bc3638027e4@mail.gmail.com> <1631da7d0903180013w13d175c2yca1b2684df6f05ed@mail.gmail.com> <15e8b9d20903180024o62455db2o9a37e87389e8c86f@mail.gmail.com> <1631da7d0903180115t79d9de95ndda9fba3e8bd7336@mail.gmail.com> Message-ID: <15e8b9d20903180818y37c93a19p274ff03aa86f5b8e@mail.gmail.com> On Wed, Mar 18, 2009 at 1:15 AM, Jeremy Manson wrote: > I'm pretty sure that it is only definitely unassigned there if it is > definitely unassigned after the switch expression. ?If you want it to > compile, you have to place the declaration before the switch > statement. ?I could be wrong about that. JLS 16.2.2 says # A local variable V is definitely unassigned (and moreover is not definitely assigned) before the block that is the body of the constructor, method, instance initializer or static initializer that declares V . So moving the declaration up should have no impact. And yet the following program compiles. Why should this compile and the previous one fail to compile? import java.io.*; class T { public static void main(String[] args) { switch (args.length) { case 0: final int i; i = 0; break; case 1: i = 1; // i is definitely unassigned here, so we assign to it System.out.println(i); break; } } } spoiler below. The answer can be found in JLS 15.26: "A variable that is declared final cannot be assigned to (unless it is a definitely unassigned (?16) blank final variable (?4.12.4)), ..." Note particularly the word "blank". You're not allowed to assign to a final variable that is definitely unassigned unless it is a blank final. The original version of this puzzler is the only way to create a variable that is final and definitely unassigned, but not a blank final. It also shows a way to create a constant variable that is not definitely assigned. Should the following snippet compile? switch (args.length) { case 0: final int i = 0; // declare a constant break; case 1: System.out.println(i); // print the value of the constant variable break; } The point of this series of puzzles is that, due to the strangeness of the switch statement, building a resource language construct based on variable scope can be subtle. The simplest way to avoid problems is to say that you can't use a resource-variable-declaration-statement at the top level within a switch statement. From felixf977 at gmail.com Wed Mar 18 08:22:48 2009 From: felixf977 at gmail.com (Felix Frost) Date: Wed, 18 Mar 2009 11:22:48 -0400 Subject: Proposal: Enhanced String constructs for Java In-Reply-To: <49BE70A3.5040303@jazillian.com> References: <49BE70A3.5040303@jazillian.com> Message-ID: I liek nu proposal betterz. We kittehs r gud, we'z found http://lolcode.com. Glad u'z enjoy mah poposal! Kthxbye -Felx Frost Kitteh Prograhamer LOLcode Expert twitter: http://twitter.com/felixf977 On Mon, Mar 16, 2009 at 11:30 AM, Andy Tripp wrote: > Felix, > > One major disadvantage you didn't mention is the addition of keywords. > This could be either a huge show-stopper issue or a complete non-issue, > depending on the reputation of the proposal submitter. > > You should either mention this disadvantage, or simply say that you > don't think it seems to be an issue, like this: > > http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000033.html > > Andy ;) > > From neal at gafter.com Wed Mar 18 10:23:46 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 10:23:46 -0700 Subject: PRE-PROPOSAL: Extension methods Message-ID: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> On Tue, Mar 17, 2009 at 11:56 PM, Kevin Krouse wrote: > I'm interested in extension methods. I'll write up a full proposal if I have any indication it's something Joe/Sun(/IBM) would consider for project Coin. The basic idea would work like this: Within a static method, you can use "this" as an new qualifier on the first method parameter, which must be a reference type. This would be reflected in the class file format as either a new flag, or a new classfile attribute ("ExtensionMethod") on the method. When an extension method has been statically imported, you can use it as if it is a member of the type of its first argument. The name lookup rules for a method invocation o.f(...) are augmented as follows. When identifying candidates for overload resolution, if no accessible candidates of the correct name are found as a member of the static type of the receiver (JLS 15.12.1 and 15.12.2), then we consider as candidates those statically imported methods with name f, and perform the overload resolution among them as if the invocation had been written f(o, ...) This is backward compatible, as it assigns meanings to expressions that were previously errors, and does not change the meaning of code that was not previously an error. There are a number of benefits to this approach. A large number of static utility class members can and probably should be retrofitted to use extension methods, making it possible to use a much more convenient syntax for common operations. import static java.util.Collections.sort; List list = ... list.sort(); // uses Collections.sort extension method Similarly, it allows extension methods to operate on arrays import static java.util.Arrays.sort; String[] strings = ... strings.sort(); // uses Arrays.sort extension method The syntactic convenience of this is greater (i.e. code becomes more readable) when multiple invocations work together in an expression. One of the more important benefits of this approach is that it enables future language changes to be defined by syntactic translation, while allowing more flexible retrofitting of those language changes onto existing APIs than would be possible without extension methods. For example, one could define an ARM construct by translation of something like protected (expression) statement into { Type1 $t1 = expression Type2 $t2 = $t1.protectedStart(); try { statement } finally { $t2.protectedEnd(); } } (with appropriate inversion of suppressed exceptions, if you please). Then, to add support for this new ARM construct to some particular API you would either add these methods to the API or define extension methods. If done using extension methods or final instance methods, they are likely to be inlined by HotSpot if used in frequently executed code, so the performance overhead is vanishingly small. Since extension methods can be added even to existing interfaces without breaking compatibility, such an ARM construct could be retrofitted onto many more APIs than the currently proposed construct. It could easily be retrofitted onto java.util.concurrent.locks.Lock, for example. See also http://www.javac.info/ExtensionMethods.html From Ruslan.Lazukov at digia.com Wed Mar 18 05:04:25 2009 From: Ruslan.Lazukov at digia.com (Ruslan) Date: Wed, 18 Mar 2009 15:04:25 +0300 Subject: Small property support. Message-ID: <49C0E349.4070601@digia.com> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Ruslan Lazukov OVERVIEW Create infrastructure for using properties in Java, but make it small change for becoming part of Java 7. I suggest to use synthetic sugar for properties in Java 7. FEATURE SUMMARY: Lack of properties in Java make developers to create a lot of solutions for solving this issue. But issue can be solved only from language level. MAJOR ADVANTAGE: Solve lack of Java property support, but this solve will be small not medium size. MAJOR BENEFIT: Improve check ability of java code. Improve readability of code. Code become less error prone. MAJOR DISADVANTAGE: Developer should understand how properties work - the same as enhanced for-each. For-each are synthetic and real code are hidden from developer. ALTERNATIVES: No; Every solution need to change language. EXAMPLES SIMPLE EXAMPLE: this code made by developer: public property int i; private void foo() { this->i = 5; int j = this->i; } will be translated by compiler to this code: private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } private void foo() { setI(5); int j = getI(); } ADVANCED EXAMPLE: code: public property String str { get { return str; } set { this.str = value; } }; transforms to this code: private String str; publiv void steStr(String value){ this.str = value; } public String getStr() { return str; } change this code (from developer side): obj2.setX(obj.getX() + obj.getY() * (obj.getZ() + obj.getName().length())); to this code (from developer side): obj->x = obj->x + obj->y * (obj->z + obj->name.length()); Every developer can easily understand is it a field pr a property. Field can be accessed by '.' (dot), and property by '->' (arrow). Examples can be read here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 DETAILS SPECIFICATION: Main problem of Java property support in Java 7 is that Sun want to create solution at one step. But also Sun do not have enough time and resources to do this for Java 7. My suggestion is to split "property" into many steps, and make some of them in Java 7. We can use documentation created for HUGE property support, and write code only in java compiler. All other stuff like changes in Reflection API - stay for next 3-5 years (for Java 8 release). HUGE property support described here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 I suggest implementation of language changes without Property object, changes in Reflection API and necessity to sit and wait 5 years for time when Java code become more readable. COMPILATION: How would the feature be compiled to class files? No additional support necessary in class files. TESTING: How can the feature be tested? The same way as for-each. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No, not for Java 7. REFLECTIVE APIS: No, not for Java 7. OTHER CHANGES: No, not for Java 7. MIGRATION: No migration needed. COMPATIBILITY BREAKING CHANGES: All existing programs remain valid. EXISTING PROGRAMS: The semantics of existing class files and legal source files and are unchanged by this feature. REFERENCES EXISTING BUGS: I think that there is a lot of bugs in Sun bug-tracking system. URL FOR PROTOTYPE (optional): Document about HUGE property that Sun presented to developers http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf, page 27. Also Sun (probably) developers create a lot of documentation how property should be supported from language level. That documents have to be used to implement this proposal fast and easy. HUGE property support described here http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 WBR, Ruslan. From reinier at zwitserloot.com Wed Mar 18 12:03:15 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 20:03:15 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> Message-ID: Howard, the IOException that spins off of file writes is obviously a clear cut case of appropriate use of a checked exception. The point is simply that 'close' on an *OUTPUTSTREAM* makes a lot of sense. Lots of outputstreams use buffering, and in theory your .close() call is the first one that will make anything filter from java through to the OS, and would thus be the first time you get an IOException. In other words, a close() call on an OutputStream can result in write() calls on an underlying non-buffered outputstream, which implies that removing IOException off of an OutputStream's close() method makes absolutely no sense whatsoever unless you also remove it from OutputStream's write() methods. If you're willing to do that, either you're arguing in favour of removing checked exceptions altogether, or otherwise you ought to be arguing that IOException should be re-homed to RuntimeException. Neither of which is on the table for coin. Because ARM should obviously handle OutputStream, it is therefore impossible, within the scope of project coin, to sensibly make ARM Closables not throw anything on close() methods. The general feeling that close() throwing IOExceptions is just plain stupid comes from *INPUTSTREAM*, where your inputstream reading has not thrown any exceptions, and has therefore, by neccessity, read all files and hit the EOF (or whatever other 'I don't need more data' marker you're using) without error. In practice, InputStream.close() throws an IOException about as often as new String(someBytes, "UTF-8"); throws an UnsupportedEncodingException (i.e.: you'll win the lottery first, and get hit by lightning a few times, before that'll ever happen). Therefore, removing IOException from InputStream (and Reader)'s close() methods makes sense, but wouldn't be backwards compatible, so isn't on the table for coin. --Reinier Zwitserloot On Mar 18, 2009, at 05:50, Howard Lovatt wrote: > Hi All, > > 2009/3/15 Neal Gafter : > > [snip] > >> Agreed, though there is one context in which it is possible to jump >> into the scope of a local variable declaration without "executing" >> the >> declaration: the switch statement. > > I thought this was only in C/C++ and Java had plugged this hole - I > guess I am wrong - do you have an example. > > Cheers, > > Howard. > From reinier at zwitserloot.com Wed Mar 18 12:11:55 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 20:11:55 +0100 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> Message-ID: In my opinion, Extension Methods and Static Methods in Interfaces augment each other nicely. You can stuff your Collections.sort() methods in the more appropriate List interface, and then static import them for seamless sorting: import java.util.List; import static java.util.List.sort; public void foo() { someList.sort(); } However, I considered Extension Methods a bit too complicated for Project Coin, and therefore submitted SMI because it seemed simple enough. Extension Methods can always be added in java8. One could even argue then that extension methods in a type that extend themselves (such as sort(this List foo) in java.util.List) are 'auto-imported', or at the very least, IDEs can suggest them as normal and auto-add the import static java.util.List.sort() statement. We don't need to consider this now, just acknowledge that we have the option when its time to think about java8 language additions. The big advantage to having both SMI and EM at that point is IDEs, which the vast majority of java programmers use. An IDE can quite easily suggest EMs from the type you're auto-completing on, and if you pick one, silently add the import statement to make it work. Contrast this to just having EMs: Either: A) The IDE needs to scan every class file in every jar on the entire classpath / in every imported module just to build a list of EMs which can then be suggested, -or- B) types need an annotation to point at a class that contains EMs. This would be a unique move for java; An annotation that is only there to help IDEs; javac can't do anything with it, other than perhaps suggest import statics ("list.sort(); ^^^ did you mean to static import java.util.Collections.sort?") -or- C) IDEs need to make arbitrary rules, such as "I'll only search for EMs within the same package/module as the type". Most of those get more complicated because any auto-complete needs to search multiple type (all parent types of the expression's calculated type). If Extension Methods are in scope for project coin, I'd love to see a proposal, and I would encourage *both* SMI and EM to be accepted. The sum would be greater than the parts. --Reinier Zwitserloot On Mar 18, 2009, at 18:23, Neal Gafter wrote: > On Tue, Mar 17, 2009 at 11:56 PM, Kevin Krouse > wrote: >> I'm interested in extension methods. > > I'll write up a full proposal if I have any indication it's something > Joe/Sun(/IBM) would consider for project Coin. The basic idea would > work like this: > > Within a static method, you can use "this" as an new qualifier on the > first method parameter, which must be a reference type. This would be > reflected in the class file format as either a new flag, or a new > classfile attribute ("ExtensionMethod") on the method. > > When an extension method has been statically imported, you can use it > as if it is a member of the type of its first argument. The name > lookup rules for a method invocation > > o.f(...) > > are augmented as follows. When identifying candidates for overload > resolution, if no accessible candidates of the correct name are found > as a member of the static type of the receiver (JLS 15.12.1 and > 15.12.2), then we consider as candidates those statically imported > methods with name f, and perform the overload resolution among them as > if the invocation had been written > > f(o, ...) > > This is backward compatible, as it assigns meanings to expressions > that were previously errors, and does not change the meaning of code > that was not previously an error. > > There are a number of benefits to this approach. A large number of > static utility class members can and probably should be retrofitted to > use extension methods, making it possible to use a much more > convenient syntax for common operations. > > import static java.util.Collections.sort; > List list = ... > list.sort(); // uses Collections.sort extension method > > Similarly, it allows extension methods to operate on arrays > > import static java.util.Arrays.sort; > String[] strings = ... > strings.sort(); // uses Arrays.sort extension method > > The syntactic convenience of this is greater (i.e. code becomes more > readable) when multiple invocations work together in an expression. > > One of the more important benefits of this approach is that it enables > future language changes to be defined by syntactic translation, while > allowing more flexible retrofitting of those language changes onto > existing APIs than would be possible without extension methods. For > example, one could define an ARM construct by translation of something > like > > protected (expression) statement > > into > > { > Type1 $t1 = expression > Type2 $t2 = $t1.protectedStart(); > try { > statement > } finally { > $t2.protectedEnd(); > } > } > > (with appropriate inversion of suppressed exceptions, if you please). > > Then, to add support for this new ARM construct to some particular API > you would either add these methods to the API or define extension > methods. If done using extension methods or final instance methods, > they are likely to be inlined by HotSpot if used in frequently > executed code, so the performance overhead is vanishingly small. > Since extension methods can be added even to existing interfaces > without breaking compatibility, such an ARM construct could be > retrofitted onto many more APIs than the currently proposed construct. > It could easily be retrofitted onto java.util.concurrent.locks.Lock, > for example. > > See also http://www.javac.info/ExtensionMethods.html From markmahieu at googlemail.com Wed Mar 18 13:05:21 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 18 Mar 2009 20:05:21 +0000 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> Message-ID: 2009/3/18 Neal Gafter > > When an extension method has been statically imported, you can use it > as if it is a member of the type of its first argument. Just out of curiosity, what do you think the behaviour should be when the 'first argument' is null? Put another way, from your experience would the model chosen here for C# be the right choice for Java? Mark From reinier at zwitserloot.com Wed Mar 18 13:28:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 18 Mar 2009 21:28:46 +0100 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> Message-ID: I don't think that's a relevant question. import static java.util.Collections.sort; List foo = something(); foo.sort(); That last line gets rewritten to: Collections.sort(foo); whether or not 'foo' is null does not change that rewrite. It's up the sort method to react to the null. For consistency you could claim its better that the runtime makes an explicit nullcheck here, I guess. But then you'd be inconsistent with the desugaring to a static method call. --Reinier Zwitserloot On Mar 18, 2009, at 21:05, Mark Mahieu wrote: > 2009/3/18 Neal Gafter > >> >> When an extension method has been statically imported, you can use it >> as if it is a member of the type of its first argument. > > > > Just out of curiosity, what do you think the behaviour should be > when the > 'first argument' is null? Put another way, from your experience > would the > model chosen here for C# be the right choice for Java? > > Mark > From fw at deneb.enyo.de Wed Mar 18 13:45:40 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 18 Mar 2009 21:45:40 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: (Reinier Zwitserloot's message of "Wed, 18 Mar 2009 20:03:15 +0100") References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> Message-ID: <87skla8sqz.fsf@mid.deneb.enyo.de> * Reinier Zwitserloot: > The general feeling that close() throwing IOExceptions is just plain > stupid comes from *INPUTSTREAM*, where your inputstream reading has > not thrown any exceptions, and has therefore, by neccessity, read all > files and hit the EOF (or whatever other 'I don't need more data' > marker you're using) without error. This requires quite a few library changes because currently, an InputStream created for a ReadableByteChannel which happens to be a WritableByteChannel as well closes both personae of the channel when the input stream's close method is invoked. You'd have to change that, or you still end up encountering exceptions during close. From fw at deneb.enyo.de Wed Mar 18 14:00:09 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 18 Mar 2009 22:00:09 +0100 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> (Neal Gafter's message of "Wed, 18 Mar 2009 10:23:46 -0700") References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> Message-ID: <87eiwu7die.fsf@mid.deneb.enyo.de> * Neal Gafter: > There are a number of benefits to this approach. A large number of > static utility class members can and probably should be retrofitted to > use extension methods, making it possible to use a much more > convenient syntax for common operations. > > import static java.util.Collections.sort; > List list = ... > list.sort(); // uses Collections.sort extension method (Does this proposal imply import statements? Would they make sense in this context?) > One of the more important benefits of this approach is that it enables > future language changes to be defined by syntactic translation, while > allowing more flexible retrofitting of those language changes onto > existing APIs than would be possible without extension methods. I think the problem here is that you have to figure out which class/static method to import to make ARM work. For a feature like ARM, where the main factor is convenience to counter sloppiness (at least from my point of view), this seems like a significant burden. I think Reinier is right that this feature alone is insufficient to implement proper ARM. But it's probably better than annotation trickery I proposed, or dictating the use of a single interface. Oh, and I wonder how this particular brand of extension method will interact with reifed/compile time generics. From jjb at google.com Wed Mar 18 14:02:14 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 18 Mar 2009 14:02:14 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <87skla8sqz.fsf@mid.deneb.enyo.de> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> Message-ID: <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> I don't think it's realistic, ever, to change this because it isn't compatible to take a throws clause off of an overridable method: it breaks subtypes. One of the things that adds to the pain is the silliness of IOException itself. Why are all exceptions raised during IO checked? No good reason:( Why, in fact, is there such a thing as an IOException? That only tells you where the exception comes from, which you can find out by looking at its class and package. Given the need for a hierarchy, it's a waste to use an exception's sole ancestor to duplicate this information. Much better is to group exceptions based on what they indicate rather than where they come from. Josh On Wed, Mar 18, 2009 at 1:45 PM, Florian Weimer wrote: > * Reinier Zwitserloot: > > > The general feeling that close() throwing IOExceptions is just plain > > stupid comes from *INPUTSTREAM*, where your inputstream reading has > > not thrown any exceptions, and has therefore, by neccessity, read all > > files and hit the EOF (or whatever other 'I don't need more data' > > marker you're using) without error. > > This requires quite a few library changes because currently, an > InputStream created for a ReadableByteChannel which happens to be a > WritableByteChannel as well closes both personae of the channel when > the input stream's close method is invoked. You'd have to change > that, or you still end up encountering exceptions during close. > > From fw at deneb.enyo.de Wed Mar 18 14:07:56 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 18 Mar 2009 22:07:56 +0100 Subject: Coin Considerations In-Reply-To: (Mark Mahieu's message of "Sat, 14 Mar 2009 23:39:22 +0000") References: <9B587463-4315-4F0E-9873-7102F02E62B6@zwitserloot.com> <873adfzo7o.fsf@mid.deneb.enyo.de> Message-ID: <87ab7i7d5f.fsf@mid.deneb.enyo.de> * Mark Mahieu: [Annotation trickery to tweak overloading] > For better or worse, using annotations for these purposes is off limits. Okay, but I think we need some way to retrofit existing classes in a fairly uniform manner. The Closable approach doesn't really fly. You probably want Process#destroy(), Timer#cancel(), ExecutorService#shutdown(), and some more. Looking for classes which implement finalize() should increase the length of the list. Many of them will free native resources, and doing as early as possible will increase overall system robustness and determinism. From neal at gafter.com Wed Mar 18 14:21:47 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 14:21:47 -0700 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> Message-ID: <15e8b9d20903181421h6c93f942p864a7208a7b5f5a6@mail.gmail.com> On Wed, Mar 18, 2009 at 1:05 PM, Mark Mahieu wrote: > 2009/3/18 Neal Gafter >> >> When an extension method has been statically imported, you can use it >> as if it is a member of the type of its first argument. > > Just out of curiosity, what do you think the behaviour should be when the > 'first argument' is null? ?Put another way, from your experience would the > model chosen here for C# be the right choice for Java? > Mark Yes, I think the right thing to do is ignore null receivers when using an extension method. From neal at gafter.com Wed Mar 18 14:28:59 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 14:28:59 -0700 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <87eiwu7die.fsf@mid.deneb.enyo.de> References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> <87eiwu7die.fsf@mid.deneb.enyo.de> Message-ID: <15e8b9d20903181428k156ffe65icf2f5a432267bb2@mail.gmail.com> On Wed, Mar 18, 2009 at 2:00 PM, Florian Weimer wrote: >> There are a number of benefits to this approach. ?A large number of >> static utility class members can and probably should be retrofitted to >> use extension methods, making it possible to use a much more >> convenient syntax for common operations. >> >> ? ? import static java.util.Collections.sort; >> ? ? List list = ... >> ? ? list.sort(); // uses Collections.sort extension method > > (Does this proposal imply import statements? ?Would they make sense in > this context?) I don't understand this question. Java already has import statements. >> One of the more important benefits of this approach is that it enables >> future language changes to be defined by syntactic translation, while >> allowing more flexible retrofitting of those language changes onto >> existing APIs than would be possible without extension methods. > > I think the problem here is that you have to figure out which > class/static method to import to make ARM work. ?For a feature like > ARM, where the main factor is convenience to counter sloppiness (at > least from my point of view), this seems like a significant burden. ?I > think Reinier is right that this feature alone is insufficient to > implement proper ARM. Agreed: in addition, we'd need some small amount of work in the libraries to *provide* the extension methods in convenient places, and conventions around what those places should be. For example, extension methods for collections would be in Collections, for arrays they'd be in Arrays, for Closeable they'd be in Closeables, etc. > Oh, and I wonder how this particular brand of extension method will > interact with reifed/compile time generics. I don't see how there could be any issue. The spec for extension methods would remain unchanged by the addition of reified generics. Extension methods are done by a syntactic transformation based on the static type of the receiver, not its dynamic type. From fw at deneb.enyo.de Wed Mar 18 14:39:06 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 18 Mar 2009 22:39:06 +0100 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <15e8b9d20903181428k156ffe65icf2f5a432267bb2@mail.gmail.com> (Neal Gafter's message of "Wed, 18 Mar 2009 14:28:59 -0700") References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> <87eiwu7die.fsf@mid.deneb.enyo.de> <15e8b9d20903181428k156ffe65icf2f5a432267bb2@mail.gmail.com> Message-ID: <87bpry5x51.fsf@mid.deneb.enyo.de> * Neal Gafter: >> (Does this proposal imply import statements? ?Would they make sense in >> this context?) > > I don't understand this question. Java already has import statements. At block level, within methods? Really? >> Oh, and I wonder how this particular brand of extension method will >> interact with reifed/compile time generics. > > I don't see how there could be any issue. The spec for extension > methods would remain unchanged by the addition of reified generics. > Extension methods are done by a syntactic transformation based on the > static type of the receiver, not its dynamic type. It might be interesting if extension methods were visible within reified generics in some way. This could be used to provide quite flexible compound literals. From neal at gafter.com Wed Mar 18 14:46:28 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 14:46:28 -0700 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <87bpry5x51.fsf@mid.deneb.enyo.de> References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> <87eiwu7die.fsf@mid.deneb.enyo.de> <15e8b9d20903181428k156ffe65icf2f5a432267bb2@mail.gmail.com> <87bpry5x51.fsf@mid.deneb.enyo.de> Message-ID: <15e8b9d20903181446l15a5d96fl797863b7c6dc7718@mail.gmail.com> On Wed, Mar 18, 2009 at 2:39 PM, Florian Weimer wrote: >>> (Does this proposal imply import statements? ?Would they make sense in >>> this context?) >> >> I don't understand this question. ?Java already has import statements. > > At block level, within methods? ?Really? No, I would not propose any changes to import declarations. From howard.lovatt at iee.org Wed Mar 18 14:51:52 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 08:51:52 +1100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: References: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> Message-ID: <3dd3f56a0903181451y84ce862h4da8b42c4b33f3e0@mail.gmail.com> Dots are also a bad solution because you can get confusing expressions: 5.<.4 Is this: (5.) < (.4) or Integer.valueof( 5 ).compareTo( Integer.valueof( 4 ) ) < 0 Therefore I withdraw the suggestion of using dots. Sorry! In hindsight I think that you can only improve comparisons by having a source statement, see proposal for source and encoding, that allows you to make bigger changes in the future. The source statement goes at the start of the file and tells the compiler which version of Java the file is in, no source statement means Java 6. So for example in Java 7 we we put, source Java7 at the start of the file. If source were added to Java 7 then in a future version, say 8, we could: 1. Fix the operation of primitive comparisons, i.e. make them consistent with Double.compareTo and Float.compareTo 2. For Float op Float and Double op Double un-box the values and perform primitive conversions (so that type is automatically promoted) 3. Then make the comparison operations call compareTo for other types if Comparable is implemented 4. Use == to call equals if Comparable is not implemented (similarly !=) 5. Introduce === which means compare addresses Can't see that we can do much in this area without source adding first. Cheers, Howard. 2009/3/18 Olivier Chorier : > I think dots are not a good solution because IDE are used to propose > auto-completion with it > > 2009/3/18 Howard Lovatt >> >> You could use new operators: >> >> .<. >> .<=. >> .>. >> .>=. >> .==. >> >> The dots are meant to remind everyone that a method, comparable, is >> called. >> > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From howard.lovatt at iee.org Wed Mar 18 14:56:21 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 08:56:21 +1100 Subject: String literals in Java 7: version 1.2 In-Reply-To: <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> Message-ID: <3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com> Hi All, 2009/3/18 : [snip] > Complex case: > Create special syntax for template processing inside strings - I guess > this can be a library issue. > We have jsr223. May be good ideaa is adding helper methods, which process > string via choosed language interptreter, i.e. > ?s.scriptEval("velocity",binding); > ?.... but - from other side ?we can't receive binding between names and > values automatically for now. Not sure that a library would work, can you give an example of the call you propose? From fw at deneb.enyo.de Wed Mar 18 14:58:11 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 18 Mar 2009 22:58:11 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> (Joshua Bloch's message of "Wed, 18 Mar 2009 14:02:14 -0700") References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> Message-ID: <87tz5q4hos.fsf@mid.deneb.enyo.de> * Joshua Bloch: > I don't think it's realistic, ever, to change this because it isn't > compatible to take a throws clause off of an overridable method: it breaks > subtypes. One of the things that adds to the pain is the silliness of > IOException itself. Why are all exceptions raised during IO checked? No > good reason:( It reminds me of Haskell. 8-) IOException is used very inconsistently. System.out.println() should certainly throw it, and there quite a few methods in File which should, too (basically, anything that hits the file system). On the other hand, the current state of affairs means that it's not possible to use the new-style for loop to iterate over all the lines in a file, which is somewhat annoying. > Why, in fact, is there such a thing as an IOException? That > only tells you where the exception comes from, which you can find out by > looking at its class and package. Given the need for a hierarchy, it's a > waste to use an exception's sole ancestor to duplicate this information. > Much better is to group exceptions based on what they indicate rather than > where they come from. I guess the only way to handle an IOException is to determine where it comes from, dynamically. The concrete cause isn't that important. For instance, if a piece of code deals with data from the network and some on-disk structure, you probably can recover locally from a network outage, but a disk write error is something that requires operator attention. Of course, with Java's IOException, you still need to wrap the I/O operations to get this distinction. But if the IOException class had some sort of associated I/O resources, a single-routed hierarchy would make some sense, I think. Anyway, I've worked with systems which lacked hierarchical exceptions, and it's not really that great, either. It's basically impossible to handle most errors locally (which is true for I/O disk errors, but not for many forms of network errors). From howard.lovatt at iee.org Wed Mar 18 15:05:43 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 09:05:43 +1100 Subject: Proposal: Embedded Expressions for String Statements Message-ID: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> I like Stefan's proposed syntax and as a way of a motivating example consider writing a toString method that gives the field values within square brackets, now you would write: "[" + field1 + ", " + field2 + ", " + field3 + "]" With the proposal you would say: "[\{field1}, \{field2}, \{field3}]" Which I find clearer. Many thanks to Stefan for writing this up formally. From howard.lovatt at iee.org Wed Mar 18 15:26:37 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 09:26:37 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <87tz5q4hos.fsf@mid.deneb.enyo.de> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <87tz5q4hos.fsf@mid.deneb.enyo.de> Message-ID: <3dd3f56a0903181526h2797caa8me37d969ac343a11c@mail.gmail.com> In my suggestion of not using checked exceptions for dispose I am not proposing retrofitting to an existing interface, I am proposing retrofitting a new interface to an existing class or wrapping an existing class in a new class that implements the new interface. I was deliberately suggesting that trying to deal with the current IO with all its vagourasies as amply highlighted by Josh, Reinier, and Florian is an impossible task. Hence the suggestion not to try. In particular I am suggesting: interface AutoResource { void autoDispose(); } When you fit AutoResource to an existing class or to a new class you have to make the modified/new class conform to the contract of AutoResource, which is that the resource is auto opened, autoDispose can be called multiple times, and autoDispose is called by the system for you. I am not saying that autoDispose can't throw an unchecked exception; just that it is inappropriate to throw a checked exception because the user of the resource can do little to recover from the problem of a closure error, so there is no point in burdening the programmer with a checked exception. In the example of a buffered write that does no writes until close is called and hence a write error is reported on close, what can the user do? The only way for the user to deal with the close exception would be to keep track of all the writes that they used so that when close fails they can be retried (like some transactional databases do). Actually it is even harder than this, you have to know which writes succeed and which failed! I can't see people wanting to do this for every print statement and alike; also it is more the functionality of some underlying framework, rather than the core language. - Howard. 2009/3/19 Florian Weimer : > * Joshua Bloch: > >> I don't think it's realistic, ever, to change this because it isn't >> compatible to take a throws clause off of an overridable method: it breaks >> subtypes. ?One of the things that adds to the pain is the silliness of >> IOException itself. ?Why are all exceptions raised during IO checked? ?No >> good reason:( > > It reminds me of Haskell. 8-) > > IOException is used very inconsistently. ?System.out.println() should > certainly throw it, and there quite a few methods in File which > should, too (basically, anything that hits the file system). > > On the other hand, the current state of affairs means that it's not > possible to use the new-style for loop to iterate over all the lines > in a file, which is somewhat annoying. > >> ?Why, in fact, is there such a thing as an IOException? ?That >> only tells you where the exception comes from, which you can find out by >> looking at its class and package. ?Given the need for a hierarchy, it's a >> waste to use an exception's sole ancestor to duplicate this information. >> ?Much better is to group exceptions based on what they indicate rather than >> where they come from. > > I guess the only way to handle an IOException is to determine where it > comes from, dynamically. ?The concrete cause isn't that important. > For instance, if a piece of code deals with data from the network and > some on-disk structure, you probably can recover locally from a > network outage, but a disk write error is something that requires > operator attention. ?Of course, with Java's IOException, you still > need to wrap the I/O operations to get this distinction. ?But if the > IOException class had some sort of associated I/O resources, a > single-routed hierarchy would make some sense, I think. > > Anyway, I've worked with systems which lacked hierarchical exceptions, > and it's not really that great, either. ?It's basically impossible to > handle most errors locally (which is true for I/O disk errors, but not > for many forms of network errors). > > ______________________________________________________________________ > 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 Mar 18 15:29:16 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 18 Mar 2009 15:29:16 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> Message-ID: <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> On Wed, Mar 18, 2009 at 2:02 PM, Joshua Bloch wrote: > I don't think it's realistic, ever, to change this because it isn't > compatible to take a throws clause off of an overridable method: it breaks > subtypes. It's not even compatible to remove a throws clause from a non-overridable method! That's because it would break callers who invoke it in a try-catch statement. From rssh at gradsoft.com.ua Wed Mar 18 12:54:56 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 18 Mar 2009 21:54:56 +0200 (EET) Subject: String literals in Java 7: version 1.2 In-Reply-To: <3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> <3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com> Message-ID: <5ee07a2d25a6c6f312ad20b1e629d899.squirrel@wmail.gradsoft.ua> > Hi All, > > 2009/3/18 : > > [snip] > >> Complex case: >> Create special syntax for template processing inside strings - I guess >> this can be a library issue. >> We have jsr223. May be good ideaa is adding helper methods, which >> process >> string via choosed language interptreter, i.e. >> ?s.scriptEval("velocity",binding); >> ?.... but - from other side ?we can't receive binding between names and >> values automatically for now. > > Not sure that a library would work, can you give an example of the > call you propose? > Example of such call can be: binding = new Binding(); binding.put("x",x); binding.put("y",y); """ A B """.evalScript("PHP",binding); If PHP is avaible via JSR223 API, then string will be evaluated to A or B. Or, if you does not like PHP, you can use velocity or java. But creating binding by hands (first 3 strings of test) kill all :( >From other side, in principle compiler can generate binding for local variables automatically, so in principle it is possible to create 'magic annotation', to write code like: int someMethod(); { int x=1; int y=2; @GenerateVariableBinding Binding binding; String s = """ A B """.evalScript("PHP",binding); System.out.println(); } (I think about formalizing and submitting such proposal, but not sure that it is possible correct define one in short terms.) From rssh at gradsoft.com.ua Wed Mar 18 12:57:53 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 18 Mar 2009 21:57:53 +0200 (EET) Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> Message-ID: <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> > I like Stefan's proposed syntax and as a way of a motivating example > consider writing a toString method that gives the field values within > square brackets, now you would write: > > "[" + field1 + ", " + field2 + ", " + field3 + "]" > > With the proposal you would say: > > "[\{field1}, \{field2}, \{field3}]" > > Which I find clearer. > Just note: now we can use much cleaner concat( field1, ',' , field2, ',' field3 ) > Many thanks to Stefan for writing this up formally. > > From howard.lovatt at iee.org Wed Mar 18 15:41:30 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 09:41:30 +1100 Subject: String literals in Java 7: version 1.2 In-Reply-To: <5ee07a2d25a6c6f312ad20b1e629d899.squirrel@wmail.gradsoft.ua> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> <3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com> <5ee07a2d25a6c6f312ad20b1e629d899.squirrel@wmail.gradsoft.ua> Message-ID: <3dd3f56a0903181541o5462e54dqd9c0c3830378130@mail.gmail.com> I don't see your binding proposal as an improvement over what we have got for many use cases, that is not to say that it isn't valuable as an API. It is an API for string processing and therefore should be a suggested library change; not part of coin. The string literals with expressions and your API proposal would be complementary, particularly if they had similar syntax. Also see a formal proposal for embedding expressions into strings on coin, it is called Proposal: Embedded Expressions for String Statements and is from Stefan Schulz. 2009/3/19 : >> Hi All, >> >> 2009/3/18 ?: >> >> [snip] >> >>> Complex case: >>> Create special syntax for template processing inside strings - I guess >>> this can be a library issue. >>> We have jsr223. May be good ideaa is adding helper methods, which >>> process >>> string via choosed language interptreter, i.e. >>> ?s.scriptEval("velocity",binding); >>> ?.... but - from other side ?we can't receive binding between names and >>> values automatically for now. >> >> Not sure that a library would work, can you give an example of the >> call you propose? >> > > Example of such call can be: > > binding = new Binding(); > binding.put("x",x); > binding.put("y",y); > > """ > ? > ? A > ? > ? B > ? > """.evalScript("PHP",binding); > > If PHP is avaible via JSR223 API, then string will be evaluated to A or B. > Or, if you does not like PHP, you can use velocity or java. > > But creating binding by hands (first 3 strings of test) kill all :( > > From other side, in principle compiler can generate binding for local > variables automatically, so in principle it is possible to create 'magic > annotation', to write code like: > > > int someMethod(); > { > int x=1; > int y=2; > @GenerateVariableBinding > Binding binding; > > String s = """ > ? > ? A > ? > ? B > ? > """.evalScript("PHP",binding); > > System.out.println(); > > } > > > (I think about formalizing and submitting such proposal, but not sure that > it is possible correct define one in short terms.) > > > > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From jjb at google.com Wed Mar 18 15:50:33 2009 From: jjb at google.com (Joshua Bloch) Date: Wed, 18 Mar 2009 15:50:33 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> Message-ID: <17b2302a0903181550q170339d2yfe0519d29f6567c4@mail.gmail.com> On Wed, Mar 18, 2009 at 3:29 PM, Neal Gafter wrote: > On Wed, Mar 18, 2009 at 2:02 PM, Joshua Bloch wrote: > > I don't think it's realistic, ever, to change this because it isn't > > compatible to take a throws clause off of an overridable method: it > breaks > > subtypes. > > It's not even compatible to remove a throws clause from a > non-overridable method! That's because it would break callers who > invoke it in a try-catch statement. > Good point. Josh From jeremy.manson at gmail.com Wed Mar 18 15:58:20 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Wed, 18 Mar 2009 15:58:20 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <3dd3f56a0903180310g59377decl384d59a78fd43a1e@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <3dd3f56a0903180310g59377decl384d59a78fd43a1e@mail.gmail.com> Message-ID: <1631da7d0903181558g6ed664c3u5a9ebf1caf123ee3@mail.gmail.com> On Wed, Mar 18, 2009 at 3:10 AM, Howard Lovatt wrote: > Hi, > > 2009/3/16 Jeremy Manson : >> I'm not objecting to versioning in principle, but I think there are >> enough unanswered questions that this proposal is probably beyond the >> scope of "small changes". > > I think one of the reasons that Java is tending to stagnate a little, > not badly, just a little, is that it is getting hard to introduces > changes. I think source will provide a relief valve - get out of jail > free. I'm not going to respond point-by-point, but the primary reason it is hard to introduce changes in Java is not because of existing keywords, or the fact that we are tied to existing source. It is because it *should* be hard to introduce changes in a widely used programming language. Too much forward progress gives you a language that looks more like a katamari than a well-considered, cohesive whole: C++ and perl come to mind as examples of this. How many different initializer syntaxes does C++ have? 15? I agree that there has been too much stagnation in the platform in the last few years, but this has nothing to do with it being difficult to change the language. It is because of political issues in the Java community. This is clearly not the right forum to discuss that, though. I think that in this specific case, you are considering adding something that only solves a small part of a much larger problem that needs to be addressed. Instead of having a point solution, which risks being at odds with solutions to the rest of the problem, what you really want is a larger, well-thought-out solution to the whole problem. Start a JSR and solve versioning for us! Everyone will be very grateful! Jeremy From rssh at gradsoft.com.ua Wed Mar 18 13:51:37 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 18 Mar 2009 22:51:37 +0200 (EET) Subject: Embedded expressions in string literals. In-Reply-To: <3dd3f56a0903181541o5462e54dqd9c0c3830378130@mail.gmail.com> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> <3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com> <5ee07a2d25a6c6f312ad20b1e629d899.squirrel@wmail.gradsoft.ua> <3dd3f56a0903181541o5462e54dqd9c0c3830378130@mail.gmail.com> Message-ID: <69037540cbb22044757365702da1ea7b.squirrel@wmail.gradsoft.ua> > I don't see your binding proposal as an improvement over what we have > got for many use cases, that is not to say that it isn't valuable as > an API. It is an API for string processing and therefore should be a > suggested library change; not part of coin. The string literals with > expressions and your API proposal would be complementary, particularly > if they had similar syntax. Also see a formal proposal for embedding > expressions into strings on coin, it is called Proposal: Embedded > Expressions for String Statements and is from Stefan Schulz. > For implementing such proposal you need a mapping between names and values. (I. e. our binding). Now, let's think about all entities, which we have: 1. binding. 2. String before process of substituting embedding expression. 3. Process of substituting embedding expression. (I. e. syntax of mini=language inside string). Applying this 3 entities we receive: 4. String after process of substituting embedding expression. Original Stefan proposal does not specify difference between 2 and 4. Problem, that if (2) exists only in program text (and transformed to 4 during compilation process), than - such transformation is possible only in static context, fixed in compile-time. This means that you can't pass such string literal to arguments, and, for example, next code snipset: int x = readX(); System.out.println("You entered \{x}"); Will produce result differ, than String message = "You entered \{x}"; int x = readX(); System.out.println(message); I belive, that fixing all such transformations in static context is fundamentally wrong. Ok, now let's interpret Stefan proposal (EESL) in dynamic context. But for this we need specify binging (explicit or implicit [in static context ?]) and mark process of interpretation by some function. I. e. receive all the complexity of embedding interpreted language. Fortunelly, this complexity already implemented in JSR223 interface. Embedded expressions proposal in such interpretation - just yet one syntax for embedded language. (We already have near 200 JVM languages, most of them implement javax.scripting interfaces) Of course, we can choose language of some simple syntax be default for string expression processing - in such case, binding will just a mechanism for implementation of EESL. > 2009/3/19 : >>> Hi All, >>> >>> 2009/3/18 ?: >>> >>> [snip] >>> >>>> Complex case: >>>> Create special syntax for template processing inside strings - I guess >>>> this can be a library issue. >>>> We have jsr223. May be good ideaa is adding helper methods, which >>>> process >>>> string via choosed language interptreter, i.e. >>>> ?s.scriptEval("velocity",binding); >>>> ?.... but - from other side ?we can't receive binding between names >>>> and >>>> values automatically for now. >>> >>> Not sure that a library would work, can you give an example of the >>> call you propose? >>> >> >> Example of such call can be: >> >> binding = new Binding(); >> binding.put("x",x); >> binding.put("y",y); >> >> """ >> ? >> ? A >> ? >> ? B >> ? >> """.evalScript("PHP",binding); >> >> If PHP is avaible via JSR223 API, then string will be evaluated to A or >> B. >> Or, if you does not like PHP, you can use velocity or java. >> >> But creating binding by hands (first 3 strings of test) kill all :( >> >> From other side, in principle compiler can generate binding for local >> variables automatically, so in principle it is possible to create 'magic >> annotation', to write code like: >> >> >> int someMethod(); >> { >> int x=1; >> int y=2; >> @GenerateVariableBinding >> Binding binding; >> >> String s = """ >> ? >> ? A >> ? >> ? B >> ? >> """.evalScript("PHP",binding); >> >> System.out.println(); >> >> } >> >> >> (I think about formalizing and submitting such proposal, but not sure >> that >> it is possible correct define one in short terms.) >> >> >> >> >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> > From Joe.Darcy at Sun.COM Wed Mar 18 16:31:12 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Wed, 18 Mar 2009 16:31:12 -0700 Subject: Small property support. In-Reply-To: <49C0E891.7000901@digia.com> References: <49C0E891.7000901@digia.com> Message-ID: <49C18440.9040908@sun.com> Greetings. As previously stated http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size properties are almost certainly out of scope for Project Coin. This proposal lacks sufficient detail for full evaluation. On 03/18/09 05:26 AM, Ruslan wrote: > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Ruslan Lazukov > > OVERVIEW > Create infrastructure for using properties in Java, but make it small > change for becoming part of Java 7. > I suggest to use synthetic sugar for properties in Java 7. > > FEATURE SUMMARY: > Lack of properties in Java make developers to create a lot of solutions > for solving this issue. > But issue can be solved only from language level. > > MAJOR ADVANTAGE: > Solve lack of Java property support, but this solve will be small not > medium size. > > MAJOR BENEFIT: > Improve check ability of java code. Improve readability of code. > Code become less error prone. > > MAJOR DISADVANTAGE: > Developer should understand how properties work - the same as enhanced > for-each. > For-each are synthetic and real code are hidden from developer. > > ALTERNATIVES: > No; Every solution need to change language. > > > [snip] > > DETAILS > SPECIFICATION: > Main problem of Java property support in Java 7 is that Sun want to > create solution at one step. > But also Sun do not have enough time and resources to do this for Java 7. > > My suggestion is to split "property" into many steps, and make some of > them in Java 7. > > We can use documentation created for HUGE property support, and write > code only in java compiler. > All other stuff like changes in Reflection API - stay for next 3-5 years > (for Java 8 release). > > HUGE property support described here > http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > As previously stated, "If a proposal does not cite chapter and verse of the JLS for parts of its specification, that is a good indication the proposal is too vague." (http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000196.html) This specification section is both too vague and not self-contained; the full information must be sent to the list and not be present only in external documents. > I suggest implementation of language changes without Property object, > changes in Reflection API and necessity to sit > and wait 5 years for time when Java code become more readable. > Adding language features properly requires coordination of changes throughout the platform; that cannot easily be done piecemeal. > > COMPILATION: How would the feature be compiled to class files? > No additional support necessary in class files. > As explained in the form's text and as done by previous proposals, like this one http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html this section is for the details of the compilation or desugaring. > TESTING: How can the feature be tested? > The same way as for-each. > That makes no sense at all. > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > No, not for Java 7. > > REFLECTIVE APIS: > No, not for Java 7. > > > OTHER CHANGES: > No, not for Java 7. > > MIGRATION: > No migration needed. > > > COMPATIBILITY > BREAKING CHANGES: > All existing programs remain valid. > > EXISTING PROGRAMS: > The semantics of existing class files and legal source files and are > unchanged by this feature. > > REFERENCES EXISTING BUGS: > I think that there is a lot of bugs in Sun bug-tracking system. > Yes, and you are supposed to find those bugs as part of submitting the form! -Joe > URL FOR PROTOTYPE (optional): > Document about HUGE property that Sun presented to developers > http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf, > page 27. > > Also Sun (probably) developers create a lot of documentation how > property should be supported from language level. > That documents have to be used to implement this proposal fast and easy. > HUGE property support described here > http://docs.google.com/Doc?id=dfhbvdfw_1f7mzf2 > > > WBR, Ruslan. > > > > From reinier at zwitserloot.com Wed Mar 18 17:16:14 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 19 Mar 2009 01:16:14 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903181526h2797caa8me37d969ac343a11c@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <87tz5q4hos.fsf@mid.deneb.enyo.de> <3dd3f56a0903181526h2797caa8me37d969ac343a11c@mail.gmail.com> Message-ID: Obviously, in response to a failed close() on an OutputStream, you'd do the same thing you usually do on a failed write(): You consider the entire writing of the file, from start to finish, as a failed endeavour. You then pop up a dialog box to the user to explain why the file save operation failed, for example, or you return a certain HTTP error, or you actively ignore the exception because you're just writing some cache info for the next instance. If at any time you are dependent on a -specific- write() call's exceptions, you should ALWAYS call flush() in between. Is there anyone else other than Howard who considers AutoClosable NOT throwing any exceptions a good idea? If not, I think we can move on. --Reinier Zwitserloot On Mar 18, 2009, at 23:26, Howard Lovatt wrote: > In my suggestion of not using checked exceptions for dispose I am not > proposing retrofitting to an existing interface, I am proposing > retrofitting a new interface to an existing class or wrapping an > existing class in a new class that implements the new interface. I was > deliberately suggesting that trying to deal with the current IO with > all its vagourasies as amply highlighted by Josh, Reinier, and Florian > is an impossible task. Hence the suggestion not to try. In particular > I am suggesting: > > interface AutoResource { void autoDispose(); } > > When you fit AutoResource to an existing class or to a new class you > have to make the modified/new class conform to the contract of > AutoResource, which is that the resource is auto opened, autoDispose > can be called multiple times, and autoDispose is called by the system > for you. I am not saying that autoDispose can't throw an unchecked > exception; just that it is inappropriate to throw a checked exception > because the user of the resource can do little to recover from the > problem of a closure error, so there is no point in burdening the > programmer with a checked exception. > > In the example of a buffered write that does no writes until close is > called and hence a write error is reported on close, what can the user > do? The only way for the user to deal with the close exception would > be to keep track of all the writes that they used so that when close > fails they can be retried (like some transactional databases do). > Actually it is even harder than this, you have to know which writes > succeed and which failed! I can't see people wanting to do this for > every print statement and alike; also it is more the functionality of > some underlying framework, rather than the core language. > > - Howard. > > 2009/3/19 Florian Weimer : >> * Joshua Bloch: >> >>> I don't think it's realistic, ever, to change this because it isn't >>> compatible to take a throws clause off of an overridable method: >>> it breaks >>> subtypes. One of the things that adds to the pain is the >>> silliness of >>> IOException itself. Why are all exceptions raised during IO >>> checked? No >>> good reason:( >> >> It reminds me of Haskell. 8-) >> >> IOException is used very inconsistently. System.out.println() should >> certainly throw it, and there quite a few methods in File which >> should, too (basically, anything that hits the file system). >> >> On the other hand, the current state of affairs means that it's not >> possible to use the new-style for loop to iterate over all the lines >> in a file, which is somewhat annoying. >> >>> Why, in fact, is there such a thing as an IOException? That >>> only tells you where the exception comes from, which you can find >>> out by >>> looking at its class and package. Given the need for a hierarchy, >>> it's a >>> waste to use an exception's sole ancestor to duplicate this >>> information. >>> Much better is to group exceptions based on what they indicate >>> rather than >>> where they come from. >> >> I guess the only way to handle an IOException is to determine where >> it >> comes from, dynamically. The concrete cause isn't that important. >> For instance, if a piece of code deals with data from the network and >> some on-disk structure, you probably can recover locally from a >> network outage, but a disk write error is something that requires >> operator attention. Of course, with Java's IOException, you still >> need to wrap the I/O operations to get this distinction. But if the >> IOException class had some sort of associated I/O resources, a >> single-routed hierarchy would make some sense, I think. >> >> Anyway, I've worked with systems which lacked hierarchical >> exceptions, >> and it's not really that great, either. It's basically impossible to >> handle most errors locally (which is true for I/O disk errors, but >> not >> for many forms of network errors). >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> From howard.lovatt at iee.org Wed Mar 18 17:18:48 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 11:18:48 +1100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> Message-ID: <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> Hi All, 2009/3/19 Neal Gafter : [snip] > It's not even compatible to remove a throws clause from a > non-overridable method! ?That's because it would break callers who > invoke it in a try-catch statement. I am not proposing to do this, I am proposing adding the new interface to existing classes if you can and if you can't then wrap the existing class in a new one. I am not proposing modifying existing interfaces at all. This is a deliberate attempt to start again with resources and provide a unified model. For example suppose as Neal has suggested that the foreach loop understood resources, it would be great to write something like: for ( final String line : AutoResources.asLines( filename ) ) { ... } where public class AutoResources { private AutoResources() {} public static FileAsLines asLines( final String filename ) throws FileNotFoundException { return new FileAsLines( filename ); } public static class FileAsLines implements AutoResource, Iterable { private final FileReader reader; FileAsLines( final String filename ) throws FileNotFoundException { reader = new FileReader( filename ); } public void autoDispose() { try { reader.close(); } catch ( IOException e ) { throw new IllegalStateException( e ); } } public Iterator iterator() { return new Iterator() { ... }; } } ... } (Note, in a previous post I have suggested that replacing keyword new when applied to an AutoResources with a new keyword, autoresource, this additional change would make this foreach example even clearer.) In the above code there is no attempt to retrofit AutoResource to FileReader, instead it is wrapped. - Howard. From howard.lovatt at iee.org Wed Mar 18 18:03:51 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 12:03:51 +1100 Subject: Embedded expressions in string literals. In-Reply-To: <69037540cbb22044757365702da1ea7b.squirrel@wmail.gradsoft.ua> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com> <637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua> <3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com> <5ee07a2d25a6c6f312ad20b1e629d899.squirrel@wmail.gradsoft.ua> <3dd3f56a0903181541o5462e54dqd9c0c3830378130@mail.gmail.com> <69037540cbb22044757365702da1ea7b.squirrel@wmail.gradsoft.ua> Message-ID: <3dd3f56a0903181803x4641ada2j5d1f99b05308fafb@mail.gmail.com> Stefan's proposal is for a dynamic binding, in particular: String message = "You entered \{x}"; is exactly the same as: String message = "You entered " + x; Which in turn is the same as: StringBuilder $message = new StringBuilder( "You entered " ); $message.append( x ); String message = $message.toString(); Therefore each time "You entered \{x}" is executed, x will be re-evaluated. -- Howard. 2009/3/19 : >> I don't see your binding proposal as an improvement over what we have >> got for many use cases, that is not to say that it isn't valuable as >> an API. It is an API for string processing and therefore should be a >> suggested library change; not part of coin. The string literals with >> expressions and your API proposal would be complementary, particularly >> if they had similar syntax. Also see a formal proposal for embedding >> expressions into strings on coin, it is called Proposal: Embedded >> Expressions for String Statements and is from Stefan Schulz. >> > > For implementing such proposal you need a mapping between names and values. > (I. e. our binding). > > Now, let's think about all entities, which we have: > > 1. binding. > 2. String before process of substituting embedding expression. > 3. Process of substituting embedding expression. (I. e. syntax of > mini=language inside string). > > Applying this 3 entities we receive: > > 4. String after process of substituting embedding expression. > > ?Original Stefan proposal does not specify difference between 2 and 4. > Problem, that > ?if (2) exists only in program text (and transformed to 4 during > compilation process), than > ? ?- such transformation is possible only in static context, fixed in > compile-time. This means that you can't pass such string literal to > arguments, and, for example, next code snipset: > > int x = readX(); > System.out.println("You entered \{x}"); > > Will produce result differ, than > > String message = "You entered \{x}"; > int x = readX(); > System.out.println(message); > > I belive, that fixing all such transformations in static context is > fundamentally wrong. > > Ok, now let's interpret Stefan proposal (EESL) in dynamic context. > But for this we need specify binging (explicit or implicit [in static > context ?]) and mark process of interpretation by some function. I. e. > receive all the complexity of embedding interpreted language. Fortunelly, > this complexity already implemented in JSR223 interface. Embedded > expressions proposal in such interpretation - just yet one syntax for > embedded language. (We already have near 200 JVM languages, most of them > implement javax.scripting interfaces) > ?Of course, we can choose language of some simple syntax be default for > string expression processing - in such case, binding will just a mechanism > for implementation of EESL. > > >> 2009/3/19 ?: >>>> Hi All, >>>> >>>> 2009/3/18 ?: >>>> >>>> [snip] >>>> >>>>> Complex case: >>>>> Create special syntax for template processing inside strings - I guess >>>>> this can be a library issue. >>>>> We have jsr223. May be good ideaa is adding helper methods, which >>>>> process >>>>> string via choosed language interptreter, i.e. >>>>> ?s.scriptEval("velocity",binding); >>>>> ?.... but - from other side ?we can't receive binding between names >>>>> and >>>>> values automatically for now. >>>> >>>> Not sure that a library would work, can you give an example of the >>>> call you propose? >>>> >>> >>> Example of such call can be: >>> >>> binding = new Binding(); >>> binding.put("x",x); >>> binding.put("y",y); >>> >>> """ >>> ? >>> ? A >>> ? >>> ? B >>> ? >>> """.evalScript("PHP",binding); >>> >>> If PHP is avaible via JSR223 API, then string will be evaluated to A or >>> B. >>> Or, if you does not like PHP, you can use velocity or java. >>> >>> But creating binding by hands (first 3 strings of test) kill all :( >>> >>> From other side, in principle compiler can generate binding for local >>> variables automatically, so in principle it is possible to create 'magic >>> annotation', to write code like: >>> >>> >>> int someMethod(); >>> { >>> int x=1; >>> int y=2; >>> @GenerateVariableBinding >>> Binding binding; >>> >>> String s = """ >>> ? >>> ? A >>> ? >>> ? B >>> ? >>> """.evalScript("PHP",binding); >>> >>> System.out.println(); >>> >>> } >>> >>> >>> (I think about formalizing and submitting such proposal, but not sure >>> that >>> it is possible correct define one in short terms.) >>> >>> >>> >>> >>> >>> ______________________________________________________________________ >>> This email has been scanned by the MessageLabs Email Security System. >>> For more information please visit http://www.messagelabs.com/email >>> ______________________________________________________________________ >>> >> > > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From howard.lovatt at iee.org Wed Mar 18 22:55:01 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 16:55:01 +1100 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <1631da7d0903181558g6ed664c3u5a9ebf1caf123ee3@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <3dd3f56a0903180310g59377decl384d59a78fd43a1e@mail.gmail.com> <1631da7d0903181558g6ed664c3u5a9ebf1caf123ee3@mail.gmail.com> Message-ID: <3dd3f56a0903182255v2b123317qd4a0751ae989952a@mail.gmail.com> Hi Jeremy, Maybe a bit more of a motivation for source is needed, but note I am not saying that the following list should be done for 7, I am saying that these items are a possibility for some point in the future and it is a good idea to put source in now so that we are well positioned for the future. Source allows continual improvement, by allowing for incompatible changes with the past. It allows graceful aging. This is quite possible on the JVM, which is quite capable of supporting multiple languages that are quite different and hence slightly source code incompatible versions of Java that are class file compatible are no problem (they still interact with each other via the JVM). Anyway here are some of the more ambitious changes that could be made once source is in place: 1. New keywords, some examples from coin proposals: module (for modules), arm (for automated resource blocks), lockprotected (for concurrent lock blocks). Many current coin proposals would be improved if you could add new keywords. 2. Big improvements to type inference could be made if a var keyword were added, like JavaFX. Going beyond what is proposed for a small amount of generic type inference. 3. Big improvements to inner classes could be made if a method keyword were added, analogous to function in JavaFX. Some of the current inner class/closure proposals without a new keyword really stretch the syntax and are almost entirely alien to Java. 4. Comparative operators for Comparable and equals could be added and add the same time the primitive comparisons could be fixed and a === operator could be introduced that compares address (== would call either equals or compareTo). There is a proposal in coin for operations for Comparable, but the proposal has problems because of backward compatibility issues. 5. The switch statement could be made sane, i.e. block structured. 6. The control blocks, if, while, for could be given return values, like JavaFX. 7. Properties could be added, like JavaFX including bind. 8. Traits could be added (my personal favourite). 9. Fix generics (possibly the most requested change). 10. etc., etc., etc. I am sure you can see how this small change now opens up many possibilities in the future and also allows Java to pick up the best features of other JVM languages (I used JavaFX as an example above, but also Scala, JRuby, Groovey, Jython, Rhino, PHP, etc.). The above list is a very quickly drawn up list; I am sure you could add your own favourites, after all we are communicating on coin and therefore have an opinion about Java and want to see it get better. I am guessing that your personal favourite will be integrating modules with source so that version tracking of libraries can be checked by the compiler, I see this as only one of many possibilities for source. -- Howard. 2009/3/19 Jeremy Manson : > On Wed, Mar 18, 2009 at 3:10 AM, Howard Lovatt wrote: >> Hi, >> >> 2009/3/16 Jeremy Manson : > >>> I'm not objecting to versioning in principle, but I think there are >>> enough unanswered questions that this proposal is probably beyond the >>> scope of "small changes". >> >> I think one of the reasons that Java is tending to stagnate a little, >> not badly, just a little, is that it is getting hard to introduces >> changes. I think source will provide a relief valve - get out of jail >> free. > > I'm not going to respond point-by-point, but the primary reason it is > hard to introduce changes in Java is not because of existing keywords, > or the fact that we are tied to existing source. ?It is because it > *should* be hard to introduce changes in a widely used programming > language. ?Too much forward progress gives you a language that looks > more like a katamari than a well-considered, cohesive whole: C++ and > perl come to mind as examples of this. ?How many different initializer > syntaxes does C++ have? ?15? > > I agree that there has been too much stagnation in the platform in the > last few years, but this has nothing to do with it being difficult to > change the language. ?It is because of political issues in the Java > community. ?This is clearly not the right forum to discuss that, > though. > > I think that in this specific case, you are considering adding > something that only solves a small part of a much larger problem that > needs to be addressed. ?Instead of having a point solution, which > risks being at odds with solutions to the rest of the problem, what > you really want is a larger, well-thought-out solution to the whole > problem. ?Start a JSR and solve versioning for us! ?Everyone will be > very grateful! > > Jeremy > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ > From howard.lovatt at iee.org Wed Mar 18 23:39:02 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 17:39:02 +1100 Subject: PROPOSAL: Method and Field Literals Message-ID: <3dd3f56a0903182339t6eb3464ds21c77d5a193308b8@mail.gmail.com> A couple of points: 1. This would be a nice addition to the language 2. Make it orthogonal so that you don't make Java harder to learn, i.e. use JavaDoc syntax, allow fields, methods, constructors, and *classes*. 3. Deprecate .class and replace with #class, Java shouldn't have new got'yas. 4. ArrayList#ArrayList() isn't a problem, it can mean constructor access in Java and the exotic identifier syntax can be used for non-Java names containing hash. 5. You don't have to solve all the problems on day one; we can come back and make the Field/Method literals better in future Java versions (also see next point), e.g. fix Field and Method to be generic. 5. If a source statement, see source and encoding proposal on coin, is added to Java then this proposal doesn't prevent future expansion of Java. In particular: A. If a new inner-class/closure/method-reference syntax is added to Java then it can use a keyword instead of having to reuse #, JavaFX for example uses function. B. A new keyword can be used for MethodHandels. C. A new keyword can be used for reflective property access From xmirog at gmail.com Wed Mar 18 23:46:15 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Thu, 19 Mar 2009 07:46:15 +0100 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> Message-ID: <49C1EA37.8090807@gmail.com> I like this feature a lot. My only concern was what happens when a new method is added to a class that has been extended with an extension method, but now I think this could be easily solved with a compiler warning when an imported extension method has the same signature as a method of the class or interface it extends. I mean that if you write a code like this when the class SomeClass class doesn't have a method sort (I'm not using interfaces now because the problem is easier to appear with classes): import static some.package.SomeClass.sort; SomeClass myObj = ... myObj.sort(); // uses SomeClass.sort extension method ...and some time later you use a new version of SomeClass which has the sort method with the same signature, the same source code could behave differently: import static some.package.SomeClass.sort; SomeClass myObj = ... myObj.sort(); // uses SomeClass.sort instance method I think that, if the compiler writes a warning like "The extension method SomeClass.sort is not used because there is a sort method in the class SomeClass", then the problem is gone, because you can do three different things: 1) Remove the extension method import and leave the call as is if you have checked that the behaviour of the new method sort is the same as the extension method's. 2) Remove the extension method import and rewrite the sort method call as a normal static class call if you have seen a different behaviour in the new sort method. 3) Leave the extension method import and write an annotation to suppress the warning if you have checked the behaviour is the same in both methods and you want your source code compatible with both versions of the class SomeClass (the extension method will be used with the old version, and the instance method with the new version). I think the warning message would allow the programmer to decide what to do and to be aware of possible behaviour changes that could be difficult to track when upgrading to a new version of an extended class. Regards, Xavi Neal Gafter escribi?: > On Tue, Mar 17, 2009 at 11:56 PM, Kevin Krouse wrote: > >> I'm interested in extension methods. >> > > I'll write up a full proposal if I have any indication it's something > Joe/Sun(/IBM) would consider for project Coin. The basic idea would > work like this: > > Within a static method, you can use "this" as an new qualifier on the > first method parameter, which must be a reference type. This would be > reflected in the class file format as either a new flag, or a new > classfile attribute ("ExtensionMethod") on the method. > > When an extension method has been statically imported, you can use it > as if it is a member of the type of its first argument. The name > lookup rules for a method invocation > > o.f(...) > > are augmented as follows. When identifying candidates for overload > resolution, if no accessible candidates of the correct name are found > as a member of the static type of the receiver (JLS 15.12.1 and > 15.12.2), then we consider as candidates those statically imported > methods with name f, and perform the overload resolution among them as > if the invocation had been written > > f(o, ...) > > This is backward compatible, as it assigns meanings to expressions > that were previously errors, and does not change the meaning of code > that was not previously an error. > > There are a number of benefits to this approach. A large number of > static utility class members can and probably should be retrofitted to > use extension methods, making it possible to use a much more > convenient syntax for common operations. > > import static java.util.Collections.sort; > List list = ... > list.sort(); // uses Collections.sort extension method > > Similarly, it allows extension methods to operate on arrays > > import static java.util.Arrays.sort; > String[] strings = ... > strings.sort(); // uses Arrays.sort extension method > > The syntactic convenience of this is greater (i.e. code becomes more > readable) when multiple invocations work together in an expression. > > One of the more important benefits of this approach is that it enables > future language changes to be defined by syntactic translation, while > allowing more flexible retrofitting of those language changes onto > existing APIs than would be possible without extension methods. For > example, one could define an ARM construct by translation of something > like > > protected (expression) statement > > into > > { > Type1 $t1 = expression > Type2 $t2 = $t1.protectedStart(); > try { > statement > } finally { > $t2.protectedEnd(); > } > } > > (with appropriate inversion of suppressed exceptions, if you please). > > Then, to add support for this new ARM construct to some particular API > you would either add these methods to the API or define extension > methods. If done using extension methods or final instance methods, > they are likely to be inlined by HotSpot if used in frequently > executed code, so the performance overhead is vanishingly small. > Since extension methods can be added even to existing interfaces > without breaking compatibility, such an ARM construct could be > retrofitted onto many more APIs than the currently proposed construct. > It could easily be retrofitted onto java.util.concurrent.locks.Lock, > for example. > > See also http://www.javac.info/ExtensionMethods.html > > > From Joe.Darcy at Sun.COM Wed Mar 18 23:52:50 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Wed, 18 Mar 2009 23:52:50 -0700 Subject: Return 'this' proposal In-Reply-To: References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> Message-ID: <49C1EBC2.3000009@sun.com> Reinier Zwitserloot wrote: > Joe, > > What's the coin viability for a proposal that does NOT change the type > system, but just introduces syntax sugar that translates: > > expression.setBar().setBaz(); > > to: > > TypeOfExpression $unique = expression; > $unique.setBar(); > $unique.setBaz(); > I'm not in favor of language changes which retrofit a fluent interface on an API not designed to have one. -Joe From reinier at zwitserloot.com Thu Mar 19 00:24:22 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 19 Mar 2009 08:24:22 +0100 Subject: Return 'this' proposal In-Reply-To: <49C1EBC2.3000009@sun.com> References: <28bca0ff0903151434w370dda8fyfb843c8aac0a8921@mail.gmail.com> <49C010FC.8050306@sun.com> <28bca0ff0903171509x5c110decl5f6a1b02421bf832@mail.gmail.com> <49C028BA.4090609@sun.com> <49C1EBC2.3000009@sun.com> Message-ID: <254D5DD0-C47E-41F0-9A61-8737C19E1128@zwitserloot.com> I think you misunderstood, Joe. The idea is not that you can do that with -any- method that returns void. The idea is that a method declares that it supports this, by way of a flag. This does not change either the signature of that method, or the type system. Just like the varargs flag, it's 'magic' that tells the code that calls the method that it can/needs to do something special (in the case of varargs, create an array. In the case of this idea, presume the result of the expression "a.methodWithTheReturnThisFlagEnabled()" is "a", and the method call's return value, if any, is completely ignored. Any library author can go back and retro-actively add these markers (though obviously they should only do that if their methods always 'return this;'), without breaking old code, or new code. If a library author feels this isn't a good idea, then they don't. --Reinier Zwitserloot On Mar 19, 2009, at 07:52, Joseph D. Darcy wrote: > Reinier Zwitserloot wrote: >> Joe, >> >> What's the coin viability for a proposal that does NOT change the >> type system, but just introduces syntax sugar that translates: >> >> expression.setBar().setBaz(); >> >> to: >> >> TypeOfExpression $unique = expression; >> $unique.setBar(); >> $unique.setBaz(); >> > > I'm not in favor of language changes which retrofit a fluent > interface on an API not designed to have one. > > -Joe > From howard.lovatt at iee.org Thu Mar 19 00:26:34 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 18:26:34 +1100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) Message-ID: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> Hi, I think that waiting until we can add Traits/Mixins would be better than adding extension methods, glue classes, continuation methods, or static methods in interfaces (Traits would likely include static methods in interfaces). When I blogged about this stuff a while back: http://www.artima.com/weblogs/viewpost.jsp?thread=220783 There was not much enthusiasm for extension methods etc., but people did like Traits: http://www.artima.com/weblogs/viewpost.jsp?thread=220916 -- Howard. From reinier at zwitserloot.com Thu Mar 19 00:30:33 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 19 Mar 2009 08:30:33 +0100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> References: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> Message-ID: Why do you feel waiting is a better idea? Unless you have some sort of language improvement in mind which is going to become impossible if SMI is added, I'd argue the reverse: Bigger changes should be introduced in bits and pieces if each piece is individually useful. --Reinier Zwitserloot On Mar 19, 2009, at 08:26, Howard Lovatt wrote: > Hi, > > I think that waiting until we can add Traits/Mixins would be better > than adding extension methods, glue classes, continuation methods, or > static methods in interfaces (Traits would likely include static > methods in interfaces). When I blogged about this stuff a while back: > > http://www.artima.com/weblogs/viewpost.jsp?thread=220783 > > There was not much enthusiasm for extension methods etc., but people > did like Traits: > > http://www.artima.com/weblogs/viewpost.jsp?thread=220916 > > > -- Howard. > From howard.lovatt at iee.org Thu Mar 19 00:45:56 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Thu, 19 Mar 2009 18:45:56 +1100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: References: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> Message-ID: <3dd3f56a0903190045x42c38d24yf6ec13c07c4dec35@mail.gmail.com> Hi, 2009/3/19 Reinier Zwitserloot : > Why do you feel waiting is a better idea? > > Unless you have some sort of language improvement in mind which is going to > become impossible if SMI is added, I'd argue the reverse: Bigger changes > should be introduced in bits and pieces if each piece is individually > useful. Just caution because a Trait proposal hasn't been put forward, outside coin scope, so I don't want to see a good Trait proposal compromised by a change introduced now. It probably isn't a big deal though if source went in (source would give you a get out of jail and allow the Trait proposal to be incompatible if need be). Same comment for the return this proposal. -- Howard. From schulz at e-Spirit.de Thu Mar 19 01:00:17 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Thu, 19 Mar 2009 09:00:17 +0100 Subject: Embedded expressions in string literals. In-Reply-To: <69037540cbb22044757365702da1ea7b.squirrel@wmail.gradsoft.ua> References: <3dd3f56a0903141919n7dd0593ale5324e7283191a7d@mail.gmail.com><637393b44ed7882132daf429ddec1c99.squirrel@wmail.gradsoft.ua><3dd3f56a0903181456p7fc71d68gac43ed1f9d98b597@mail.gmail.com><5ee07a2d25a6c6f312ad20b1e629d899.squirrel@wmail.gradsoft.ua><3dd3f56a0903181541o5462e54dqd9c0c3830378130@mail.gmail.com> <69037540cbb22044757365702da1ea7b.squirrel@wmail.gradsoft.ua> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC105DFB8C@osiris2.e-spirit.de> The proposal I set up only provides some syntax sugar for embedding expressions in Strings. It's not about deferring expression evaluation or late binding. Although, this might be desireable, it is better to be solved by a proper closure solution, which obviously is out of scope for Coin. Stefan > -----Original Message----- > From: coin-dev-bounces at openjdk.java.net > [mailto:coin-dev-bounces at openjdk.java.net] On Behalf Of > rssh at gradsoft.com.ua > Sent: Wednesday, March 18, 2009 9:52 PM > To: Howard Lovatt > Cc: coin-dev > Subject: Re: Embedded expressions in string literals. > > > I don't see your binding proposal as an improvement over > what we have > > got for many use cases, that is not to say that it isn't valuable as > > an API. It is an API for string processing and therefore should be a > > suggested library change; not part of coin. The string literals with > > expressions and your API proposal would be complementary, > particularly > > if they had similar syntax. Also see a formal proposal for embedding > > expressions into strings on coin, it is called Proposal: Embedded > > Expressions for String Statements and is from Stefan Schulz. > > > > For implementing such proposal you need a mapping between > names and values. > (I. e. our binding). > > Now, let's think about all entities, which we have: > > 1. binding. > 2. String before process of substituting embedding expression. > 3. Process of substituting embedding expression. (I. e. syntax of > mini=language inside string). > > Applying this 3 entities we receive: > > 4. String after process of substituting embedding expression. > > Original Stefan proposal does not specify difference between 2 and 4. > Problem, that > if (2) exists only in program text (and transformed to 4 during > compilation process), than > - such transformation is possible only in static context, fixed in > compile-time. This means that you can't pass such string literal to > arguments, and, for example, next code snipset: > > int x = readX(); > System.out.println("You entered \{x}"); > > Will produce result differ, than > > String message = "You entered \{x}"; > int x = readX(); > System.out.println(message); > > I belive, that fixing all such transformations in static context is > fundamentally wrong. > > Ok, now let's interpret Stefan proposal (EESL) in dynamic context. > But for this we need specify binging (explicit or implicit [in static > context ?]) and mark process of interpretation by some function. I. e. > receive all the complexity of embedding interpreted language. > Fortunelly, > this complexity already implemented in JSR223 interface. Embedded > expressions proposal in such interpretation - just yet one syntax for > embedded language. (We already have near 200 JVM languages, > most of them > implement javax.scripting interfaces) > Of course, we can choose language of some simple syntax be > default for > string expression processing - in such case, binding will > just a mechanism > for implementation of EESL. > > > > 2009/3/19 : > >>> Hi All, > >>> > >>> 2009/3/18 ?: > >>> > >>> [snip] > >>> > >>>> Complex case: > >>>> Create special syntax for template processing inside > strings - I guess > >>>> this can be a library issue. > >>>> We have jsr223. May be good ideaa is adding helper methods, which > >>>> process > >>>> string via choosed language interptreter, i.e. > >>>> =s.scriptEval("velocity",binding); > >>>> =.... but - from other side =we can't receive binding > between names > >>>> and > >>>> values automatically for now. > >>> > >>> Not sure that a library would work, can you give an example of the > >>> call you propose? > >>> > >> > >> Example of such call can be: > >> > >> binding = new Binding(); > >> binding.put("x",x); > >> binding.put("y",y); > >> > >> """ > >> ? > >> ? A > >> ? > >> ? B > >> ? > >> """.evalScript("PHP",binding); > >> > >> If PHP is avaible via JSR223 API, then string will be > evaluated to A or > >> B. > >> Or, if you does not like PHP, you can use velocity or java. > >> > >> But creating binding by hands (first 3 strings of test) kill all :( > >> > >> From other side, in principle compiler can generate > binding for local > >> variables automatically, so in principle it is possible to > create 'magic > >> annotation', to write code like: > >> > >> > >> int someMethod(); > >> { > >> int x=1; > >> int y=2; > >> @GenerateVariableBinding > >> Binding binding; > >> > >> String s = """ > >> ? > >> ? A > >> ? > >> ? B > >> ? > >> """.evalScript("PHP",binding); > >> > >> System.out.println(); > >> > >> } > >> > >> > >> (I think about formalizing and submitting such proposal, > but not sure > >> that > >> it is possible correct define one in short terms.) > >> > >> > >> > >> > >> > >> > ______________________________________________________________________ > >> This email has been scanned by the MessageLabs Email > Security System. > >> For more information please visit http://www.messagelabs.com/email > >> > ______________________________________________________________________ > >> > > > > > > From schulz at e-Spirit.de Thu Mar 19 01:03:17 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Thu, 19 Mar 2009 09:03:17 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> The concat-variant to me is even worse readable than the original +-notation, having three consecutive commas in between. The proposal already mentions concatenation of any kind as alternative, although not mentioning concat(). Maybe worth expanding. Stefan > -----Original Message----- > From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] > Sent: Wednesday, March 18, 2009 8:58 PM > To: Howard Lovatt > Cc: coin-dev at openjdk.java.net; Schulz, Stefan > Subject: Re: Proposal: Embedded Expressions for String Statements > > > I like Stefan's proposed syntax and as a way of a motivating example > > consider writing a toString method that gives the field > values within > > square brackets, now you would write: > > > > "[" + field1 + ", " + field2 + ", " + field3 + "]" > > > > With the proposal you would say: > > > > "[\{field1}, \{field2}, \{field3}]" > > > > Which I find clearer. > > > > Just note: now we can use much cleaner > concat( field1, ',' , field2, ',' field3 ) > > > > > Many thanks to Stefan for writing this up formally. > > > > > > > > From jacek.p.kolodziejczyk at gmail.com Thu Mar 19 01:26:45 2009 From: jacek.p.kolodziejczyk at gmail.com (Jacek Kolodziejczyk) Date: Thu, 19 Mar 2009 09:26:45 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators Message-ID: <49C201C5.3090200@gmail.com> Hi, 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(); Returning true by list?.isEmpty() would make much more sense, because semantically the null list does not have any elements, so it means it is empty. The bottom line is that what the method returns when called on a null object is an implementation detail of that method, so it should be specified in that method's body. For another example if I wanted to print "Unknown" when person object is null, then every time I call Person.toString() I must write person?.toString() ?: "Unknown"; This violates the fundamental DRY principle. I could improve it by putting "Unknown" to a static field or a separate static method, but still the best would be if person?.toString() just returned "Unknown" when person is null. The rest of this message proposes a way to introduce object oriented handling of null methods invocations (though I apologize this is not in-depth analysis) If the method's body starts with if (this == null) statement, e.g. class List { public boolean isEmpty() { if (this == null) return true; return data.length == 0; } } then Java 7 compiler could compile it to both the traditional method: public boolean isEmpty() { // the if (this == null) ... block is removed return data.length == 0; } as well as to a static wrapper method: private static boolean isEmptyNullSafe(List _this) { if (_this == null) return true; return _this.isEmpty(); } (The name of this static method should be reserved by the compiler in such case to prevent name clashes with methods already existing in the source code) This way the isEmpty() method would work the same way if called normally: list.isEmpty() , throwing NPE. But the null safe call: list?.isEmpty() would compile to: List.isEmptyNullSafe(list); and return true, if the list is null. Some discussion on this issue have taken place on my blog: http://codervirtue.blogspot.com/2009/03/null-safe-invocation-in-java-7.html#comments Regards Jacek Kolodziejczyk From Joe.Darcy at Sun.COM Thu Mar 19 01:38:37 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Thu, 19 Mar 2009 01:38:37 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <3dd3f56a0903171754h7845bc78waa3aca1c2401b704@mail.gmail.com> References: <3dd3f56a0903171754h7845bc78waa3aca1c2401b704@mail.gmail.com> Message-ID: <49C2048D.406@sun.com> Howard Lovatt wrote: > Hi Joe, > > Thanks for the response, answers in text. > > 2009/3/18 Joseph D. Darcy wrote: > > [snip] > > > > >>> 1. Deprecate raw declarations, new ArrayList() becomes a deprecated >>> warning - you need to say new ArrayList(). >>> > > > > > That could be a fine lint option. You could also write an annotation > > processor that used the javac tree API to generated such warnings/errors > > today. > > > > Yes you could - but I think it would be better in the language so that > every implementation gets this useful behaviour. > Language changes are not a quick way to enact change. It is certainly possible that all implementations of interest can get a desirable feature without a language change and that such universal changes are usable sooner than a language change can be made officially available. All Java SE 6 compiler implementations are required to support annotation processing and each that I'm aware of has a tree API to provide additional information; therefore, additional checks that can easily be written as annotation processors are much better implemented and promulgated as annotation processors. >>> 2a. Deprecate self references, you get a deprecated warning for class >>> Type>, you wouldn't use generics in this case. >>> > > > > >> F-bounds are part of Java's generics. >> > > > > Yes. But I am suggesting that we deprecate it because no one likes it. > Simply because a feature is complicated or disliked doesn't imply it isn't technically desirable or necessary! > The complication and confusion that it brings outweighs its benefit. > Less is more. > > [snip] > > > > >>> 3. Deprecate the ability to specify multiple bounds, e.g. instead of >>> static > T max(Collection>> extends T>) you write static T max(Collection) (note >>> Comparable would not be parameterised with the new syntax since you >>> would almost always want Comparable). >>> > > > > > There are reasons why multiple bounds are supported. > > > > Yes. Again not worth the trouble - don't use generics in these > backward compatibility cases. The multiple bounds and the trick of putting Object as the first bound to maintain the desired erasure were added in JDK 5 to solve actual problems; see Gilad's "Generics in the Java Programming Language." http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf -Joe From Joe.Darcy at Sun.COM Thu Mar 19 01:45:18 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Thu, 19 Mar 2009 01:45:18 -0700 Subject: Proposal: Improved Wildcard Syntax for Java In-Reply-To: <3dd3f56a0903171629s528fcf91habde1bbac53ffc75@mail.gmail.com> References: <3dd3f56a0903171629s528fcf91habde1bbac53ffc75@mail.gmail.com> Message-ID: <49C2061E.5030805@sun.com> Hello. Howard Lovatt wrote: > Hi Joe, > > Emails overlapped, you sent me one whilst I was replying to you, hence > second email. > > 2009/3/18 Joseph D. Darcy wrote: > > [snip] > > >>> There is only one change to the type system; which is to allow >>> covariant assignment, e.g. List lo = new ArrayList(). >>> This isn't a drastic change, arrays already do this. >>> >> This is in general *not* type safe. Arrays allow one to do this because >> array types are reified and there is a store-check at runtime when writing >> into an array. Since generics in Java are implemented via erasure, this >> implementation strategy is not possible for Lists and Sets, etc. >> > > In the example I sent to Neal I showed how you can write a List that > generates an ArrayStoreException, that still uses erasure, by using a > factory (java.lang.reflect.Array.newInstance( ... )) to generate a > correctly typed array. That sort of trick can only work on types that are reifiable; List> or something with multiple bounds wouldn't work. Also see the checked collections wrapper methods in java.util.Collections. > The underlying array generates the > ArrayStoreException. Therefore it is possible to have generic > covariant assignment, erasure, and runtime type safety simultaneously. > > Trying to catch this error, incorrect use of an aliased generic, in > the type system isn't worth the trouble, arrays have a more useful > That is exactly the sort of issue type systems are designed to catch! -Joe From develop4lasu at gmail.com Thu Mar 19 01:57:44 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 19 Mar 2009 09:57:44 +0100 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49C201C5.3090200@gmail.com> References: <49C201C5.3090200@gmail.com> Message-ID: <28bca0ff0903190157u59e7b61cw2bd3c3579188bb96@mail.gmail.com> 2009/3/19 Jacek Kolodziejczyk > Hi, > > 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(); > > Returning true by list?.isEmpty() would make much more sense, because > semantically the null list does not have any elements, so it means it is > empty. The bottom line is that what the method returns when > called on a null object is an implementation detail of that > method, so it should be specified in that method's body. > > For another example if I wanted to print "Unknown" when person object is > null, then every time I call Person.toString() I must write > person?.toString() ?: "Unknown"; > This violates the fundamental DRY principle. I could improve it by > putting "Unknown" to a static field or a separate static method, but > still the best would be if person?.toString() just returned "Unknown" > when person is null. > > The rest of this message proposes a way to introduce object oriented > handling of null methods invocations (though I apologize this is not > in-depth analysis) > > If the method's body starts with if (this == null) statement, e.g. > class List { > public boolean isEmpty() { > if (this == null) return true; > return data.length == 0; > } > } > > then Java 7 compiler could compile it to both the traditional method: > public boolean isEmpty() { > // the if (this == null) ... block is removed > return data.length == 0; > } > > as well as to a static wrapper method: > private static boolean isEmptyNullSafe(List _this) { > if (_this == null) return true; > return _this.isEmpty(); > } > > (The name of this static method should be reserved by the compiler in > such case to prevent name clashes with methods already existing in the > source code) > > This way the isEmpty() method would work the same way if called normally: > list.isEmpty() > , throwing NPE. > > But the null safe call: > list?.isEmpty() > would compile to: > List.isEmptyNullSafe(list); > and return true, if the list is null. > > Some discussion on this issue have taken place on my blog: > > http://codervirtue.blogspot.com/2009/03/null-safe-invocation-in-java-7.html#comments > > Regards > Jacek Kolodziejczyk > > > Interesting. But note that glue classes can handle this. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Thu Mar 19 01:58:23 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 19 Mar 2009 09:58:23 +0100 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> References: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> Message-ID: <28bca0ff0903190158x546eb3c2t3db4bc8400254556@mail.gmail.com> 2009/3/19 Howard Lovatt > Hi, > > I think that waiting until we can add Traits/Mixins would be better > than adding extension methods, glue classes, continuation methods, or > static methods in interfaces (Traits would likely include static > methods in interfaces). When I blogged about this stuff a while back: > > http://www.artima.com/weblogs/viewpost.jsp?thread=220783 > > There was not much enthusiasm for extension methods etc., but people > did like Traits: > > http://www.artima.com/weblogs/viewpost.jsp?thread=220916 > > > -- Howard. > > Some time ago I wandered about 'Trails', 'literal Traits' (same as Trails but contains method as String and it's interpreted in inherited classes). But after few talks about it I found that it's not good idea because: 1. When some one write method in class and then some Interface in .jar will have added method with same signature, but designed for other purpose the we will have hard to localize bugs. 2. If methods are compiled to Interface then then it's problem when you want include interfaces to client side applet. Should u include all required classes as well? It can be quite problem for peoples who write applets. ('literal Traits' are ok here) -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From joshua.suereth at gmail.com Thu Mar 19 04:46:53 2009 From: joshua.suereth at gmail.com (Josh Suereth) Date: Thu, 19 Mar 2009 07:46:53 -0400 Subject: PROPOSAL: Static Methods in Interfaces (v1.1) In-Reply-To: References: <3dd3f56a0903190026v47a9530cs56706f6b46950ba2@mail.gmail.com> Message-ID: <55b774930903190446o70cc6395h505404e3775a96cc@mail.gmail.com> On Thu, Mar 19, 2009 at 3:30 AM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Why do you feel waiting is a better idea? > > Unless you have some sort of language improvement in mind which is > going to become impossible if SMI is added, I'd argue the reverse: > Bigger changes should be introduced in bits and pieces if each piece > is individually useful. > > --Reinier Zwitserloot > > While I'd argue that extension methods are useful (although something slightly more powerful like scala implicit conversions may be a better idea), I'm not 100% sold on static methods on interfaces. I do think it's a great idea for alternative JVM languages who *are* defining traits using a combination of interfaces + static methods. So, in this case I'd love to see this in the JVM, but not sure I would use it from the Java language itself until it became more useful (i.e. full out traits). To the argument against by virtue of "This would be harder to use in applets", I would apply the same caution to any language feature: "Don't abuse it". Obviously some third-party jars would potentially do so that you want to make use of, however tools like proguard or jarjar could potentially have options to remove unused methods from classes when "minifying" your distro (assuming no reflection is used). I don't think any feature should be allowed/denied on the basis of abuse. I can still synchronize("hello") {} all day long in java. From neal at gafter.com Thu Mar 19 07:13:43 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 19 Mar 2009 07:13:43 -0700 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <49C201C5.3090200@gmail.com> References: <49C201C5.3090200@gmail.com> Message-ID: <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> 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. From forax at univ-mlv.fr Thu Mar 19 08:10:31 2009 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Thu, 19 Mar 2009 16:10:31 +0100 Subject: PRE-PROPOSAL: Extension methods In-Reply-To: <15e8b9d20903181421h6c93f942p864a7208a7b5f5a6@mail.gmail.com> References: <15e8b9d20903181023m5163ee50xa9cb8c3c33d47e1@mail.gmail.com> <15e8b9d20903181421h6c93f942p864a7208a7b5f5a6@mail.gmail.com> Message-ID: <49C26067.9040707@univ-mlv.fr> I vote NO. The problem with extension method is that it doesn't mix well with polymorphism. Example: interface List { ... } class Collections { public static void sort(this List list) { // extension methods ... // 1 } } class SortedList implements List { public void sort() { ... // 2 } } import static java.util.Collections.*; ... List list=... list.sort(); // call 1 SortedList slist=... slist.sort(); // call 2 List slist2=slist; slist2.sort(); // call 1 The last call is not intuitive in a well known language in which late binding is the default behavior. R?mi From develop4lasu at gmail.com Fri Mar 20 07:35:55 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 20 Mar 2009 15:35:55 +0100 Subject: Glue classes proposal 0.9 Message-ID: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: Glue classes allow to link utils direct with objects. MAJOR ADVANTAGE: + Forgotten functionality can be not such big deal now. MAJOR BENEFIT(s): + New functions can be easy localized (critically important while introduce new peoples into project). + Security: glue class do not see anything protected. + Light binding new functions with existing classes. + Number of used classes reduction. + Allow to assign methods and functions(static methods) to arrays, classes, interfaces, ? + It's proof against same method occurs in class and delegator as well like in two delegators. + Allow to link gained(.jar) logic with new one, witch is impossible before final developer implements his classes. + Allow to project compact interfaces and do not worry about additional logic. MAJOR DISADVANTAGE: Do not know any ;) sorry. ALTERNATIVES: Utils classes, more work on project, duplicated code... EXAMPLES SIMPLE EXAMPLE: Now time: public class base { public static T[] flatten(T[][] this) { int length = 0; for (T[] subArray : this) { length += subArray.length; } T[] ret = (T[]) Array.newInstance(this.getClass().getComponentType().getComponentType(), length); int pos = 0; for (T[] subArray : this) { System.arraycopy(subArray, 0, ret, pos, subArray.length); pos += subArray.length; } return ret; } } Now time(usage): public static void main(String[] args) { Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { 9, 0 } }; System.out.println(Arrays.toString(base.flatten(array))); } Glue: public class base glue( T[][] ) { public glue T[] flatten( this) { int length = 0; for (T[] subArray : this) { length += subArray.length; } T[] ret = (T[]) Array.newInstance(this.getClass().getComponentType().getComponentType(), length); int pos = 0; for (T[] subArray : this) { System.arraycopy(subArray, 0, ret, pos, subArray.length); pos += subArray.length; } return ret; } } Glue(usage): public static void main(String[] args) { Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { 9, 0 } }; System.out.println(array..flatten()..toString()); } ADVANCED EXAMPLE: Now time: public class base { public static int addAll( ArrayList this, Iterator iterator) { int added = 0; while (iterator.hasNext()) { added += this.add(iterator.next()) ? 1 : 0; } return added; } public static int addAll(ArrayList this, E[] elements) { int added = 0; for (T t : elements) { added += this.add(t) ? 1 : 0; } return added; } } Now time(usage): public static void main(String[] args) { Integer[] add = new Integer[] { 1, 2, 34, 2, 5, }; ArrayList arrayList = new ArrayList(); ArrayList finall = new ArrayList(); base.addAll(arrayList, add); base.addAll(finall, add); base.addAll(finall,arrayList.iterator()); System.out.println(finall); } Glue: public class base glue( ArrayList ){ public glue int addAll( this, Iterator iterator) { int added = 0; while (iterator.hasNext()) { added += this.add(iterator.next()) ? 1 : 0; } return added; } public glue int addAll( this, E[] elements) { int added = 0; for (T t : elements) { added += this.add(t) ? 1 : 0; } return added; } } Glue(usage): public static void main(String[] args) { Integer[] add = new Integer[] { 1, 2, 34, 2, 5, }; ArrayList arrayList = new ArrayList(); ArrayList finall = new ArrayList(); arrayList..addAll(add); finall..addAll(add); finall..addAll(arrayList.iterator()); System.out.println(finall); } Glue second: public class base glue( Date ) { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); public glue String format( this ) { synchronized (sdf) { return sdf.format(this); } } private static final Date applicationStart = new Date(); public static glue Date applicationStart() { return applicationStart; } } Glue second(usage): public static void main(String[] args) { System.out.println(Date..applicationStart()..format()); } DETAILS SPECIFICATION: JLS 8.8: ClassDeclaration: NormalClassDeclaration GlueClassDeclaration EnumDeclaration GlueClassDeclaration ClassModifiers_opt class Identifier TypeParameters_opt glue ( GlueFormalParameter ) GlueClassBody GlueFormalParameter VariableModifiers Type GlueClassBody: { GlueClassBodyDeclarations_opt } GlueClassBodyDeclarations: GlueClassBodyDeclaration GlueClassBodyDeclarations GlueClassBodyDeclaration GlueClassBodyDeclaration: GlueClassMemberDeclaration StaticInitializer GlueClassMemberDeclaration: FieldDeclaration StaticMethodDeclaration GlueMethodDeclaration StaticClassDeclaration InterfaceDeclaration ; GlueMethodDeclaration: GlueMethodHeader MethodBody GlueMethodHeader: MethodModifiers_opt glue TypeParameters*opt ResultType GlueMethodDeclarator Throwsopt GlueMethodDeclarator: Identifier ( this,*opt FormalParameterListopt ) *opt: 'this' occurs always and only if glue method is not static. TypeParameters from GlueClassDeclaration are always visible for TypeParameters in GlueMethodHeader (even if method is static). 15.12 Method Invocation Expressions: GlueMethodInvocation:
Primary .. NonWildTypeArguments*_opt TypeName_opt GlueMethodIdentifier ( ArgumentList_opt )
super .. NonWildTypeArguments*_opt GlueMethodIdentifier ( ArgumentList_opt )
ClassName . super .. NonWildTypeArguments*_opt GlueMethodIdentifier ( ArgumentList_opt )
TypeName .. NonWildTypeArguments* GlueMethodIdentifier ( ArgumentList_opt )

NonWildTypeArguments* suit TypeParameters in GlueMethodHeader.

COMPILATION: If object (except null) is valid for GlueFormalParameter then glue-method can be called for this object. If type is compatible with GlueFormalParameter then static glue-method can be called for this type. For non static methods glued-object is passed as first 'this' parameter. Compiled method signature contains TypeParameters from GlueClassDeclaration (at start), and it's always static. TESTING: Like simple static methods. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: None. COMPATIBILITY New jars are fully compatible. Code is only backward compatible. REFERENCES Glue classes proposal 0.9 : http://lasu2string.blogspot.com/2009/03/glue-classes-proposal-09.html Bug: Extension of 'Interface' definition to include class (static) methods: http://bugs.sun.com/view_bug.do?bug_id=4093687 -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Thomas.Hawtin at Sun.COM Thu Mar 19 09:41:02 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Thu, 19 Mar 2009 16:41:02 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <3dd3f56a0903181451y84ce862h4da8b42c4b33f3e0@mail.gmail.com> References: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> <3dd3f56a0903181451y84ce862h4da8b42c4b33f3e0@mail.gmail.com> Message-ID: <49C2759E.3020104@sun.com> Howard Lovatt wrote: > Dots are also a bad solution because you can get confusing expressions: > > 5.<.4 > > Is this: > > (5.) < (.4) This is a lexical issue. The lexer is greedy, so yes the tokens would be "5." "<" ".4"[1]. I don't believe this lexical issue would be a real problem in real code. For instance the expressions "f<.4" and "i.<.4" would both work as expected. Tom [1] >> and >>> are the only real oddities in Java. As well as being double and triple close of generics, they are some obscure operators that don't really belong in Java (IMO). From reinier at zwitserloot.com Fri Mar 20 08:17:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 20 Mar 2009 16:17:07 +0100 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <49C2759E.3020104@sun.com> References: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> <3dd3f56a0903181451y84ce862h4da8b42c4b33f3e0@mail.gmail.com> <49C2759E.3020104@sun.com> Message-ID: <62D234A3-F3C8-49EF-A8A9-099C20FAB439@zwitserloot.com> Your average java programmer does not know that the lexer is greedy, and making knowledge of this mandatory to understand what's happening when Joe Q. Java sees "5.<.4" is a bad idea. --Reinier Zwitserloot On Mar 19, 2009, at 17:41, Tom Hawtin wrote: > Howard Lovatt wrote: >> Dots are also a bad solution because you can get confusing >> expressions: >> >> 5.<.4 >> >> Is this: >> >> (5.) < (.4) > > This is a lexical issue. The lexer is greedy, so yes the tokens > would be > "5." "<" ".4"[1]. I don't believe this lexical issue would be a real > problem in real code. For instance the expressions "f<.4" and "i.<.4" > would both work as expected. > > Tom > > [1] >> and >>> are the only real oddities in Java. As well as being > double and triple close of generics, they are some obscure operators > that don't really belong in Java (IMO). > From neal at gafter.com Fri Mar 20 08:27:08 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Mar 2009 08:27:08 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> Message-ID: <15e8b9d20903200827m6e048c80y3de33547aca3f97e@mail.gmail.com> On Thu, Mar 19, 2009 at 5:55 PM, Joshua Bloch wrote: >> ?I find this comment?offensive, > > Sorry. ?I really did not mean to offend. I do believe that the particular > case of iterables requiring termination is a red herring. ?I know C# > supports it, but Java went the other way a long time ago. I believe that > you're the only one who as expressed ?enthusiasm for this use case. The only other person to comment on the issue has been Howard, and I'd interpret his response as supportive. In any case, you know quite well that the quality of a language change can't be measured by the body count. Actual experience is required. > I see > it as harmful scope creep that could keep a really important facility out of > the next release. ?The proposed construct was designed to address a severe > problem with existing types. I understand the urgency you feel around this proposal, given the very tight time schedule to design it right (1 month), and the very literal complexity budget that the solution must fall within. However, a solution must make sense not just during the transition of existing code, but it also must fit cleanly into the language after that transition is complete. That's what most worries me about this proposal. We should not compromise the language based on this imposed sense of urgency. > Important or not, it isn't a use case for this construct. ?It's specifically > excluded from this proposal. ?I offered to write a proposal for locks, but > people didn't seem all that interested so I didn't write it. We all clearly understand that this use case is not well addressed by the proposal in its current form, and we seem to have some consensus that a *separate* language construct would not be ideal. That's why further work is worthwhile. >> I'm still hoping to see a revision of the proposal that incorporates >> the changes you suggested be considered... > > In the next couple days. Excellent. I'm retrofitting of a bunch of code using the new construct and, while I don't have a complete compiler for the construct, I have enough experience using it to raise a few ergonomic issues in both the syntax and semantics that should be addressed. I'd rather report that feedback based on the latest version of the proposal. From neal at gafter.com Thu Mar 19 13:03:29 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 19 Mar 2009 13:03:29 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> Message-ID: <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> On Thu, Mar 19, 2009 at 12:32 PM, Joshua Bloch wrote: >> Experience >> with C#'s foreach loop and IDisposable/IEnumerable has shown the >> combination to be very useful, as it avoids some very awkward >> situations when both resources and loops are used together in a >> program. >> >> These kinds of issues make me think that more actual experience with >> the proposed construct will be required before we can have confidence >> that it is "right". > > I disagree. ?Java long ago rejected the use of iterators that required > explicit termination. ?This is simply a non-issue in the Java ecosystem. > ?I'm not saying that it was an entirely good decision, but it is the > decision we made. If we aim to add something like ARM, then we're no longer talking about explicit termination. In any case, it is because of the existence of these kinds of disagreements that I believe more experience is needed. The risks are too high for us to rush such constructs into the language without carefully considering the interactions, without a substantial opportunity to develop experience with it, and without allowing the proposal's spec to respond to that experience. From neal at gafter.com Fri Mar 20 08:35:29 2009 From: neal at gafter.com (Neal Gafter) Date: Fri, 20 Mar 2009 08:35:29 -0700 Subject: Glue classes proposal 0.9 In-Reply-To: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> Message-ID: <15e8b9d20903200835r3a85bb3bwac565151afc1e89f@mail.gmail.com> There really isn't enough of a specification for me to understand how this language feature fits together. What are the semantics? Is a glue class like a container for extension methods? On Fri, Mar 20, 2009 at 7:35 AM, Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? > > OVERVIEW > > FEATURE SUMMARY: > Glue classes allow to link utils direct with objects. > > MAJOR ADVANTAGE: > + Forgotten functionality can be not such big deal now. > > MAJOR BENEFIT(s): > + New functions can be easy localized (critically important while introduce > new peoples into project). > + Security: glue class do not see anything protected. > + Light binding new functions with existing classes. > + Number of used classes reduction. > + Allow to assign methods and functions(static methods) to arrays, classes, > interfaces, ... > + It's proof against same method occurs in class and delegator as well like > in two delegators. > + Allow to link gained(.jar) logic with new one, witch is impossible before > final developer implements his classes. > + Allow to project compact interfaces and do not worry about additional > logic. > > > MAJOR DISADVANTAGE: > Do not know any ;) sorry. > > ALTERNATIVES: > Utils classes, more work on project, duplicated code... > > > EXAMPLES > > SIMPLE EXAMPLE: > > > Now time: > public class base { > > public static T[] flatten(T[][] this) { > int length = 0; > for (T[] subArray : this) { > length += subArray.length; > } > T[] ret = (T[]) > Array.newInstance(this.getClass().getComponentType().getComponentType(), > length); > int pos = 0; > for (T[] subArray : this) { > System.arraycopy(subArray, 0, ret, pos, subArray.length); > pos += subArray.length; > } > return ret; > } > > } > Now time(usage): > public static void main(String[] args) { > Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { > 9, 0 } }; > System.out.println(Arrays.toString(base.flatten(array))); > } > > Glue: > public class base glue( T[][] ) { > > public glue T[] flatten( this) { > int length = 0; > for (T[] subArray : this) { > length += subArray.length; > } > T[] ret = (T[]) > Array.newInstance(this.getClass().getComponentType().getComponentType(), > length); > int pos = 0; > for (T[] subArray : this) { > System.arraycopy(subArray, 0, ret, pos, subArray.length); > pos += subArray.length; > } > return ret; > } > > } > Glue(usage): > public static void main(String[] args) { > Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { > 9, 0 } }; > System.out.println(array..flatten()..toString()); > } > > ADVANCED EXAMPLE: > Now time: > public class base { > > public static int addAll( ArrayList this, Iterator > iterator) { > int added = 0; > while (iterator.hasNext()) { > added += this.add(iterator.next()) ? 1 : 0; > } > return added; > } > > public static int addAll(ArrayList this, E[] elements) > { > int added = 0; > for (T t : elements) { > added += this.add(t) ? 1 : 0; > } > return added; > } > > } > Now time(usage): > public static void main(String[] args) { > Integer[] add = new Integer[] { 1, 2, 34, 2, 5, }; > ArrayList arrayList = new ArrayList(); > ArrayList finall = new ArrayList(); > > base.addAll(arrayList, add); > base.addAll(finall, add); > base.addAll(finall,arrayList.iterator()); > > System.out.println(finall); > } > > Glue: > public class base glue( ArrayList ){ > > public glue int addAll( this, Iterator iterator) { > int added = 0; > while (iterator.hasNext()) { > added += this.add(iterator.next()) ? 1 : 0; > } > return added; > } > > public glue int addAll( this, E[] elements) { > int added = 0; > for (T t : elements) { > added += this.add(t) ? 1 : 0; > } > return added; > } > > } > Glue(usage): > public static void main(String[] args) { > Integer[] add = new Integer[] { 1, 2, 34, 2, 5, }; > ArrayList arrayList = new ArrayList(); > ArrayList finall = new ArrayList(); > > arrayList..addAll(add); > finall..addAll(add); > finall..addAll(arrayList.iterator()); > > System.out.println(finall); > } > > Glue second: > public class base glue( Date ) > { > private static final SimpleDateFormat sdf = new > SimpleDateFormat("yyyy.MM.dd"); > > public glue String format( this ) { > synchronized (sdf) { > return sdf.format(this); > } > } > > private static final Date applicationStart = new Date(); > > public static glue Date applicationStart() { > return applicationStart; > } > } > Glue second(usage): > public static void main(String[] args) { > System.out.println(Date..applicationStart()..format()); > } > DETAILS > > SPECIFICATION: > JLS 8.8: > ClassDeclaration: > NormalClassDeclaration > GlueClassDeclaration > EnumDeclaration > > GlueClassDeclaration > ClassModifiers_opt class Identifier TypeParameters_opt glue ( > GlueFormalParameter ) GlueClassBody > > GlueFormalParameter > VariableModifiers Type > > GlueClassBody: > { GlueClassBodyDeclarations_opt } > > GlueClassBodyDeclarations: > GlueClassBodyDeclaration > GlueClassBodyDeclarations GlueClassBodyDeclaration > > GlueClassBodyDeclaration: > GlueClassMemberDeclaration > StaticInitializer > > GlueClassMemberDeclaration: > FieldDeclaration > StaticMethodDeclaration > GlueMethodDeclaration > StaticClassDeclaration > InterfaceDeclaration > ; > > GlueMethodDeclaration: > GlueMethodHeader MethodBody > > GlueMethodHeader: > MethodModifiers_opt glue TypeParameters*opt ResultType > GlueMethodDeclarator Throwsopt > > GlueMethodDeclarator: > Identifier ( this,*opt FormalParameterListopt ) > > *opt: 'this' occurs always and only if glue method is not static. > > TypeParameters from GlueClassDeclaration are always visible for > TypeParameters in GlueMethodHeader (even if method is static). > > > 15.12 Method Invocation Expressions: > > GlueMethodInvocation:
> Primary .. NonWildTypeArguments*_opt TypeName_opt GlueMethodIdentifier ( > ArgumentList_opt )
> super .. NonWildTypeArguments*_opt GlueMethodIdentifier ( ArgumentList_opt > )
> ClassName . super .. NonWildTypeArguments*_opt GlueMethodIdentifier ( > ArgumentList_opt )
> TypeName .. NonWildTypeArguments* GlueMethodIdentifier ( ArgumentList_opt > )

> > NonWildTypeArguments* suit TypeParameters in GlueMethodHeader.

> > > > > > > > COMPILATION: > If object (except null) is valid for GlueFormalParameter then glue-method > can be called for this object. > If type is compatible with GlueFormalParameter then static glue-method can > be called for this type. > For non static methods glued-object is passed as first 'this' parameter. > Compiled method signature contains TypeParameters from GlueClassDeclaration > (at start), and it's always static. > > > TESTING: > Like simple static methods. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > None. > > COMPATIBILITY > New jars are fully compatible. Code is only backward compatible. > > REFERENCES > > Glue classes proposal 0.9 : > http://lasu2string.blogspot.com/2009/03/glue-classes-proposal-09.html > > Bug: Extension of 'Interface' definition to include class (static) methods: > http://bugs.sun.com/view_bug.do?bug_id=4093687 > > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From Thomas.Hawtin at Sun.COM Fri Mar 20 08:35:35 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Fri, 20 Mar 2009 15:35:35 +0000 Subject: Draft proposal: allow the use of relational operators on Comparable classes In-Reply-To: <62D234A3-F3C8-49EF-A8A9-099C20FAB439@zwitserloot.com> References: <3dd3f56a0903180404n23f06b22p3f6d0158a27eb40d@mail.gmail.com> <3dd3f56a0903181451y84ce862h4da8b42c4b33f3e0@mail.gmail.com> <49C2759E.3020104@sun.com> <62D234A3-F3C8-49EF-A8A9-099C20FAB439@zwitserloot.com> Message-ID: <49C3B7C7.3020601@sun.com> Reinier Zwitserloot wrote: > Your average java programmer does not know that the lexer is greedy, and > making knowledge of this mandatory to understand what's happening when > Joe Q. Java sees "5.<.4" is a bad idea. Why would J.Q.J ever see "5.<.4"?? He or she may conceivably see "5. References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> Message-ID: <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> Neal. On Thu, Mar 19, 2009 at 12:17 PM, Neal Gafter wrote: > > Rather, I'm talking about the implicit Iterator variable that is > created by the expansion of the for-each loop. Unlike Iterable, > Iterators are one-shot, so making one a resource is natural. But, > with the current ARM proposal, there is no way to use the for-each > loop with an Iterable whose Iterator is an AutoResource. Experience > with C#'s foreach loop and IDisposable/IEnumerable has shown the > combination to be very useful, as it avoids some very awkward > situations when both resources and loops are used together in a > program. > > These kinds of issues make me think that more actual experience with > the proposed construct will be required before we can have confidence > that it is "right". > I disagree. Java long ago rejected the use of iterators that required explicit termination. This is simply a non-issue in the Java ecosystem. I'm not saying that it was an entirely good decision, but it is the decision we made. Josh From jjb at google.com Fri Mar 20 08:57:53 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 20 Mar 2009 08:57:53 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903200827m6e048c80y3de33547aca3f97e@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> <15e8b9d20903200827m6e048c80y3de33547aca3f97e@mail.gmail.com> Message-ID: <17b2302a0903200857p63df033m90b0dcf58796ecb8@mail.gmail.com> Neal, Please report your "ergonomic issues" now, so that I can take advantage of your work in the next rev, which I hope to write this weekend. Thanks, Josh On Fri, Mar 20, 2009 at 8:27 AM, Neal Gafter wrote: > On Thu, Mar 19, 2009 at 5:55 PM, Joshua Bloch wrote: > > >> I'm still hoping to see a revision of the proposal that incorporates > >> the changes you suggested be considered... > > > > In the next couple days. > > Excellent. I'm retrofitting of a bunch of code using the new > construct and, while I don't have a complete compiler for the > construct, I have enough experience using it to raise a few ergonomic > issues in both the syntax and semantics that should be addressed. I'd > rather report that feedback based on the latest version of the > proposal. > From jjb at google.com Thu Mar 19 17:55:25 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 19 Mar 2009 17:55:25 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> Message-ID: <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> Neal, I find this comment offensive, Sorry. I really did not mean to offend. I do believe that the particular case of iterables requiring termination is a red herring. I know C# supports it, but Java went the other way a long time ago. I believe that you're the only one who as expressed enthusiasm for this use case. I see it as harmful scope creep that could keep a really important facility out of the next release. The proposed construct was designed to address a severe problem with existing types. especially considering your disagreement with Howard and > Jeremy about declaration scope rather than a new block-structured > statement form, Not really a disagreement. In the end, we both came to the conclusion that block-structured was probably the right thing for Java today. > or with me and Peter and Stefan about whether Lock is > an important use case, Important or not, it isn't a use case for this construct. It's specifically excluded from this proposal. I offered to write a proposal for locks, but people didn't seem all that interested so I didn't write it. Doug Lea himself isn't interested. He's fine with try-finally for that purpose. Unlike closing closeables, people don't get unlockng locks wrong most of the time. Yes, you could save a few characters of typing and perhaps make your code a bit clearer, but it's not even a common use case. > or with me and Bob Lee about whether suppressed > exceptions be handled by clients, etc. Not sure what you mean by this one, but I'd love to know! I'm still hoping to see a revision of the proposal that incorporates > the changes you suggested be considered: the changes to the Disposable > interface, support for an expression as well as a declaration, a > variation to suppress the exception on close, and recording suppressed > exceptions. When do you anticipate a refinement of the proposal will > include these for further analysis? In the next couple days. I had hoped to have it out by now, but I've been awfully busy lately. (A family emergency has turned me into a single working dad for the week.) Sorry the proposal isn't revised yet, and sorry if I offended, Josh From jjb at google.com Thu Mar 19 14:55:23 2009 From: jjb at google.com (Joshua Bloch) Date: Thu, 19 Mar 2009 14:55:23 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> Message-ID: <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> Neal, On Thu, Mar 19, 2009 at 1:03 PM, Neal Gafter wrote: > On Thu, Mar 19, 2009 at 12:32 PM, Joshua Bloch wrote: > In any case, it is because of the existence of these kinds of > disagreements that I believe more experience is needed. With all due respect, I don't see a lot of people disagreeing; I see one person disagreeing vociferously. For the most part, others are discussing the details to make sure that we do a good job on important cases. The automatic resource management statement is a facility that would solve a huge problem that affects the great majority of programmers today, and we know how to solve it well enough to address the great bulk of that problem. Josh From jodastephen at gmail.com Thu Mar 19 10:18:32 2009 From: jodastephen at gmail.com (Stephen Colebourne) Date: Thu, 19 Mar 2009 17:18:32 +0000 Subject: Proposal: Elvis and Other Null-Safe Operators In-Reply-To: <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> References: <49C201C5.3090200@gmail.com> <15e8b9d20903190713i67595fe1hac45db43e4dc522c@mail.gmail.com> Message-ID: <49C27E68.7020709@gmail.com> 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 From neal at gafter.com Thu Mar 19 12:17:33 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 19 Mar 2009 12:17:33 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903142231j7d13b28s1e01ad48d50e1819@mail.gmail.com> <1631da7d0903142256q698c5602tb414a7b81c1e133c@mail.gmail.com> <15e8b9d20903142329i197dfdfej6f817c44ffabdf31@mail.gmail.com> <3dd3f56a0903172150j721b2903m41f5edf251ff75d8@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> Message-ID: <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> On Wed, Mar 18, 2009 at 5:18 PM, Howard Lovatt wrote: > For example suppose as Neal has suggested > that the foreach loop understood resources, it would be great to write > something like: > > ? ?for ( final String line : AutoResources.asLines( filename ) ) { ... } Howard- I think you may have missed my point. It isn't the Iterable that the for-each loop needs to handle as a resource, because the programmer can easily do that himself try (final AutoResource linesInFile = AutoResources.asLines(filename)) { for ( String line : linesInFile ) { ... } } Rather, I'm talking about the implicit Iterator variable that is created by the expansion of the for-each loop. Unlike Iterable, Iterators are one-shot, so making one a resource is natural. But, with the current ARM proposal, there is no way to use the for-each loop with an Iterable whose Iterator is an AutoResource. Experience with C#'s foreach loop and IDisposable/IEnumerable has shown the combination to be very useful, as it avoids some very awkward situations when both resources and loops are used together in a program. These kinds of issues make me think that more actual experience with the proposed construct will be required before we can have confidence that it is "right". Regards, Neal From develop4lasu at gmail.com Fri Mar 20 10:04:47 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 20 Mar 2009 18:04:47 +0100 Subject: Glue classes proposal 0.9 In-Reply-To: <15e8b9d20903200835r3a85bb3bwac565151afc1e89f@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <15e8b9d20903200835r3a85bb3bwac565151afc1e89f@mail.gmail.com> Message-ID: <28bca0ff0903201004r6ebf7ee2n83f5129ee118636c@mail.gmail.com> W dniu 20 marca 2009 16:35 u?ytkownik Neal Gafter napisa?: > There really isn't enough of a specification for me to understand how > this language feature fits together. What are the semantics? Is a > glue class like a container for extension methods? > > > The skipped parts are the same as in JLS, so you need it to understand specification. Yes. Glue Class is container for static methods. You can think about it as set of methods with extracted main part of TypeParameters and first argument type to class header. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From jeremy.manson at gmail.com Thu Mar 19 17:05:58 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Thu, 19 Mar 2009 17:05:58 -0700 Subject: PRE-PROPOSAL: Source and Encoding keyword In-Reply-To: <3dd3f56a0903182255v2b123317qd4a0751ae989952a@mail.gmail.com> References: <3dd3f56a0903150430j2c7286fdnae7683a1f79435c1@mail.gmail.com> <1631da7d0903151346k504cce94v72ca95cad24b385e@mail.gmail.com> <3dd3f56a0903180310g59377decl384d59a78fd43a1e@mail.gmail.com> <1631da7d0903181558g6ed664c3u5a9ebf1caf123ee3@mail.gmail.com> <3dd3f56a0903182255v2b123317qd4a0751ae989952a@mail.gmail.com> Message-ID: <1631da7d0903191705s7c8005dfo89888c829beb9b88@mail.gmail.com> I wasn't denying that this could, conceivably, allow you to make sweeping changes to the language more easily. I never claimed there wasn't a motivation for this change. My point was and remains that versioning of sweeping changes to the language is only (a relatively small) part of a much larger problem of versioning, and it would make more sense to tackle the large problem than to add this keyword (which may or may not fit with a larger solution, when all of the parts of the larger solution are in place). Jeremy On Wed, Mar 18, 2009 at 10:55 PM, Howard Lovatt wrote: > Hi Jeremy, > > Maybe a bit more of a motivation for source is needed, but note I am > not saying that the following list should be done for 7, I am saying > that these items are a possibility for some point in the future and it > is a good idea to put source in now so that we are well positioned for > the future. Source allows continual improvement, by allowing for > incompatible changes with the past. It allows graceful aging. This is > quite possible on the JVM, which is quite capable of supporting > multiple languages that are quite different and hence slightly source > code incompatible versions of Java that are class file compatible are > no problem (they still interact with each other via the JVM). > > Anyway here are some of the more ambitious changes that could be made > once source is in place: > > 1. New keywords, some examples from coin proposals: module (for > modules), arm (for automated resource blocks), lockprotected (for > concurrent lock blocks). Many current coin proposals would be improved > if you could add new keywords. > > 2. Big improvements to type inference could be made if a var keyword > were added, like JavaFX. Going beyond what is proposed for a small > amount of generic type inference. > > 3. Big improvements to inner classes could be made if a method keyword > were added, analogous to function in JavaFX. Some of the current inner > class/closure proposals without a new keyword really stretch the > syntax and are almost entirely alien to Java. > > 4. Comparative operators for Comparable ?and equals could be added and > add the same time the primitive comparisons could be fixed and a === > operator could be introduced that compares address (== would call > either equals or compareTo). There is a proposal in coin for > operations for Comparable, but the proposal has problems because of > backward compatibility issues. > > 5. The switch statement could be made sane, i.e. block structured. > > 6. The control blocks, if, while, for could be given return values, like JavaFX. > > 7. Properties could be added, like JavaFX including bind. > > 8. Traits could be added (my personal favourite). > > 9. Fix generics (possibly the most requested change). > > 10. etc., etc., etc. > > I am sure you can see how this small change now opens up many > possibilities in the future and also allows Java to pick up the best > features of other JVM languages (I used JavaFX as an example above, > but also Scala, JRuby, Groovey, Jython, Rhino, PHP, etc.). The above > list is a very quickly drawn up list; I am sure you could add your own > favourites, after all we are communicating on coin and therefore have > an opinion about Java and want to see it get better. I am guessing > that your personal favourite will be integrating modules with source > so that version tracking of libraries can be checked by the compiler, > I see this as only one of many possibilities for source. > > ?-- Howard. > > > 2009/3/19 Jeremy Manson : >> On Wed, Mar 18, 2009 at 3:10 AM, Howard Lovatt wrote: >>> Hi, >>> >>> 2009/3/16 Jeremy Manson : >> >>>> I'm not objecting to versioning in principle, but I think there are >>>> enough unanswered questions that this proposal is probably beyond the >>>> scope of "small changes". >>> >>> I think one of the reasons that Java is tending to stagnate a little, >>> not badly, just a little, is that it is getting hard to introduces >>> changes. I think source will provide a relief valve - get out of jail >>> free. >> >> I'm not going to respond point-by-point, but the primary reason it is >> hard to introduce changes in Java is not because of existing keywords, >> or the fact that we are tied to existing source. ?It is because it >> *should* be hard to introduce changes in a widely used programming >> language. ?Too much forward progress gives you a language that looks >> more like a katamari than a well-considered, cohesive whole: C++ and >> perl come to mind as examples of this. ?How many different initializer >> syntaxes does C++ have? ?15? >> >> I agree that there has been too much stagnation in the platform in the >> last few years, but this has nothing to do with it being difficult to >> change the language. ?It is because of political issues in the Java >> community. ?This is clearly not the right forum to discuss that, >> though. >> >> I think that in this specific case, you are considering adding >> something that only solves a small part of a much larger problem that >> needs to be addressed. ?Instead of having a point solution, which >> risks being at odds with solutions to the rest of the problem, what >> you really want is a larger, well-thought-out solution to the whole >> problem. ?Start a JSR and solve versioning for us! ?Everyone will be >> very grateful! >> >> Jeremy >> >> ______________________________________________________________________ >> This email has been scanned by the MessageLabs Email Security System. >> For more information please visit http://www.messagelabs.com/email >> ______________________________________________________________________ >> > From fw at deneb.enyo.de Fri Mar 20 12:01:33 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Fri, 20 Mar 2009 20:01:33 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> (Howard Lovatt's message of "Thu, 19 Mar 2009 09:05:43 +1100") References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> Message-ID: <87mybgrpbm.fsf@mid.deneb.enyo.de> * Howard Lovatt: > With the proposal you would say: > > "[\{field1}, \{field2}, \{field3}]" > > Which I find clearer. Won't this encourage programmers to write even more code with cross-site scripting and SQL injection vulnerabilities? From jeremy.manson at gmail.com Fri Mar 20 13:02:35 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Fri, 20 Mar 2009 13:02:35 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> Message-ID: <1631da7d0903201302y1bdfc516i4be9a5ddbb6e8f3b@mail.gmail.com> On Thu, Mar 19, 2009 at 5:55 PM, Joshua Bloch wrote: > especially considering your disagreement with Howard and >> Jeremy about declaration scope rather than a new block-structured >> statement form, > > > Not really a disagreement. In the end, we both came to the conclusion that > block-structured was probably the right thing for Java today. > I really don't *want* to interject myself here, but in the interests of clarity and not being misrepresented by anyone, I will say what I actually think about the proposal. I like it. In an ideal world, in a language that we could start from scratch, I would like declaration scoping. Java is not such a language. In Java, nothing meaningful happens when variables go out of scope, other than that they are not lexically available. It doesn't even mean that objects pointed to are now unreachable -- a compiler can decide to make objects unreachable before the only variables pointing to them go out of scope! Having semantics for nested scopes is a C++-ism, not a Java-ism. I think it would be nice to have support for opening and closing resources in a way that does not require you to declare a variable (just as the standard for loop doesn't require you to declare a variable in the initializer). I don't think that that is actually all that important by comparison with what the proposal provides, and I believe it can be retrofitted later (potentially in a later Java revision) if we decide it is necessary. I think the biggest reason to include it now is probably that everyone will be asking why we didn't include it. Jeremy From phil.swenson at gmail.com Thu Mar 19 08:33:37 2009 From: phil.swenson at gmail.com (phil swenson) Date: Thu, 19 Mar 2009 09:33:37 -0600 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> Message-ID: funny, i just joined the list specifically to ask about this subject. why not just copy the groovy implementation of this? $var or ${expresion} ? in groovy it would be: "[$field1, $field2, $field3]" or with the explicit expression syntax: "[${field1}, ${field2}, ${field3}]" I hate escape characters :) On Thu, Mar 19, 2009 at 2:03 AM, Schulz, Stefan wrote: > The concat-variant to me is even worse readable than the original +-notation, having three consecutive commas in between. > The proposal already mentions concatenation of any kind as alternative, although not mentioning concat(). Maybe worth expanding. > > Stefan > >> -----Original Message----- >> From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] >> Sent: Wednesday, March 18, 2009 8:58 PM >> To: Howard Lovatt >> Cc: coin-dev at openjdk.java.net; Schulz, Stefan >> Subject: Re: Proposal: Embedded Expressions for String Statements >> >> > I like Stefan's proposed syntax and as a way of a motivating example >> > consider writing a toString method that gives the field >> values within >> > square brackets, now you would write: >> > >> > ? ? "[" + field1 + ", " + field2 + ", " + field3 + "]" >> > >> > With the proposal you would say: >> > >> > ? ? "[\{field1}, \{field2}, \{field3}]" >> > >> > Which I find clearer. >> > >> >> Just note: now we can use much cleaner >> ?concat( field1, ',' , field2, ',' field3 ) >> >> >> >> > Many thanks to Stefan for writing this up formally. >> > >> > >> >> >> >> > > From John.Rose at Sun.COM Fri Mar 20 13:50:05 2009 From: John.Rose at Sun.COM (John Rose) Date: Fri, 20 Mar 2009 13:50:05 -0700 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> Message-ID: I wrote the spec. draft and implementation (in antlr) for Groovy gstring syntax; I did the work with the intention of helping the JSR 241 Groovy standard. It could work in Java with adjustments, and the Groovy spec. is detailed enough to be a starting point. I don't really have time to work on it though. That's why I haven't done a proposal. For Java, to extend the string syntax and emphasize that a new string is being constructed, I recommend this: new "$foo, ${bar}s." The new kwd enables the dollars. Other details to be taken from the Groovy spec. Best wishes, -- John (on my iPhone) On Mar 19, 2009, at 8:33 AM, phil swenson wrote: > funny, i just joined the list specifically to ask about this subject. > > why not just copy the groovy implementation of this? $var or $ > {expresion} ? > in groovy it would be: > "[$field1, $field2, $field3]" > > or with the explicit expression syntax: > "[${field1}, ${field2}, ${field3}]" > > > I hate escape characters :) > > > On Thu, Mar 19, 2009 at 2:03 AM, Schulz, Stefan > wrote: >> The concat-variant to me is even worse readable than the original +- >> notation, having three consecutive commas in between. >> The proposal already mentions concatenation of any kind as >> alternative, although not mentioning concat(). Maybe worth expanding. >> >> Stefan >> >>> -----Original Message----- >>> From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] >>> Sent: Wednesday, March 18, 2009 8:58 PM >>> To: Howard Lovatt >>> Cc: coin-dev at openjdk.java.net; Schulz, Stefan >>> Subject: Re: Proposal: Embedded Expressions for String Statements >>> >>>> I like Stefan's proposed syntax and as a way of a motivating >>>> example >>>> consider writing a toString method that gives the field >>> values within >>>> square brackets, now you would write: >>>> >>>> "[" + field1 + ", " + field2 + ", " + field3 + "]" >>>> >>>> With the proposal you would say: >>>> >>>> "[\{field1}, \{field2}, \{field3}]" >>>> >>>> Which I find clearer. >>>> >>> >>> Just note: now we can use much cleaner >>> concat( field1, ',' , field2, ',' field3 ) >>> >>> >>> >>>> Many thanks to Stefan for writing this up formally. >>>> >>>> >>> >>> >>> >>> >> >> > From tim at peierls.net Fri Mar 20 14:08:18 2009 From: tim at peierls.net (Tim Peierls) Date: Fri, 20 Mar 2009 17:08:18 -0400 Subject: Feedback and comments on ARM proposal Message-ID: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> How about using a special package -- java.lang.auto, say -- with initially only one or two interfaces -- AutoCloseable and AutoDisposable, say -- and word the ARM proposal so that only subtypes of interfaces with a single, parameterless method that are declared in this special package are allowed in the ARM try-initialization? The idea here is to remove the decision about which clean-up methods to support from the current proposal and make it a library design issue. --tim From markmahieu at googlemail.com Fri Mar 20 14:18:05 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 20 Mar 2009 21:18:05 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> Message-ID: Or perhaps a marker interface rather than a special package? That might be more consistent with existing 'special behaviour' (eg. Serializable). I definitely like the idea of leaving it to the individual libraries to decide. Mark On 20 Mar 2009, at 21:08, Tim Peierls wrote: > How about using a special package -- java.lang.auto, say -- with > initially > only one or two interfaces -- AutoCloseable and AutoDisposable, say > -- and > word the ARM proposal so that only subtypes of interfaces with a > single, > parameterless method that are declared in this special package are > allowed > in the ARM try-initialization? > > The idea here is to remove the decision about which clean-up > methods to > support from the current proposal and make it a library design issue. > > --tim > From jjb at google.com Fri Mar 20 14:19:16 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 20 Mar 2009 14:19:16 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> Message-ID: <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> Tim, This is very clever! While it doesn't allow programmers to create their own interfaces for use with the construct, it allows future release of the platform to broaden the applicability of the construct without changing the language. And it does so without abusing annotations. While it's not a typical uses of packages, it wouldn't be the first time the language gave special standing to a package. For example, members of java.lang are automatically imported on demand. What do others think? Josh On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: > How about using a special package -- java.lang.auto, say -- with initially > only one or two interfaces -- AutoCloseable and AutoDisposable, say -- and > word the ARM proposal so that only subtypes of interfaces with a single, > parameterless method that are declared in this special package are allowed > in the ARM try-initialization? > > The idea here is to remove the decision about which clean-up methods to > support from the current proposal and make it a library design issue. > > --tim > > From crazybob at crazybob.org Fri Mar 20 14:23:14 2009 From: crazybob at crazybob.org (Bob Lee) Date: Fri, 20 Mar 2009 14:23:14 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> Message-ID: +1. I also like not adding types directly to java.lang. On Fri, Mar 20, 2009 at 2:19 PM, Joshua Bloch wrote: > Tim, > This is very clever! While it doesn't allow programmers to create their > own > interfaces for use with the construct, it allows future release of the > platform to broaden the applicability of the construct without changing the > language. And it does so without abusing annotations. While it's not a > typical uses of packages, it wouldn't be the first time the language gave > special standing to a package. For example, members of java.lang are > automatically imported on demand. > > What do others think? > > Josh > > On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: > > > How about using a special package -- java.lang.auto, say -- with > initially > > only one or two interfaces -- AutoCloseable and AutoDisposable, say -- > and > > word the ARM proposal so that only subtypes of interfaces with a single, > > parameterless method that are declared in this special package are > allowed > > in the ARM try-initialization? > > > > The idea here is to remove the decision about which clean-up methods to > > support from the current proposal and make it a library design issue. > > > > --tim > > > > > > From rssh at gradsoft.com.ua Fri Mar 20 14:32:53 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Fri, 20 Mar 2009 23:32:53 +0200 (EET) Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> Message-ID: <9e0aed38eefeb26cb3ccd8188fbf65b2.squirrel@wmail.gradsoft.ua> > funny, i just joined the list specifically to ask about this subject. > > why not just copy the groovy implementation of this? $var or > ${expresion} ? > in groovy it would be: > "[$field1, $field2, $field3]" > > or with the explicit expression syntax: > "[${field1}, ${field2}, ${field3}]" > > Hmm, this broke, for example, near all tests of implementation of any scripting language with special meaning of '$'. So, to be not dangerous for old code, string with embedded expressions enabled must be prefixed by special symbol ('@' ?) > I hate escape characters :) > > > On Thu, Mar 19, 2009 at 2:03 AM, Schulz, Stefan > wrote: >> The concat-variant to me is even worse readable than the original >> +-notation, having three consecutive commas in between. >> The proposal already mentions concatenation of any kind as alternative, >> although not mentioning concat(). Maybe worth expanding. >> >> Stefan >> >>> -----Original Message----- >>> From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] >>> Sent: Wednesday, March 18, 2009 8:58 PM >>> To: Howard Lovatt >>> Cc: coin-dev at openjdk.java.net; Schulz, Stefan >>> Subject: Re: Proposal: Embedded Expressions for String Statements >>> >>> > I like Stefan's proposed syntax and as a way of a motivating example >>> > consider writing a toString method that gives the field >>> values within >>> > square brackets, now you would write: >>> > >>> > ? ? "[" + field1 + ", " + field2 + ", " + field3 + "]" >>> > >>> > With the proposal you would say: >>> > >>> > ? ? "[\{field1}, \{field2}, \{field3}]" >>> > >>> > Which I find clearer. >>> > >>> >>> Just note: now we can use much cleaner >>> ?concat( field1, ',' , field2, ',' field3 ) >>> >>> >>> >>> > Many thanks to Stefan for writing this up formally. >>> > >>> > >>> >>> >>> >>> >> >> > > From reinier at zwitserloot.com Fri Mar 20 16:24:47 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 21 Mar 2009 00:24:47 +0100 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> Message-ID: <2ECD0E29-6A41-4711-9AA5-C7FFCA47DBF2@zwitserloot.com> Interesting idea. I'm ambivalent; one specific interface with a void close() throws Exception method works for me, but this is slightly more flexible and sufficiently simple too. As long as one of those two things makes it in java7, I'm happy :P Using a special package which contains only interfaces that serve as AutoDisposable: Okay. Can you add your own to this? Technically you can just put "java.lang.auto.Foo" in your own jar files, do those get picked up, or will java.lang.auto become a sealed package of some sort, or will it be limited to only interfaces in the java.lang.auto package in the java-core module? If any programmer can add their own, I think a marker interface is a better idea. In either case, *IF* anybody is allowed to add their own, javac should optimally be expanded to, at compile time, whine about mistakes: If you add a non-interface to it, or an interface with more than 1 method, or with 1 method but that method takes parameters. It can even sort of, kind of, solve locking: public interface java.lang.auto.DisposableLock { void unlock(); } public interface java.util.concurrent.Lock implements DisposableLock { ... } try ( lock ) { lock.lock(); //People are going to forget this, unfortunately doWhatever(); } --Reinier Zwitserloot On Mar 20, 2009, at 22:23, Bob Lee wrote: > +1. I also like not adding types directly to java.lang. > > On Fri, Mar 20, 2009 at 2:19 PM, Joshua Bloch wrote: > >> Tim, >> This is very clever! While it doesn't allow programmers to create >> their >> own >> interfaces for use with the construct, it allows future release of >> the >> platform to broaden the applicability of the construct without >> changing the >> language. And it does so without abusing annotations. While it's >> not a >> typical uses of packages, it wouldn't be the first time the >> language gave >> special standing to a package. For example, members of java.lang are >> automatically imported on demand. >> >> What do others think? >> >> Josh >> >> On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: >> >>> How about using a special package -- java.lang.auto, say -- with >> initially >>> only one or two interfaces -- AutoCloseable and AutoDisposable, >>> say -- >> and >>> word the ARM proposal so that only subtypes of interfaces with a >>> single, >>> parameterless method that are declared in this special package are >> allowed >>> in the ARM try-initialization? >>> >>> The idea here is to remove the decision about which clean-up >>> methods to >>> support from the current proposal and make it a library design >>> issue. >>> >>> --tim >>> >>> >> >> > From markmahieu at googlemail.com Fri Mar 20 16:35:27 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 20 Mar 2009 23:35:27 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <2ECD0E29-6A41-4711-9AA5-C7FFCA47DBF2@zwitserloot.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> <2ECD0E29-6A41-4711-9AA5-C7FFCA47DBF2@zwitserloot.com> Message-ID: 2009/3/20 Reinier Zwitserloot > > Using a special package which contains only interfaces that serve as > AutoDisposable: Okay. Can you add your own to this? Technically you > can just put "java.lang.auto.Foo" in your own jar files, do those get > picked up, or will java.lang.auto become a sealed package of some > sort, or will it be limited to only interfaces in the java.lang.auto > package in the java-core module? If any programmer can add their own, > I think a marker interface is a better idea. Regardless of the specific mechanism, being able to add new interfaces might mean that java.sql could declare an AutoFreeable type suitable for free()ing a java.sql.Blob, Clob, Array or SQLXML. Ditto for those APIs that chose destroy(), cleanup(), shutdown() etc. Mark From neal at gafter.com Thu Mar 19 17:33:25 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 19 Mar 2009 17:33:25 -0700 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <87skla8sqz.fsf@mid.deneb.enyo.de> <17b2302a0903181402w26793798vdd2a744f3492de84@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> Message-ID: <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> On Thu, Mar 19, 2009 at 2:55 PM, Joshua Bloch wrote: > With all due respect, I don't see a lot of people disagreeing; I see one > person disagreeing vociferously. ?For the most part, others are discussing > the details to make sure that we do a good job on important cases. Is "one person disagreeing" something like "one hand clapping"? If this was directed at me, I'm not sure what you feel I was disagreeing about. I was analyzing the proposal's interactions with other language features (iteration, in this case), noting issues, and making specific suggestions to address them. I find this comment offensive, especially considering your disagreement with Howard and Jeremy about declaration scope rather than a new block-structured statement form, or with me and Peter and Stefan about whether Lock is an important use case, or with me and Bob Lee about whether suppressed exceptions be handled by clients, etc. I think we can respectfully discuss the issues while moving the process forward without making it personal. I'm still hoping to see a revision of the proposal that incorporates the changes you suggested be considered: the changes to the Disposable interface, support for an expression as well as a declaration, a variation to suppress the exception on close, and recording suppressed exceptions. When do you anticipate a refinement of the proposal will include these for further analysis? From schulz at e-spirit.de Fri Mar 20 16:47:36 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 21 Mar 2009 00:47:36 +0100 Subject: Feedback and comments on ARM proposal In-Reply-To: <2ECD0E29-6A41-4711-9AA5-C7FFCA47DBF2@zwitserloot.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com><17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> <2ECD0E29-6A41-4711-9AA5-C7FFCA47DBF2@zwitserloot.com> Message-ID: <49C42B18.6090905@e-spirit.de> Hm, maybe I am blind to see, why it wouldn't then be possible to add a second "marker" interface "AutoOpenable". I'm just a bit unsure, what the compiler has to do here. Will a ClosableResource have to be implemented directly, or may interfaces extend it? Sounds like quite some class traversing. Stefan Reinier Zwitserloot schrieb: > Interesting idea. I'm ambivalent; one specific interface with a void > close() throws Exception method works for me, but this is slightly > more flexible and sufficiently simple too. As long as one of those two > things makes it in java7, I'm happy :P > > > Using a special package which contains only interfaces that serve as > AutoDisposable: Okay. Can you add your own to this? Technically you > can just put "java.lang.auto.Foo" in your own jar files, do those get > picked up, or will java.lang.auto become a sealed package of some > sort, or will it be limited to only interfaces in the java.lang.auto > package in the java-core module? If any programmer can add their own, > I think a marker interface is a better idea. > > > In either case, *IF* anybody is allowed to add their own, javac should > optimally be expanded to, at compile time, whine about mistakes: If > you add a non-interface to it, or an interface with more than 1 > method, or with 1 method but that method takes parameters. > > > It can even sort of, kind of, solve locking: > > public interface java.lang.auto.DisposableLock { > void unlock(); > } > > public interface java.util.concurrent.Lock implements DisposableLock > { ... } > > > try ( lock ) { > lock.lock(); //People are going to forget this, unfortunately > doWhatever(); > } > > > --Reinier Zwitserloot > > > > On Mar 20, 2009, at 22:23, Bob Lee wrote: > > > +1. I also like not adding types directly to java.lang. > > > > On Fri, Mar 20, 2009 at 2:19 PM, Joshua Bloch wrote: > > > >> Tim, > >> This is very clever! While it doesn't allow programmers to create > >> their > >> own > >> interfaces for use with the construct, it allows future release of > >> the > >> platform to broaden the applicability of the construct without > >> changing the > >> language. And it does so without abusing annotations. While it's > >> not a > >> typical uses of packages, it wouldn't be the first time the > >> language gave > >> special standing to a package. For example, members of java.lang are > >> automatically imported on demand. > >> > >> What do others think? > >> > >> Josh > >> > >> On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: > >> > >>> How about using a special package -- java.lang.auto, say -- with > >> initially > >>> only one or two interfaces -- AutoCloseable and AutoDisposable, > >>> say -- > >> and > >>> word the ARM proposal so that only subtypes of interfaces with a > >>> single, > >>> parameterless method that are declared in this special package are > >> allowed > >>> in the ARM try-initialization? > >>> > >>> The idea here is to remove the decision about which clean-up > >>> methods to > >>> support from the current proposal and make it a library design > >>> issue. > >>> > >>> --tim > >>> > >>> > >> > >> > > > > > From schulz at e-spirit.de Fri Mar 20 17:03:57 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 21 Mar 2009 01:03:57 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: References: Message-ID: <49C42EED.7030805@e-spirit.de> In the light of the discussions on how to markup embedded expressions, it seems a really good idea to introduce a new form of String expressions (e.g. using a back-tick or triple-quotes as delimiter), which captures embedded expressions and "escape-free" and multiline Strings at the same time. For example by having ${ as new escape sequence introducing embedded expressions and $\ to introduce escape characters (where $\{ would escape from embedded expressions, $\\ from escape characters and, e.g., $\n would be a line break). I'm not sure about the $foo form, though. While it seems to require more characters now for escaping, the chances are quite high that the two sequences ${ and $\ are rare in normal text and the common sequences \n and \t can be replaced by using the multiline feature. It requires a bit more on pre-scanning the code, but this is only at compile-time when transforming the new String to old String, I think. Stefan John Rose schrieb: > I wrote the spec. draft and implementation (in antlr) for Groovy > gstring syntax; I did the work with the intention of helping the JSR > 241 Groovy standard. It could work in Java with adjustments, and the > Groovy spec. is detailed enough to be a starting point. I don't > really have time to work on it though. That's why I haven't done a > proposal. > > For Java, to extend the string syntax and emphasize that a new string > is being constructed, I recommend this: > > new "$foo, ${bar}s." > > The new kwd enables the dollars. Other details to be taken from the > Groovy spec. > > Best wishes, > > -- John (on my iPhone) > > On Mar 19, 2009, at 8:33 AM, phil swenson > wrote: > > > funny, i just joined the list specifically to ask about this subject. > > > > why not just copy the groovy implementation of this? $var or $ > > {expresion} ? > > in groovy it would be: > > "[$field1, $field2, $field3]" > > > > or with the explicit expression syntax: > > "[${field1}, ${field2}, ${field3}]" > > > > > > I hate escape characters :) > > > > > > On Thu, Mar 19, 2009 at 2:03 AM, Schulz, Stefan > > wrote: > >> The concat-variant to me is even worse readable than the original +- > >> notation, having three consecutive commas in between. > >> The proposal already mentions concatenation of any kind as > >> alternative, although not mentioning concat(). Maybe worth expanding. > >> > >> Stefan > >> > >>> -----Original Message----- > >>> From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] > >>> Sent: Wednesday, March 18, 2009 8:58 PM > >>> To: Howard Lovatt > >>> Cc: coin-dev at openjdk.java.net; Schulz, Stefan > >>> Subject: Re: Proposal: Embedded Expressions for String Statements > >>> > >>>> I like Stefan's proposed syntax and as a way of a motivating > >>>> example > >>>> consider writing a toString method that gives the field > >>> values within > >>>> square brackets, now you would write: > >>>> > >>>> "[" + field1 + ", " + field2 + ", " + field3 + "]" > >>>> > >>>> With the proposal you would say: > >>>> > >>>> "[\{field1}, \{field2}, \{field3}]" > >>>> > >>>> Which I find clearer. > >>>> > >>> > >>> Just note: now we can use much cleaner > >>> concat( field1, ',' , field2, ',' field3 ) > >>> > >>> > >>> > >>>> Many thanks to Stefan for writing this up formally. > >>>> > >>>> > >>> > >>> > >>> > >>> > >> > >> > > > From jeremy.manson at gmail.com Fri Mar 20 17:13:07 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Fri, 20 Mar 2009 17:13:07 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> Message-ID: <1631da7d0903201713le726850q98a59a89b7edf53e@mail.gmail.com> Does it matter that java.lang.auto wouldn't be auto-imported? Jeremy On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: > How about using a special package -- java.lang.auto, say -- with initially > only one or two interfaces -- AutoCloseable and AutoDisposable, say -- and > word the ARM proposal so that only subtypes of interfaces with a single, > parameterless method that are declared in this special package are allowed > in the ARM try-initialization? > > The idea here is to remove the decision about which clean-up methods to > support from the current proposal and make it a library design issue. > > --tim > > From markmahieu at googlemail.com Fri Mar 20 17:20:33 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 00:20:33 +0000 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <49C42EED.7030805@e-spirit.de> References: <49C42EED.7030805@e-spirit.de> Message-ID: Hi Stefan, Do you have any thoughts about how this new form of String might be internationalized? Mark 2009/3/21 Stefan Schulz > In the light of the discussions on how to markup embedded expressions, > it seems a really good idea to introduce a new form of String > expressions (e.g. using a back-tick or triple-quotes as delimiter), > which captures embedded expressions and "escape-free" and multiline > Strings at the same time. For example by having ${ as new escape > sequence introducing embedded expressions and $\ to introduce escape > characters (where $\{ would escape from embedded expressions, $\\ from > escape characters and, e.g., $\n would be a line break). I'm not sure > about the $foo form, though. > While it seems to require more characters now for escaping, the chances > are quite high that the two sequences ${ and $\ are rare in normal text > and the common sequences \n and \t can be replaced by using the > multiline feature. > It requires a bit more on pre-scanning the code, but this is only at > compile-time when transforming the new String to old String, I think. > > Stefan > > John Rose schrieb: > > I wrote the spec. draft and implementation (in antlr) for Groovy > > gstring syntax; I did the work with the intention of helping the JSR > > 241 Groovy standard. It could work in Java with adjustments, and the > > Groovy spec. is detailed enough to be a starting point. I don't > > really have time to work on it though. That's why I haven't done a > > proposal. > > > > For Java, to extend the string syntax and emphasize that a new string > > is being constructed, I recommend this: > > > > new "$foo, ${bar}s." > > > > The new kwd enables the dollars. Other details to be taken from the > > Groovy spec. > > > > Best wishes, > > > > -- John (on my iPhone) > > > > On Mar 19, 2009, at 8:33 AM, phil swenson > > wrote: > > > > > funny, i just joined the list specifically to ask about this subject. > > > > > > why not just copy the groovy implementation of this? $var or $ > > > {expresion} ? > > > in groovy it would be: > > > "[$field1, $field2, $field3]" > > > > > > or with the explicit expression syntax: > > > "[${field1}, ${field2}, ${field3}]" > > > > > > > > > I hate escape characters :) > > > > > > > > > On Thu, Mar 19, 2009 at 2:03 AM, Schulz, Stefan > > > wrote: > > >> The concat-variant to me is even worse readable than the original +- > > >> notation, having three consecutive commas in between. > > >> The proposal already mentions concatenation of any kind as > > >> alternative, although not mentioning concat(). Maybe worth expanding. > > >> > > >> Stefan > > >> > > >>> -----Original Message----- > > >>> From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] > > >>> Sent: Wednesday, March 18, 2009 8:58 PM > > >>> To: Howard Lovatt > > >>> Cc: coin-dev at openjdk.java.net; Schulz, Stefan > > >>> Subject: Re: Proposal: Embedded Expressions for String Statements > > >>> > > >>>> I like Stefan's proposed syntax and as a way of a motivating > > >>>> example > > >>>> consider writing a toString method that gives the field > > >>> values within > > >>>> square brackets, now you would write: > > >>>> > > >>>> "[" + field1 + ", " + field2 + ", " + field3 + "]" > > >>>> > > >>>> With the proposal you would say: > > >>>> > > >>>> "[\{field1}, \{field2}, \{field3}]" > > >>>> > > >>>> Which I find clearer. > > >>>> > > >>> > > >>> Just note: now we can use much cleaner > > >>> concat( field1, ',' , field2, ',' field3 ) > > >>> > > >>> > > >>> > > >>>> Many thanks to Stefan for writing this up formally. > > >>>> > > >>>> > > >>> > > >>> > > >>> > > >>> > > >> > > >> > > > > > > > From jjb at google.com Fri Mar 20 17:22:15 2009 From: jjb at google.com (Joshua Bloch) Date: Fri, 20 Mar 2009 17:22:15 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <1631da7d0903201713le726850q98a59a89b7edf53e@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <1631da7d0903201713le726850q98a59a89b7edf53e@mail.gmail.com> Message-ID: <17b2302a0903201722t50f2515boc1afdb749797f1cb@mail.gmail.com> Jeremy, I don't think so; it would be used (almost) exclusively by the classes that implement its interface(s). Josh On Fri, Mar 20, 2009 at 5:13 PM, Jeremy Manson wrote: > Does it matter that java.lang.auto wouldn't be auto-imported? > > Jeremy > > On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: > > How about using a special package -- java.lang.auto, say -- with > initially > > only one or two interfaces -- AutoCloseable and AutoDisposable, say -- > and > > word the ARM proposal so that only subtypes of interfaces with a single, > > parameterless method that are declared in this special package are > allowed > > in the ARM try-initialization? > > > > The idea here is to remove the decision about which clean-up methods to > > support from the current proposal and make it a library design issue. > > > > --tim > > > > > > From phil.swenson at gmail.com Fri Mar 20 19:37:53 2009 From: phil.swenson at gmail.com (phil swenson) Date: Fri, 20 Mar 2009 20:37:53 -0600 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <49C42EED.7030805@e-spirit.de> References: <49C42EED.7030805@e-spirit.de> Message-ID: excellent approach. Doesn't break old code and gives me everything I'd ever want (no escapes, embedded variables and expressions). I vote for the back tick delimiter. On Fri, Mar 20, 2009 at 6:03 PM, Stefan Schulz wrote: > In the light of the discussions on how to markup embedded expressions, > it seems a really good idea to introduce a new form of String > expressions (e.g. using a back-tick or triple-quotes as delimiter), > which captures embedded expressions and "escape-free" and multiline > Strings at the same time. For example by having ${ as new escape > sequence introducing embedded expressions and $\ to introduce escape > characters (where $\{ would escape from embedded expressions, $\\ from > escape characters and, e.g., $\n would be a line break). I'm not sure > about the $foo form, though. > While it seems to require more characters now for escaping, the chances > are quite high that the two sequences ${ and $\ are rare in normal text > and the common sequences \n and \t can be replaced by using the > multiline feature. > It requires a bit more on pre-scanning the code, but this is only at > compile-time when transforming the new String to old String, I think. > > Stefan > > John Rose schrieb: >> I wrote the spec. draft and implementation (in antlr) for Groovy >> gstring syntax; I did the work with the intention of helping the JSR >> 241 Groovy standard. ?It could work in Java with adjustments, and the >> Groovy spec. is detailed enough to be a starting point. ? I don't >> really have time to work on it though. That's why I haven't done a >> proposal. >> >> For Java, to extend the string syntax and emphasize that a new string >> is being constructed, I recommend this: >> >> ? ?new "$foo, ${bar}s." >> >> The new kwd enables the dollars. Other details to be taken from the >> Groovy spec. >> >> Best wishes, >> >> -- John ?(on my iPhone) >> >> On Mar 19, 2009, at 8:33 AM, phil swenson >> wrote: >> >> ?> funny, i just joined the list specifically to ask about this subject. >> ?> >> ?> why not just copy the groovy implementation of this? ? $var or $ >> ?> {expresion} ? >> ?> in groovy it would be: >> ?> "[$field1, $field2, $field3]" >> ?> >> ?> or with the explicit expression syntax: >> ?> "[${field1}, ${field2}, ${field3}]" >> ?> >> ?> >> ?> I hate escape characters :) >> ?> >> ?> >> ?> On Thu, Mar 19, 2009 at 2:03 AM, Schulz, Stefan >> ?> wrote: >> ?>> The concat-variant to me is even worse readable than the original +- >> ?>> notation, having three consecutive commas in between. >> ?>> The proposal already mentions concatenation of any kind as >> ?>> alternative, although not mentioning concat(). Maybe worth expanding. >> ?>> >> ?>> Stefan >> ?>> >> ?>>> -----Original Message----- >> ?>>> From: rssh at gradsoft.com.ua [mailto:rssh at gradsoft.com.ua] >> ?>>> Sent: Wednesday, March 18, 2009 8:58 PM >> ?>>> To: Howard Lovatt >> ?>>> Cc: coin-dev at openjdk.java.net; Schulz, Stefan >> ?>>> Subject: Re: Proposal: Embedded Expressions for String Statements >> ?>>> >> ?>>>> I like Stefan's proposed syntax and as a way of a motivating >> ?>>>> example >> ?>>>> consider writing a toString method that gives the field >> ?>>> values within >> ?>>>> square brackets, now you would write: >> ?>>>> >> ?>>>> ? ? "[" + field1 + ", " + field2 + ", " + field3 + "]" >> ?>>>> >> ?>>>> With the proposal you would say: >> ?>>>> >> ?>>>> ? ? "[\{field1}, \{field2}, \{field3}]" >> ?>>>> >> ?>>>> Which I find clearer. >> ?>>>> >> ?>>> >> ?>>> Just note: now we can use much cleaner >> ?>>> ?concat( field1, ',' , field2, ',' field3 ) >> ?>>> >> ?>>> >> ?>>> >> ?>>>> Many thanks to Stefan for writing this up formally. >> ?>>>> >> ?>>>> >> ?>>> >> ?>>> >> ?>>> >> ?>>> >> ?>> >> ?>> >> ?> >> > > From xmirog at gmail.com Sat Mar 21 00:20:49 2009 From: xmirog at gmail.com (=?ISO-8859-1?Q?Xavi_Mir=F3?=) Date: Sat, 21 Mar 2009 08:20:49 +0100 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <17b2302a0903201419v69ac5443y8969808536647eac@mail.gmail.com> Message-ID: <49C49551.4090807@gmail.com> +1. A brilliant idea! Xavi Joshua Bloch escribi?: > Tim, > This is very clever! While it doesn't allow programmers to create their own > interfaces for use with the construct, it allows future release of the > platform to broaden the applicability of the construct without changing the > language. And it does so without abusing annotations. While it's not a > typical uses of packages, it wouldn't be the first time the language gave > special standing to a package. For example, members of java.lang are > automatically imported on demand. > > What do others think? > > Josh > > On Fri, Mar 20, 2009 at 2:08 PM, Tim Peierls wrote: > > >> How about using a special package -- java.lang.auto, say -- with initially >> only one or two interfaces -- AutoCloseable and AutoDisposable, say -- and >> word the ARM proposal so that only subtypes of interfaces with a single, >> parameterless method that are declared in this special package are allowed >> in the ARM try-initialization? >> >> The idea here is to remove the decision about which clean-up methods to >> support from the current proposal and make it a library design issue. >> >> --tim >> >> >> > > > From schulz at e-spirit.de Sat Mar 21 02:27:00 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sat, 21 Mar 2009 10:27:00 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: References: Message-ID: <49C4B2E4.1060004@e-spirit.de> Hm, no, not yet. If such Strings reside in a resource file, they obviusly cannot be handled by the compiler (as any constructed or externalized String wouldn't be). So one would still need to "evaluate" the localized String, passing the required context (i.e. variable bindings) to the evaluation routine. One could offer the parsing part the compiler is using as utility, though. In script languages like PHP, there is a system function "eval", which automatically binds all visible variables to the evaluation process. I am not sure whether such an approach would be viable in Java. Stefan Mark Mahieu schrieb: > Hi Stefan, > > Do you have any thoughts about how this new form of String might be > internationalized? > > Mark > From reinier at zwitserloot.com Sat Mar 21 03:11:42 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 21 Mar 2009 11:11:42 +0100 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: <49C4B2E4.1060004@e-spirit.de> References: <49C4B2E4.1060004@e-spirit.de> Message-ID: In most other languages, the backtick delimiter is used to force an identifier (e.g. scala). Because java is bound to get this sooner rather than later too, I strenously object to using backticks for this. e.g: public void `for`(String foo) { //look, a method named after a keyword! } NB: Joe, will you be writing the proposal on this? You mentioned something along these lines when you announced coin at http://blogs.sun.com/darcy/entry/project_coin --Reinier Zwitserloot On Mar 21, 2009, at 10:27, Stefan Schulz wrote: > Hm, no, not yet. If such Strings reside in a resource file, they > obviusly cannot be handled by the compiler (as any constructed or > externalized String wouldn't be). So one would still need to > "evaluate" > the localized String, passing the required context (i.e. variable > bindings) to the evaluation routine. One could offer the parsing part > the compiler is using as utility, though. > In script languages like PHP, there is a system function "eval", which > automatically binds all visible variables to the evaluation process. I > am not sure whether such an approach would be viable in Java. > > Stefan > > Mark Mahieu schrieb: >> Hi Stefan, >> >> Do you have any thoughts about how this new form of String might be >> internationalized? >> >> Mark >> > From scolebourne at joda.org Sat Mar 21 06:17:18 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 21 Mar 2009 13:17:18 +0000 Subject: PROPOSAL: Elvis operator Message-ID: <49C4E8DE.4040803@joda.org> I'm re-submitting the Elvis operator as a separate proposal to ensure it is treated as such. So far I've not heard any arguments against this on this list, and there are lots of positives. I've also added significantly to the rationale, examples and references, including the point that many developers and coding standards avoid the use of the ternary (requiring if/else), making Elvis a significant saving in verbosity. Stephen ------------------------------------------------------------------- Elvis Operator for Java AUTHOR(S): Stephen Colebourne primarily written up by Neal Gafter (Neal Gafter is responsible for the formal write-up[5] of the proposal detailed below. However, in private communication he indicated that he did not intend to submit it to Project Coin, as indicated in his write-up: "[I do] not specifically advocate adding these features to the Java programming language. Rather, this document is offered as an example of a language change proposal in a form suitable for consideration in the JDK7 small language changes JSR. Specifically, it is more like a specification than a tutorial or sales job.". As such, this proposal is submitted by myself, thanks to Neal's willingness to allow me to reuse his write-up. For the submission, I have reworded the advantages/benefits/disadvantages/alternatives sections from Neal's original document and added detail to the examples. Please see the original[5] to compare Neal's version to mine.) *OVERVIEW* FEATURE SUMMARY: The ?: binary "Elvis" operator results in the value of the left-hand-side if it is not null, avoiding evaluation of the right-hand-side. If the left-hand-side is null, the right-hand-side is evaluated and is the result. MAJOR ADVANTAGE: It is a common occurance in most large systems to find code that checks for and handles null. As null is an awkward value to process, a common requirement is to provide a default value instead of null, for example an empty string or an empty list. The current code for providing a default value is more verbose than it needs to be. This proposal provides a simple syntax sugar to ease the verboseness. The second advantage is to reduce the number of NullPointerExceptions. These frequently occur late in the development cycle, significantly slowing delivery. Academic analysis [6] showed that 5% of the bugs found in the release of Eclipse JDT v3.3 were directly due to NPE. Better null-handling is the most-wanted change in Java based on developer polls [1]. MAJOR BENEFIT: The common coding pattern of checking for null and supplying a default value is greatly simplified. Developers need to default for null in two main scenarios. The first is when handling input from APIs that return null. While this may be considered by some to be a design flaw in the API, the reality is that it is extremely common. Keeping it hard to handle the null value doesn't make it any more likely that the API be changed to stop returning null. The second is when auto-unboxing. The current auto-unboxing feature is considered dangerous by some coding shops, who have banned its use as a result. This is because it can produce NPE from unexpected places. The addition of the Elvis operator provides a simple way for developers to handle any potential null value, thus greatly enhancing the value of auto-unboxing. (Currently, a developer has to write an if statement, which introduces an extra block which entirely defeats the purpose of the 'convenience' unboxing). The simplification of the code necessary to default for null is also likely to have positive side effects. Because the code is simpler to write, developers will be more likely to include the defaulting of null. This will have the benefit of reducing the number of NullPointerExceptions. The JSR-305/208 project is proposing adding nullable annotations to Java. The Elvis operator would dovetail nicely with this work, as it would provide a safe way to convert from a @Nullable to a @NotNull variable. Finally, the proposed operator will, in certain cases, generally be slightly more performant and correct code than that written by hand. This is because the LHS of the expression will only be evaluated once with the proposed change, whereas a developer will normally evaluate it twice (ie. consider the case where the LHS is a method call not a simple variable). MAJOR DISADVANTAGE: Associated costs in documentation, tutorials and overall language size. The principle perceived disadvantage, is that it encourages, rather than discourages, the use of null values in APIs. No one is disputing that empty arrays or empty collections should be returned from APIs rather than nulls, however that is only a small proportion of the returned types in any large system. Many large systems consist of large numbers of JavaBean type objects which may have null values for many of their fields (representing an absence of information, invalid data, etc.). In these cases, null is a suitable and valuable value to hold in those fields, and is widely used as such. Accessing the resulting data for use often requires defaulting the null value, and that is where this proposal comes in. ALTERNATIVES: Use the ternary expression, as today. However, since many developers and coding standards argue against the ternary [7], it may be necessary to handle the defaulting of null in an if/else and 2-8 lines of code (depending on how you like your braces). Whether using the ternary or an if/else, the important business logic is hidden by the need to handle the low-level null issue. It is possible to solve this issue using a library, such as Utils.defaultValue(value, valueIfNull). This is still verbose and intrusive, possibly more so than just writing a ternary expression. *EXAMPLES* SIMPLE EXAMPLE: String s = mayBeNull ?: "null"; whereas, today this is written: String s = (mayBeNull != null ? mayBeNull : "null"); or (since many developers and coding shops disapprove of the ternary [7]): String s; if (mayBeNull != null) { s = mayBeNull; } else { s = "null"; } Auto-unboxing example: Integer ival = ...; // may be null int i = ival ?: -1; // no NPE from unboxing ADVANCED EXAMPLE: private Map hitCounts = ... public synchronized void countPageHit(String pageName) { int count = hitCounts.get(pageName) ?: 0; hitCounts.put(pageName, ++count); } Without this feature, a developer would currently write **: public synchronized void countPageHit(String pageName) { Integer countVal = hitCounts.get(pageName); int count = (countVal != null ? countVal : 0); hitCounts.put(pageName, ++count); } or: public synchronized void countPageHit(String pageName) { Integer countVal = hitCounts.get(pageName); if (countVal == null) { hitCounts.put(pageName, 0); } else { hitCounts.put(pageName, ++countVal); } } ** In fact I suspect that a fair few developers would forget the null check at first and just assign to int, resulting in a NPE during testing *DETAILS* SPECIFICATION: Lexical: We do not add any tokens to the language. Rather, we introduce new operators that are composed of a sequence of existing tokens. Syntax: The folllowing new grammar rules are added to the syntax ConditionalExpression: ElvisExpression ElvisExpression: ConditionalOrExpression ? : ConditionalExpression Semantics: An Elvis expression e1?:e2 first evaluates the expression e1. It is an error if this is not a reference type. If the result is non-null, then that is the Elvis expression's result. Otherwise, e2 is evaluated and is the result of the Elvis expression. In either case, the type of the result is the same as the type of ((e1 != null) ? e1 : e2). [Note: this section must mention bringing the operands to a common type, for example by unboxing when e2 is a primitive, using the same rules as the ternary operator] Exception Analysis: No change Definite Assignment: JLS section 16.1 (definite assignment and expressions) is augmented with the following new subsections 16.1.x Elvis Operator * v is definitely assigned after e1?:e2 iff v is definitely assigned after e1. * v is definitely unassigned after e1?:e2 iff v is definitely unassigned after e2. * in an expression of the form e1?:e2, v is [un]assigned before e2 iff v is [un]assigned after e1. COMPILATION: These new expression forms can be desugared as follows: * e1?:e2 is rewritten as (t != null ? t : e2) where t is a new temporary that holds the computed value of the expression e1. TESTING: This feature can be tested by exercising the new expression form, verifying the correct behavior in erroneous and non-erroneous situations, with or without null as the value of the left-hand operand, with or without primitives, and with respect to definite assignment. LIBRARY SUPPORT: No library support is required. REFLECTIVE APIS: No reflective APIs require any changes. However, the not-yet-public javac Tree APIs, which describe the syntactic structure of Java statements and expressions, should be augmented with a new tree form for this new expression type. OTHER CHANGES: No other platform changes are required. MIGRATION: No migration of existing code is recommended. These new language features are mainly to be used in new code. However, IDEs should provide refactoring advice for taking advantage of these new operators when existing code uses the corresponding idiom. *COMPATIBILITY* BREAKING CHANGES: No breaking changes are caused by this proposal. EXISTING PROGRAMS: Because the changes are purely the introduction of a new expression form, there is no impact on the meaning of existing code. *REFERENCES* EXISTING BUGS: Related, though not exact matches: 6341875: New for loop should treat null as an empty list 6303028: Conditional operator + autoboxing throws NullPointerException 6212662: Boxing/Unboxing detector for == that will always fail URL FOR PROTOTYPE: No Java prototype exists at this time. However, Groovy[2] and Fan[3] (among others) have the Elvis operator. OTHER REFERENCES [1] Summary of three recent language change polls showing better null handling as a key developer request - http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_everyone [2] Groovy Operators - http://groovy.codehaus.org/Operators [3] Fan operators - http://fandev.org/doc/docLang/Expressions.html#nullConvenience [4] Stephen Colebourne's brief on null-safe operators - http://docs.google.com/View?docid=dfn5297z_3c73gwb [5] The version of this proposal written by Neal Gafter - http://docs.google.com/Doc?docid=ddb3zt39_78frdf87dc&hl=en [6] Academic analysis of nulls, http://users.encs.concordia.ca/~chalin/papers/2006-003.v3s-pub.pdf [7] Avoiding or limiting use of the ternary: http://users.csc.calpoly.edu/~jdalbey/SWE/code_std.html http://www.coderanch.com/t/408524/Java-General-beginner/java/Ternary-operator-with-if-elseif http://www.aptana.com/dev/index.php/Java_Coding_Standard https://jjguidelines.dev.java.net/book/html/apas04.html http://qpid.apache.org/java-coding-standards.html From lapsus63 at gmail.com Sat Mar 21 06:56:02 2009 From: lapsus63 at gmail.com (Olivier Chorier) Date: Sat, 21 Mar 2009 14:56:02 +0100 Subject: PROPOSAL: Elvis operator In-Reply-To: <49C4E8DE.4040803@joda.org> References: <49C4E8DE.4040803@joda.org> Message-ID: I initially thought it was a good idea, but after a bit reflection, I don't think it is a real 'plus' compared with the ternary operator. For example, how would you simplify those lines of code (assuming the coder loves ternary operator) : int value = object == null ? -1 : (object.getSubObject() == null ? -1 : (object.getSubObject().getValue() == null ? -1 : object.getSubObject().getValue())); Does somebody has an idea (excepting using an ugly try-catch statement) to write this much clearer ? (sorry for code indentation) 2009/3/21 Stephen Colebourne > I'm re-submitting the Elvis operator as a separate proposal to ensure it > is treated as such. So far I've not heard any arguments against this on > this list, and there are lots of positives. > > I've also added significantly to the rationale, examples and references, > including the point that many developers and coding standards avoid the > use of the ternary (requiring if/else), making Elvis a significant > saving in verbosity. > > Stephen > > ------------------------------------------------------------------- > Elvis Operator for Java > AUTHOR(S): > Stephen Colebourne > primarily written up by Neal Gafter > > (Neal Gafter is responsible for the formal write-up[5] of the proposal > detailed below. However, in private communication he indicated that he > did not intend to submit it to Project Coin, as indicated in his > write-up: "[I do] not specifically advocate adding these features to the > Java programming language. Rather, this document is offered as an > example of a language change proposal in a form suitable for > consideration in the JDK7 small language changes JSR. Specifically, it > is more like a specification than a tutorial or sales job.". > > As such, this proposal is submitted by myself, thanks to Neal's > willingness to allow me to reuse his write-up. For the submission, I > have reworded the advantages/benefits/disadvantages/alternatives > sections from Neal's original document and added detail to the examples. > Please see the original[5] to compare Neal's version to mine.) > > > *OVERVIEW* > > FEATURE SUMMARY: > The ?: binary "Elvis" operator results in the value of the > left-hand-side if it is not null, avoiding evaluation of the > right-hand-side. If the left-hand-side is null, the right-hand-side is > evaluated and is the result. > > MAJOR ADVANTAGE: > It is a common occurance in most large systems to find code that checks > for and handles null. As null is an awkward value to process, a common > requirement is to provide a default value instead of null, for example > an empty string or an empty list. The current code for providing a > default value is more verbose than it needs to be. This proposal > provides a simple syntax sugar to ease the verboseness. > > The second advantage is to reduce the number of NullPointerExceptions. > These frequently occur late in the development cycle, significantly > slowing delivery. Academic analysis [6] showed that 5% of the bugs found > in the release of Eclipse JDT v3.3 were directly due to NPE. > > Better null-handling is the most-wanted change in Java based on > developer polls [1]. > > MAJOR BENEFIT: > The common coding pattern of checking for null and supplying a default > value is greatly simplified. > > Developers need to default for null in two main scenarios. The first is > when handling input from APIs that return null. While this may be > considered by some to be a design flaw in the API, the reality is that > it is extremely common. Keeping it hard to handle the null value doesn't > make it any more likely that the API be changed to stop returning null. > > The second is when auto-unboxing. The current auto-unboxing feature is > considered dangerous by some coding shops, who have banned its use as a > result. This is because it can produce NPE from unexpected places. The > addition of the Elvis operator provides a simple way for developers to > handle any potential null value, thus greatly enhancing the value of > auto-unboxing. (Currently, a developer has to write an if statement, > which introduces an extra block which entirely defeats the purpose of > the 'convenience' unboxing). > > The simplification of the code necessary to default for null is also > likely to have positive side effects. Because the code is simpler to > write, developers will be more likely to include the defaulting of null. > This will have the benefit of reducing the number of NullPointerExceptions. > > The JSR-305/208 project is proposing adding nullable annotations to > Java. The Elvis operator would dovetail nicely with this work, as it > would provide a safe way to convert from a @Nullable to a @NotNull > variable. > > Finally, the proposed operator will, in certain cases, generally be > slightly more performant and correct code than that written by hand. > This is because the LHS of the expression will only be evaluated once > with the proposed change, whereas a developer will normally evaluate it > twice (ie. consider the case where the LHS is a method call not a simple > variable). > > MAJOR DISADVANTAGE: > Associated costs in documentation, tutorials and overall language size. > > The principle perceived disadvantage, is that it encourages, rather than > discourages, the use of null values in APIs. No one is disputing that > empty arrays or empty collections should be returned from APIs rather > than nulls, however that is only a small proportion of the > returned types in any large system. Many large systems consist of large > numbers of JavaBean type objects which may have null values for many of > their fields (representing an absence of information, invalid data, > etc.). In these cases, null is a suitable and valuable value to hold in > those fields, and is widely used as such. Accessing the resulting data > for use often requires defaulting the null value, and that is where this > proposal comes in. > > ALTERNATIVES: > Use the ternary expression, as today. However, since many developers and > coding standards argue against the ternary [7], it may be necessary to > handle the defaulting of null in an if/else and 2-8 lines of code > (depending on how you like your braces). Whether using the ternary or an > if/else, the important business logic is hidden by the need to handle > the low-level null issue. > > It is possible to solve this issue using a library, such as > Utils.defaultValue(value, valueIfNull). This is still verbose and > intrusive, possibly more so than just writing a ternary expression. > > > *EXAMPLES* > > SIMPLE EXAMPLE: > > String s = mayBeNull ?: "null"; > > whereas, today this is written: > > String s = (mayBeNull != null ? mayBeNull : "null"); > > or (since many developers and coding shops disapprove of the ternary [7]): > > String s; > if (mayBeNull != null) { > s = mayBeNull; > } else { > s = "null"; > } > > > Auto-unboxing example: > Integer ival = ...; // may be null > int i = ival ?: -1; // no NPE from unboxing > > > ADVANCED EXAMPLE: > private Map hitCounts = ... > public synchronized void countPageHit(String pageName) { > int count = hitCounts.get(pageName) ?: 0; > hitCounts.put(pageName, ++count); > } > > Without this feature, a developer would currently write **: > > public synchronized void countPageHit(String pageName) { > Integer countVal = hitCounts.get(pageName); > int count = (countVal != null ? countVal : 0); > hitCounts.put(pageName, ++count); > } > > or: > > public synchronized void countPageHit(String pageName) { > Integer countVal = hitCounts.get(pageName); > if (countVal == null) { > hitCounts.put(pageName, 0); > } else { > hitCounts.put(pageName, ++countVal); > } > } > > ** In fact I suspect that a fair few developers would forget the null > check at first and just assign to int, resulting in a NPE during testing > > > *DETAILS* > > SPECIFICATION: > Lexical: > > We do not add any tokens to the language. Rather, we introduce new > operators that are composed of a sequence of existing tokens. > > Syntax: > > The folllowing new grammar rules are added to the syntax > > ConditionalExpression: > > ElvisExpression > > ElvisExpression: > > ConditionalOrExpression ? : ConditionalExpression > > Semantics: > > An Elvis expression e1?:e2 first evaluates the expression e1. It is an > error if this is not a reference type. If the result is non-null, then > that is the Elvis expression's result. Otherwise, e2 is evaluated and > is the result of the Elvis expression. In either case, the type of the > result is the same as the type of ((e1 != null) ? e1 : e2). [Note: this > section must mention bringing the operands to a common type, for example > by unboxing when e2 is a primitive, using the same rules as the ternary > operator] > > Exception Analysis: > > No change > > Definite Assignment: > > JLS section 16.1 (definite assignment and expressions) is augmented with > the following new subsections > > 16.1.x Elvis Operator > > * v is definitely assigned after e1?:e2 iff v is definitely > assigned after e1. > * v is definitely unassigned after e1?:e2 iff v is definitely > unassigned after e2. > * in an expression of the form e1?:e2, v is [un]assigned before e2 > iff v is [un]assigned after e1. > > > COMPILATION: > These new expression forms can be desugared as follows: > > * e1?:e2 is rewritten as (t != null ? t : e2) > > where t is a new temporary that holds the computed value of the > expression e1. > > TESTING: > This feature can be tested by exercising the new expression form, > verifying the correct behavior in erroneous and non-erroneous > situations, with or without null as the value of the left-hand operand, > with or without primitives, and with respect to definite assignment. > > LIBRARY SUPPORT: > No library support is required. > > REFLECTIVE APIS: > No reflective APIs require any changes. However, the not-yet-public > javac Tree APIs, which describe the syntactic structure of Java > statements and expressions, should be augmented with a new tree form for > this new expression type. > > OTHER CHANGES: > No other platform changes are required. > > MIGRATION: > No migration of existing code is recommended. These new language > features are mainly to be used in new code. However, IDEs should > provide refactoring advice for taking advantage of these new operators > when existing code uses the corresponding idiom. > > > *COMPATIBILITY* > > BREAKING CHANGES: > No breaking changes are caused by this proposal. > > EXISTING PROGRAMS: > Because the changes are purely the introduction of a new expression > form, there is no impact on the meaning of existing code. > > > *REFERENCES* > > EXISTING BUGS: > Related, though not exact matches: > 6341875: New for loop should treat null as an empty list > 6303028: Conditional operator + autoboxing throws NullPointerException > 6212662: Boxing/Unboxing detector for == that will always fail > > URL FOR PROTOTYPE: > No Java prototype exists at this time. However, Groovy[2] and Fan[3] > (among others) have the Elvis operator. > > OTHER REFERENCES > [1] Summary of three recent language change polls showing better null > handling as a key developer request - > http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_everyone > [2] Groovy Operators - http://groovy.codehaus.org/Operators > [3] Fan operators - > http://fandev.org/doc/docLang/Expressions.html#nullConvenience > [4] Stephen Colebourne's brief on null-safe operators - > http://docs.google.com/View?docid=dfn5297z_3c73gwb > [5] The version of this proposal written by Neal Gafter - > http://docs.google.com/Doc?docid=ddb3zt39_78frdf87dc&hl=en > [6] Academic analysis of nulls, > http://users.encs.concordia.ca/~chalin/papers/2006-003.v3s-pub.pdf > [7] Avoiding or limiting use of the ternary: > http://users.csc.calpoly.edu/~jdalbey/SWE/code_std.html > > http://www.coderanch.com/t/408524/Java-General-beginner/java/Ternary-operator-with-if-elseif > http://www.aptana.com/dev/index.php/Java_Coding_Standard > https://jjguidelines.dev.java.net/book/html/apas04.html > http://qpid.apache.org/java-coding-standards.html > > > > > From develop4lasu at gmail.com Sat Mar 21 06:56:10 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 14:56:10 +0100 Subject: Feedback and comments on ARM proposal - resend In-Reply-To: <1631da7d0903201302y1bdfc516i4be9a5ddbb6e8f3b@mail.gmail.com> References: <3dd3f56a0903141955o28a612b9m82da4d5379bb66ff@mail.gmail.com> <15e8b9d20903181529l6d66f2fcqe2f0a8a390254450@mail.gmail.com> <3dd3f56a0903181718j76ae23ffi58bacb2351c66bbc@mail.gmail.com> <15e8b9d20903191217y1b4e512dwfa6bfa3093419b2@mail.gmail.com> <17b2302a0903191232q6379bb6p114056962f63d63c@mail.gmail.com> <15e8b9d20903191303x2e80f2few3e09141f1b58bc8c@mail.gmail.com> <17b2302a0903191455t57a9c452gc540b7afe6597e2e@mail.gmail.com> <15e8b9d20903191733j4e42e301jc66b36876f00b20d@mail.gmail.com> <17b2302a0903191755m7faabd14ue79bdf197c73c071@mail.gmail.com> <1631da7d0903201302y1bdfc516i4be9a5ddbb6e8f3b@mail.gmail.com> Message-ID: <28bca0ff0903210656j3affea89g495dd93351478fbe@mail.gmail.com> I do not agree with that and what's more I think you misunderstood the problem. I'll try to track genesis: The described problem exists because you try to write algorithm with graph structure with sequence code, which is impossible now time. As example: static void copy(String src, String dest) throws IOException { InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(dest); try { byte[] buf = new byte[8 * 1024]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally { out.close(); } } finally { in.close(); } } That problem can be shown as: red line: right side can be executed only if left succeed blue line: right side can be executed when left side ended or will not be executed. http://alan.umcs.lublin.pl/~lasu/develop/alg.gif The problem is more deep than it looks like. And how would ARM handle the situation when closing have to be done in proper order, or we will have to get all information about exceptions? What's more, throwing exception(s) in the air (ignore it) by default is really bad solution like in try-finally. Now, see how, in my opinion, this should be handled: Let's bring more constructions: Summon block will make that all expressions in it are executed no mater if previously one succeed or not. What's more, block as a result will return exception or exceptions that occurred in its body depending on mode. Let's assume that all values & variables for which expression fails to assign will be set to null. Summon block mode: first: block will result in first throwed exception last: block will result in last throwed exception all: block will result in all throwed exceptions as array summon(mode){}:: exception Bloc : simple block that will be skipped from execution on first exception. block{}; Now see the same code: summon(all){ // collect all exceptions new FileInputStream(src) ::in; // value is null if constructor fails. (in!=null?new FileOutputStream(dest):null) ::out; if ((in!=null)&&(out!=null)) block{ // execution will stop at first exception. byte[] buf = new byte[8 * 1024]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } if (in!=null) in.close(); if (out!=null) out.close; }::exceptions; if (exceptions.length==0) return true; ... // error handle or: summon(all){ new FileInputStream(src) ::in; // value is null if constructor fails. if (in!=null){ new FileOutputStream(dest) ::out; if (out!=null){ block{ // execution will stop at first exception. byte[] buf = new byte[8 * 1024]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } out.close(); } in.close(); } }::exceptions; if (exceptions.length==0) return true; ... // error handle Maybe, that's not the best way to handle this, but AMR is not a solution in that case at all. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sat Mar 21 07:23:32 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 15:23:32 +0100 Subject: PROPOSAL: Elvis operator In-Reply-To: References: <49C4E8DE.4040803@joda.org> Message-ID: <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> 2009/3/21 Olivier Chorier > I initially thought it was a good idea, but after a bit reflection, I don't > think it is a real 'plus' compared with the ternary operator. > > For example, how would you simplify those lines of code (assuming the coder > loves ternary operator) : > > int value = object == null ? -1 : > (object.getSubObject() == null ? -1 : > (object.getSubObject().getValue() == null ? -1 : > object.getSubObject().getValue())); > > Does somebody has an idea (excepting using an ugly try-catch statement) to > write this much clearer ? > (sorry for code indentation) > > > 2009/3/21 Stephen Colebourne > > > > You wrong, this should look like: int value = object.?getSubObject().?getValue() ?: -1 But there is another problem that I would like to see handled: What if we have default SubObject which we can use when main one is null, and it's ugly generic: SubObject subObject = object.?getSubObject() ?: default; int value = subObject.?getValue() ?: -1; // here we can use subObject now same in other syntax: int value = object.?getSubObject() ?:( subObject ) .?getValue() ?: -1; and other syntax: object.?getSubObject() :: subObject; int value = ( subObject ?: default ).?getValue() ?: -1; // here we can use subObject and other: int value = ( object.?getSubObject() ?: default ).?getValue() ?: -1; Consider witch is easier to read. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From lapsus63 at gmail.com Sat Mar 21 08:04:41 2009 From: lapsus63 at gmail.com (Olivier Chorier) Date: Sat, 21 Mar 2009 16:04:41 +0100 Subject: Fwd: PROPOSAL: Elvis operator In-Reply-To: References: <49C4E8DE.4040803@joda.org> <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> Message-ID: ---------- Forwarded message ---------- From: Olivier Chorier Date: 2009/3/21 Subject: Re: PROPOSAL: Elvis operator To: Marek Kozie? using : ...using a loop (an unexpected shortcut sent the mail sorry) 2009/3/21 Olivier Chorier > Ok, what about : > > int value ?= object.getSubObject().getValue() : -1; > > Pros : > - I think the compiler could easily retranscript it using > - Much more readable > > Cons : > - The potential problem is that the "interpretation" differs from an &= or > += operator > > 2009/3/21 Marek Kozie? > > 2009/3/21 Olivier Chorier >> >>> I initially thought it was a good idea, but after a bit reflection, I >>> don't >>> think it is a real 'plus' compared with the ternary operator. >>> >>> For example, how would you simplify those lines of code (assuming the >>> coder >>> loves ternary operator) : >>> >>> int value = object == null ? -1 : >>> (object.getSubObject() == null ? -1 : >>> (object.getSubObject().getValue() == null ? -1 : >>> object.getSubObject().getValue())); >>> >>> Does somebody has an idea (excepting using an ugly try-catch statement) >>> to >>> write this much clearer ? >>> (sorry for code indentation) >>> >>> >>> 2009/3/21 Stephen Colebourne >>> >>> >>> >>> You wrong, this should look like: >> >> int value = object.?getSubObject().?getValue() ?: -1 >> >> But there is another problem that I would like to see handled: >> >> What if we have default SubObject which we can use when main one is null, >> and it's ugly generic: >> >> SubObject subObject = >> object.?getSubObject() ?: default; >> >> int value = subObject.?getValue() ?: -1; >> >> // here we can use subObject >> >> now same in other syntax: >> >> int value = object.?getSubObject() ?:( subObject ) .?getValue() ?: -1; >> >> and other syntax: >> >> object.?getSubObject() :: subObject; >> >> int value = ( subObject ?: default ).?getValue() ?: -1; >> >> // here we can use subObject >> >> and other: >> >> int value = ( object.?getSubObject() ?: default ).?getValue() ?: -1; >> >> Consider witch is easier to read. >> -- >> Pozdrowionka. / Regards. >> Lasu aka Marek Kozie? >> >> http://lasu2string.blogspot.com/ >> > > From tim at peierls.net Sat Mar 21 08:09:20 2009 From: tim at peierls.net (Tim Peierls) Date: Sat, 21 Mar 2009 11:09:20 -0400 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> Message-ID: <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> On Fri, Mar 20, 2009 at 5:18 PM, Mark Mahieu wrote: > Or perhaps a marker interface rather than a special package? That might be > more consistent with existing 'special behaviour' (eg. Serializable). And a magic interface seems simpler than a magic package. It would make it a lot easier for people to roll their own AutoXyz variants. OTOH, maybe unrestricted extensibility is just asking for trouble? --tim From develop4lasu at gmail.com Sat Mar 21 08:14:15 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 16:14:15 +0100 Subject: PROPOSAL: Elvis operator In-Reply-To: References: <49C4E8DE.4040803@joda.org> <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> Message-ID: <28bca0ff0903210814s5253b9das125c3fdb45c0cf5@mail.gmail.com> W dniu 21 marca 2009 16:00 u?ytkownik Olivier Chorier napisa?: > > Ok, what about : > > int value ?= object.getSubObject().getValue()? : -1; > > Pros : > ?- I think the compiler could easily retranscript it using > ?- Much more readable > > Cons : > - The potential problem is that the "interpretation" differs from an &= or += operator > It's ok for me, in this case. But did you ever wander why NPE is so common? Isn't that because people do not want write so much if-s and declare so many one time used variables. but ?: can give something nice: void f(Some some){ ( some.getOut ?: defOut ).write(...); ... } while ?= would require to: void f(Some some){ OutputStream out ?= some.getOut : defOut; out.write(...); // Now we need worry for 'out' till end of function. ... } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From markmahieu at googlemail.com Sat Mar 21 08:30:27 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 15:30:27 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> Message-ID: 2009/3/21 Tim Peierls > On Fri, Mar 20, 2009 at 5:18 PM, Mark Mahieu wrote: > >> Or perhaps a marker interface rather than a special package? That might >> be more consistent with existing 'special behaviour' (eg. Serializable). > > > And a magic interface seems simpler than a magic package. It would make it > a lot easier for people to roll their own AutoXyz variants. OTOH, maybe > unrestricted extensibility is just asking for trouble? > > --tim > Possibly, though I'm sure that people who will 'abuse' ARM by applying it to inappropriate APIs would be just as likely to do so with a restricted set of interfaces anyway. Names like 'close' are wonderfully generic and easy to incorporate into an API if you've convinced yourself that the end justifies the means. I don't think there's any way it (either approach) would allow people to cause trouble with APIs they don't own though. For example, I couldn't get ARM to call Iterator.remove() at the end of my try blocks :) I guess I'm most interested in those APIs that would otherwise be left out in the cold, like the new JDBC 4 java.sql methods I mentioned in another email. Mark From tim at peierls.net Sat Mar 21 09:07:58 2009 From: tim at peierls.net (Tim Peierls) Date: Sat, 21 Mar 2009 12:07:58 -0400 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> Message-ID: <63b4e4050903210907ma441ff0qefd96644eb95cda8@mail.gmail.com> On Sat, Mar 21, 2009 at 11:30 AM, Mark Mahieu wrote: > For example, I couldn't get ARM to call Iterator.remove() at the end of my > try blocks :) > Sure you could! You just have to really mean it. :-) public class AutoRemovingIterator extends ForwardingIterator implements AutoRemovable { private AutoRemovingIterator(Iterator it) { this.it = it; } protected Iterator delegate() { return it; } private final Iterator it; public static AutoRemovingIterator autoRemove(Iterator it) { return new AutoRemovingIterator(it); } } // In other code, with autoRemove statically imported: try (AutoRemovingIterator elementIterator : autoRemove(elements.iterator())) { // Use elementIterator ... when you're done, elementIterator.remove() will be called. } Not that this contributes anything useful to the discussion. --tim From jjb at google.com Sat Mar 21 09:08:49 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 21 Mar 2009 09:08:49 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> Message-ID: <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> Mark and Tim, I think it might be easier to specify (and implement the package variant. Roughly speaking, the legal types for "manageable resources" are those that are assignment compatible with one and only one of the classes in java.lang.auto. While it's not generally possible to enumerate over classes in a package, the compiler can be (are, in fact) tied to particular versions of the platform so this shouldn't present too big a problem (though it could limit extensibility by JRE hackers). What about the magic marker interface (if you'll pardon my wordplay)? This may be difficult to specify. Loosely speaking you want a manageable resource to be assignment compatible with one and only one interface that extends the magic marker. But this opens a whole can of works. What if you have an interface that extends an interface that extends the magic marker? There should be nothing wrong with that. While there may be some easy way to specify this (and give it reasonable semantics) it isn't jumping out at me. If anyone has any clever ideas along these lines, I'd love to know. Josh On Sat, Mar 21, 2009 at 8:30 AM, Mark Mahieu wrote: > 2009/3/21 Tim Peierls > > > On Fri, Mar 20, 2009 at 5:18 PM, Mark Mahieu >wrote: > > > >> Or perhaps a marker interface rather than a special package? That might > >> be more consistent with existing 'special behaviour' (eg. Serializable). > > > > > > And a magic interface seems simpler than a magic package. It would make > it > > a lot easier for people to roll their own AutoXyz variants. OTOH, maybe > > unrestricted extensibility is just asking for trouble? > > > > --tim > > > > Possibly, though I'm sure that people who will 'abuse' ARM by applying it > to > inappropriate APIs would be just as likely to do so with a restricted set > of > interfaces anyway. Names like 'close' are wonderfully generic and easy to > incorporate into an API if you've convinced yourself that the end justifies > the means. > I don't think there's any way it (either approach) would allow people to > cause trouble with APIs they don't own though. For example, I couldn't get > ARM to call Iterator.remove() at the end of my try blocks :) > > I guess I'm most interested in those APIs that would otherwise be left out > in the cold, like the new JDBC 4 java.sql methods I mentioned in another > email. > > Mark > > From markmahieu at googlemail.com Sat Mar 21 09:12:48 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 16:12:48 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903210907ma441ff0qefd96644eb95cda8@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <63b4e4050903210907ma441ff0qefd96644eb95cda8@mail.gmail.com> Message-ID: LOL, ok yes you could do that :) What I meant was that you couldn't write it like this: try (Iterator elementIterator : autoRemove(elements.iterator())) { // Use elementIterator ... } ... unless of course 'Iterator' is your own Iterator type rather than the java.util version :) Mark 2009/3/21 Tim Peierls > On Sat, Mar 21, 2009 at 11:30 AM, Mark Mahieu wrote: > >> For example, I couldn't get ARM to call Iterator.remove() at the end of my >> try blocks :) >> > > Sure you could! You just have to really mean it. :-) > > public class AutoRemovingIterator extends ForwardingIterator > implements AutoRemovable { > private AutoRemovingIterator(Iterator it) { this.it = it; } > protected Iterator delegate() { return it; } > private final Iterator it; > > public static AutoRemovingIterator autoRemove(Iterator it) { > return new AutoRemovingIterator(it); > } > } > > // In other code, with autoRemove statically imported: > > try (AutoRemovingIterator elementIterator : > autoRemove(elements.iterator())) { > // Use elementIterator ... when you're done, > elementIterator.remove() will be called. > } > > Not that this contributes anything useful to the discussion. > > --tim > > From paul.martin at gmail.com Sat Mar 21 09:15:15 2009 From: paul.martin at gmail.com (Paul Martin) Date: Sat, 21 Mar 2009 16:15:15 +0000 Subject: PROPOSAL: Named method parameters Message-ID: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> I'd like to propose the implementation of optionally named method parameters, and suggest that they are particularly useful when creating immutable objects (which are important in our increasingly concurrent world). Note that this is a topic that seems to have been considered before (see the note in http://paulhammant.com/blog/announcing_paranamer.html which suggests that it was even considered for Java 6), but I can't see it in the current list of Java 7 changes or in the Project Coin mailing list archives (though others have also discussed it in relation to Java 7, such as Alex Miller in http://tech.puredanger.com/2007/08/15/dr-java7/ and http://tech.puredanger.com/2007/10/11/java7-roundup-32/). Therefore I am proposing it here - I think that it is an important change (unless anyone can suggest how I can reasonably create an immutable object with four or more properties without using a Builder or a list of unnamed parameters). Also note that other relevant references include: http://blogs.sun.com/abuckley/entry/named_parameters (which discusses why parameter reordering might be difficult), http://beust.com/weblog/archives/000096.html (which suggests that we do not need named parameters, but really just shows the use of the Builder pattern which has limitations). Named method parameters AUTHOR(S): Paul Martin OVERVIEW FEATURE SUMMARY: Named parameters allow a method or constructor caller to explicitly state the parameter name of each parameter value passed to the method or constructor. Without named parameters, only the order of the parameter values is significant (and it may not be clear what each value represents). MAJOR ADVANTAGE: This is a relatively simple way of introducing named parameters to the Java platform. MAJOR BENEFIT: Named parameters allow method calls with relatively long lists of parameters (greater than 3) to be understood by developers. This can also facilitate the direct use of constructors and factory methods to create immutable objects, where otherwise Builders or mutable JavaBeans would be required. MAJOR DISADVANTAGE: The syntax for method calls would change to allow both named and unnamed parameters to be used. Named parameters might be used too often, which could unnecessarily clutter source files. Metadata to store the names of the parameters must be added to classfiles (for example as annotations). The use of annotations to describe named parameters would mean that no metadata would be stored about the parameter names used by the method caller, and so no runtime checks to match the parameter names being used could be made (only compile-time). If the parameter names change (but otherwise the method signature does not), then the method caller would not be aware of the changes until it was recompiled. Note that this is existing behaviour for unnamed parameters, and would only be a problem if the meaning of the parameters also changes (which should indicate that the caller would need to change anyway, but this would not be detected automatically at runtime). ALTERNATIVES: Unnamed parameters can make the same method calls as named parameters, but if there are many parameters they are harder to understand and prone to ordering-related bugs (particularly for primitive types or Strings). The Builder pattern can be used to simulate named parameters in constructors/factory methods. For example the following class uses a Builder to initialise itself (note that only two properties are used to simplify the example): public final class MyClass { private final String name; private final int age; private MyClass(Builder b) { this.name = b.name; this.age = b.age; } public static class Builder { private String name; private int age; /** * Name to set. */ public Builder setName(String name) { this.name = name; return this; } /** * Age to set */ public Builder setAge(int age) { this.age = age; return this; } public MyClass build() { return new MyClass(this); } } } Objects can then be constructed in the following manner: MyClass obj = new MyClass.Builder().setName("Fred").setAge(53).build(); However, the use of a builder requires additional code, and all parameters are effectively optional from the perspective of the compiler (it cannot easily check that all of the required setter methods have been called), so bugs may occur where parameter values are not set. Note that runtime checks can be made to ensure that all property values are set, but they involve additional work and cannot be used by the compiler (though static analysis of the code in conjunction with annotations might be able to repeat many of these checks). There are also many ways to implement named parameters that are different to the solution proposed here. These include: Implement optional named parameters on all methods: This avoids the need for the @PublicParameterNames annotation, but may mean inconsistent usage of named parameters - the annotation is also a suggestion for the use of named parameters by the caller (which IDEs can also make use of). This will also highlight the difference to classfiles compiled with earlier versions of Java, where named parameters cannot be used at all (since it will then not be obvious when named parameters can and cannot be used). Add parameter names to the classfile as 'fundamental' method metadata rather than as annotations: This may allow closer integration of the named parameters with the rest of the language, but its impact on the rest of the language (and JVM) is much greater. The same inconsistencies and incompatibilities described in the previous alternative would also apply. In addition, the use of annotations should not preclude the subsequent modification of classfiles in a later release - the annotations could still remain (at a potential cost of some duplication). EXAMPLES SIMPLE EXAMPLE: Constructor declaration: @PublicParameterNames public MyClass(String name, int age) { .... Constructor use: MyClass obj = new MyClass(name: "Fred", age: 53); ADVANCED EXAMPLE: Show advanced usage(s) of the feature. The full class definition from the simple example is shown below, as a contrast to that provided in the Builder example. public final class MyClass { private final String name; private final int age; /** * @param name Name to set * @param age Age to set */ @PublicParameterNames public MyClass(String name, int age) { this.name = name; this.age = age; } } DETAILS SPECIFICATION: The @PublicParameterNames annotation is used on a constructor or method to allow named parameters to be used when calling it. It can also be applied to a class or package to apply to all methods within. Similarly, a @NoParameterNames annotation can be used on a constructor, method, or class to override the use of @PublicParameterNames at a higher level. The compiler can then automatically generate a @PublicParameterName(value="parameter-name") annotation for each affected method. These can then be used by the compiler (and IDE) to validate the parameter names used by callers of the method or constructor. The use of parameter names by callers is always optional (primarily for backwards compatibility). However, parameter names cannot be used for some parameters and not others (this would make the code harder to read). Parameters must always be specified in the same order regardless of whether parameter names are used - parameter reordering by callers is not allowed (reordering would make overloading difficult, and is not really necessary). Inheritance: Neither the @PublicParameterNames annotation (and @NoParameterNames annotation), or the names of the parameters themselves, need to be inherited. This is because only static evaluation of a caller's parameter names will be applied (rather than at runtime), so the callers parameter names only need to match those of the declared type of the target. However, it would still be advisable to reuse the same parameter names and annotations when overriding a method (IDEs could help with this). COMPILATION: The compiler must automatically generate a @PublicParameterName(value="parameter-name") annotation for each method and constructor annotated with @PublicParameterNames (or whose the parent class or package is annotated with @PublicParameterNames and the child class or method does not override it with @NoParameterNames). For example: int myMethod(int param1, String param2) Would effectively become: int myMethod(@PublicParameterName("param1") int param1, @PublicParameterName("param2") String param2) Method-calling syntax would need to change, using a colon to separate the parameter name and value where the are used. For example: MyClass obj = new MyClass(name: "Fred", age: 53); When a method caller uses parameter names, the compiler must check that those parameter names exactly match the value of generated @PublicParameterName annotations of the target method or constructor. It is a compilation error if they do not match or the target method or constructor does not have named parameters. IDEs can use the @PublicParameterNames and @NoParameterNames annotations (or @PublicParameterName directly) to automatically insert the relevant parameter names as part of code-completion. Additional refactoring support would also be required to enable parameter names to be renamed, or added and removed completely. Frameworks such as Spring can use the same annotations to allow objects to be created from their configuration files using named parameters to constructors and factory methods. Currently they only allow objects to be created from configuration files as JavaBeans (with setter methods) or with ordered (and unnamed) parameters. TESTING: The feature can be tested by compiling and running programs that exercise the feature. LIBRARY SUPPORT: No. REFLECTIVE APIS: java.lang.reflect.Method and java.lang.reflect.Constructor could be enhanced with new methods that return parameter names. However, that is not required to successfully implement the proposal. OTHER CHANGES: No. The use of named parameters is always optional. The javadoc tool already documents parameter names. Other tools/libraries might benefit from these changes, but their use is not required. MIGRATION: The @PublicParameterNames annotation (and @NoParameterNames annotation) simply needs to be added to the appropriate methods. IDEs could then suggest the use of parameter names for the method's callers, and apply the changes automatically. COMPATIBILITY BREAKING CHANGES: No. EXISTING PROGRAMS: The changes required by this feature should be transparent to existing source and class files if annotations are used internally to describe the named parameters. I am not sure what the impact would be otherwise. REFERENCES EXISTING BUGS: 4124331 (though it is set to 11-Closed, Will Not Fix, request for enhancement, and from 1998) From neal at gafter.com Sat Mar 21 09:26:20 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Mar 2009 09:26:20 -0700 Subject: PROPOSAL: Named method parameters In-Reply-To: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> Message-ID: <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> Annotations should not affect the semantics of any other language construct. I think if you want to add support for named parameters, the support should be available everywhere. What are the changes to the spec for overload resolution? On Sat, Mar 21, 2009 at 9:15 AM, Paul Martin wrote: > I'd like to propose the implementation of optionally named method > parameters, and suggest that they are particularly useful when creating > immutable objects (which are important in our increasingly concurrent > world). > > Note that this is a topic that seems to have been considered before (see the > note in http://paulhammant.com/blog/announcing_paranamer.html which suggests > that it was even considered for Java 6), but I can't see it in the current > list of Java 7 changes or in the Project Coin mailing list archives (though > others have also discussed it in relation to Java 7, such as Alex Miller in > http://tech.puredanger.com/2007/08/15/dr-java7/ and > http://tech.puredanger.com/2007/10/11/java7-roundup-32/). ?Therefore I am > proposing it here - I think that it is an important change (unless anyone > can suggest how I can reasonably create an immutable object with four or > more properties without using a Builder or a list of unnamed parameters). > > Also note that other relevant references include: > http://blogs.sun.com/abuckley/entry/named_parameters (which discusses why > parameter reordering might be difficult), > http://beust.com/weblog/archives/000096.html (which suggests that we do not > need named parameters, but really just shows the use of the Builder pattern > which has limitations). > > > Named method parameters > > AUTHOR(S): > > Paul Martin > > OVERVIEW > > FEATURE SUMMARY: > > Named parameters allow a method or constructor caller to explicitly state > the parameter name of each parameter value passed to the method or > constructor. ?Without named parameters, only the order of the parameter > values is significant (and it may not be clear what each value represents). > > MAJOR ADVANTAGE: > > This is a relatively simple way of introducing named parameters to the Java > platform. > > MAJOR BENEFIT: > > Named parameters allow method calls with relatively long lists of parameters > (greater than 3) to be understood by developers. ?This can also facilitate > the direct use of constructors and factory methods to create immutable > objects, where otherwise Builders or mutable JavaBeans would be required. > > MAJOR DISADVANTAGE: > > The syntax for method calls would change to allow both named and unnamed > parameters to be used. > > Named parameters might be used too often, which could unnecessarily clutter > source files. > > Metadata to store the names of the parameters must be added to classfiles > (for example as annotations). > > The use of annotations to describe named parameters would mean that no > metadata would be stored about the parameter names used by the method > caller, and so no runtime checks to match the parameter names being used > could be made (only compile-time). ?If the parameter names change (but > otherwise the method signature does not), then the method caller would not > be aware of the changes until it was recompiled. ?Note that this is existing > behaviour for unnamed parameters, and would only be a problem if the meaning > of the parameters also changes (which should indicate that the caller would > need to change anyway, but this would not be detected automatically at > runtime). > > ALTERNATIVES: > > Unnamed parameters can make the same method calls as named parameters, but > if there are many parameters they are harder to understand and prone to > ordering-related bugs (particularly for primitive types or Strings). > > The Builder pattern can be used to simulate named parameters in > constructors/factory methods. ?For example the following class uses a > Builder to initialise itself (note that only two properties are used to > simplify the example): > > ? ?public final class MyClass { > > ? ? ? ?private final String name; > ? ? ? ?private final int age; > > ? ? ? ?private MyClass(Builder b) { > ? ? ? ? ? ?this.name = b.name; > ? ? ? ? ? ?this.age = b.age; > ? ? ? ?} > > ? ? ? ?public static class Builder { > > ? ? ? ? ? ?private String name; > ? ? ? ? ? ?private int age; > > ? ? ? ? ? ?/** > ? ? ? ? ? ? * Name to set. > ? ? ? ? ? ? */ > ? ? ? ? ? ?public Builder setName(String name) { > ? ? ? ? ? ? ? this.name = name; > ? ? ? ? ? ? ? return this; > ? ? ? ? ? ?} > > ? ? ? ? ? ?/** > ? ? ? ? ? ? * Age to set > ? ? ? ? ? ?*/ > ? ? ? ? ? ?public Builder setAge(int age) { > ? ? ? ? ? ? ? ?this.age = age; > ? ? ? ? ? ? ? ?return this; > ? ? ? ? ? ?} > > ? ? ? ? ? ?public MyClass build() { > ? ? ? ? ? ? ? return new MyClass(this); > ? ? ? ? ? ?} > ? ? ? ?} > ? ?} > > Objects can then be constructed in the following manner: > > ? ?MyClass obj = new MyClass.Builder().setName("Fred").setAge(53).build(); > > However, the use of a builder requires additional code, and all parameters > are effectively optional from the perspective of the compiler (it cannot > easily check that all of the required setter methods have been called), so > bugs may occur where parameter values are not set. ?Note that runtime checks > can be made to ensure that all property values are set, but they involve > additional work and cannot be used by the compiler (though static analysis > of the code in conjunction with annotations might be able to repeat many of > these checks). > > There are also many ways to implement named parameters that are different to > the solution proposed here. ?These include: > > Implement optional named parameters on all methods: ?This avoids the need > for the @PublicParameterNames annotation, but may mean inconsistent usage of > named parameters - the annotation is also a suggestion for the use of named > parameters by the caller (which IDEs can also make use of). ?This will also > highlight the difference to classfiles compiled with earlier versions of > Java, where named parameters cannot be used at all (since it will then not > be obvious when named parameters can and cannot be used). > > Add parameter names to the classfile as 'fundamental' method metadata rather > than as annotations: This may allow closer integration of the named > parameters with the rest of the language, but its impact on the rest of the > language (and JVM) is much greater. ?The same inconsistencies and > incompatibilities described in the previous alternative would also apply. > In addition, the use of annotations should not preclude the subsequent > modification of classfiles in a later release - the annotations could still > remain (at a potential cost of some duplication). > > EXAMPLES > > SIMPLE EXAMPLE: > > Constructor declaration: > > ? ?@PublicParameterNames > ? ?public MyClass(String name, int age) { .... > > Constructor use: > > ? ?MyClass obj = new MyClass(name: "Fred", age: 53); > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > The full class definition from the simple example is shown below, as a > contrast to that provided in the Builder example. > > ? ?public final class MyClass { > > ? ? ? ?private final String name; > ? ? ? ?private final int age; > > ? ? ? ?/** > ? ? ? ? * @param name Name to set > ? ? ? ? * @param age Age to set > ? ? ? ? */ > > ? ? ? ?@PublicParameterNames > ? ? ? ?public MyClass(String name, int age) { > ? ? ? ? ? ?this.name = name; > ? ? ? ? ? ?this.age = age; > ? ? ? ?} > ? ?} > > DETAILS > > SPECIFICATION: > > The @PublicParameterNames annotation is used on a constructor or method to > allow named parameters to be used when calling it. ?It can also be applied > to a class or package to apply to all methods within. ?Similarly, a > @NoParameterNames annotation can be used on a constructor, method, or class > to override the use of @PublicParameterNames at a higher level. > > The compiler can then automatically generate a > @PublicParameterName(value="parameter-name") annotation for each affected > method. ?These can then be used by the compiler (and IDE) to validate the > parameter names used by callers of the method or constructor. > > The use of parameter names by callers is always optional (primarily for > backwards compatibility). ?However, parameter names cannot be used for some > parameters and not others (this would make the code harder to read). > > Parameters must always be specified in the same order regardless of whether > parameter names are used - parameter reordering by callers is not allowed > (reordering would make overloading difficult, and is not really necessary). > > Inheritance: Neither the @PublicParameterNames annotation (and > @NoParameterNames annotation), or the names of the parameters themselves, > need to be inherited. ?This is because only static evaluation of a caller's > parameter names will be applied (rather than at runtime), so the callers > parameter names only need to match those of the declared type of the > target. ?However, it would still be advisable to reuse the same parameter > names and annotations when overriding a method (IDEs could help with this). > > COMPILATION: > > The compiler must automatically generate a > @PublicParameterName(value="parameter-name") annotation for each method and > constructor annotated with @PublicParameterNames (or whose the parent class > or package is annotated with @PublicParameterNames and the child class or > method does not override it with @NoParameterNames). > > For example: > > ? ?int myMethod(int param1, String param2) > > Would effectively become: > > ? ?int myMethod(@PublicParameterName("param1") int param1, > @PublicParameterName("param2") String param2) > > Method-calling syntax would need to change, using a colon to separate the > parameter name and value where the are used. ?For example: > > ? MyClass obj = new MyClass(name: "Fred", age: 53); > > When a method caller uses parameter names, the compiler must check that > those parameter names exactly match the value of generated > @PublicParameterName annotations of the target method or constructor. ?It is > a compilation error if they do not match or the target method or constructor > does not have named parameters. > > IDEs can use the @PublicParameterNames and @NoParameterNames annotations (or > @PublicParameterName directly) to automatically insert the relevant > parameter names as part of code-completion. ?Additional refactoring support > would also be required to enable parameter names to be renamed, or added and > removed completely. > > Frameworks such as Spring can use the same annotations to allow objects to > be created from their configuration files using named parameters to > constructors and factory methods. ?Currently they only allow objects to be > created from configuration files as JavaBeans (with setter methods) or with > ordered (and unnamed) parameters. > > TESTING: > > The feature can be tested by compiling and running programs that exercise > the feature. > > LIBRARY SUPPORT: > > No. > > REFLECTIVE APIS: > > java.lang.reflect.Method and java.lang.reflect.Constructor could be enhanced > with new methods that return parameter names. ?However, that is not required > to successfully implement the proposal. > > OTHER CHANGES: > > No. ?The use of named parameters is always optional. ?The javadoc tool > already documents parameter names. ?Other tools/libraries might benefit from > these changes, but their use is not required. > > MIGRATION: > > The @PublicParameterNames annotation (and @NoParameterNames annotation) > simply needs to be added to the appropriate methods. ?IDEs could then > suggest the use of parameter names for the method's callers, and apply the > changes automatically. > > COMPATIBILITY > > BREAKING CHANGES: > > No. > > EXISTING PROGRAMS: > > The changes required by this feature should be transparent to existing > source and class files if annotations are used internally to describe the > named parameters. ?I am not sure what the impact would be otherwise. > > REFERENCES > > EXISTING BUGS: > > 4124331 (though it is set to 11-Closed, Will Not Fix, request for > enhancement, and from 1998) > > From markmahieu at googlemail.com Sat Mar 21 09:37:32 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 16:37:32 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> Message-ID: Hi Josh, 2009/3/21 Joshua Bloch > What if you have an interface that extends an interface that extends the > magic marker? There should be nothing wrong with that. While there may be > some easy way to specify this (and give it reasonable semantics) it isn't > jumping out at me. If anyone has any clever ideas along these lines, I'd > love to know. > I'm probably missing the point, but doesn't the JLS generally use the phrase 'is a subtype of' to describe this kind of relationship? Mark From lapsus63 at gmail.com Sat Mar 21 09:47:10 2009 From: lapsus63 at gmail.com (Olivier Chorier) Date: Sat, 21 Mar 2009 17:47:10 +0100 Subject: PROPOSAL: Elvis operator In-Reply-To: <28bca0ff0903210814s5253b9das125c3fdb45c0cf5@mail.gmail.com> References: <49C4E8DE.4040803@joda.org> <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> <28bca0ff0903210814s5253b9das125c3fdb45c0cf5@mail.gmail.com> Message-ID: Oh, ok, I get it : Ex. : int value = object.getSubObject().getValue() ?: -1 ; So, I'm not sure the use of .? to be necessary. What do you think about an explicit ((MyObject) null)... ?: defValue; Marek told: *< subObject = object.?getSubObject() ?: default;>>* --> "default" would have to be cast as SubObject, wouldn't it ? Finally, another idea could be not to use '?:' neither '.?' but a reversed way to use: int value = object?.getSubObject()?.getValue()? : -1 - object null ? return -1; - object.getSubObject() null ? return -1; - object.getSubObject().getValue() null ? return -1; But it implies the multiple use of '?', which is in my opinion not very sexy (but more detailed and "configurable") 2009/3/21 Marek Kozie? > W dniu 21 marca 2009 16:00 u?ytkownik Olivier Chorier > napisa?: > > > > Ok, what about : > > > > int value ?= object.getSubObject().getValue() : -1; > > > > Pros : > > - I think the compiler could easily retranscript it using > > - Much more readable > > > > Cons : > > - The potential problem is that the "interpretation" differs from an &= > or += operator > > > > It's ok for me, in this case. > > But did you ever wander why NPE is so common? Isn't that because > people do not want write so much if-s and declare so many one time > used variables. > > but ?: can give something nice: > void f(Some some){ > ( some.getOut ?: defOut ).write(...); > ... > } > > while ?= would require to: > void f(Some some){ > OutputStream out ?= some.getOut : defOut; > out.write(...); > // Now we need worry for 'out' till end of function. > ... > } > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From rssh at gradsoft.com.ua Sat Mar 21 09:47:24 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sat, 21 Mar 2009 18:47:24 +0200 (EET) Subject: PROPOSAL: Named method parameters In-Reply-To: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> Message-ID: <24d31156a0f60c01c53cd886f6e1d55a.squirrel@wmail.gradsoft.ua> Great, One small note: I see requirements to programmer: - pass parameters at same order - write @PublicParameterNames in all places, where can be parameter names: too restrictive. 1. Are really ordering parameters by names in call is difficult task ? In worse case it is one extra loop. 2. For choosing policy to apply: parameter names by default if this is possible, looks for me, much cleaner. Also note, that exists implementation of embedding parameter names into classfile and accessing ones via extensions of reflection API http://paranamer.codehaus.org/ Which (I think) can be mention here. > I'd like to propose the implementation of optionally named method > parameters, and suggest that they are particularly useful when creating > immutable objects (which are important in our increasingly concurrent > world). > > Note that this is a topic that seems to have been considered before (see > the > note in http://paulhammant.com/blog/announcing_paranamer.html which > suggests > that it was even considered for Java 6), but I can't see it in the current > list of Java 7 changes or in the Project Coin mailing list archives > (though > others have also discussed it in relation to Java 7, such as Alex Miller > in > http://tech.puredanger.com/2007/08/15/dr-java7/ and > http://tech.puredanger.com/2007/10/11/java7-roundup-32/). Therefore I am > proposing it here - I think that it is an important change (unless anyone > can suggest how I can reasonably create an immutable object with four or > more properties without using a Builder or a list of unnamed parameters). > > Also note that other relevant references include: > http://blogs.sun.com/abuckley/entry/named_parameters (which discusses why > parameter reordering might be difficult), > http://beust.com/weblog/archives/000096.html (which suggests that we do > not > need named parameters, but really just shows the use of the Builder > pattern > which has limitations). > > > Named method parameters > > AUTHOR(S): > > Paul Martin > > OVERVIEW > > FEATURE SUMMARY: > > Named parameters allow a method or constructor caller to explicitly state > the parameter name of each parameter value passed to the method or > constructor. Without named parameters, only the order of the parameter > values is significant (and it may not be clear what each value > represents). > > MAJOR ADVANTAGE: > > This is a relatively simple way of introducing named parameters to the > Java > platform. > > MAJOR BENEFIT: > > Named parameters allow method calls with relatively long lists of > parameters > (greater than 3) to be understood by developers. This can also facilitate > the direct use of constructors and factory methods to create immutable > objects, where otherwise Builders or mutable JavaBeans would be required. > > MAJOR DISADVANTAGE: > > The syntax for method calls would change to allow both named and unnamed > parameters to be used. > > Named parameters might be used too often, which could unnecessarily > clutter > source files. > > Metadata to store the names of the parameters must be added to classfiles > (for example as annotations). > > The use of annotations to describe named parameters would mean that no > metadata would be stored about the parameter names used by the method > caller, and so no runtime checks to match the parameter names being used > could be made (only compile-time). If the parameter names change (but > otherwise the method signature does not), then the method caller would not > be aware of the changes until it was recompiled. Note that this is > existing > behaviour for unnamed parameters, and would only be a problem if the > meaning > of the parameters also changes (which should indicate that the caller > would > need to change anyway, but this would not be detected automatically at > runtime). > > ALTERNATIVES: > > Unnamed parameters can make the same method calls as named parameters, but > if there are many parameters they are harder to understand and prone to > ordering-related bugs (particularly for primitive types or Strings). > > The Builder pattern can be used to simulate named parameters in > constructors/factory methods. For example the following class uses a > Builder to initialise itself (note that only two properties are used to > simplify the example): > > public final class MyClass { > > private final String name; > private final int age; > > private MyClass(Builder b) { > this.name = b.name; > this.age = b.age; > } > > public static class Builder { > > private String name; > private int age; > > /** > * Name to set. > */ > public Builder setName(String name) { > this.name = name; > return this; > } > > /** > * Age to set > */ > public Builder setAge(int age) { > this.age = age; > return this; > } > > public MyClass build() { > return new MyClass(this); > } > } > } > > Objects can then be constructed in the following manner: > > MyClass obj = new > MyClass.Builder().setName("Fred").setAge(53).build(); > > However, the use of a builder requires additional code, and all parameters > are effectively optional from the perspective of the compiler (it cannot > easily check that all of the required setter methods have been called), so > bugs may occur where parameter values are not set. Note that runtime > checks > can be made to ensure that all property values are set, but they involve > additional work and cannot be used by the compiler (though static analysis > of the code in conjunction with annotations might be able to repeat many > of > these checks). > > There are also many ways to implement named parameters that are different > to > the solution proposed here. These include: > > Implement optional named parameters on all methods: This avoids the need > for the @PublicParameterNames annotation, but may mean inconsistent usage > of > named parameters - the annotation is also a suggestion for the use of > named > parameters by the caller (which IDEs can also make use of). This will > also > highlight the difference to classfiles compiled with earlier versions of > Java, where named parameters cannot be used at all (since it will then not > be obvious when named parameters can and cannot be used). > > Add parameter names to the classfile as 'fundamental' method metadata > rather > than as annotations: This may allow closer integration of the named > parameters with the rest of the language, but its impact on the rest of > the > language (and JVM) is much greater. The same inconsistencies and > incompatibilities described in the previous alternative would also apply. > In addition, the use of annotations should not preclude the subsequent > modification of classfiles in a later release - the annotations could > still > remain (at a potential cost of some duplication). > > EXAMPLES > > SIMPLE EXAMPLE: > > Constructor declaration: > > @PublicParameterNames > public MyClass(String name, int age) { .... > > Constructor use: > > MyClass obj = new MyClass(name: "Fred", age: 53); > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > The full class definition from the simple example is shown below, as a > contrast to that provided in the Builder example. > > public final class MyClass { > > private final String name; > private final int age; > > /** > * @param name Name to set > * @param age Age to set > */ > > @PublicParameterNames > public MyClass(String name, int age) { > this.name = name; > this.age = age; > } > } > > DETAILS > > SPECIFICATION: > > The @PublicParameterNames annotation is used on a constructor or method to > allow named parameters to be used when calling it. It can also be applied > to a class or package to apply to all methods within. Similarly, a > @NoParameterNames annotation can be used on a constructor, method, or > class > to override the use of @PublicParameterNames at a higher level. > > The compiler can then automatically generate a > @PublicParameterName(value="parameter-name") annotation for each affected > method. These can then be used by the compiler (and IDE) to validate the > parameter names used by callers of the method or constructor. > > The use of parameter names by callers is always optional (primarily for > backwards compatibility). However, parameter names cannot be used for > some > parameters and not others (this would make the code harder to read). > > Parameters must always be specified in the same order regardless of > whether > parameter names are used - parameter reordering by callers is not allowed > (reordering would make overloading difficult, and is not really > necessary). > > Inheritance: Neither the @PublicParameterNames annotation (and > @NoParameterNames annotation), or the names of the parameters themselves, > need to be inherited. This is because only static evaluation of a > caller's > parameter names will be applied (rather than at runtime), so the callers > parameter names only need to match those of the declared type of the > target. However, it would still be advisable to reuse the same parameter > names and annotations when overriding a method (IDEs could help with > this). > > COMPILATION: > > The compiler must automatically generate a > @PublicParameterName(value="parameter-name") annotation for each method > and > constructor annotated with @PublicParameterNames (or whose the parent > class > or package is annotated with @PublicParameterNames and the child class or > method does not override it with @NoParameterNames). > > For example: > > int myMethod(int param1, String param2) > > Would effectively become: > > int myMethod(@PublicParameterName("param1") int param1, > @PublicParameterName("param2") String param2) > > Method-calling syntax would need to change, using a colon to separate the > parameter name and value where the are used. For example: > > MyClass obj = new MyClass(name: "Fred", age: 53); > > When a method caller uses parameter names, the compiler must check that > those parameter names exactly match the value of generated > @PublicParameterName annotations of the target method or constructor. It > is > a compilation error if they do not match or the target method or > constructor > does not have named parameters. > > IDEs can use the @PublicParameterNames and @NoParameterNames annotations > (or > @PublicParameterName directly) to automatically insert the relevant > parameter names as part of code-completion. Additional refactoring > support > would also be required to enable parameter names to be renamed, or added > and > removed completely. > > Frameworks such as Spring can use the same annotations to allow objects to > be created from their configuration files using named parameters to > constructors and factory methods. Currently they only allow objects to be > created from configuration files as JavaBeans (with setter methods) or > with > ordered (and unnamed) parameters. > > TESTING: > > The feature can be tested by compiling and running programs that exercise > the feature. > > LIBRARY SUPPORT: > > No. > > REFLECTIVE APIS: > > java.lang.reflect.Method and java.lang.reflect.Constructor could be > enhanced > with new methods that return parameter names. However, that is not > required > to successfully implement the proposal. > > OTHER CHANGES: > > No. The use of named parameters is always optional. The javadoc tool > already documents parameter names. Other tools/libraries might benefit > from > these changes, but their use is not required. > > MIGRATION: > > The @PublicParameterNames annotation (and @NoParameterNames annotation) > simply needs to be added to the appropriate methods. IDEs could then > suggest the use of parameter names for the method's callers, and apply the > changes automatically. > > COMPATIBILITY > > BREAKING CHANGES: > > No. > > EXISTING PROGRAMS: > > The changes required by this feature should be transparent to existing > source and class files if annotations are used internally to describe the > named parameters. I am not sure what the impact would be otherwise. > > REFERENCES > > EXISTING BUGS: > > 4124331 (though it is set to 11-Closed, Will Not Fix, request for > enhancement, and from 1998) > > From paul.martin at gmail.com Sat Mar 21 09:48:54 2009 From: paul.martin at gmail.com (Paul Martin) Date: Sat, 21 Mar 2009 16:48:54 +0000 Subject: PROPOSAL: Named method parameters In-Reply-To: <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> Message-ID: <4ce75f920903210948m18c09280y5c091e64349d127d@mail.gmail.com> Hi, > Annotations should not affect the semantics of any other language > construct. I think if you want to add support for named parameters, > the support should be available everywhere. Yes, perhaps this is contentious. I suppose that I had a few areas that I wanted to address: - Ease of implementation - using annotations seems like a relatively low-impact way of getting named parameters (both in adding and retrieving the parameter name metadata). It is perhaps less powerful than integrating them directly into the core of the language, but that wouldn't fit within the scope of Coin (and I'm not sure that I'd want to wait for Java 8 until I had a good solution for creating immutable objects). - Documentation / IDE support - using annotations can also suggest where named parameters should used. I thought that the annotations are somewhat like @Override, in that we are not changing much of the behaviour of the compiled classes (other than automatically including appropriate generated @PublicNamedParameter annotation), since the selection of the method to be called and the order of the parameters will not change, but instead the annotations are primarily concerned with validating the code. The alternative would be to allow named parameters to be used to call all methods. This could still be implemented by automatically generating @PublicNamedParameter annotations, so wouldn't necessarily affect the proposal much (and @PublicNamedParameters annotations could also be used on methods, etc. for documentation / IDE suggestion purposes if really required). However I couldn't think of a good solution when working with legacy class files (compiled prior to Java 7), since they would not support named parameters but it would not be obvious to a developer why they didn't. The annotations would at least make that explicit. Do you think that there (language) areas that would not be covered by the use of named parameters? > What are the changes to the spec for overload resolution? I thought that named parameters should not affect overload resolution at all - so you could not overload based upon parameter names, you would only be able to overload based upon parameter types. Named parameters can then really just be thought of as providing some level of code documentation and verification to the compiler, along with support for runtime frameworks (such as Spring) to similarly verify parameter names. Do you think that named parameters in principle are a good/reasonable idea? Thanks, Paul From tim at peierls.net Sat Mar 21 09:54:02 2009 From: tim at peierls.net (Tim Peierls) Date: Sat, 21 Mar 2009 12:54:02 -0400 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> Message-ID: <63b4e4050903210954h3895158kb4b1682c3d7ddc6d@mail.gmail.com> On Sat, Mar 21, 2009 at 12:08 PM, Joshua Bloch wrote: > What about the magic marker interface (if you'll pardon my wordplay)? This > may be difficult to specify. > There are spec issues to resolve with the magic package approach, too: What do you do if an interface type extends two or more interfaces from java.lang.auto? Probably not hard to find reasonable answers, but you could say the same about the magic marker approach. I think the hard question is how much extensibility to allow up front. Magic Marker would make language libertarians happy, possibly at the risk of increased abuse of ARM. Magic Package is the conservative response; it focuses on the known problems, while preventing all but the very determined from creating their own auto types (with bootclasspath trickery). I suppose Magic Package doesn't rule out later on granting new magic powers to types in java.lang.auto, including, say, the magic marker power. --tim From fw at deneb.enyo.de Sat Mar 21 10:00:10 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 21 Mar 2009 18:00:10 +0100 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> (Joshua Bloch's message of "Sat, 21 Mar 2009 09:08:49 -0700") References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> Message-ID: <87hc1mdd5x.fsf@mid.deneb.enyo.de> * Joshua Bloch: > I think it might be easier to specify (and implement the package variant. > Roughly speaking, the legal types for "manageable resources" are those that > are assignment compatible with one and only one of the classes in > java.lang.auto. While it's not generally possible to enumerate over classes > in a package, the compiler can be (are, in fact) tied to particular versions > of the platform so this shouldn't present too big a problem (though it could > limit extensibility by JRE hackers). If the interface has to reside in a package java.lang.auto.disposer, you could name the interface by the name of the method, and generate implementations automatically. For instance, java.lang.auto.disposer.foo would behave as if it were implemented as package java.lang.auto.disposer; public interface foo { foo() throws Exception; } java.io.Closeable would look like this: package java.io; import java.io.IOException; public interface Closeable extends java.lang.auto.disposer.close { public void close() throws IOException; } If some other language mechanism eventually made this obsolete, those generated interfaces could likely incorporate this mechanism automatically. But perhaps this is too cute (but I think similar approaches where proposed to deal with tuples). From paul.martin at gmail.com Sat Mar 21 10:03:37 2009 From: paul.martin at gmail.com (Paul Martin) Date: Sat, 21 Mar 2009 17:03:37 +0000 Subject: PROPOSAL: Named method parameters In-Reply-To: <24d31156a0f60c01c53cd886f6e1d55a.squirrel@wmail.gradsoft.ua> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <24d31156a0f60c01c53cd886f6e1d55a.squirrel@wmail.gradsoft.ua> Message-ID: <4ce75f920903211003o542bd2a2sbbc91d4507203cfd@mail.gmail.com> Hi, Thanks. > One small note: I see requirements to programmer: > - pass parameters at same order I tried to state that in the specification section, though I probably was not clear enough (Neal Gafter also had a similar comment about overloading). I thought that nothing should change about the method call (ordering, overloading) except that the parameter names would also be checked to ensure that they matched. Maybe it is similar to the type erasure of generics - they are significant when compiling, but not so much at runtime. > - write @PublicParameterNames in all places, where can be parameter names: > too restrictive. I think that this may have been a contentious issue in the past - it seems that paranamer was created because its authors didn't want to use such annotations (which seems to have been discussed for Java 6) - see http://paulhammant.com/blog/announcing_paranamer.html However (for the reasons that I said in reply to Neal earlier in this thread), I do like the idea of using annotations as documentation, to prompt IDE suggestions, and to distinguish between code compiled for Java 7 (which would support named parameters) and code compiled for earlier versions which would not. > 1. Are really ordering parameters by names in call is difficult task ? In > worse case it is one extra loop. > 2. For choosing policy to apply: parameter names by default if this is > possible, looks for me, much cleaner. In theory this could be done, though the overloading and overriding rules would then become more difficult. What happens if you have two overloaded methods which have the same parameter names and types, but in different orders, for example: void method(int a, String b) and void method(String b, int a) Currently these are treated as separate methods and can be resolved correctly, but if named parameters allowed you to reorder them, then it might be more difficult to choose the correct implementation (particularly if there are other parameters that are not reordered, and/or you have a hierarchy of overridden and overloaded classes). This would also require more extensive language changes (which I think would be out of scope for project Coin). I found the following blog entry from Alexander Buckley which I think nicely explains this in more detail: http://blogs.sun.com/abuckley/entry/named_parameters Also, thanks for mentioning paranamer - I meant to include that in the intro of my email but forgot! From markmahieu at googlemail.com Sat Mar 21 10:29:57 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 17:29:57 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903210954h3895158kb4b1682c3d7ddc6d@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> <63b4e4050903210954h3895158kb4b1682c3d7ddc6d@mail.gmail.com> Message-ID: 2009/3/21 Tim Peierls > > I think the hard question is how much extensibility to allow up front. > Magic Marker would make language libertarians happy, possibly at the risk of > increased abuse of ARM. Magic Package is the conservative response; it > focuses on the known problems, while preventing all but the very determined > from creating their own auto types (with bootclasspath trickery). > Is there any experience from the introduction of java.lang.Iterable that might be useful to review in this context? Iterable gave an opening for people to misuse the foreach construct, but I've seen very few examples of that happening, personally (and none that I can recall in real, live code-bases). I suppose Magic Package doesn't rule out later on granting new magic powers > to types in java.lang.auto, including, say, the magic marker power. > > --tim > Yes... I think that would be unlikely in practice though. If the set of disposable interfaces provided with Java 7 is restricted, future APIs would naturally use those even if the method names aren't ideal for their specific case. Mark From scolebourne at joda.org Sat Mar 21 10:33:52 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 21 Mar 2009 17:33:52 +0000 Subject: Enhanced for each loop iteration control Message-ID: <49C52500.4000706@joda.org> Enhanced for each loop iteration control This proposal extends the for each loop to allow access to meta data including the index and the remove method. (This proposal doesn't really go into enough detail - with JSR-310 my time here is limited. I'd hope that there is just about enough though....) ----------------------------------------------------------------------------------- Enhanced for each loop iteration control AUTHOR(S): Stephen Colebourne *OVERVIEW* FEATURE SUMMARY: Extends the Java 5 for-each loop to allow access to the loop index, whether this is the first or last iteration, and to remove the current item. MAJOR ADVANTAGE: The for-each loop is almost certainly the most new popular feature from Java 5. It works because it increases the abstraction level - instead of having to express the low-level details of how to loop around a list or array (with an index or iterator), the developer simply states that they want to loop and the language takes care of the rest. However, all the benefit is lost as soon as the developer needs to access the index or to remove an item. The original Java 5 for each work took a relatively conservative stance on a number of issues aiming to tackle the 80% case. However, loops are such a common form in coding that the remaining 20% that was not tackled represents a significant body of code. The process of converting the loop back from the for each to be index or iterator based is painful. This is because the old loop style if significantly lower-level, more verbose and less clear. It is also painful as most IDEs don't support this kind of 'de-refactoring'. MAJOR BENEFIT: A common coding idiom is expressed at a higher abstraction than at present. This aids readability and clarity. Accessing the index currently requires using an int based loop, or placing a separate int counter outside the loop (which then remains in scope after the loop). The proposed solution doesn't result in manual manipulation of the index. Accessing the iterator remove requires using an iterator based loop. With generics this is remarkably verbose. The proposed solution is significantly shorter and cleaner. MAJOR DISADVANTAGE: The enhanced for each loop is complicated with additional functionality. (This is mitigated by being easy and obvious to use) More code is generated magically by the compiler. (This is mitigated by a simple desugaring) ALTERNATIVES: Use the existing language constructs, typically the standard for loop. Use BGGA/JCA style closures, with control statements. It should be noted that these are consistently the most controversial parts of the closure debate, making the 'let's wait for closures' argument against this proposal weaker (as any final closures implementation may not include control statements). *EXAMPLES* SIMPLE EXAMPLE: StringBuilder buf = new StringBuilder(); for (String str : list : it) { if (str == null) { it.remove(); } } whereas, today we write: StringBuilder buf = new StringBuilder(); for (Iterator it = list.iterator(); it.hasNext();) { String str = it.next(); if (str == null) { it.remove(); } } ADVANCED EXAMPLE: Example1: for (String str : list : it) { System.out.println("Row " + it.index() + " has the value " + str); } whereas, today we might write: int index = 0; for (String str : list) { System.out.println("Row " + index + " has the value " + str); index++; } or for (int i = 0; i < list.size(); i++) { String str = list.get(i); System.out.println("Row " + index + " has the value " + str); } Example 2: StringBuilder buf = new StringBuilder(); for (String str : list : it) { if (it.isFirst()) { buf.append(str); } else { buf.append(", ").append(str); } } StringBuilder buf = new StringBuilder(); for (String str : list : it) { if (it.isLast()) { buf.append(str); } else { buf.append(str).append(", "); } } *DETAILS* SPECIFICATION: Lexical: No new tokens are added. The colon token is reused in the extended enhanced for each statement. Syntax: EnhancedForStatement: for ( VariableModifiersopt Type Identifier : Expression) Statement for ( VariableModifiersopt Type Identifier : Expression : Ident) Statement Semantics: The first enhanced for each statement (the current form) will compile as it does today. The extended enhanced for each statement will operate as follows. The iterator control variable is a standard variable declared to be final. It will never be null. The type is dependent on whether the expression is an array or an Iterable. It will either be ArrayIterationControl or IterableIterationControl. The type is not specified as it is redundent information, ie. the type is inferred. It is scoped for the life of the loop. public final class IterableIterationControlIterator { public IterableIterationControlIterator(Iterable iterable) { this.control = new IterableIterationControl(iterable.iterator()); } public boolean hasNext() { return control.hasNext() } public T next() { return control.next() } public IterableIterationControl control() { return control } } public final class IterableIterationControl { public IterableIterationControl(Iterator iteratorToWrap) { this.it = iteratorToWrap; } boolean hasNext() { return it.hasNext() } T next() { originalIndex++; if (lastWasRemoved) { lastWasRemoved = false } else { index++ } return it.next() } public T remove() { removed++; lastWasRemoved = true; return it.remove() } public int index() { return index } public int originalIndex() { return originalIndex } public boolean isFirst() { return index == 1 } public boolean isLast() { return it.hasNext() == false } } public final class ArrayIterationControlIterator { public ArrayIterationControlIterator(T[] array) { this.control = new ArrayIterationControl(array); } public boolean hasNext() { return control.hasNext() } public T next() { return control.next() } public ArrayIterationControl control() { return control } } public final class ArrayIterationControl { public ArrayIterationControl(T[] array) { this.array = array; } boolean hasNext() { return index < array.length; } T next() { return array[++index]; } public int index() { return index - 1; } public boolean isFirst() { return index == 1; } public boolean isLast() { return index == array.length; } } Exception analysis: The method remove() on the iteration control variable can throw an UnsuportedOperationException. However, this is no different from any other method call. Definite assignment: The new variable iteration control variable is a final variable that is definitely assigned from creation. COMPILATION: The extended enhanced for each loop is implemented by wrapping the two control classes around the Iterable or the array. The Iterable design is desugared from: for (T item : iterable : control) { ... } to: { IterableIterationControlIterator $it = new IterableIterationControlIterator(iterable); IterableIterationControl control = $it.control(); while ($it.hasNext()) { T item = $it.next(); ... } } The array design is desugared similarly: { ArrayIterationControlIterator $it = new ArrayIterationControlIterator(iterable); ArrayIterationControl control = $it.control(); while ($it.hasNext()) { T item = $it.next(); ... } } There is the option to optimise this if the iteration control variable is not assigned to any other variable or passed to any other method. However, that is out of scope for now. TESTING: Testing will be similar to the enhanced for loop. Arrays and Iterables of various types and sizes will be used. The null expression will also be tested. LIBRARY SUPPORT: Yes, as detailed above. REFLECTIVE APIS: No. OTHER CHANGES: The javac tree API would need to be updated to model the change. MIGRATION: Migration is not required. However, an IDE refactoring could now convert more int and Iterator based for loops than it does at present. *COMPATIBILITY* BREAKING CHANGES: No breaking changes are known using this conversion scheme. EXISTING PROGRAMS: This conversion is pure syntax sugar, so there are no known interactions with existing programs. *REFERENCES* EXISTING BUGS: I searched the bug database, but nothing came up (which is surprising). URL FOR PROTOTYPE: None DOCUMENTS: [1] Stephen Colebourne's blog: http://www.jroller.com/scolebourne/entry/java_7_for_each_loop [2] Stephen Colebourne's original writeup: http://docs.google.com/Edit?docID=dfn5297z_15ck7x5ghr *DESIGN ISSUES* There are numerous alternative ways in which this feature can be added. These include: - using the keyword: for (String str : list) { for.remove(); // problem is nested for loops } - using a label as a psuedo-variable: it: for (String str : list) { it:remove(); // note colon and not dot } - using an additional clause before the for each colon: for (String str, int index : list) { // no access to remove, and conflicts for for each for maps } The chosen solution involves simple Java classes, and a simple desugar. The downside of the chosen solution is performance, as it involves creating two wrapping objects and routing hasNext() and next() via additional layers of method calls. A possible extension would be for the compiler to identify if the iteration control variable is not passed to another method. If so, then the code could be all be generated inline. From fw at deneb.enyo.de Sat Mar 21 10:34:08 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 21 Mar 2009 18:34:08 +0100 Subject: PROPOSAL: Named method parameters In-Reply-To: <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> (Neal Gafter's message of "Sat, 21 Mar 2009 09:26:20 -0700") References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> Message-ID: <87tz5mbx0v.fsf@mid.deneb.enyo.de> * Neal Gafter: > Annotations should not affect the semantics of any other language > construct. I think if you want to add support for named parameters, > the support should be available everywhere. This is very difficult because so far, parameter names are an implementation detail and might differ across implementations (and within a class hierarchy). Standard ML kind of solves the issue by having a lightweight syntax for constructing record values, and I wonder if this isn't the right approach to fit named parameters on an existing language. From develop4lasu at gmail.com Sat Mar 21 10:56:25 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 18:56:25 +0100 Subject: PROPOSAL: Named method parameters In-Reply-To: <87tz5mbx0v.fsf@mid.deneb.enyo.de> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> Message-ID: <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> Builders are really great tool, but they need to be written manually. In other way there will be problem, if final object need contains data and builder only key for that data. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Sat Mar 21 11:01:56 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 21 Mar 2009 11:01:56 -0700 Subject: PROPOSAL: Extend Scope of Imports to Include Package Annotations In-Reply-To: <1236591753.49b4e489344d7@www.paradise.net.nz> References: <1236591753.49b4e489344d7@www.paradise.net.nz> Message-ID: <49C52B94.1050403@sun.com> Hi Bruce. I've discussed your proposal with Alex and we agree this is a fine change to incorporate under JLS maintenance. Thanks for sending this in, -Joe brucechapman at paradise.net.nz wrote: > html version at http://docs.google.com/Doc?id=dcvp3mkv_3fc5hqngp > > Extend Scope of Imports to Include Package Annotations > > AUTHOR(S): Bruce Chapman > > OVERVIEW > > FEATURE SUMMARY: > JLS3 says Import statements do not apply to package statements and therefore by > implication they do not apply to annotations on package statements. However > JDK6's javac does use import statements to resolve types in package annotations, > for which a Bug has been accepted. This proposal is to change the language > specification to be consistent with the compiler in order to yield a more > pragmatic solution than fixing the bug in the compiler. > > > MAJOR ADVANTAGE: > > Annotations on packages will no longer need to fully qualify type names for > annotation types, and for any class literals used as annotation values. > > MAJOR DISADVANTAGE: > With millions of developers someone somewhere might find this counterproductive. > I cannot imagine how. > > > ALTERNATIVES: > > The alternative to changing the language spec is to fix the bug, which may well > be a breaking change for anyone who has inadvertently or knowingly taken > advantage of the bug. > > EXAMPLES > SIMPLE EXAMPLE: > > @Generated("something") package a.b; > > import java.lang.annotations.Generated; > > is currently illegal and must be written as > > @java.lang.annotations.Generated("something") package a.b; > > ADVANCED EXAMPLE: > > > Currently this is illegal > > @Deprecated package my.package; > > because the implicit import of java.lang.Deprecated is out of scope of the > package statement's annotation. This change would bring all imports into scope > and make the example legal (regardless of any arguments for or against > annotating a package as deprecated - it's just an example) > > DETAILS > SPECIFICATION: > > > JLS Section 7.5 needs additions (in bold) > > The scope of a type imported by a single-type-import declaration (?7.5.1) or > a type-import-on-demand declaration (?7.5.2) is all the class and interface type > declarations (?7.6) in the compilation unit in which the import declaration > appears, as well as any annotations on the compilation unit's package statement > if present. > > and > > The scope of the entities(s) it introduces specifically does not include the > package statement's PackageName, other import declarations in the current > compilation unit, or other compilation units in the same package. > > COMPILATION: > > JDK 6 already implements this feature (unless bug 6470991 has been fixed). > Implementation is just a JLS change. If the bug has been fixed, implementation > involves reversing the changes that fixed the bug. > > TESTING: > > Check that annotations are resolved using import statements. > > Check both annotation types and class literals used in annotation element values. > > Check both implicit imports from java.lang as well as single-type-import and > type-import-on-demand imports. > > Check that an import correctly shadows a type with the same simple name in the > same package. > > LIBRARY SUPPORT: > > No library support required. > > REFLECTIVE APIS: > > No change > > OTHER CHANGES: > none > MIGRATION: > Tools can apply their existing import statement management logic to annotations > on package statements. > > COMPATIBILITY > BREAKING CHANGES: > > It is possible to contrive a breaking change where a single-type-import > declaration d in a compilation unit c of package p that imports a type named n > shadows the declaration of a top level annotation type named n declared in > another compilation unit of p and c's package declaration has an annotation > using the type n. Prior to this change n should mean p.n and after this change > will refer to the type in d. However the the bug means that it will already be > refering to the type in d. > > > Due to the bug this theoretical situation can be discounted as no worse than the > converse situation caused by fixing the bug. > > EXISTING PROGRAMS: > > This is a compile time name resolution issue and will not affect exisitng source > or class files except as noted under breaking changes. > > > REFERENCES > EXISTING BUGS: > > Bug 6470991 This documents how the compiler differs from the JLS, and behaves > according to this proposal. > > URL FOR PROTOTYPE (optional): > > Due to the bug, the existing JDK can be used as a prototype. > http://java.sun.com/javase/downloads > > > From jjb at google.com Sat Mar 21 11:01:52 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 21 Mar 2009 11:01:52 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> Message-ID: <17b2302a0903211101u74e74c08u48cb0ade7b6cc03d@mail.gmail.com> Mark, On Sat, Mar 21, 2009 at 9:37 AM, Mark Mahieu wrote: > Hi Josh, > > 2009/3/21 Joshua Bloch > >> What if you have an interface that extends an interface that extends the >> magic marker? There should be nothing wrong with that. While there may be >> some easy way to specify this (and give it reasonable semantics) it isn't >> jumping out at me. If anyone has any clever ideas along these lines, I'd >> love to know. >> > > I'm probably missing the point, but doesn't the JLS generally use the > phrase 'is a subtype of' to describe this kind of relationship? > I don't think I did a good job of explaining the problem. Consider this: interface Closeable extends MagicMarker { void close(); } interface Foo extends Closeable { // Must be OK for ARM // Lots of methods } class bar implements Foo { // Must be OK for ARM // Lots of methods } interface Baz extends Foo { // // No new methods } class Qux Implements Foo, Baz { // Probably OK for Arm ] interface Disposable extends MagicMarker { public void dispose(); } class Nope implements Closeable, Disposeable { // Probably not OK for ARM } The problem with Nope is that it contains two "magic methods" (sole parameterless method in an interface that directly extends MagicMarker). Is it sufficient to say that a class must have one and only one magic method to make it eligible for automatic resource management? Is it practical to implement this in the compiler? I dunno. Josh Josh From jjb at google.com Sat Mar 21 11:06:08 2009 From: jjb at google.com (Joshua Bloch) Date: Sat, 21 Mar 2009 11:06:08 -0700 Subject: Feedback and comments on ARM proposal In-Reply-To: <63b4e4050903210954h3895158kb4b1682c3d7ddc6d@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> <63b4e4050903210954h3895158kb4b1682c3d7ddc6d@mail.gmail.com> Message-ID: <17b2302a0903211106m2991ffablc84734006e1dcb94@mail.gmail.com> On Sat, Mar 21, 2009 at 9:54 AM, Tim Peierls wrote: > On Sat, Mar 21, 2009 at 12:08 PM, Joshua Bloch wrote: > >> What about the magic marker interface (if you'll pardon my wordplay)? This >> may be difficult to specify. >> > > There are spec issues to resolve with the magic package approach, too: What > do you do if an interface type extends two or more interfaces from > java.lang.auto? Probably not hard to find reasonable answers, but you could > say the same about the magic marker approach. > I do think it's (a bit) harder with the magic marker approach, as you can have multiple paths to one "root" magic marker interface, as per previous mail. The package would contain a bunch of interfaces each of which has exactly one parameterless method. (Each such method would probably have a name distinct form all of the others, but that's not a hard requirement.) If you implement two or more such interfaces, you lose. That's a pretty simple rule. Happy weekend, Josh From jeremy.manson at gmail.com Sat Mar 21 12:41:11 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sat, 21 Mar 2009 12:41:11 -0700 Subject: PROPOSAL: Elvis operator In-Reply-To: <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> References: <49C4E8DE.4040803@joda.org> <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> Message-ID: <1631da7d0903211241m796ba5a7jffa45828fd61455b@mail.gmail.com> On Sat, Mar 21, 2009 at 7:23 AM, Marek Kozie? wrote: > 2009/3/21 Olivier Chorier > >> I initially thought it was a good idea, but after a bit reflection, I don't >> think it is a real 'plus' compared with the ternary operator. >> >> For example, how would you simplify those lines of code (assuming the coder >> loves ternary operator) : >> >> int value = object == null ? -1 : >> ? ? ? ? ? ? ? ?(object.getSubObject() == null ? -1 : >> ? ? ? ? ? ? ? ? ? ? ? ?(object.getSubObject().getValue() == null ? -1 : >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? object.getSubObject().getValue())); >> >> Does somebody has an idea (excepting using an ugly try-catch statement) to >> write this much clearer ? >> (sorry for code indentation) >> >> >> 2009/3/21 Stephen Colebourne >> >> >> >> You wrong, this should look like: > > int value = object.?getSubObject().?getValue() ?: -1 > It is worth pointing out that after strenuous objection, Stephen took .? out of this proposal. Jeremy From develop4lasu at gmail.com Sat Mar 21 12:45:35 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 20:45:35 +0100 Subject: PROPOSAL: Elvis operator In-Reply-To: <1631da7d0903211241m796ba5a7jffa45828fd61455b@mail.gmail.com> References: <49C4E8DE.4040803@joda.org> <28bca0ff0903210723s355941bfp8b54e0dbb9477f3e@mail.gmail.com> <1631da7d0903211241m796ba5a7jffa45828fd61455b@mail.gmail.com> Message-ID: <28bca0ff0903211245o13b03374qf8010f6d483a164c@mail.gmail.com> W dniu 21 marca 2009 20:41 u?ytkownik Jeremy Manson napisa?: > > It is worth pointing out that after strenuous objection, Stephen took > .? out of this proposal. > > Jeremy > I would say that Elvis operator is taken out. Null-safe is fine. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sat Mar 21 12:52:36 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 20:52:36 +0100 Subject: I need your opinion... Message-ID: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> There is no point in writing a proposal if people will not use it. I have found that some parts of programming are problems for me and for the others, but you might have a different experience so I would like to hear your opinion about listed points. 1. After some time, I found that there was better solution for consider operator: Allow final variables and final Fields (except blank final), to not having explicit Type. Consider operator can help in dealing with generics, which are pain in the as.. I often found that Types took even 50% code, which is insane. Normal: for ( ComparablePair> pair : statisticsCollectors ){ ? } Consider operator: for ( ::pair : statisticsCollectors ){ ? } New final way: for ( final pair : statisticsCollectors ){ ? } New final way & while-each loop: while ( final pair : final iterator = statisticsCollectors.iterator() ){ if ( ! isValid(pair.getKey()) ) iterator.remove( pair ); } 2. Add forget keyword to allow erase variable from current context (block): - For method parameters it's now impossible. - Assigning null to variable is lame and not possible for final variables. - Blocks not always fit to this purpose. 3. Are glue classes hard to understand? 4. Blocks in classes: Peoples often do not use formatters because they do not keep logical order in class structure, this would allow to define proper grouping. class Some{ { // block boo private Boo boo; public Boo getBoo(){ return boo; } public void setBoo(Boo boo){ this.boo = boo; } }//end block } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From John.Rose at Sun.COM Sat Mar 21 13:40:38 2009 From: John.Rose at Sun.COM (John Rose) Date: Sat, 21 Mar 2009 13:40:38 -0700 Subject: I need your opinion... In-Reply-To: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > Allow final variables and final Fields (except blank final), to not > having explicit Type. Yes. Someone should work exactly this (and no more) into a separate proposal, if it hasn't been done already. -- John Alternatives: "? foo" would sort of work since the "?" works, as a wildcard, for some other type uses, but it is way too strange looking. A new declare-and-assign operator would be nice for a wrist- friendly language, but IMO it is too different from existing Java declaration syntaxes. Beyond subjective esthetics, consistency of syntax is important to both mechanical and biological parsers. Meanwhile, "final" variables avoid ambiguities about programmer intention for additional assignments to mutable variables, so "final" works with extra grace for auto-typed variables. From rssh at gradsoft.com.ua Sat Mar 21 13:46:14 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sat, 21 Mar 2009 22:46:14 +0200 (EET) Subject: Enhanced String literal for Java: version 1.4 (final ?) Message-ID: <17813eab9af423648fb4ce01993a90da.squirrel@wmail.gradsoft.ua> Changes from previous release: - removed windowsLf() and unixLf() String member functions. - library changes (i.e. String.platformLf() is implemented) - added reference to LongString annotation implementation by Bruce Chapman AUTHOR(s): Ruslan Shevchenko, Reinier Zwitserloot (if agree) version:1.4 snapshot. OVERVIEW: FEATURE SUMMARY: new string literals in java language: * multiline string literals. * raw string literals without escape processing. Note, that this proposal say nothing about possible embedding expressions in string literals: we belive this can be done on another level (i.e. library level, by extending family of format functions or reusing JSR223 scripting interface or metaprogramming-level, by parsing ready string literal by annotation processor or hight-level compiler pass) MAJOR ADVANTAGE: Possibility more elegant to code strings from other languages, such as sql constructions or inline xml (for multiline strings) or regular expressions (for string literals without escape processing). MAJOR DISADVANTAGE Small increasing of language complexity. ALTERNATIVES: For multiline strings use operations and concatenation methods, such as:
  String,contact("Multiline \n",
                 "string ");
 
or
  String bigString="First line\n"+
                   "second line"
 
For unescaped ('raw') stings - use escaping of ordinary java string. EXAMPLES SIMPLE EXAMPLE: Multiline string:
  StringBuilder sb = new StringBuilder();
  sb.append("""select a from Area a, CountryCodes cc
                where
                   cc.isoCode='UA'
                  and
                   a.owner = cc.country
              """);
  if (question.getAreaName()!=null) {
     sb.append("""and
                  a.name like ?
               """);
     sqlParams.setString(++i,question.getAreaName());
  }
 
instead:
  StringBuilder sb = new StringBuilder();
  sb.append("select a from Area a, CountryCodes cc\n");
  sb.append("where cc.isoCode='UA'\n");
  sb.append("and a.owner=cc.country'\n");
  if (question.getAreaName()!=null) {
     sb.append("and a.name like ?");
     sqlParams.setString(++i,question.getAreaName());
  }
 
 String platformDepended="""q
 """.platformLf();
 
is 'q\n' if run on Unix and 'q\n\r' if run on Windows.
 String platformIndepended="""q
 q""";
 
is always "q\nq". Unescaped String:
 String myParrern=''..*\.*'';
 
instead
 String myParrern="\..*\\.*";
 
 String fname=''C:\Program Files\My Program\Configuration'';
 
instead
 String myParrern="C:\\Program Files\\My Program\\Configuration";
 
ADVANCED EXAMPLE:
 String empty="""
 """;
 
is empty.
 String foo = """
     bar
                 baz
       bla
     qux";
 
is equal to: String foo = "bar\n baz\n bla\nqux"; and the following:
 String foo = """
    foo
 bar""";
 
is a compile-time error.
 String manyQuotes="""\"""\"\"\"""";
 
is """""
  String s = """I'm  long string in groovy stile wi\
  th \\ at end of line""";
 
is:
I'm  long string in groovy stile with \ at end of line
  String s = ''I'm  long string in groovy stile wi\
  th \\ at end of line'';
 
is:
 I'm  long string in groovy stile wi
 th \\ at end of line
 
DETAILS: Multiline strings are part of program text, which begin and ends by three double quotes. I. e. grammar in 3.10.5 of JLS can be extented as:
MultilineStringLiteral:
        """ MultilineStringCharacters/opt """

MultilineStringCharacters:
        MultilineStringCharacter
        MultilineStringCharacters  (MultilineStringCharacter but not ")
        (MultilineStringCharacters but not "") "

MultilineStringCharacter:
        InputCharacter but not \
        EscapeSequence
        LineTermination
        EolEscapeSequence

EolEscapeSequence: \LineTermination.

Unescaped strings are part of program text, which begin and ends by two single quotes.
 RowStringLiteral:
                   '' RowInputCharacters/opt ''

 RowInputCharacters:
                      ' (InputCharacter but not ')
                     |
                      (InputCharacter but not ') '
                     |
                      LineTermination
Method for replacing line termination sequences in string to native format of host platform must be added to standard library. COMPILATION: Handling of multiline strings: Text within """ brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. escape sequences in each line are processed exactly as in ordinary Java strings. 3. sequence \LineTermination at the end of line is erased and such line cause line be concatenated with next line in one. 4. elimination of leading whitespaces are processed in next way: - at first determinate sequence of whitespace symbols (exclude LineTermination, i.e. ST, HP, FF) at first nonempty line in sequence. let's call it 'leading whitespace sequence' - all next lines, except case, when last line consists only from multiline string close quotes (""") must start with same leading whitespace sequence. - whitespace processing erase such leading sequence from resulting lines. If line does not start with leading whitespace sequence, than compilation warning is issued 5. set of lines after erasing of leading whitespace sequence is concatenated, with LF (i. e. '\n') line-termination sequences between two neighbour lines, regardless of host system Handling of row strings: Text within '' brackets processed in next way: 1. splitted to sequence of lines by line termination symbols. 2. set of lines after erasing of leading whitespace sequence is concatenated, with '\n' line-termination sequences between two neighbour lines, No escape processing, no leading whitespace elimination are performed for receiving of resulting string value. new strings literals created and used in .class files exactly as ordinary strings. TESTING: add new strings literals to test-cases for all combinations of finished and unfinished escape sequences and quotes. LIBRARY SUPPORT: add method platformLf() to class String, which convert newlines to form, suitable for running platform. s.platformLf() - returns string which replace all line-termination sequences in s by value of system property 'line.separator' REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/view_bug.do?bug_id=4165111 http://bugs.sun.com/view_bug.do?bug_id=4472509 http://docs.google.com/View?docid=d36kv8n_32g9zj7pdd by by Jacek Furmankiewicz http://blog.efftinge.de/2008/10/multi-line-string-literals-in-java.html library implementation by Sven Efftinge http://www.jroller.com/scolebourne/entry/java_7_multi_line_string - proposal by Stephen Colebourne http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000331.html - alternative joke proposal by Felix Frost https://rapt.dev.java.net/nonav/docs/api/net/java/dev/rapt/proposed/generators/LongString.html annotation-based implementation by Bruce Chapman URL FOR PROTOTYPE: Compiler changes with set of jtreg tests is available from mercurial repository at http://datacenter.gradsoft.ua/mercurial/cgi/hgwebdir.cgi/jdk7/tl/langtools/ Library changes with simple test: http://datacenter.gradsoft.ua/mercurial/cgi/hgwebdir.cgi/jdk7/jdk/ From rssh at gradsoft.com.ua Sat Mar 21 13:50:23 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sat, 21 Mar 2009 22:50:23 +0200 (EET) Subject: Enhanced String literal for Java: version 1.4 (final ?) In-Reply-To: <17813eab9af423648fb4ce01993a90da.squirrel@wmail.gradsoft.ua> References: <17813eab9af423648fb4ce01993a90da.squirrel@wmail.gradsoft.ua> Message-ID: <675afc01c0ee257560b3ce1fee9c4342.squirrel@wmail.gradsoft.ua> Sorry, last URL is incorrect. Correct: http://datacenter.gradsoft.ua/mercurial/cgi/hgwebdir.cgi/jdk7/tl/jdk/ > URL FOR PROTOTYPE: > > Compiler changes with set of jtreg tests is available from mercurial > repository at > http://datacenter.gradsoft.ua/mercurial/cgi/hgwebdir.cgi/jdk7/tl/langtools/ > > Library changes with simple test: > http://datacenter.gradsoft.ua/mercurial/cgi/hgwebdir.cgi/jdk7/jdk/ > > > > > From rssh at gradsoft.com.ua Sat Mar 21 13:56:07 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sat, 21 Mar 2009 22:56:07 +0200 (EET) Subject: I need your opinion... In-Reply-To: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <36ef2a91720ecba59e86cb9d87ab8de1.squirrel@wmail.gradsoft.ua> > > 1. > After some time, I found that there was better solution for consider > operator: > Allow final variables and final Fields (except blank final), to not > having explicit Type. > > Consider operator can help in dealing with generics, which are pain > in the as.. > I often found that Types took even 50% code, which is insane. > > Normal: > for ( ComparablePair> pair : > statisticsCollectors ){ ??? } > > Consider operator: > for ( ::pair : statisticsCollectors ){ ??? } > Good, but not 'strictly' required. > New final way: > for ( final pair : statisticsCollectors ){ ??? } > > New final way & while-each loop: > while ( final pair : final iterator = > statisticsCollectors.iterator() ){ > if ( ! isValid(pair.getKey()) ) iterator.remove( pair ); > } > > 2. > Add forget keyword to allow erase variable from current context (block): > - For method parameters it's now impossible. > - Assigning null to variable is lame and not possible for final > variables. > - Blocks not always fit to this purpose. > Why ? > 3. > Are glue classes hard to understand? > Exists many more-known names for similar functionality ('traits', as in scala, 'flawors' in lisp dialects) > 4. > Blocks in classes: > Peoples often do not use formatters because they do not keep logical > order in class structure, this would allow to define proper grouping. > > class Some{ > { // block boo > private Boo boo; > > public Boo getBoo(){ > return boo; > } > > public void setBoo(Boo boo){ > this.boo = boo; > } > }//end block > } > This I can't understand. I. e. block without any semantics - why ? From patrick at moor.ws Sat Mar 21 14:01:44 2009 From: patrick at moor.ws (Patrick Moor) Date: Sat, 21 Mar 2009 14:01:44 -0700 Subject: I need your opinion... In-Reply-To: References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <49C555B8.6030206@moor.ws> John Rose wrote: > On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > >> Allow final variables and final Fields (except blank final), to not >> having explicit Type. > > Yes. Someone should work exactly this (and no more) into a separate > proposal, if it hasn't been done already. use this as a template: http://bugs.sun.com/view_bug.do?bug_id=4459053 - patrick > > -- John > > Alternatives: "? foo" would sort of work since the "?" works, as a > wildcard, for some other type uses, but it is way too strange > looking. A new declare-and-assign operator would be nice for a wrist- > friendly language, but IMO it is too different from existing Java > declaration syntaxes. Beyond subjective esthetics, consistency of > syntax is important to both mechanical and biological parsers. > Meanwhile, "final" variables avoid ambiguities about programmer > intention for additional assignments to mutable variables, so "final" > works with extra grace for auto-typed variables. > > From markmahieu at googlemail.com Sat Mar 21 14:26:15 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 21:26:15 +0000 Subject: Feedback and comments on ARM proposal In-Reply-To: <17b2302a0903211101u74e74c08u48cb0ade7b6cc03d@mail.gmail.com> References: <63b4e4050903201408v6612e888hd6b1ac35777ac4e9@mail.gmail.com> <63b4e4050903210809v1cfa44e8v3f0f511b65d86be3@mail.gmail.com> <17b2302a0903210908w1ad50d23q999770ab26b845ca@mail.gmail.com> <17b2302a0903211101u74e74c08u48cb0ade7b6cc03d@mail.gmail.com> Message-ID: <4997412E-A99D-44F7-93B1-0ADF064DA971@googlemail.com> On 21 Mar 2009, at 18:01, Joshua Bloch wrote: > I don't think I did a good job of explaining the problem. Consider > this: Ah, ok I'm with you! Thanks for the explanation. > The problem with Nope is that it contains two "magic > methods" (sole parameterless method in an interface that directly > extends MagicMarker). Is it sufficient to say that a class must > have one and only one magic method to make it eligible for > automatic resource management? Right, clearly we'd need to be more specific about all this. I guess I should offer something up, so here's a first stab at it (caveat: not JLS-quality): A variable/expression with static type T is eligible for automatic resource management iff T has exactly one method m for which all of the following hold: * m has no parameters * there exists one or more type S where: * S declares exactly one method, which is override-equivalent with m * S is an interface which directly extends MagicMarker * S :> T I suppose we might also want to consider whether it should be an error for a class to implement MagicMarker directly, or for an interface that extends it to supply the 'wrong' number/type of methods, etc. > Is it practical to implement this in the compiler? I dunno. To me, it bears more than a passing resemblance to determining the single-abstract-method in CICE, and I don't remember that aspect as being particularly difficult to implement. Purely anecdotal though, of course. > > Josh > Mark From scolebourne at joda.org Sat Mar 21 14:42:15 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 21 Mar 2009 21:42:15 +0000 Subject: PROPOSAL: Elvis operator In-Reply-To: <49C4E8DE.4040803@joda.org> References: <49C4E8DE.4040803@joda.org> Message-ID: <49C55F37.9080109@joda.org> Stephen Colebourne wrote: > I'm re-submitting the Elvis operator as a separate proposal to ensure it > is treated as such. So far I've not heard any arguments against this on > this list, and there are lots of positives. To be absolutely clear - the original proposal "Elvis and other null-safe operators" remains alive, I haven't revoked it. The purpose of this proposal today is to allow Elvis to be considered on its own, and in addition to the combination of Elvis and null-safe access. Stephen From scolebourne at joda.org Sat Mar 21 14:46:08 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 21 Mar 2009 21:46:08 +0000 Subject: PROPOSAL: Enhanced for each loop iteration control Message-ID: <49C56020.2070207@joda.org> Enhanced for each loop iteration control (re-sent with correct subject line) This proposal extends the for each loop to allow access to meta data including the index and the remove method. (This proposal doesn't really go into enough detail - with JSR-310 my time here is limited. I'd hope that there is just about enough though....) ----------------------------------------------------------------------------------- Enhanced for each loop iteration control AUTHOR(S): Stephen Colebourne *OVERVIEW* FEATURE SUMMARY: Extends the Java 5 for-each loop to allow access to the loop index, whether this is the first or last iteration, and to remove the current item. MAJOR ADVANTAGE: The for-each loop is almost certainly the most new popular feature from Java 5. It works because it increases the abstraction level - instead of having to express the low-level details of how to loop around a list or array (with an index or iterator), the developer simply states that they want to loop and the language takes care of the rest. However, all the benefit is lost as soon as the developer needs to access the index or to remove an item. The original Java 5 for each work took a relatively conservative stance on a number of issues aiming to tackle the 80% case. However, loops are such a common form in coding that the remaining 20% that was not tackled represents a significant body of code. The process of converting the loop back from the for each to be index or iterator based is painful. This is because the old loop style if significantly lower-level, more verbose and less clear. It is also painful as most IDEs don't support this kind of 'de-refactoring'. MAJOR BENEFIT: A common coding idiom is expressed at a higher abstraction than at present. This aids readability and clarity. Accessing the index currently requires using an int based loop, or placing a separate int counter outside the loop (which then remains in scope after the loop). The proposed solution doesn't result in manual manipulation of the index. Accessing the iterator remove requires using an iterator based loop. With generics this is remarkably verbose. The proposed solution is significantly shorter and cleaner. MAJOR DISADVANTAGE: The enhanced for each loop is complicated with additional functionality. (This is mitigated by being easy and obvious to use) More code is generated magically by the compiler. (This is mitigated by a simple desugaring) ALTERNATIVES: Use the existing language constructs, typically the standard for loop. Use BGGA/JCA style closures, with control statements. It should be noted that these are consistently the most controversial parts of the closure debate, making the 'let's wait for closures' argument against this proposal weaker (as any final closures implementation may not include control statements). *EXAMPLES* SIMPLE EXAMPLE: StringBuilder buf = new StringBuilder(); for (String str : list : it) { if (str == null) { it.remove(); } } whereas, today we write: StringBuilder buf = new StringBuilder(); for (Iterator it = list.iterator(); it.hasNext();) { String str = it.next(); if (str == null) { it.remove(); } } ADVANCED EXAMPLE: Example1: for (String str : list : it) { System.out.println("Row " + it.index() + " has the value " + str); } whereas, today we might write: int index = 0; for (String str : list) { System.out.println("Row " + index + " has the value " + str); index++; } or for (int i = 0; i < list.size(); i++) { String str = list.get(i); System.out.println("Row " + index + " has the value " + str); } Example 2: StringBuilder buf = new StringBuilder(); for (String str : list : it) { if (it.isFirst()) { buf.append(str); } else { buf.append(", ").append(str); } } StringBuilder buf = new StringBuilder(); for (String str : list : it) { if (it.isLast()) { buf.append(str); } else { buf.append(str).append(", "); } } *DETAILS* SPECIFICATION: Lexical: No new tokens are added. The colon token is reused in the extended enhanced for each statement. Syntax: EnhancedForStatement: for ( VariableModifiersopt Type Identifier : Expression) Statement for ( VariableModifiersopt Type Identifier : Expression : Ident) Statement Semantics: The first enhanced for each statement (the current form) will compile as it does today. The extended enhanced for each statement will operate as follows. The iterator control variable is a standard variable declared to be final. It will never be null. The type is dependent on whether the expression is an array or an Iterable. It will either be ArrayIterationControl or IterableIterationControl. The type is not specified as it is redundent information, ie. the type is inferred. It is scoped for the life of the loop. public final class IterableIterationControlIterator { public IterableIterationControlIterator(Iterable iterable) { this.control = new IterableIterationControl(iterable.iterator()); } public boolean hasNext() { return control.hasNext() } public T next() { return control.next() } public IterableIterationControl control() { return control } } public final class IterableIterationControl { public IterableIterationControl(Iterator iteratorToWrap) { this.it = iteratorToWrap; } boolean hasNext() { return it.hasNext() } T next() { originalIndex++; if (lastWasRemoved) { lastWasRemoved = false } else { index++ } return it.next() } public T remove() { removed++; lastWasRemoved = true; return it.remove() } public int index() { return index } public int originalIndex() { return originalIndex } public boolean isFirst() { return index == 1 } public boolean isLast() { return it.hasNext() == false } } public final class ArrayIterationControlIterator { public ArrayIterationControlIterator(T[] array) { this.control = new ArrayIterationControl(array); } public boolean hasNext() { return control.hasNext() } public T next() { return control.next() } public ArrayIterationControl control() { return control } } public final class ArrayIterationControl { public ArrayIterationControl(T[] array) { this.array = array; } boolean hasNext() { return index < array.length; } T next() { return array[++index]; } public int index() { return index - 1; } public boolean isFirst() { return index == 1; } public boolean isLast() { return index == array.length; } } Exception analysis: The method remove() on the iteration control variable can throw an UnsuportedOperationException. However, this is no different from any other method call. Definite assignment: The new variable iteration control variable is a final variable that is definitely assigned from creation. COMPILATION: The extended enhanced for each loop is implemented by wrapping the two control classes around the Iterable or the array. The Iterable design is desugared from: for (T item : iterable : control) { ... } to: { IterableIterationControlIterator $it = new IterableIterationControlIterator(iterable); IterableIterationControl control = $it.control(); while ($it.hasNext()) { T item = $it.next(); ... } } The array design is desugared similarly: { ArrayIterationControlIterator $it = new ArrayIterationControlIterator(iterable); ArrayIterationControl control = $it.control(); while ($it.hasNext()) { T item = $it.next(); ... } } There is the option to optimise this if the iteration control variable is not assigned to any other variable or passed to any other method. However, that is out of scope for now. TESTING: Testing will be similar to the enhanced for loop. Arrays and Iterables of various types and sizes will be used. The null expression will also be tested. LIBRARY SUPPORT: Yes, as detailed above. REFLECTIVE APIS: No. OTHER CHANGES: The javac tree API would need to be updated to model the change. MIGRATION: Migration is not required. However, an IDE refactoring could now convert more int and Iterator based for loops than it does at present. *COMPATIBILITY* BREAKING CHANGES: No breaking changes are known using this conversion scheme. EXISTING PROGRAMS: This conversion is pure syntax sugar, so there are no known interactions with existing programs. *REFERENCES* EXISTING BUGS: I searched the bug database, but nothing came up (which is surprising). URL FOR PROTOTYPE: None DOCUMENTS: [1] Stephen Colebourne's blog: http://www.jroller.com/scolebourne/entry/java_7_for_each_loop [2] Stephen Colebourne's original writeup: http://docs.google.com/Edit?docID=dfn5297z_15ck7x5ghr *DESIGN ISSUES* There are numerous alternative ways in which this feature can be added. These include: - using the keyword: for (String str : list) { for.remove(); // problem is nested for loops } - using a label as a psuedo-variable: it: for (String str : list) { it:remove(); // note colon and not dot } - using an additional clause before the for each colon: for (String str, int index : list) { // no access to remove, and conflicts for for each for maps } The chosen solution involves simple Java classes, and a simple desugar. The downside of the chosen solution is performance, as it involves creating two wrapping objects and routing hasNext() and next() via additional layers of method calls. A possible extension would be for the compiler to identify if the iteration control variable is not passed to another method. If so, then the code could be all be generated inline. From fw at deneb.enyo.de Sat Mar 21 14:46:44 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 21 Mar 2009 22:46:44 +0100 Subject: I need your opinion... In-Reply-To: (John Rose's message of "Sat, 21 Mar 2009 13:40:38 -0700") References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <87y6uy35x7.fsf@mid.deneb.enyo.de> * John Rose: > On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > >> Allow final variables and final Fields (except blank final), to not >> having explicit Type. > > Yes. Someone should work exactly this (and no more) into a separate > proposal, if it hasn't been done already. What should be the inferred type of an expression with an intersection type? Is there an answer which is acceptable in the COIN context? From develop4lasu at gmail.com Sat Mar 21 14:47:11 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 22:47:11 +0100 Subject: I need your opinion... In-Reply-To: References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <28bca0ff0903211447y1c77063fr4ddf8e53ad0ce611@mail.gmail.com> 2009/3/21 John Rose : > On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > >> Allow final variables and final Fields (except blank final), to not >> having explicit Type. > > Yes. ?Someone should work exactly this (and no more) into a separate > proposal, if it hasn't been done already. > > -- John > > Alternatives: "? foo" would sort of work since the "?" works, as a wildcard, > for some other type uses, but it is way too strange looking. ?A new > declare-and-assign operator would be nice for a wrist-friendly language, but > IMO it is too different from existing Java declaration syntaxes. ?Beyond > subjective esthetics, consistency of syntax is important to both mechanical > and biological parsers. ?Meanwhile, "final" variables avoid ambiguities > about programmer intention for additional assignments to mutable variables, > so "final" works with extra grace for auto-typed variables. > > Yes '?' would be problem while reading. I was thinking some time ago about ?? as auto detemined Type: final Map map = new HashMap(); but that would make more problems and combinations. 2009/3/21 : >> [snip] >> >> 2. >> Add forget keyword to allow erase variable from current context (block): >> ? ?- For method parameters it's now impossible. >> ? ?- Assigning null to variable is lame and not possible for final >> variables. >> ? ?- Blocks not always fit to this purpose. >> > > ?Why ? > It's good to be able to say that variable should be not used any more in current context, just like when stream was just closed. When you will back to code after few months, this will be not problem for you (while you may forget that this should not be used any more). >> 3. >> Are glue classes hard to understand? >> > > ?Exists many more-known names for similar functionality ?('traits', as in > scala, 'flawors' in lisp dialects) > I mean logic not name. And this is nothing similar with traits (lisp I do not know). Glue classes you can 'bind' to few classes at once. >> 4. >> Blocks in classes: [snip] > > ?This I can't understand. I. e. block without any semantics - why ? > > I would like to group logic in classes, if I have adding login i want keep it close without resignation of code formatter. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sat Mar 21 14:56:51 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 22:56:51 +0100 Subject: I need your opinion... In-Reply-To: <87y6uy35x7.fsf@mid.deneb.enyo.de> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> Message-ID: <28bca0ff0903211456i115eee6i6079ce8b377507a1@mail.gmail.com> 2009/3/21 Florian Weimer : > * John Rose: > >> On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: >> >>> Allow final variables and final Fields (except blank final), to not >>> having explicit Type. >> >> Yes. ?Someone should work exactly this (and no more) into a separate >> proposal, if it hasn't been done already. > > What should be the inferred type of an expression with an intersection > type? ?Is there an answer which is acceptable in the COIN context? > That would be type of type's intersection, just like it work now days: class A {} class B extends A {} public static void main(String[] args) { B some= (true?new A(): new B()); // error cannot cast A to B } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Sat Mar 21 15:21:35 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 21 Mar 2009 23:21:35 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> Message-ID: I think without having a way to specify default values, this really isn't going to replace the builder pattern. Being allowed to re-order should also be on the table, a the very least. Here's all the technical detail of a proposal that might, maybe, fit inside project coin's scope. First off: Of all methods that have the same name (but different paramlists, e.g. overloading), only one is allowed to be named in the first place. If you're overriding it and also want YOUR version to be named, then your parameter list must be in the exact same order *AND* each parameter must have the exact same name as the overridden method (that's a new compiler check). If you're overridding a non-named method and you turn it into a named parameter method, that's fine. If you're overriding a named method and you don't make it named, that's fine too - but, it is still considered named. (100% analogous to how you can de-varargs a method in a subtype, but the compiler still considers it varargs). That should solve overloading and inheritance problems. Then, the syntax itself: public named void foo(int x = 5, List list = new ArrayList(), String foo) { //as normal } The 'named' is a new context sensitive keyword (if 'module' can be one, then this isn't too much of a stretch), and, only for named methods, you can supply expressions that serve as defaults. Each expression is evaluated exactly once, during your class initialization (so, the ArrayList above is SHARED amongst all method invocations! - I'd force it to be immutable but java does not have such a facility). The system works by translating all value expressions into public final fields with a specific name. Javac, when finding a caller to a named method, will re-order as needed and add references to those fields to fill in the gaps. So, the above becomes: public final int foo$x = 5; public final List foo$list = new ArrayList(); public void foo(int x, List list, String foo) { //as normal } The fields have the Synthetic flag set. The method is compiled with param names, exactly the same way names are saved when turning on debug information (regardless of the actual -g:vars flag value), and a new flag called 'Named'. The following call: ClassName.foo(foo: "hello", x:10); is compiled exactly the same way the following would be compiled: ClassName.foo(10, ClassName.foo$list, "hello"); If you use the named syntax, then every parameter MUST be named. If you use no names, that's fine, but you don't get any of the sugar - You'd have to supply all 3 parameters, in the right order. I'm fairly sure this is migration and source compatible, even in the case of subclasses, is not ambiguous (even in light of overriding classes, implementing types, and overloading the method), introduces no high-impact new features, other than forcing -g:vars (which I think is minor; most compilers already do this, especially for libraries, so that auto-complete can offer nicer names for the parameters than 'arg0', 'arg1', and 'arg2'). Having the compiler dig through a type's entire parent tree including interfaces to figure out if the method is named in any of the subtypes seems high impact, but as I mentioned: It's not - javac already does this to figure out if an array in the last position is declared as a varargs in any supertype, and if so, treats that as a vararg. Specifically, any library out there can update their classes and even their interfaces with 'named' keywords WITHOUT breaking any kind of compatibility; existing class files will continue to work, and recompiling old code in a javac v7 without accounting for the 'named' feature does not break those either. To highlight the way the 'named' property is inherited from any supertype with an example: public interface SuperType { void foo(String... args); named void bar(String arg); } public class Baz implements SuperType { void foo(String[] args); void bar(String arg); } Baz b = new Baz(); b.foo("a", "b"); //legal TODAY b.bar(arg: "foo"); //would be legal too Even if the subclass does not have -g:vars on, the names are still available via the supertype. In fact, without the 'named' modifier, the names of the parameters in a subclass are IGNORED (they could be different, and that would hence not be backwards compatible, which is bad). So, any 'named' marked methods must have equal names, but only one of the methods needs to be marked as such, and it 'infects' all subtypes. The syntax will not clash much with the parser, and the context sensitive keyword is extremely unlikely to introduce problems (if you have a *type* named 'named', you'd break things, but types are usually capitalized. The 'module' keyword suffers from the same issue, I believe. Three questions: A) Is this a good idea? Do you like it? Would you use it? (I think its stellar, but then, I'm proposing it). B) Did I miss something (is it more complicated than I make it out to be), or is something unclear? Specifically, did I miss something that does not make it backwards, migration, and source compatible? C) Might this be within scope for project coin? I'll definitely write it up if it stands a chance. --Reinier Zwitserloot On Mar 21, 2009, at 18:56, Marek Kozie? wrote: > Builders are really great tool, but they need to be written manually. > > In other way there will be problem, if final object need contains data > and builder only key for that data. > > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From develop4lasu at gmail.com Sat Mar 21 15:22:46 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 21 Mar 2009 23:22:46 +0100 Subject: I need your opinion... In-Reply-To: <87y6uy35x7.fsf@mid.deneb.enyo.de> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> Message-ID: <28bca0ff0903211522t316c8f2et9d0b2372074a8038@mail.gmail.com> 2009/3/21 Florian Weimer : > * John Rose: > >> On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: >> >>> Allow final variables and final Fields (except blank final), to not >>> having explicit Type. >> >> Yes. ?Someone should work exactly this (and no more) into a separate >> proposal, if it hasn't been done already. > > What should be the inferred type of an expression with an intersection > type? ?Is there an answer which is acceptable in the COIN context? > After some thoughts: interface A {} interface B {} interface C {} class cABC implements A, B, C {} class cAC implements A, C {} public static void main(String[] args) { Object x = (true?new cABC():new cAC()); // now days } but it could be extended to (in matter of time): A&C y = (true?new cABC():new cAC()); -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From markmahieu at googlemail.com Sat Mar 21 15:42:10 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 21 Mar 2009 22:42:10 +0000 Subject: I need your opinion... In-Reply-To: <28bca0ff0903211522t316c8f2et9d0b2372074a8038@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <28bca0ff0903211522t316c8f2et9d0b2372074a8038@mail.gmail.com> Message-ID: 2009/3/21 Marek Kozie? > > > but it could be extended to (in matter of time): > A&C y = (true?new cABC():new cAC()); Ah, but is it A&C or ABC|AC ? :) If you haven't seen it, you may find the following paper interesting: 'Union Types for Object-Oriented Programming', Atsushi Igarushi and Hideshi Nagira, Kyoto University, Japan. ACM SAC 2006 Mark From reinier at zwitserloot.com Sat Mar 21 15:51:44 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 21 Mar 2009 23:51:44 +0100 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <87y6uy35x7.fsf@mid.deneb.enyo.de> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> Message-ID: <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> Intersection types are annoying, to say the least. Possibly hand-wave it away by stating that you can't use those expressions in this new language construct. Or, a slight adaptation to that: If all but 1 of the intersection types are subtypes of the other one, and this can be said for only 1 type, then that type wins. Thus: final foo = someBoolean ? Arrays.asList("foo", "bar") : new ArrayList(); foo's type would be List, because that's the type of one of the intersections (List), and all other types of that intersection (ArrayList) are a subtype of this, and there's no other type for which this can be said. However, writing up the specifics of this sounds difficult to say the least, and it can always be added in java8 if it causes an inordinate amount of whining. Either way, this: final foo = someBoolean ? new LinkedList() : new ArrayList(); would be a compiler error. What should foo be? List? AbstractList? Serializable? Cloneable? Object? They're all common supertypes, and there's no clear winner in the set; attempting to use the nearest common parent still gives you 2 winning options: Serializable, and Cloneable, while in actual fact you were probably shooting for List, which isn't even close to the winner here, what with AbstractList in the way, and AbstractList itself being 2 removed from LinkedList, which extends AbstractSequentialList, which extends AbstractList. I think it'll be okay to just compiler-error on those, because I expect the majority usage would be something akin to: final foo = methodCall(); --Reinier Zwitserloot On Mar 21, 2009, at 22:46, Florian Weimer wrote: > * John Rose: > >> On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: >> >>> Allow final variables and final Fields (except blank final), to not >>> having explicit Type. >> >> Yes. Someone should work exactly this (and no more) into a separate >> proposal, if it hasn't been done already. > > What should be the inferred type of an expression with an intersection > type? Is there an answer which is acceptable in the COIN context? > From develop4lasu at gmail.com Sat Mar 21 16:43:55 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 22 Mar 2009 00:43:55 +0100 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> Message-ID: <28bca0ff0903211643ld1902falfffce7d16b7f82ad@mail.gmail.com> 2009/3/21 Reinier Zwitserloot : > Intersection types are annoying, to say the least. Possibly hand-wave > it away by stating that you can't use those expressions in this new > language construct. > > Or, a slight adaptation to that: If all but 1 of the intersection > types are subtypes of the other one, and this can be said for only 1 > type, then that type wins. Thus: > > final foo = someBoolean ? Arrays.asList("foo", "bar") : new > ArrayList(); > > foo's type would be List, because that's the type of one of > the intersections (List), and all other types of that > intersection (ArrayList) are a subtype of this, and there's no > other type for which this can be said. However, writing up the > specifics of this sounds difficult to say the least, and it can always > be added in java8 if it causes an inordinate amount of whining. > > Either way, this: > > final foo = someBoolean ? new LinkedList() : new > ArrayList(); > > would be a compiler error. What should foo be? List? > AbstractList? Serializable? Cloneable? Object? They're all > common supertypes, and there's no clear winner in the set; attempting > to use the nearest common parent still gives you 2 winning options: > Serializable, and Cloneable, while in actual fact you were probably > shooting for List, which isn't even close to the winner here, > what with AbstractList in the way, and AbstractList itself being 2 > removed from LinkedList, which extends AbstractSequentialList, which > extends AbstractList. > > > I think it'll be okay to just compiler-error on those, because I > expect the majority usage would be something akin to: > > final foo = methodCall(); > > ?--Reinier Zwitserloot > > > > On Mar 21, 2009, at 22:46, Florian Weimer wrote: > >> * John Rose: >> >>> On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: >>> >>>> Allow final variables and final Fields (except blank final), to not >>>> having explicit Type. >>> >>> Yes. ?Someone should work exactly this (and no more) into a separate >>> proposal, if it hasn't been done already. >> >> What should be the inferred type of an expression with an intersection >> type? ?Is there an answer which is acceptable in the COIN context? >> > > > Most natural be for me would be (autoboxing is forbidden): If at least one of intersected types is Object then returned type is Object and no error occurs. Else If only one type (except Object) is effect of intersection then it is the type and no warning nor error should occur. Else If both types have common ancestor (except Object) then ancestor is the type and no warning should occurs. Else error should occurs. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sat Mar 21 16:46:48 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 22 Mar 2009 00:46:48 +0100 Subject: I need your opinion... In-Reply-To: References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <28bca0ff0903211522t316c8f2et9d0b2372074a8038@mail.gmail.com> Message-ID: <28bca0ff0903211646o57f25b4dx928c7d2e01e76072@mail.gmail.com> W dniu 21 marca 2009 23:42 u?ytkownik Mark Mahieu napisa?: > > 2009/3/21 Marek Kozie? >> >> but it could be extended to (in matter of time): >> A&C ?y = (true?new cABC():new cAC()); > > Ah, but is it A&C or ABC|AC ? > :) > If you haven't seen it, you may find the following paper interesting: > 'Union Types for Object-Oriented Programming', Atsushi Igarushi and Hideshi > Nagira, Kyoto University, Japan. ACM SAC 2006 > > Mark > If I understand you correctly: and A & C meaning is same as in and cABC | cAC mean one of ... but we do not know which. That would be A&B because after each intersection it decrease type complication, while cABC | cAC would increase it at end. But this is more about future Java path. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From i30817 at gmail.com Sat Mar 21 17:07:58 2009 From: i30817 at gmail.com (Paulo Levi) Date: Sun, 22 Mar 2009 00:07:58 +0000 Subject: Anyone ever considered named tuples? Message-ID: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> Out of the blue, a few days ago, i wondered if a tuple construct that had names, ie: (String directory, String file) for instance, would make any sense? I know that spaghetti code should be factored to map to simple functions with simple return arguments, but i saw sooooo much code that had simple container semantics. A tuple object written as a compiler code transformation like autoboxing would make a lot of sense if it allowed names to be defined at use site. I'm sure you know that this can be simulated by some creative use of generics and static import, but the names (one ... first) are pretty bad. Just throwing a idea, don't bite my head off. From i30817 at gmail.com Sat Mar 21 17:12:36 2009 From: i30817 at gmail.com (Paulo Levi) Date: Sun, 22 Mar 2009 00:12:36 +0000 Subject: Anyone ever considered named tuples? In-Reply-To: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> References: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> Message-ID: <212322090903211712h6f9853bbofb2e575661ee77e6@mail.gmail.com> Also would finally stop the awkwardness that occurs when binding with c functions that receive pointers as a output mechanism. And code receiving arrays just to have two return values. Two INDEXED return values. Urghh. From neal at gafter.com Sat Mar 21 17:30:55 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Mar 2009 17:30:55 -0700 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> Message-ID: <15e8b9d20903211730x23a69a98x3eba561a1fee87b8@mail.gmail.com> On Sat, Mar 21, 2009 at 3:21 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Of all methods that have the same name (but different paramlists, e.g. > overloading), only one is allowed to be named in the first place. Honestly, I think this is a fatal restriction. I like named parameters, but not if restricted to a single member of any overload set. From neal at gafter.com Sat Mar 21 17:35:43 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Mar 2009 17:35:43 -0700 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> Message-ID: <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> Type inference, and the lub() operation that generates these intersection types, does not produce intersection types in which any member is a subtype of any other member of the set of intersected types. So, these rules about how to handle such situations are not necessary. What's the problem just leaving the type of the variable an intersection type? On Sat, Mar 21, 2009 at 3:51 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > Intersection types are annoying, to say the least. Possibly hand-wave > it away by stating that you can't use those expressions in this new > language construct. > > Or, a slight adaptation to that: If all but 1 of the intersection > types are subtypes of the other one, and this can be said for only 1 > type, then that type wins. Thus: > > final foo = someBoolean ? Arrays.asList("foo", "bar") : new > ArrayList(); > > foo's type would be List, because that's the type of one of > the intersections (List), and all other types of that > intersection (ArrayList) are a subtype of this, and there's no > other type for which this can be said. However, writing up the > specifics of this sounds difficult to say the least, and it can always > be added in java8 if it causes an inordinate amount of whining. > > Either way, this: > > final foo = someBoolean ? new LinkedList() : new > ArrayList(); > > would be a compiler error. What should foo be? List? > AbstractList? Serializable? Cloneable? Object? They're all > common supertypes, and there's no clear winner in the set; attempting > to use the nearest common parent still gives you 2 winning options: > Serializable, and Cloneable, while in actual fact you were probably > shooting for List, which isn't even close to the winner here, > what with AbstractList in the way, and AbstractList itself being 2 > removed from LinkedList, which extends AbstractSequentialList, which > extends AbstractList. > > > I think it'll be okay to just compiler-error on those, because I > expect the majority usage would be something akin to: > > final foo = methodCall(); > > --Reinier Zwitserloot > > > > On Mar 21, 2009, at 22:46, Florian Weimer wrote: > > > * John Rose: > > > >> On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > >> > >>> Allow final variables and final Fields (except blank final), to not > >>> having explicit Type. > >> > >> Yes. Someone should work exactly this (and no more) into a separate > >> proposal, if it hasn't been done already. > > > > What should be the inferred type of an expression with an intersection > > type? Is there an answer which is acceptable in the COIN context? > > > > > From neal at gafter.com Sat Mar 21 17:41:22 2009 From: neal at gafter.com (Neal Gafter) Date: Sat, 21 Mar 2009 17:41:22 -0700 Subject: Anyone ever considered named tuples? In-Reply-To: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> References: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> Message-ID: <15e8b9d20903211741m3ac58828o197162183a47ff1@mail.gmail.com> The standard name for this kind of thing is "structural types". Today, when this kind of need arises in Java people are forced to define a POD ("plain-old-data") class (nominal type) as the container. Without considering its merits, as an extension of the type system such things are out of scope for project Coin. On Sat, Mar 21, 2009 at 5:07 PM, Paulo Levi wrote: > Out of the blue, a few days ago, i wondered if a tuple construct that had > names, > ie: (String directory, String file) for instance, would make any sense? > I know that spaghetti code should be factored to map to simple functions > with simple return arguments, but i saw sooooo much code that had simple > container semantics. > A tuple object written as a compiler code transformation like autoboxing > would make > a lot of sense if it allowed names to be defined at use site. > I'm sure you know that this can be simulated by some creative use of > generics and static import, > but the names (one ... first) are pretty bad. > > Just throwing a idea, don't bite my head off. > > From Joe.Darcy at Sun.COM Sat Mar 21 19:21:10 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 21 Mar 2009 19:21:10 -0700 Subject: I need your opinion... In-Reply-To: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <49C5A096.8010706@sun.com> Greetings. I find none of these compelling for Project Coin. -Joe Marek Kozie? wrote: > There is no point in writing a proposal if people will not use it. > I have found that some parts of programming are problems for me and > for the others, > but you might have a different experience so I would like to hear your > opinion about listed points. > > 1. > After some time, I found that there was better solution for consider operator: > Allow final variables and final Fields (except blank final), to not > having explicit Type. > > Consider operator can help in dealing with generics, which are pain > in the as.. > I often found that Types took even 50% code, which is insane. > > Normal: > for ( ComparablePair> pair : > statisticsCollectors ){ ? } > > Consider operator: > for ( ::pair : statisticsCollectors ){ ? } > > New final way: > for ( final pair : statisticsCollectors ){ ? } > > New final way & while-each loop: > while ( final pair : final iterator = > statisticsCollectors.iterator() ){ > if ( ! isValid(pair.getKey()) ) iterator.remove( pair ); > } > > 2. > Add forget keyword to allow erase variable from current context (block): > - For method parameters it's now impossible. > - Assigning null to variable is lame and not possible for final variables. > - Blocks not always fit to this purpose. > > 3. > Are glue classes hard to understand? > > 4. > Blocks in classes: > Peoples often do not use formatters because they do not keep logical > order in class structure, this would allow to define proper grouping. > > class Some{ > { // block boo > private Boo boo; > > public Boo getBoo(){ > return boo; > } > > public void setBoo(Boo boo){ > this.boo = boo; > } > }//end block > } > > From Joe.Darcy at Sun.COM Sat Mar 21 19:28:35 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 21 Mar 2009 19:28:35 -0700 Subject: Glue classes proposal 0.9 In-Reply-To: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> Message-ID: <49C5A253.5000304@sun.com> From this proposal, I do not understand what you are trying to propose. -Joe Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? > > OVERVIEW > > FEATURE SUMMARY: > Glue classes allow to link utils direct with objects. > > MAJOR ADVANTAGE: > + Forgotten functionality can be not such big deal now. > > MAJOR BENEFIT(s): > + New functions can be easy localized (critically important while introduce > new peoples into project). > + Security: glue class do not see anything protected. > + Light binding new functions with existing classes. > + Number of used classes reduction. > + Allow to assign methods and functions(static methods) to arrays, classes, > interfaces, ? > + It's proof against same method occurs in class and delegator as well like > in two delegators. > + Allow to link gained(.jar) logic with new one, witch is impossible before > final developer implements his classes. > + Allow to project compact interfaces and do not worry about additional > logic. > > > MAJOR DISADVANTAGE: > Do not know any ;) sorry. > > ALTERNATIVES: > Utils classes, more work on project, duplicated code... > > > EXAMPLES > > SIMPLE EXAMPLE: > > > Now time: > public class base { > > public static T[] flatten(T[][] this) { > int length = 0; > for (T[] subArray : this) { > length += subArray.length; > } > T[] ret = (T[]) > Array.newInstance(this.getClass().getComponentType().getComponentType(), > length); > int pos = 0; > for (T[] subArray : this) { > System.arraycopy(subArray, 0, ret, pos, subArray.length); > pos += subArray.length; > } > return ret; > } > > } > Now time(usage): > public static void main(String[] args) { > Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { > 9, 0 } }; > System.out.println(Arrays.toString(base.flatten(array))); > } > > Glue: > public class base glue( T[][] ) { > > public glue T[] flatten( this) { > int length = 0; > for (T[] subArray : this) { > length += subArray.length; > } > T[] ret = (T[]) > Array.newInstance(this.getClass().getComponentType().getComponentType(), > length); > int pos = 0; > for (T[] subArray : this) { > System.arraycopy(subArray, 0, ret, pos, subArray.length); > pos += subArray.length; > } > return ret; > } > > } > Glue(usage): > public static void main(String[] args) { > Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { > 9, 0 } }; > System.out.println(array..flatten()..toString()); > } > > ADVANCED EXAMPLE: > Now time: > public class base { > > public static int addAll( ArrayList this, Iterator > iterator) { > int added = 0; > while (iterator.hasNext()) { > added += this.add(iterator.next()) ? 1 : 0; > } > return added; > } > > public static int addAll(ArrayList this, E[] elements) > { > int added = 0; > for (T t : elements) { > added += this.add(t) ? 1 : 0; > } > return added; > } > > } > Now time(usage): > public static void main(String[] args) { > Integer[] add = new Integer[] { 1, 2, 34, 2, 5, }; > ArrayList arrayList = new ArrayList(); > ArrayList finall = new ArrayList(); > > base.addAll(arrayList, add); > base.addAll(finall, add); > base.addAll(finall,arrayList.iterator()); > > System.out.println(finall); > } > > Glue: > public class base glue( ArrayList ){ > > public glue int addAll( this, Iterator iterator) { > int added = 0; > while (iterator.hasNext()) { > added += this.add(iterator.next()) ? 1 : 0; > } > return added; > } > > public glue int addAll( this, E[] elements) { > int added = 0; > for (T t : elements) { > added += this.add(t) ? 1 : 0; > } > return added; > } > > } > Glue(usage): > public static void main(String[] args) { > Integer[] add = new Integer[] { 1, 2, 34, 2, 5, }; > ArrayList arrayList = new ArrayList(); > ArrayList finall = new ArrayList(); > > arrayList..addAll(add); > finall..addAll(add); > finall..addAll(arrayList.iterator()); > > System.out.println(finall); > } > > Glue second: > public class base glue( Date ) > { > private static final SimpleDateFormat sdf = new > SimpleDateFormat("yyyy.MM.dd"); > > public glue String format( this ) { > synchronized (sdf) { > return sdf.format(this); > } > } > > private static final Date applicationStart = new Date(); > > public static glue Date applicationStart() { > return applicationStart; > } > } > Glue second(usage): > public static void main(String[] args) { > System.out.println(Date..applicationStart()..format()); > } > DETAILS > > SPECIFICATION: > JLS 8.8: > ClassDeclaration: > NormalClassDeclaration > GlueClassDeclaration > EnumDeclaration > > GlueClassDeclaration > ClassModifiers_opt class Identifier TypeParameters_opt glue ( > GlueFormalParameter ) GlueClassBody > > GlueFormalParameter > VariableModifiers Type > > GlueClassBody: > { GlueClassBodyDeclarations_opt } > > GlueClassBodyDeclarations: > GlueClassBodyDeclaration > GlueClassBodyDeclarations GlueClassBodyDeclaration > > GlueClassBodyDeclaration: > GlueClassMemberDeclaration > StaticInitializer > > GlueClassMemberDeclaration: > FieldDeclaration > StaticMethodDeclaration > GlueMethodDeclaration > StaticClassDeclaration > InterfaceDeclaration > ; > > GlueMethodDeclaration: > GlueMethodHeader MethodBody > > GlueMethodHeader: > MethodModifiers_opt glue TypeParameters*opt ResultType > GlueMethodDeclarator Throwsopt > > GlueMethodDeclarator: > Identifier ( this,*opt FormalParameterListopt ) > > *opt: 'this' occurs always and only if glue method is not static. > > TypeParameters from GlueClassDeclaration are always visible for > TypeParameters in GlueMethodHeader (even if method is static). > > > 15.12 Method Invocation Expressions: > > GlueMethodInvocation:
> Primary .. NonWildTypeArguments*_opt TypeName_opt GlueMethodIdentifier ( > ArgumentList_opt )
> super .. NonWildTypeArguments*_opt GlueMethodIdentifier ( ArgumentList_opt > )
> ClassName . super .. NonWildTypeArguments*_opt GlueMethodIdentifier ( > ArgumentList_opt )
> TypeName .. NonWildTypeArguments* GlueMethodIdentifier ( ArgumentList_opt > )

> > NonWildTypeArguments* suit TypeParameters in GlueMethodHeader.

> > > > > > > > COMPILATION: > If object (except null) is valid for GlueFormalParameter then glue-method > can be called for this object. > If type is compatible with GlueFormalParameter then static glue-method can > be called for this type. > For non static methods glued-object is passed as first 'this' parameter. > Compiled method signature contains TypeParameters from GlueClassDeclaration > (at start), and it's always static. > > > TESTING: > Like simple static methods. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > None. > > COMPATIBILITY > New jars are fully compatible. Code is only backward compatible. > > REFERENCES > > Glue classes proposal 0.9 : > http://lasu2string.blogspot.com/2009/03/glue-classes-proposal-09.html > > Bug: Extension of 'Interface' definition to include class (static) methods: > http://bugs.sun.com/view_bug.do?bug_id=4093687 > > > > From Joe.Darcy at Sun.COM Sat Mar 21 19:30:19 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sat, 21 Mar 2009 19:30:19 -0700 Subject: Proposal: Embedded Expressions for String Statements In-Reply-To: References: <49C4B2E4.1060004@e-spirit.de> Message-ID: <49C5A2BB.8050108@sun.com> Reinier Zwitserloot wrote: [snip] > NB: Joe, will you be writing the proposal on this? You mentioned > something along these lines when you announced coin at http://blogs.sun.com/darcy/entry/project_coin > > --Reinier Zwitserloot > A proposal including this should be sent to the list in the near future. -Joe From lk at teamten.com Sat Mar 21 23:41:36 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Sat, 21 Mar 2009 23:41:36 -0700 Subject: List comprehensions Message-ID: <997cab100903212341g6c4dead2iaf16a6d2be7137d7@mail.gmail.com> Reinier Zwitserloot wrote: > list comprehensions, /IF/ they produce a complete list and not a > lazily evaluating iterable, is just syntax sugar. In my proposal (http://docs.google.com/View?docid=d4tx2hw_46fkz8x6gt) it's lazy /and/ syntactic sugar, but it requires that variables (other than the source iterable) be final, as you said in a different post. This is slightly inconvenient, but I wouldn't introduce all the problems of closures just to deal with that. I agree that immediately evaluating the list is easier and safer all around. R?mi Forax made a similar observation on the kijaro mailing list. I can't exactly remember why I didn't do that. I think I was influenced by Python's drift towards making everything streams. I had also recently read SICP, which pushes for stream computation. And perhaps I wasn't sure which implementation of List to use. Also there are some cases where it's more efficient; see the examples in the spec that are based on SICP and FCM examples. It wouldn't take you long to try your immediate-eval idea. Copy the listcomprehensions branch of kijaro. The parsing is already done for you, and the desugaring code would just get massively simpler. (The current implementation must generate two nested classes to create an Iterable that returns an Iterator.) I'd be happy to help you if you get stuck. In fact your new code would look a lot like the foreach desugar. It'd be pretty simple, and I'm surprised that Joe thinks it's out of scope for Coin. It's smaller than many of the other ideas. Lawrence Kesteloot From jjb at google.com Sun Mar 22 00:02:20 2009 From: jjb at google.com (Joshua Bloch) Date: Sun, 22 Mar 2009 00:02:20 -0700 Subject: I need your opinion... In-Reply-To: References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <17b2302a0903220002s7f9bba1at8a9a5cc18542ceac@mail.gmail.com> Mark, I have to disagree with my esteemed colleague John on this one. I believe that every language has certain characteristics that make it what it is, and that these things simply shouldn't be changed. I believe that one such attribute of Java is that all declared entities have an explicit declared type. I believe it would do great harm to the language to change this. Josh On Sat, Mar 21, 2009 at 1:40 PM, John Rose wrote: > On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > > > Allow final variables and final Fields (except blank final), to not > > having explicit Type. > > Yes. Someone should work exactly this (and no more) into a separate > proposal, if it hasn't been done already. > > -- John > > Alternatives: "? foo" would sort of work since the "?" works, as a > wildcard, for some other type uses, but it is way too strange > looking. A new declare-and-assign operator would be nice for a wrist- > friendly language, but IMO it is too different from existing Java > declaration syntaxes. Beyond subjective esthetics, consistency of > syntax is important to both mechanical and biological parsers. > Meanwhile, "final" variables avoid ambiguities about programmer > intention for additional assignments to mutable variables, so "final" > works with extra grace for auto-typed variables. > > > From neal at gafter.com Sun Mar 22 00:27:18 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 22 Mar 2009 00:27:18 -0700 Subject: I need your opinion... Message-ID: <49c5e849.1f588c0a.291c.37ba@mx.google.com> A Java-like language went through this kind of change a few years ago and was extremely well received by its users. I understand your philosophical position, but it isn't supported by the evidence. -----Original Message----- From: Joshua Bloch Sent: Sunday, March 22, 2009 12:02 AM To: John Rose Cc: coin-dev Subject: Re: I need your opinion... Mark, I have to disagree with my esteemed colleague John on this one. I believe that every language has certain characteristics that make it what it is, and that these things simply shouldn't be changed. I believe that one such attribute of Java is that all declared entities have an explicit declared type. I believe it would do great harm to the language to change this. Josh On Sat, Mar 21, 2009 at 1:40 PM, John Rose wrote: > On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > > > Allow final variables and final Fields (except blank final), to not > > having explicit Type. > > Yes. Someone should work exactly this (and no more) into a separate > proposal, if it hasn't been done already. > > -- John > > Alternatives: "? foo" would sort of work since the "?" works, as a > wildcard, for some other type uses, but it is way too strange > looking. A new declare-and-assign operator would be nice for a wrist- > friendly language, but IMO it is too different from existing Java > declaration syntaxes. Beyond subjective esthetics, consistency of > syntax is important to both mechanical and biological parsers. > Meanwhile, "final" variables avoid ambiguities about programmer > intention for additional assignments to mutable variables, so "final" > works with extra grace for auto-typed variables. > > > From rssh at gradsoft.com.ua Sun Mar 22 00:27:39 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 22 Mar 2009 09:27:39 +0200 (EET) Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> Message-ID: <65b87d317c68362a0e2a1395ea53715f.squirrel@wmail.gradsoft.ua> > > The 'named' is a new context sensitive keyword (if 'module' can be > one, then this isn't too much of a stretch), and, only for named > methods, you can supply expressions that serve as defaults. Each > expression is evaluated exactly once, during your class initialization > (so, the ArrayList above is SHARED amongst all method invocations! - > I'd force it to be immutable but java does not have such a facility). > It is possible to restrict default parameters be final. It's not exactly 'immutable' but better than nothing. > > > Three questions: > > A) Is this a good idea? Do you like it? Would you use it? (I think its > stellar, but then, I'm proposing it). > for me - all ok except extra keyword. I think that it is possible do not add new keyword (by example - using annotation, which can be not only package-level, but class-level (for all methods) and package-level(for all classes in packages and subpackages); IMHO better just view all method as named, cost of incompatibility is less, than cost of adding new word in near each method definition) //Also Note, that javac is not only implementation of java parser, exists many parsers in tools, build with javacc and antrlr, wich have no support for 'context-depended' keywords in grammar. Adding each 'context-depended' framework to such grammars is non-trivial hack. > B) Did I miss something (is it more complicated than I make it out to > be), or is something unclear? Specifically, did I miss something that > does not make it backwards, migration, and source compatible? > > C) Might this be within scope for project coin? I'll definitely write > it up if it stands a chance. > > > --Reinier Zwitserloot > > > > On Mar 21, 2009, at 18:56, Marek Kozie?? wrote: > >> Builders are really great tool, but they need to be written manually. >> >> In other way there will be problem, if final object need contains data >> and builder only key for that data. >> >> >> >> -- >> Pozdrowionka. / Regards. >> Lasu aka Marek Kozie?? >> >> http://lasu2string.blogspot.com/ >> > > > From rssh at gradsoft.com.ua Sun Mar 22 00:48:50 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 22 Mar 2009 09:48:50 +0200 (EET) Subject: I need your opinion... In-Reply-To: <28bca0ff0903211447y1c77063fr4ddf8e53ad0ce611@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <28bca0ff0903211447y1c77063fr4ddf8e53ad0ce611@mail.gmail.com> Message-ID: >> > > I mean logic not name. > And this is nothing similar with traits (lisp I do not know). > Glue classes you can 'bind' to few classes at once. > May be. Different people think in different way. For me, glue classes is 'traits' (i.e. compositivie units of behaviour) mixed with 'extension methods'. I. e. reading you proposal I think 30 seconds, that say 'o, traits with extension method'. If word 'like traits wich can be bound to classes as extension methods' was in the first paragragh that time to understand such proposal for me, was 3 sec. instead 30. But this is only as my head work (I can tell you what is hard to understand only from my introspection, sorry). Other people think in different way, so may be functionality of glue classes is bound to such terms only for me. Other people will tell you what hard for them. Yet one thing, which can help: add more concrete example and describe in detail process of method call (if method call is changed on JVM level) or compiling to traditional java source code (if method call does not changed on JVM level). For example, I can't understand - how JVM or compiler will locate trait with such function signature during method call ? By building dependency 'glue dependency graph' and collecting candidated in all possible glue classes ? From fw at deneb.enyo.de Sun Mar 22 02:40:06 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 22 Mar 2009 10:40:06 +0100 Subject: I need your opinion... In-Reply-To: <28bca0ff0903211456i115eee6i6079ce8b377507a1@mail.gmail.com> ("Marek =?utf-8?Q?Kozie=C5=82=22's?= message of "Sat, 21 Mar 2009 22:56:51 +0100") References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <28bca0ff0903211456i115eee6i6079ce8b377507a1@mail.gmail.com> Message-ID: <87vdq1sxop.fsf@mid.deneb.enyo.de> * Marek Kozie?: >> What should be the inferred type of an expression with an intersection >> type? ?Is there an answer which is acceptable in the COIN context? > That would be type of type's intersection, just like it work now days: > > class A {} > class B extends A {} > > public static void main(String[] args) { > B some= (true?new A(): new B()); // error cannot cast A to B > } The type of the expression is A. I was wondering about the case of a method with a type parameter as the return type, and the type parameter has a bound containing an intersection type. This cannot be expressed using Java syntax. I'm not sure what would happen at the byte code level. It's probably fine to issue repeated casts for each use which doesn't match the erasure (but I seem to recall that interface types are reduced to Object anyway, so this might not be necessary). The JLS even says that variables can't have type parameters as their types, but there seems to be some mistake. From fw at deneb.enyo.de Sun Mar 22 02:43:57 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 22 Mar 2009 10:43:57 +0100 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> (Neal Gafter's message of "Sat, 21 Mar 2009 17:35:43 -0700") References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> Message-ID: <87r60psxia.fsf@mid.deneb.enyo.de> * Neal Gafter: > What's the problem just leaving the type of the variable an intersection > type? For local variables, I think it's possible. For fields, it requires class file format changes, and updates to the reflection and JSR 269 APIs. I could be mistaken, though. From develop4lasu at gmail.com Sun Mar 22 03:48:35 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 22 Mar 2009 11:48:35 +0100 Subject: I need your opinion... In-Reply-To: <49C5A096.8010706@sun.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <49C5A096.8010706@sun.com> Message-ID: <28bca0ff0903220348vf914ba9jc326ee17083b7c10@mail.gmail.com> 2009/3/22 Joseph D. Darcy : > Greetings. > > I find none of these compelling for Project Coin. > > -Joe > > Could you tell what 'compelling' mean for you? W dniu 22 marca 2009 08:02 u?ytkownik Joshua Bloch napisa?: > > Mark, > I have to disagree with my esteemed colleague John on this one. ?I believe > that every language has certain characteristics that make it what it is, and > that these things simply shouldn't be changed. ?I believe that one such > attribute of Java is that all declared entities have an explicit declared > type. ?I believe it would do great harm to the language to change this. > ?? Josh I agree with you, but in my opinion Java is not on last step of it's evolution. At simple code language gain powder to focus on logic, but while I started to use generics or multi-thread applications my focus moved to much to types. when you see code: return arraylist.get(arraylist.size()-1).getIdentificator().getName(); You can count that there are 4 valuse without explicit types: return arraylist.(Container get( (int arraylist.size()) -1)) .(Identificator getIdentificator())).( String getName()); As you see i added explicid types but it decreased redability of code, same thing programers need to deal with every day. Now second example: a) Standard code (+/-): String name = arraylist.get(arraylist.size()-1).getIdentificator().getName(); Data data = arraylist.get(arraylist.size()-1).Data(); ... b) Proper code: String name; Data data; { final Container lastPerson = arraylist.get(arraylist.size()-1); name = lastPerson.getIdentificator().getName(); data = lastPerson.Data(); } // lastPerson == you shouldn't use it ... c) with final (& forget): final lastPerson = arraylist.get(arraylist.size()-1); String name = lastPerson.getIdentificator().getName(); Data data = lastPerson.Data(); // forget lastPerson; // if you shouldn't use it any more Most peoples will not explicit declare lastPerson and write code in (a) form ( more compact code, do not have to deal with new variable on all method) , while in (b) case final and block is almost always overlooked, (c) force people to use proper style because if they will use final they will know that 'it is what it is' and, will think twice before make it value. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From howard.lovatt at iee.org Sun Mar 22 04:08:24 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Sun, 22 Mar 2009 22:08:24 +1100 Subject: PROPOSAL: Named method parameters Message-ID: <3dd3f56a0903220408r798e3c54nf35c756969134638@mail.gmail.com> Hi All, Couple of points: 1. Named parameters with default values can be coded reasonably easily at present: public class MyClass { public static class Args { public String name = "Fred"; public int age = 53; } public MyClass(Args args) { .... } } MyClass mc2 = new MyClass( new MyClass.Args() {{ name = "Joe"; }} ); 2. If some construct that allowed for new classes to be generated with less syntax made it into Java at some point in the future, e.g. http://www.artima.com/weblogs/viewpost.jsp?thread=182412 (which I suggested), then the above method would be even easier. Therefore it might not be a good time to introduce this since it could become obsolete. 3. It would be good if anything in this space was consistent with JavaFX (which has named parameters), so that call compatibility can be ensured. -- Howard. From vilya.harvey at gmail.com Sun Mar 22 04:42:36 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Sun, 22 Mar 2009 11:42:36 +0000 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <15e8b9d20903211730x23a69a98x3eba561a1fee87b8@mail.gmail.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> <15e8b9d20903211730x23a69a98x3eba561a1fee87b8@mail.gmail.com> Message-ID: <6aef848f0903220442v6de22dffsd5567418796fc54f@mail.gmail.com> 2009/3/22 Neal Gafter > On Sat, Mar 21, 2009 at 3:21 PM, Reinier Zwitserloot < > reinier at zwitserloot.com> wrote: > > > Of all methods that have the same name (but different paramlists, e.g. > > overloading), only one is allowed to be named in the first place. > > > Honestly, I think this is a fatal restriction. I like named parameters, > but > not if restricted to a single member of any overload set. > > Subjectively, most of the time I write overloaded methods as a way of providing default parameters for some cases. Actually being able to specify the default parameters in the first place would mean that I simply wouldn't need to have the overloads. Granted, there is the occasional case which doesn't fit in that pattern, but for me it's a minor case so it wouldn't be a show stopper - especially since you can fall back to the current position of just not using named parameters there. Vil. From paul.martin at gmail.com Sun Mar 22 05:57:53 2009 From: paul.martin at gmail.com (Paul Martin) Date: Sun, 22 Mar 2009 12:57:53 +0000 Subject: PROPOSAL: Named method parameters Message-ID: <4ce75f920903220557wcd903abh1f433f0931e7f731@mail.gmail.com> Hi, In reply to Howard Lovatt (who proposed a simpler syntax for creating classes): Your suggestion does seem interesting, but I have a few of questions: - Would it be possible for the compiler or a tool like Findbugs to ensure that all of the Args members had been set? Your example allows default values to be easily defined, but I don't think that the language can (currently) determine that name would always be set (if it didn't have a default). This was really one of my main arguments agaist the Builder pattern (which your proposal seems to refine). - Would the overhead of effectively creating a new anounymous inner class for every method invocation be significant? - In the general case, does this make the programmers intent clear - is passing an Args-style object effectively the same as just using named parameters directly? On the other hand, when my main desire is to use such parameters when constructing immutable object, then perhaps the distinction is moot. - Is this approach effectively the same as that suggested earlier by Florian Weimer, who noted that "Standard ML kind of solves the issue by having a lightweight syntax for constructing record values"? - How are JavaFX named parameters used/implemented? From what I can see, they are only used in object constructors, so perhaps they work in a similar way to your suggestion, though perhaps subclassing the class being constructed directly (rather than subclassing an argument class). I suppose the limitation with this (if that is correct) is that it might be harder to use static factory methods (though argument classes could then be used I expect). In any case, if named parameters are not implemented, I certainly think that your simpler Args class could be used in many cases instead of the more complex Builder. Regards, Paul From paul.martin at gmail.com Sun Mar 22 06:35:32 2009 From: paul.martin at gmail.com (Paul Martin) Date: Sun, 22 Mar 2009 13:35:32 +0000 Subject: PRE-PROPOSAL: Named method parameters with defaults. Message-ID: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> Hi, In reply to Reinier Zwitserloot's pre-proposal: Could you separate named parameters from default parameter values into two proposals, since I don't think that they need to be directly related? Could you take the C++ approach of only allowing default values for parameters at the end of the parameter list? The compiler could then synthesise additional overloaded methods with and without the default parameters being used. Rather than having a shared instance variable (which would not work for static methods, would not be thread-safe, and could only use immutable objects, unless I misunderstood your explanation), could the compiler just add extra statements to the beginning of each method to initialise the default value (depending upon whether the parameter was passed)? This does of course mean that default parameters can only be used at the end of the parameter list, but is perhaps easier to integrate. However, I'm not sure how @Override would be handled - what would happen if you overrode a method and then added an extra default parameter (calls made using a default value for the new parameter are effectively calling a method that overrides the original, but calls that specify a value for the new parameter are not). Maybe that would just be an error? After that, I think that your suggestion for named parameters seem largely similar to mine, though with different implementation details: - 'named' keyword instead of @PublicParameterNames annotation - Only one named method for overloaded methods and same parameter names for overridden methods instead of not having those restrictions (I am not sure why you thought that you needed them - was that the interaction of default parameters?) - Store parameter names using debug-style mechanisms instead of adding annotations (I wasn't really aware that this could be done). I'm not too concerned about the particular implementation approach chosen, as long as the result is reasonable! How far do proposals in project coin have to go when specifying implementations? More generally, does anyone know why named parameters were not implemented in earlier versions of Java? Paul From reinier at zwitserloot.com Sun Mar 22 06:55:56 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Mar 2009 14:55:56 +0100 Subject: Anyone ever considered named tuples? In-Reply-To: <15e8b9d20903211741m3ac58828o197162183a47ff1@mail.gmail.com> References: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> <15e8b9d20903211741m3ac58828o197162183a47ff1@mail.gmail.com> Message-ID: <2B47822E-2ED5-417F-87A9-7F6AF502F76B@zwitserloot.com> Actually, you could create this quite simply without changing the type system by allowing a simpler syntax to create POJOs. Something like: public data class Person { String name; int age; boolean male; } which would be compiled to a method with those fields as private final, 1 constructor (would dovetail nicely with the 'named' suggestion), 3 public getters named according to javabean semantics (getName, getAge, isMale), a toString, an equals, a hashCode, and a clone method. You can add more methods to it if you want to, and even replace the auto-generated ones (if its already there, it won't be autogenerated). --Reinier Zwitserloot On Mar 22, 2009, at 01:41, Neal Gafter wrote: > The standard name for this kind of thing is "structural types". > Today, when > this kind of need arises in Java people are forced to define a POD > ("plain-old-data") class (nominal type) as the container. Without > considering its merits, as an extension of the type system such > things are > out of scope for project Coin. > > On Sat, Mar 21, 2009 at 5:07 PM, Paulo Levi wrote: > >> Out of the blue, a few days ago, i wondered if a tuple construct >> that had >> names, >> ie: (String directory, String file) for instance, would make any >> sense? >> I know that spaghetti code should be factored to map to simple >> functions >> with simple return arguments, but i saw sooooo much code that had >> simple >> container semantics. >> A tuple object written as a compiler code transformation like >> autoboxing >> would make >> a lot of sense if it allowed names to be defined at use site. >> I'm sure you know that this can be simulated by some creative use of >> generics and static import, >> but the names (one ... first) are pretty bad. >> >> Just throwing a idea, don't bite my head off. >> >> > From reinier at zwitserloot.com Sun Mar 22 07:01:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Mar 2009 15:01:07 +0100 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> Message-ID: The problem would be complexity; now, for the first time, you can have method-local variables whose type is an intersection type; until now that wasn't possible. I don't advocate allowing this syntax for fields (private final foo = "hello!";) but if that is ever added, what type would foo be if you ask via reflection? If that kind of complexity is within scope for coin, by all means. If type intersections already find a common supertype in the obvious cases, that's great! Makes this proposal even simpler. --Reinier Zwitserloot On Mar 22, 2009, at 01:35, Neal Gafter wrote: > Type inference, and the lub() operation that generates these > intersection types, does not produce intersection types in which any > member is a subtype of any other member of the set of intersected > types. So, these rules about how to handle such situations are not > necessary. > > What's the problem just leaving the type of the variable an > intersection type? > > On Sat, Mar 21, 2009 at 3:51 PM, Reinier Zwitserloot > wrote: > Intersection types are annoying, to say the least. Possibly hand-wave > it away by stating that you can't use those expressions in this new > language construct. > > Or, a slight adaptation to that: If all but 1 of the intersection > types are subtypes of the other one, and this can be said for only 1 > type, then that type wins. Thus: > > final foo = someBoolean ? Arrays.asList("foo", "bar") : new > ArrayList(); > > foo's type would be List, because that's the type of one of > the intersections (List), and all other types of that > intersection (ArrayList) are a subtype of this, and there's no > other type for which this can be said. However, writing up the > specifics of this sounds difficult to say the least, and it can always > be added in java8 if it causes an inordinate amount of whining. > > Either way, this: > > final foo = someBoolean ? new LinkedList() : new > ArrayList(); > > would be a compiler error. What should foo be? List? > AbstractList? Serializable? Cloneable? Object? They're all > common supertypes, and there's no clear winner in the set; attempting > to use the nearest common parent still gives you 2 winning options: > Serializable, and Cloneable, while in actual fact you were probably > shooting for List, which isn't even close to the winner here, > what with AbstractList in the way, and AbstractList itself being 2 > removed from LinkedList, which extends AbstractSequentialList, which > extends AbstractList. > > > I think it'll be okay to just compiler-error on those, because I > expect the majority usage would be something akin to: > > final foo = methodCall(); > > --Reinier Zwitserloot > > > > On Mar 21, 2009, at 22:46, Florian Weimer wrote: > > > * John Rose: > > > >> On Mar 21, 2009, at 12:52 PM, Marek Kozie? wrote: > >> > >>> Allow final variables and final Fields (except blank final), to > not > >>> having explicit Type. > >> > >> Yes. Someone should work exactly this (and no more) into a > separate > >> proposal, if it hasn't been done already. > > > > What should be the inferred type of an expression with an > intersection > > type? Is there an answer which is acceptable in the COIN context? > > > > > From reinier at zwitserloot.com Sun Mar 22 07:07:03 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Mar 2009 15:07:03 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <65b87d317c68362a0e2a1395ea53715f.squirrel@wmail.gradsoft.ua> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> <65b87d317c68362a0e2a1395ea53715f.squirrel@wmail.gradsoft.ua> Message-ID: <71110083-83E3-458A-9296-FB4D8250B7DE@zwitserloot.com> Making them final doesn't help at all. The extra keyword is neccessary because I don't see any other way of making it work. Annotations aren't the right vehicle for this, as has been said many times on the coin-dev list. There are other parsers out there, yes, and I'm an opponent of context- sensitive keywords, but that decision has -already- been made: 'module' is going to be a context-sensitive keyword in java7, and no amount of chatter on coin-dev is going to change this. I'm rolling with it :) --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 22, 2009, at 08:27, rssh at gradsoft.com.ua wrote: >> >> The 'named' is a new context sensitive keyword (if 'module' can be >> one, then this isn't too much of a stretch), and, only for named >> methods, you can supply expressions that serve as defaults. Each >> expression is evaluated exactly once, during your class >> initialization >> (so, the ArrayList above is SHARED amongst all method invocations! - >> I'd force it to be immutable but java does not have such a facility). >> > > It is possible to restrict default parameters be final. It's not > exactly > 'immutable' but better than nothing. > >> >> >> Three questions: >> >> A) Is this a good idea? Do you like it? Would you use it? (I think >> its >> stellar, but then, I'm proposing it). >> > > for me - all ok except extra keyword. I think that it is possible do > not > add new keyword (by example - using annotation, which can be not only > package-level, but class-level (for all methods) and package-level(for > all classes in packages and subpackages); IMHO better just view all > method as > named, cost of incompatibility is less, than cost of adding new word > in > near each method definition) > > //Also Note, that javac is not only implementation of java parser, > exists > many parsers in tools, build with javacc and antrlr, wich have no > support > for 'context-depended' keywords in grammar. Adding each 'context- > depended' > framework to such grammars is non-trivial hack. > > > >> B) Did I miss something (is it more complicated than I make it out to >> be), or is something unclear? Specifically, did I miss something that >> does not make it backwards, migration, and source compatible? >> >> C) Might this be within scope for project coin? I'll definitely write >> it up if it stands a chance. >> >> >> --Reinier Zwitserloot >> >> >> >> On Mar 21, 2009, at 18:56, Marek Kozie?? wrote: >> >>> Builders are really great tool, but they need to be written >>> manually. >>> >>> In other way there will be problem, if final object need contains >>> data >>> and builder only key for that data. >>> >>> >>> >>> -- >>> Pozdrowionka. / Regards. >>> Lasu aka Marek Kozie?? >>> >>> http://lasu2string.blogspot.com/ >>> >> >> >> > > From reinier at zwitserloot.com Sun Mar 22 07:53:57 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Mar 2009 15:53:57 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <15e8b9d20903211730x23a69a98x3eba561a1fee87b8@mail.gmail.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> <15e8b9d20903211730x23a69a98x3eba561a1fee87b8@mail.gmail.com> Message-ID: As Vilya suggested, with default parameters, the need for overloading mostly goes away. However, I don't see how the restriction can go away. Given: public named void foo(String arg1, int arg2 = 5, String arg3 = "foo") {} public named void foo(String arg1 = "bar", String arg3) {} which method is to be called for this method invocation: foo(arg1: "a", arg3: "b"); There's absolutely no way to tell. There are plenty of tricks to apply to ensure the above situation cannot occur, but trying to write up a formal spec for those feels extremely un-coin-ish. My proposal involves foregoing the ability to overload for now; there is nothing in the proposal that prevents a future addition to the JLS to allow it, including the complex ruleset needed to ensure ambiguous situations cannot occur. An attempt at a ruleset to allow overloading: 1) For all named methods, first produce a signature list. This list consists of treating each parameter type/name pair as either existing or not existing (IF it has a default), or existing (if it does not). So, the first 'foo' method above would boil down to this list: void(arg1: String, arg2: int, arg3: String) void(arg1: String, arg2: int) void(arg1: String, arg3: String) void(arg1: String) 2) For each method name, concatenate all the lists. 3) Check if there are duplicates in the list. A duplicate consists of 100% match between BOTH name AND type. If there is such a duplicate, generate a compile time error. If there is NO such duplicate, that doesn't neccessarily mean it will compile; the usual rules of overloading still apply. The following two methods would be okay under this ruleset but still wouldn't compile: named void foo(String arg1, String arg2) {} named void foo(String arg3, String arg4) {} I'd love to write it up if somebody gives me some direction in regards to whether this is A) A good idea, B) fits within coin, and C) Should or should not include the extra complication listed above. --Reinier Zwitserloot On Mar 22, 2009, at 01:30, Neal Gafter wrote: > On Sat, Mar 21, 2009 at 3:21 PM, Reinier Zwitserloot > wrote: > Of all methods that have the same name (but different paramlists, e.g. > overloading), only one is allowed to be named in the first place. > > Honestly, I think this is a fatal restriction. I like named > parameters, but not if restricted to a single member of any overload > set. From neal at gafter.com Sun Mar 22 07:54:08 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 22 Mar 2009 07:54:08 -0700 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <87r60psxia.fsf@mid.deneb.enyo.de> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> <87r60psxia.fsf@mid.deneb.enyo.de> Message-ID: <15e8b9d20903220754ha406f83k7effd345954c77aa@mail.gmail.com> On Sun, Mar 22, 2009 at 2:43 AM, Florian Weimer wrote: > * Neal Gafter: > > > What's the problem just leaving the type of the variable an intersection > > type? > > For local variables, I think it's possible. For fields, it requires > class file format changes, and updates to the reflection and JSR 269 > APIs. I could be mistaken, though. > I would suggest this kind of type inference only be allowed for local variables. That makes the spec and implementation fairly simple. From fw at deneb.enyo.de Sun Mar 22 08:15:06 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 22 Mar 2009 16:15:06 +0100 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <15e8b9d20903220754ha406f83k7effd345954c77aa@mail.gmail.com> (Neal Gafter's message of "Sun, 22 Mar 2009 07:54:08 -0700") References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> <87r60psxia.fsf@mid.deneb.enyo.de> <15e8b9d20903220754ha406f83k7effd345954c77aa@mail.gmail.com> Message-ID: <87iqm1fv2d.fsf@mid.deneb.enyo.de> * Neal Gafter: > On Sun, Mar 22, 2009 at 2:43 AM, Florian Weimer wrote: > >> * Neal Gafter: >> >> > What's the problem just leaving the type of the variable an intersection >> > type? >> >> For local variables, I think it's possible. For fields, it requires >> class file format changes, and updates to the reflection and JSR 269 >> APIs. I could be mistaken, though. >> > > I would suggest this kind of type inference only be allowed for local > variables. That makes the spec and implementation fairly simple. Makes sense. Does the definition of LocalVariableTypeTable need updating? I assume the intersection type would show up in it. (I can't find its specification, unfortunately. It seems this wasn't merged into the JVM spec.) From reinier at zwitserloot.com Sun Mar 22 08:42:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sun, 22 Mar 2009 16:42:07 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> Message-ID: <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> I just don't see much value in named parameters without having defaults (or using them to choose between overloads, but that would require massive changes). Defaults without named parameters does have interesting use cases, but withOUT named parameters, you add two extra complications that do NOT exist if you force-combine them with named parameters: 1) Given: foo("bar");, which of the two parameters is supposed to be "bar" and which is supposed to be "foo" if the method sig is: public void foo(String a = "foo", String b = "bar") {}? That problem does not arise with named params. 2) For backwards compatibility reasons, defaults don't kick in unless a compiler specifically accounts for them (after all, its magic that occurs mostly on the invocation side!).Your method is essentially flagged. The 'named' keyword makes this process less transparent, which is IMO a good thing. In other words, only the defaults aspect of it is worth separating, but separating that doesn't really make the proposal much simpler. If I'm undervaluing the benefits of named parameters, by all means, fill out a proposal yourself and/or edit the one I'll be writing up. Contact me so we can work together. --Reinier Zwitserloot On Mar 22, 2009, at 14:35, Paul Martin wrote: > Hi, > > In reply to Reinier Zwitserloot's pre-proposal: > > Could you separate named parameters from default parameter values into > two proposals, since I don't think that they need to be directly > related? > > Could you take the C++ approach of only allowing default values for > parameters at the end of the parameter list? The compiler could then > synthesise additional overloaded methods with and without the default > parameters being used. Rather than having a shared instance variable > (which would not work for static methods, would not be thread-safe, > and could only use immutable objects, unless I misunderstood your > explanation), could the compiler just add extra statements to the > beginning of each method to initialise the default value (depending > upon whether the parameter was passed)? > > This does of course mean that default parameters can only be used at > the end of the parameter list, but is perhaps easier to integrate. > However, I'm not sure how @Override would be handled - what would > happen if you overrode a method and then added an extra default > parameter (calls made using a default value for the new parameter are > effectively calling a method that overrides the original, but calls > that specify a value for the new parameter are not). Maybe that would > just be an error? > > After that, I think that your suggestion for named parameters seem > largely similar to mine, though with different implementation details: > - 'named' keyword instead of @PublicParameterNames annotation > - Only one named method for overloaded methods and same parameter > names for overridden methods instead of not having those restrictions > (I am not sure why you thought that you needed them - was that the > interaction of default parameters?) > - Store parameter names using debug-style mechanisms instead of adding > annotations (I wasn't really aware that this could be done). > > I'm not too concerned about the particular implementation approach > chosen, as long as the result is reasonable! How far do proposals in > project coin have to go when specifying implementations? > > > More generally, does anyone know why named parameters were not > implemented in earlier versions of Java? > > Paul > From rssh at gradsoft.com.ua Sun Mar 22 08:51:24 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 22 Mar 2009 17:51:24 +0200 (EET) Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <71110083-83E3-458A-9296-FB4D8250B7DE@zwitserloot.com> References: <4ce75f920903210915pa2b27b3g38841e342a78de77@mail.gmail.com> <15e8b9d20903210926k18d73f32h796446aeb873a6a8@mail.gmail.com> <87tz5mbx0v.fsf@mid.deneb.enyo.de> <28bca0ff0903211056p577e1757r4e21913ca627ce63@mail.gmail.com> <65b87d317c68362a0e2a1395ea53715f.squirrel@wmail.gradsoft.ua> <71110083-83E3-458A-9296-FB4D8250B7DE@zwitserloot.com> Message-ID: > Making them final doesn't help at all. > > The extra keyword is neccessary because I don't see any other way of > making it work. Annotations aren't the right vehicle for this, as has Why not made all methods be with named parameters by default ? For classes, which compiled with pre-7 compiler, just use defaults values for names, for example _1, _2, .. etc. > been said many times on the coin-dev list. > Hmm, I missed something (?) Sorry, can you point me to right mail in archive or tell why annotations is impossible. ? I remember annotation critics but with same reasons, as I criticize new keywords. > There are other parsers out there, yes, and I'm an opponent of context- > sensitive keywords, but that decision has -already- been made: > 'module' is going to be a context-sensitive keyword in java7, and no > amount of chatter on coin-dev is going to change this. I'm rolling > with it :) > One hack better than two hacks, .... which is better then 100 hacks. But you are right - this is question of taste. > --Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On Mar 22, 2009, at 08:27, rssh at gradsoft.com.ua wrote: > >>> >>> The 'named' is a new context sensitive keyword (if 'module' can be >>> one, then this isn't too much of a stretch), and, only for named >>> methods, you can supply expressions that serve as defaults. Each >>> expression is evaluated exactly once, during your class >>> initialization >>> (so, the ArrayList above is SHARED amongst all method invocations! - >>> I'd force it to be immutable but java does not have such a facility). >>> >> >> It is possible to restrict default parameters be final. It's not >> exactly >> 'immutable' but better than nothing. >> >>> >>> >>> Three questions: >>> >>> A) Is this a good idea? Do you like it? Would you use it? (I think >>> its >>> stellar, but then, I'm proposing it). >>> >> >> for me - all ok except extra keyword. I think that it is possible do >> not >> add new keyword (by example - using annotation, which can be not only >> package-level, but class-level (for all methods) and package-level(for >> all classes in packages and subpackages); IMHO better just view all >> method as >> named, cost of incompatibility is less, than cost of adding new word >> in >> near each method definition) >> >> //Also Note, that javac is not only implementation of java parser, >> exists >> many parsers in tools, build with javacc and antrlr, wich have no >> support >> for 'context-depended' keywords in grammar. Adding each 'context- >> depended' >> framework to such grammars is non-trivial hack. >> >> >> >>> B) Did I miss something (is it more complicated than I make it out to >>> be), or is something unclear? Specifically, did I miss something that >>> does not make it backwards, migration, and source compatible? >>> >>> C) Might this be within scope for project coin? I'll definitely write >>> it up if it stands a chance. >>> >>> >>> --Reinier Zwitserloot >>> >>> >>> >>> On Mar 21, 2009, at 18:56, Marek Kozie????? wrote: >>> >>>> Builders are really great tool, but they need to be written >>>> manually. >>>> >>>> In other way there will be problem, if final object need contains >>>> data >>>> and builder only key for that data. >>>> >>>> >>>> >>>> -- >>>> Pozdrowionka. / Regards. >>>> Lasu aka Marek Kozie????? >>>> >>>> http://lasu2string.blogspot.com/ >>>> >>> >>> >>> >> >> > > From rssh at gradsoft.com.ua Sun Mar 22 09:14:15 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 22 Mar 2009 18:14:15 +0200 (EET) Subject: PROPOSAL: Named method parameters Message-ID: >void method(int a, String b) and void method(String b, int a) > > Currently these are treated as separate methods and can be resolved > correctly, but if named parameters allowed you to reorder them, then it > might be more difficult to choose the correct implementation (particularly > if there are other parameters that are not reordered, and/or you have a > hierarchy of overridden and overloaded classes). This would also require (In java we already have such situation with varargs and autoboxing - JSL specify choose method with minimum number of transformations between argument list and set of method parameters) Also I belive, that just raise compiler error when changes only permutations are acceptable. From neal at gafter.com Sun Mar 22 10:04:28 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 22 Mar 2009 10:04:28 -0700 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <87iqm1fv2d.fsf@mid.deneb.enyo.de> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> <87r60psxia.fsf@mid.deneb.enyo.de> <15e8b9d20903220754ha406f83k7effd345954c77aa@mail.gmail.com> <87iqm1fv2d.fsf@mid.deneb.enyo.de> Message-ID: <15e8b9d20903221004g2e9b9679lfdf82330c231d624@mail.gmail.com> On Sun, Mar 22, 2009 at 8:15 AM, Florian Weimer wrote: > * Neal Gafter: > > I would suggest this kind of type inference only be allowed for local > > variables. ? That makes the spec and implementation fairly simple. > > Makes sense. > > Does the definition of LocalVariableTypeTable need updating? ?I assume > the intersection type would show up in it. ?(I can't find its > specification, unfortunately. ?It seems this wasn't merged into the > JVM spec.) The spec you're looking for is http://java.sun.com/docs/books/vmspec/2nd-edition/ClassFileFormat-final-draft.pdf Yes, section 4.4.4 would have to add a syntax for intersection types, and the implementation of the debugging APIs would need to be extended to handle it. No VM changes are required, though, as the VM just ignores these attributes. From develop4lasu at gmail.com Sun Mar 22 11:58:51 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 22 Mar 2009 19:58:51 +0100 Subject: Final variables without explicit type: Intersection types issue. In-Reply-To: <15e8b9d20903220754ha406f83k7effd345954c77aa@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <87y6uy35x7.fsf@mid.deneb.enyo.de> <0C5E9B01-3748-450D-B5A0-39A59C6B7B84@zwitserloot.com> <15e8b9d20903211735r2135f69cqb3a9e04891fbb433@mail.gmail.com> <87r60psxia.fsf@mid.deneb.enyo.de> <15e8b9d20903220754ha406f83k7effd345954c77aa@mail.gmail.com> Message-ID: <28bca0ff0903221158o17db4794ua16fe471d8157093@mail.gmail.com> 2009/3/22 Neal Gafter : > On Sun, Mar 22, 2009 at 2:43 AM, Florian Weimer wrote: > > I would suggest this kind of type inference only be allowed for local > variables. ?That makes the spec and implementation fairly simple. > > This should be configurable, like: On highest security level: Omitting type is allowed if equal is followed by new keyword or by cast expression. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Sun Mar 22 14:35:18 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 22 Mar 2009 14:35:18 -0700 Subject: (update) Use "default" keyword for default visibility In-Reply-To: <49AF0E94.6000206@sun.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <49AD1C0B.3070907@joda.org> <43577BD5-8BD8-45F0-B190-EB04FBB283C3@iam.unibe.ch> <49AF0E94.6000206@sun.com> Message-ID: <49C6AF16.5090803@sun.com> Greetings. Joseph D. Darcy wrote: > Hello. > > While the lack of an explicit name for the default accessibility in > Java has slightly annoyed me at times over the years, I don't think it > in isolation is such a troublesome issue that a language change is > warranted. > I've conferred with Alex on this request. Since the JSR 294 expert group is working on adding a "module" accessibility level to the language, that group is in a good position to weigh the pros and cons of adding an explicit "package" modifier at the same time, a change they are considering. Therefore, Project Coin should defer the decision on an explicit package modifier to the JSR 294 expert group. -Joe From develop4lasu at gmail.com Sun Mar 22 15:10:42 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 22 Mar 2009 23:10:42 +0100 Subject: Glue classes proposal 0.9 In-Reply-To: <49C5A253.5000304@sun.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <49C5A253.5000304@sun.com> Message-ID: <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> 2009/3/22 Joseph D. Darcy : > From this proposal, I do not understand what you are trying to propose. > > -Joe > > 2009/3/22 : > > ?May be. Different people think in different way. > For me, glue classes is 'traits' (i.e. compositivie units of behaviour) > mixed with 'extension methods'. I. e. reading you proposal I think 30 > seconds, that say 'o, traits with extension method'. If word 'like traits > wich can be bound to classes as extension methods' was in the first > paragragh that time to understand such proposal for me, was 3 sec. instead > 30. ?But this is only as my head work (I can tell you what is hard to > understand only from my introspection, sorry). ?Other people think in > different way, so may be functionality of glue classes is bound to such > terms only for me. Other people will tell you what hard for them. > > Yet one thing, which can help: add more concrete example and describe > in detail process of method call (if method call is changed on JVM level) > ?or compiling to traditional java source code (if method call does not > changed on JVM level). > > For example, I can't understand - how JVM or compiler will locate trait > with such function signature during method call ? By building dependency > 'glue dependency graph' and collecting candidated in all possible glue > classes ? > > I'll follow full process then. Let's say, we write sample program doing something... Part 1 (we have already some glue classes defined) class Some{ T[] elements; } Now, we need all elements greater than given one import java.util.arrays.base; import java.util.arrays.sorted; class Some{ T[] elements; T[] getGreater(T element, Comparator comparator){ T[] ret = elements.clone(); ret..sort( comparator ); int index =ret..binarySearch( element, comparator ); if (index==0) return ret; if (index>=0) return ret..copyOfRange( index, ret.length ); else{ index = Math.min(-index -1, ret.length); return ret..copyOfRange( index, ret.length ); } } } When we write: ret..sort(...) java.util.arrays.base is added to import. We can even make it more precise and write ret..base.sort(...) which can help to be clear what logic we are using, or ret..java.util.arrays.base.sort(...) not as nice as read but it allows to write correct code in some rare cases. In my opinion, this looks really simple and what's more, it's highly resistant to changes. If someone adds the same method in some jar used in project, a whole code will be still more or less OK. If we do not have class with added method (let it be sort()) and we use short notation ..sort(...), everything will be still OK (then we may want to see the warning because that code is unclear) and if we used normal notation ..base.sort(...), then (even if we have modified class in import), all will be working fine. The only problem is when we have two glue classes in import with the same methods and we use short notation, when error should occurs. All those behaviours are common for Java classes. Now, the same code today, for comparing: class Some { T[] elements; T[] getGreater(T element, Comparator comparator) { T[] ret = elements.clone(); Arrays.sort(ret, comparator); int index = Arrays.binarySearch(ret, element, comparator); if (index == 0) return ret; if (index >= 0) return Arrays.copyOfRange(ret, index, ret.length); else { index = Math.min(-index - 1, ret.length); return Arrays.copyOfRange(ret, index, ret.length); } } } 2. Glue classes localization: As you can see glue class header contains in itself a method header and can be used to determine if object is valid for binding: class sorted glue (T[]) {...} So you can think about it as a class with method glue: glue (T[] valid){ /* nothing */ } if type is valid for parameter 'valid' in this method, then glue will work. This means that we can use intersection and bounds if we need them. 3. Glue class names. Glue class names should start with lower case, because it groups sub-logic rather than a new one. 4. header resolving of dynamic methods Let's consider: class sorted glue (T[]) { glue int binarySearch(this, T element,Comparator comparator){...} } after mixing glue class header with binarySearch method we will obtain: static int binarySearch(T[] this, T element,Comparator comparator){...} So as you can see, finally it's s normal static method (with object passed as first parameter in background) in which form glue method(s) should be compiled (this would allow to call this methods from older Java versions). This means also that current utils classes can be mostly converted to new form with backward compatibility. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From paul.martin at gmail.com Sun Mar 22 15:28:10 2009 From: paul.martin at gmail.com (Paul Martin) Date: Sun, 22 Mar 2009 22:28:10 +0000 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> Message-ID: <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> Hi, > I just don't see much value in named parameters without having defaults (or > using them to choose between overloads, but that would require massive > changes). Defaults without named parameters does have interesting use cases, > but withOUT named parameters, you add two extra complications that do NOT > exist if you force-combine them with named parameters: I'm particularly interested in using named parameters to help call constructors or factory methods of immutable classes, where a number of final member variables need to be set. The named parameters help describe the calls, and in this case default parameters would not necessarily be needed. Certainly named parameters and defaults affect similar areas of the language, and might work well together, but I think that we can also consider them separately (as well as together). In particular I consider that named parameters let you achieve something that is hard to do otherwise (readable lists of mandatory parameters), whereas default parameters can be achieved with overloaded methods (delegating to a 'master' method). > 1) Given: foo("bar");, which of the two parameters is supposed to be "bar" > and which is supposed to be "foo" if the method sig is: > > public void foo(String a = "foo", String b = "bar") {}? > > That problem does not arise with named params. If C++-style default parameters are used, then only default parameters at the end of the parameter list can be used. In this example, a would be set to "bar" and b would default to "bar". Or with one of your examples from an earlier thread: public named void foo(String arg1, int arg2 = 5, String arg3 = "foo") {} Then the following call would be an error: foo(arg1: "a", arg3: "b"); Only the following calls would be allowed: foo(arg1: "a", arg2: 2, arg3: "b"); foo(arg1: "a", arg2: 2); foo(arg1: "a"); This would simplify method selection, and I suppose would be the only way to do so without named parameters. Requiring the use of named parameters could let you use defaults in the middle of the parameter list, but then you are left with restrictions on how they can be overloaded and overridden (which might be more problematic). > If I'm undervaluing the benefits of named parameters, by all means, fill out > a proposal yourself and/or edit the one I'll be writing up. Contact me so we > can work together. I think that my named parameters proposal (in an earlier thread) still largely holds, though it doesn't consider default values, and the use of annotations seems to be contentious (and is certainly not the only solution), but I think that it potentially requires the fewest changes to the language. However, I think that named parameters with default values and also just default parameter values would also be valid and useful proposals, and probably provide more functionality at the cost of greater change required. In addition, the simpler constructor syntax mentioned by Howard Lovatt could also be useful (but maybe out of scope of Project Coin). There also seem to be a range of ways to implement named parameters which really be applied to each solution (annotations, keywords, and named parameters by default). Therefore, do you know what the real goal of the proposals presented in this group should be? Is it to just identify the possibilities and discover their advantages and disadvantages, or is some consensus also required? Should just one (potentially combined) proposal be produced for named parameters, or should separate proposals be produced for each variation? Does the compiler group have any suggestions (Joe Darcy)? I'm certainly happy to help in any way (and am enjoying these constructive discussions). Paul From tim at peierls.net Sun Mar 22 15:29:38 2009 From: tim at peierls.net (Tim Peierls) Date: Sun, 22 Mar 2009 18:29:38 -0400 Subject: Glue classes proposal 0.9 In-Reply-To: <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <49C5A253.5000304@sun.com> <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> Message-ID: <63b4e4050903221529o6c4d4f55kc6562451d36bcded@mail.gmail.com> On Sun, Mar 22, 2009 at 6:10 PM, Marek Kozie? wrote: > I'll follow full process then. > > Let's say, we write sample program doing something... > > Part 1 (we have already some glue classes defined) I couldn't get past this point. What's a glue class? --tim From Mike.Duigou at Sun.COM Sun Mar 22 15:55:57 2009 From: Mike.Duigou at Sun.COM (Mike Duigou) Date: Sun, 22 Mar 2009 15:55:57 -0700 Subject: Loosen Constructor super()/this() call restrictions Message-ID: AUTHOR(S): Mike Duigou OVERVIEW FEATURE SUMMARY: Currently, if present, a call to another constructer via super() or this() must be the first statement of a constructor. This proposal would loosen the restrictions on calls to super() and this () to allow local variable declaration and several types of statements to appear before the call to super() or this(). MAJOR ADVANTAGE: This proposal is most useful when the constructor parameters must be mutated before calling the other super() or this() constructor. MAJOR BENEFIT: This proposal may allow for simpler, easier to understand constructions in the calling of super() and this() constructors. It also eliminates the need for some static factory methods which are currently used to work around this problem. The resulting code is more uniform in the use of constructors to create objects. MAJOR DISADVANTAGE: This is a change to the Java language grammar and will require changes to compilers, static analysis tools and any other uses that parse Java source code. ALTERNATIVES: The common alternatives when the input parameters cannot be easily mutated into the required parameters for calling another constructor are to provide a static factory method that does the work instead of a constructor. Private varargs constructors that understand a specific order of parameters passed are also used. EXAMPLES Show us the code! SIMPLE EXAMPLE: /** * presents a measurement in fractional inches. */ public class Inches { private final int numerator; private final int denominator; public Inches( int numerator, int denominator ) { this.numerator = numerator; this.denominator = denominator; } public Inches( int whole, int numerator, int denominator ) { // simple this() call this( whole * denominator + numerator, denominator ); } /** * A private constructor for the unpleasant technique of using var args to pass * constructor parameters. */ private Inches( int ... params ) { this(params[0], params[1]); } /** * Makes use of a static method to transform decimal into numerator and denominator * which are then passed to the private varargs constructor. */ public Inches( float decimal ) { this(convert(decimal)); } /** * produces a length 2 int array with the numerator at index 0 and the * denominator at index 1 */ private static int[] convert(float decimal) { int[] result = new int[2]; // [0] numerator, [1] denominator // ... conversion happens here ... return result; } /** * Static factory method which does the conversion and returns * a new Inch object */ public static Inches toInches(double) { int dec_numerator; int dec_denominator; // ... conversion happens here ... return new Inches( dec_numerator, dec_denominator ); } /** * Converts a decimal fraction measurement in inches to it's closest fractional representation. * Note : accuracy is limited to 1/1024th. */ public Inches( double decimal ) { int dec_numerator; // not allowed by Java 6 grammar int dec_denominator; if( Math.abs(decimal) < (1.0 / 1024) ) { dec_numerator = 0; dec_denominator = 1; } else { // ... conversion happens here ... } this( dec_numerator, dec_denominator ); } The Inches(double decimal) constructor demonstrates the new grammar by declaring local variables and performing calculations upon the input parameter before calling another constructor via this(). This example is important because the conversion from a decimal fraction to a numerator and denominator produces two results from one input. DETAILS SPECIFICATION: The grammar is extended to allow declaration of local variables and statements involving only local variables, parameters, static fields and static methods to occur before the super() or this() constructor is called. COMPILATION: Unknown impact. TESTING: No special testing requirements are required for this extension. Simple unit tests should be able to exercise all of the required behaviour. LIBRARY SUPPORT: None. REFLECTIVE APIS: Calling constructors via reflection as an alternative to explicit calls to this() or super() constructors is not currently supported and this change does not impact that. OTHER CHANGES: No changes are likely needed to JNI, Javadoc or JPDA. MIGRATION: Most source changes to use this feature would be manually performed as they likely entail the introduction of new local variables to hold intermediate results before super() or this() is called. New constructors could be provided to take the place of static factory methods and the methods deprecated and replaced with one statement bodies consisting of "return new Foo()" with matching params to their own. COMPATIBILITY BREAKING CHANGES: I believe this change is 100% backwards compatible for source code as it does not restrict or change the meaning of any existing statements. EXISTING PROGRAMS: As all of the changes are captured within the constructor method it is unlikely existing programs would be impacted by this change. REFERENCES EXISTING BUGS: None known. URL FOR PROTOTYPE (optional): None available. From develop4lasu at gmail.com Sun Mar 22 16:26:42 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 00:26:42 +0100 Subject: Anyone ever considered named tuples? In-Reply-To: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> References: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> Message-ID: <28bca0ff0903221626g4662f8b3g673134ee5f87622d@mail.gmail.com> 2009/3/22 Paulo Levi : > Out of the blue, a few days ago, i wondered if a tuple construct that had > names, > ie: (String directory, String file) for instance, would make any sense? > I know that spaghetti code should be factored to map to simple functions > with simple return arguments, but i saw sooooo much code that had simple > container semantics. > A tuple object written as a compiler code transformation like autoboxing > would make > a lot of sense if it allowed names to be defined at use site. > I'm sure you know that this can be simulated by some creative use of > generics and static import, > but the names (one ... first) are pretty bad. > > Just throwing a idea, don't bite my head off. > > You need tuples or multiple return values? I do not see any good reason to introduce tuples. While no multiple return values is lack in language in my opinion. See simple method: (boolean isSucceed, T replaced) replace(T element){ int i = index(element); if (i<0) return(false,null); T old = elements[i]; elements[i] = element; return (true,old); } use: void sample_1(...){ boolean efect = container.replace(element).isSucceed; ... } void sample_2(...){ Boo old = container.replace(element).replaced; ... } void sample_3(...){ (boolean efect = .isSucceed,Boo old = .replaced) = container.replace(element); ... } void sample_4(...){ final replaced = container.replace(element); boolean efect = replaced.isSucceed; Boo old = replaced.replaced; // forget replaced; ... } Did you ever tried to do it now time? synchronize(container){ T old = container.get(element); if (old!=null){ // problem if element is null container.replace(element); } } But there is no point to introduce that if we will have to index results. I also disagree that maps should be used to obtain that target, while this can be done in 100% in 'static' way. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sun Mar 22 16:27:43 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 00:27:43 +0100 Subject: Glue classes proposal 0.9 In-Reply-To: <63b4e4050903221529o6c4d4f55kc6562451d36bcded@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <49C5A253.5000304@sun.com> <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> <63b4e4050903221529o6c4d4f55kc6562451d36bcded@mail.gmail.com> Message-ID: <28bca0ff0903221627l1a0715d7xac0170de6ef3da8a@mail.gmail.com> W dniu 22 marca 2009 23:29 u?ytkownik Tim Peierls napisa?: > On Sun, Mar 22, 2009 at 6:10 PM, Marek Kozie? > wrote: >> >> ?? ? ? I'll follow full process then. >> >> Let's say, we write sample program doing something... >> >> Part 1 (we have already some glue classes defined) > > I couldn't get past this point. What's a glue class? > --tim At start, think about it as classes responsible for adding new methods to existing types. here glue classes are: - base - sorted glue methods are: - .sort(...) - .binarySearch(...) - .copyOfRange(...) -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sun Mar 22 16:36:23 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 00:36:23 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> Message-ID: <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> 1. Problems: - in notation suggested by you, compilator and people may find problem with determining valid method signature (when we have few methods with same names) Same as now time: void a(Boo boo); void a(String booName); call: .a((String) null); now imagine that Boo is generic ... - when some one would change default value (how already compiled code should react?), that why i think that values should be stored on special static fields. 2. Some solution could bring keeping parameter blank for default value: foo(,"bar"); // first is default; foo("bar",); // second is default; 3. Genesis If you think that this can replace builders, then in my opinion you are wrong. When class need so many parameters, so it become problem to list them in proper order, then obtaining those data is also problem, so even if we will have named parameters 'generally' problem will do not decrease. I found it while I created some library: It become common for peoples that while it was hard for them to collect all data at once they produces their own builders, so at end, to many parameters mean that in each dependent project someone will create it's own builder, and it's no mater, if they will be able to call parameters by names, or not. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Sun Mar 22 16:48:46 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Mar 2009 00:48:46 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> Message-ID: <05C1E4C5-B65B-4800-A14D-FB274257E0E2@zwitserloot.com> 1. [problems with determining correct method signature] Not a (new) problem - that's a problem of overloading in general. Names help, if anything. Also one of the reasons for my suggestion to only allow 'named' on one method in a stack of overloads. Also: that's why the 'named' keyword is required and why there is no default 'everything is named' option. Old code uses no names -> no defaults either -> no issues with existing code that has much overloading with ample opportunity for ambiguous invocations if defaults are introduced. 2. [What happens if defaults change?] Changing default value is fine of course - they are stored in fields in the same class as the method. 3. [Builder pattern still needed because of order] But you CAN change the order. --Reinier Zwitserloot On Mar 23, 2009, at 00:36, Marek Kozie? wrote: > 1. Problems: > - in notation suggested by you, compilator and people may find problem > with determining valid method signature (when we have few methods with > same names) > Same as now time: > void a(Boo boo); > void a(String booName); > call: > .a((String) null); > now imagine that Boo is generic ... > > - when some one would change default value (how already compiled code > should react?), that why i think that values should be stored on > special static fields. > > 2. Some solution could bring keeping parameter blank for default > value: > foo(,"bar"); // first is default; > foo("bar",); // second is default; > > 3. Genesis > If you think that this can replace builders, then in my opinion you > are wrong. > When class need so many parameters, so it become problem to list them > in proper order, then obtaining those data is also problem, so even if > we will have named parameters 'generally' problem will do not > decrease. > I found it while I created some library: > It become common for peoples that while it was hard for them to > collect all data at once they produces their own builders, so at end, > to many parameters mean that in each dependent project someone will > create it's own builder, and it's no mater, if they will be able to > call parameters by names, or not. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From develop4lasu at gmail.com Sun Mar 22 17:07:36 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 01:07:36 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <05C1E4C5-B65B-4800-A14D-FB274257E0E2@zwitserloot.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> <05C1E4C5-B65B-4800-A14D-FB274257E0E2@zwitserloot.com> Message-ID: <28bca0ff0903221707gc2cb032la8ec17c4e547df35@mail.gmail.com> 2009/3/23 Reinier Zwitserloot : [snip] > 3. [Builder pattern still needed because of order] But you CAN change the > order. > > ?--Reinier Zwitserloot Yes i know. But functionality of this solution is limited, while interactions are huge. If you will need give all for example 9 parameters, you will still need to check if you didn't omitted any, this mean more text for analyse. In this code you can ignore some parameter if you need: class SomeBuilder{ SomeBuilder setA(A a){...}; SomeBuilder setB(B a){...}; ... } call: new Some( new SomeBuilder().setA(a).setB(b)... ); When there is a lot parameters soon or later you will need builder (more or less). What more when happen that you will want obtain A & B & C from some new created object D: All modification for builder will be adding method: SomeBuilder setABC(D d){...}; , while in given solution you will need copy & paste constructor and modify it. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Sun Mar 22 17:47:09 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Mar 2009 01:47:09 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <28bca0ff0903221707gc2cb032la8ec17c4e547df35@mail.gmail.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> <05C1E4C5-B65B-4800-A14D-FB274257E0E2@zwitserloot.com> <28bca0ff0903221707gc2cb032la8ec17c4e547df35@mail.gmail.com> Message-ID: If your goal is to find a way to eliminate the builder pattern - good luck. I don't think any proposal other than the builder pattern can replace the builder pattern. Even python and friends have rare usage of the builder pattern. This proposal has named parameters, defaults, and allows shuffling order. What more could you possibly want out of a proposal to make direct method invocation easier when there are many parameters? --Reinier Zwitserloot On Mar 23, 2009, at 01:07, Marek Kozie? wrote: > 2009/3/23 Reinier Zwitserloot : > [snip] >> 3. [Builder pattern still needed because of order] But you CAN >> change the >> order. >> >> --Reinier Zwitserloot > > Yes i know. > But functionality of this solution is limited, while interactions > are huge. > If you will need give all for example 9 parameters, you will still > need to check if you didn't omitted any, this mean more text for > analyse. > > In this code you can ignore some parameter if you need: > class SomeBuilder{ > SomeBuilder setA(A a){...}; > SomeBuilder setB(B a){...}; > ... > } > > call: > new Some( new SomeBuilder().setA(a).setB(b)... ); > > When there is a lot parameters soon or later you will need builder > (more or less). > > What more when happen that you will want obtain A & B & C from some > new created object D: > All modification for builder will be adding method: > SomeBuilder setABC(D d){...}; > , while in given solution you will need copy & paste constructor and > modify it. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ From jeremy.manson at gmail.com Sun Mar 22 17:49:30 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 22 Mar 2009 17:49:30 -0700 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: References: Message-ID: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> It seems to me that you might need more semantics. For example, the specification should probably work with the definite assignment rules to make sure that the calls to super / this, if present, both definitely happen and only happen exactly once per constructor. Here are a couple of constructors for class Foo that should probably result in compilation errors: Foo() { if (something) { super(blah) } } Foo() { super(blah); super(blah); } Also, it seems to me that you would want to be careful about access to fields of the parent object before the invocation of super(). Jeremy On Sun, Mar 22, 2009 at 3:55 PM, Mike Duigou wrote: > ? ? AUTHOR(S): Mike Duigou > > ? ? OVERVIEW > > ? ? FEATURE SUMMARY: Currently, if present, a call to another > constructer via super() or this() must be the first statement of a > constructor. This proposal would loosen the restrictions on calls to > super() and this () to allow local variable declaration and ?several > types of statements to appear before the call to super() or this(). > > ? ? MAJOR ADVANTAGE: This proposal is most useful when the > constructor parameters must be mutated before calling the other > super() or this() constructor. > > ? ? MAJOR BENEFIT: This proposal may allow for simpler, easier to > understand constructions in the calling of super() and this() > constructors. It also eliminates the need for some static factory > methods which are currently used to work around this problem. The > resulting code is more uniform in the use of constructors to create > objects. > > ? ? MAJOR DISADVANTAGE: This is a change to the Java language grammar > and will require changes to compilers, static analysis tools and any > other uses that parse Java source code. > > ? ? ALTERNATIVES: The common alternatives when the input parameters > cannot be easily mutated into the required parameters for calling > another constructor are to provide a static factory method that does > the work instead of a constructor. Private varargs constructors that > understand a specific order of parameters passed are also used. > > ? ? EXAMPLES > > ? ? Show us the code! > > ? ? SIMPLE EXAMPLE: > > ? ? ? ?/** > ? ? ? ? * ? presents a measurement in fractional inches. > ? ? ? ? */ > ? ? ? ?public class Inches { > ? ? ? ? ? ?private final int numerator; > > ? ? ? ? ? ?private final int denominator; > > ? ? ? ? ? ? public Inches( int numerator, int denominator ) { > ? ? ? ? ? ? ? ?this.numerator = numerator; > ? ? ? ? ? ? ? ? this.denominator = denominator; > ? ? ? ? ? ?} > > ? ? ? ? ? ?public Inches( int whole, int numerator, int denominator ) { > ? ? ? ? ? ? ? ? // simple this() call > ? ? ? ? ? ? ? ? this( whole * denominator + numerator, denominator ); > ? ? ? ? ? ?} > > ? ? ? ? ? ?/** > ? ? ? ? ? ? * A private constructor for the unpleasant technique of > using var args to pass > ? ? ? ? ? ? * constructor parameters. > ? ? ? ? ? ?*/ > ? ? ? ? ? ?private Inches( int ... params ) { > ? ? ? ? ? ? ? ? this(params[0], params[1]); > ? ? ? ? ? ?} > > ? ? ? ? ? ?/** > ? ? ? ? ? ?* ? Makes use of a static method to transform decimal into > numerator and denominator > ? ? ? ? ? ?* ? which are then passed to the private varargs constructor. > ? ? ? ? ? ?*/ > ? ? ? ? ? ? public Inches( float decimal ) { > ? ? ? ? ? ? ? ?this(convert(decimal)); > ? ? ? ? ? ?} > > ? ? ? ? ? ?/** > ? ? ? ? ? ?* produces a length 2 int array with the numerator at index 0 and > the > ? ? ? ? ? ? * denominator at index 1 > ? ? ? ? ? ? */ > ? ? ? ? ? ?private static int[] convert(float decimal) { > ? ? ? ? ? ? ? ?int[] result = new int[2]; // [0] numerator, [1] denominator > > ? ? ? ? ? ? ? ?// ... conversion happens here ... > > ? ? ? ? ? ? ? ?return result; > ? ? ? ? ? ?} > > ? ? ? ? ? ?/** > ? ? ? ? ? ?* Static factory method which does the conversion and returns > ? ? ? ? ? ? * a new Inch object > ? ? ? ? ? ? */ > ? ? ? ? ? ? public static Inches toInches(double) { > ? ? ? ? ? ? ? ?int dec_numerator; > ? ? ? ? ? ? ? ?int dec_denominator; > > ? ? ? ? ? ? ? ?// ... conversion happens here ... > > ? ? ? ? ? ? ? ?return new Inches( dec_numerator, dec_denominator ); > ? ? ? ? ? ?} > > ? ? ? ? ? ?/** > ? ? ? ? ? ? * ?Converts a decimal fraction measurement in inches to > it's closest fractional representation. > ? ? ? ? ? ? * ?Note : accuracy is limited to 1/1024th. > ? ? ? ? ? ?*/ > ? ? ? ? ? ?public Inches( double decimal ) { > ? ? ? ? ? ? ? ?int dec_numerator; ? ? ? // not allowed by Java 6 grammar > ? ? ? ? ? ? ? ?int dec_denominator; > > ? ? ? ? ? ? ? ?if( Math.abs(decimal) < (1.0 / 1024) ) { > ? ? ? ? ? ? ? ? ? ? ? ?dec_numerator = 0; > ? ? ? ? ? ? ? ? ? ? ? ?dec_denominator = 1; > ? ? ? ? ? ? ? ?} else { > ? ? ? ? ? ? ? ? ? ? ? ?// ... conversion happens here ... > ? ? ? ? ? ? ? ?} > > ? ? ? ? ? ? ? ?this( dec_numerator, dec_denominator ); > ? ? ? ? ? ?} > > ? ? ? ? ? The Inches(double decimal) constructor demonstrates the new > grammar by declaring local variables and performing calculations upon > the input parameter before calling another constructor via this(). > This example is important because the conversion from a decimal > fraction to a numerator and denominator produces two results from one > input. > > ? ? DETAILS > > ? ? SPECIFICATION: The grammar is extended to allow declaration of > local variables and statements involving only local variables, > parameters, static fields and static methods to occur before the > super() or this() constructor is called. > > ? ? COMPILATION: Unknown impact. > > ? ? TESTING: No special testing requirements are required for this > extension. Simple unit tests should be able to exercise all of > ? ? ? ?the required behaviour. > > ? ? LIBRARY SUPPORT: None. > > ? ? REFLECTIVE APIS: Calling constructors via reflection as an > alternative to explicit calls to this() or super() constructors is not > currently supported and this change does not impact that. > > ? ? OTHER CHANGES: No changes are likely needed to JNI, Javadoc or > JPDA. > > ? ? MIGRATION: Most source changes to use this feature would be > manually performed as they likely entail the introduction of new local > variables to hold intermediate results before super() or this() is > called. New constructors could be provided to take the place of static > factory methods and the methods deprecated and replaced with one > statement bodies consisting of "return new Foo()" with matching params > to their own. > > ? ? COMPATIBILITY > > ? ? BREAKING CHANGES: I believe this change is 100% backwards > compatible for source code as it does not restrict or change the > meaning of any existing statements. > > ? ? EXISTING PROGRAMS: As all of the changes are captured within the > constructor method it is unlikely existing programs would be > ? ? ? ?impacted by this change. > > ? ? REFERENCES > > ? ? EXISTING BUGS: None known. > > ? ? URL FOR PROTOTYPE (optional): None available. > > > From jeremy.manson at gmail.com Sun Mar 22 18:07:56 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 22 Mar 2009 18:07:56 -0700 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> Message-ID: <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> Also, you probably need to state that super will now be inserted as the first thing that happens in a constructor only when static analysis determines that there are no calls to super() or this() in the code. One of the benefits of super() being the first thing called in a constructor was that a subclass could never see a partially initialized version of its super-class stuff. With that in mind, what are the new semantics like? For example, now that this() and super() can come in the middle of a constructor, are the semantics implicitly changed so that you can catch exceptions thrown by this() and super()? Does that mean that objects can now be seen as partially initialized in sub-constructors? In the same vein, is there any desire to prevent code from accessing fields / methods of superclasses before super() is invoked? Jeremy On Sun, Mar 22, 2009 at 5:49 PM, Jeremy Manson wrote: > It seems to me that you might need more semantics. ?For example, the > specification should probably work with the definite assignment rules > to make sure that the calls to super / this, if present, both > definitely happen and only happen exactly once per constructor. ?Here > are a couple of constructors for class Foo that should probably result > in compilation errors: > > ?Foo() { > ? ?if (something) { > ? ? ?super(blah) > ? ?} > ?} > ?Foo() { > ? ?super(blah); > ? ?super(blah); > ?} > > Also, it seems to me that you would want to be careful about access to > fields of the parent object before the invocation of super(). > > Jeremy > > On Sun, Mar 22, 2009 at 3:55 PM, Mike Duigou wrote: >> ? ? AUTHOR(S): Mike Duigou >> >> ? ? OVERVIEW >> >> ? ? FEATURE SUMMARY: Currently, if present, a call to another >> constructer via super() or this() must be the first statement of a >> constructor. This proposal would loosen the restrictions on calls to >> super() and this () to allow local variable declaration and ?several >> types of statements to appear before the call to super() or this(). >> >> ? ? MAJOR ADVANTAGE: This proposal is most useful when the >> constructor parameters must be mutated before calling the other >> super() or this() constructor. >> >> ? ? MAJOR BENEFIT: This proposal may allow for simpler, easier to >> understand constructions in the calling of super() and this() >> constructors. It also eliminates the need for some static factory >> methods which are currently used to work around this problem. The >> resulting code is more uniform in the use of constructors to create >> objects. >> >> ? ? MAJOR DISADVANTAGE: This is a change to the Java language grammar >> and will require changes to compilers, static analysis tools and any >> other uses that parse Java source code. >> >> ? ? ALTERNATIVES: The common alternatives when the input parameters >> cannot be easily mutated into the required parameters for calling >> another constructor are to provide a static factory method that does >> the work instead of a constructor. Private varargs constructors that >> understand a specific order of parameters passed are also used. >> >> ? ? EXAMPLES >> >> ? ? Show us the code! >> >> ? ? SIMPLE EXAMPLE: >> >> ? ? ? ?/** >> ? ? ? ? * ? presents a measurement in fractional inches. >> ? ? ? ? */ >> ? ? ? ?public class Inches { >> ? ? ? ? ? ?private final int numerator; >> >> ? ? ? ? ? ?private final int denominator; >> >> ? ? ? ? ? ? public Inches( int numerator, int denominator ) { >> ? ? ? ? ? ? ? ?this.numerator = numerator; >> ? ? ? ? ? ? ? ? this.denominator = denominator; >> ? ? ? ? ? ?} >> >> ? ? ? ? ? ?public Inches( int whole, int numerator, int denominator ) { >> ? ? ? ? ? ? ? ? // simple this() call >> ? ? ? ? ? ? ? ? this( whole * denominator + numerator, denominator ); >> ? ? ? ? ? ?} >> >> ? ? ? ? ? ?/** >> ? ? ? ? ? ? * A private constructor for the unpleasant technique of >> using var args to pass >> ? ? ? ? ? ? * constructor parameters. >> ? ? ? ? ? ?*/ >> ? ? ? ? ? ?private Inches( int ... params ) { >> ? ? ? ? ? ? ? ? this(params[0], params[1]); >> ? ? ? ? ? ?} >> >> ? ? ? ? ? ?/** >> ? ? ? ? ? ?* ? Makes use of a static method to transform decimal into >> numerator and denominator >> ? ? ? ? ? ?* ? which are then passed to the private varargs constructor. >> ? ? ? ? ? ?*/ >> ? ? ? ? ? ? public Inches( float decimal ) { >> ? ? ? ? ? ? ? ?this(convert(decimal)); >> ? ? ? ? ? ?} >> >> ? ? ? ? ? ?/** >> ? ? ? ? ? ?* produces a length 2 int array with the numerator at index 0 and >> the >> ? ? ? ? ? ? * denominator at index 1 >> ? ? ? ? ? ? */ >> ? ? ? ? ? ?private static int[] convert(float decimal) { >> ? ? ? ? ? ? ? ?int[] result = new int[2]; // [0] numerator, [1] denominator >> >> ? ? ? ? ? ? ? ?// ... conversion happens here ... >> >> ? ? ? ? ? ? ? ?return result; >> ? ? ? ? ? ?} >> >> ? ? ? ? ? ?/** >> ? ? ? ? ? ?* Static factory method which does the conversion and returns >> ? ? ? ? ? ? * a new Inch object >> ? ? ? ? ? ? */ >> ? ? ? ? ? ? public static Inches toInches(double) { >> ? ? ? ? ? ? ? ?int dec_numerator; >> ? ? ? ? ? ? ? ?int dec_denominator; >> >> ? ? ? ? ? ? ? ?// ... conversion happens here ... >> >> ? ? ? ? ? ? ? ?return new Inches( dec_numerator, dec_denominator ); >> ? ? ? ? ? ?} >> >> ? ? ? ? ? ?/** >> ? ? ? ? ? ? * ?Converts a decimal fraction measurement in inches to >> it's closest fractional representation. >> ? ? ? ? ? ? * ?Note : accuracy is limited to 1/1024th. >> ? ? ? ? ? ?*/ >> ? ? ? ? ? ?public Inches( double decimal ) { >> ? ? ? ? ? ? ? ?int dec_numerator; ? ? ? // not allowed by Java 6 grammar >> ? ? ? ? ? ? ? ?int dec_denominator; >> >> ? ? ? ? ? ? ? ?if( Math.abs(decimal) < (1.0 / 1024) ) { >> ? ? ? ? ? ? ? ? ? ? ? ?dec_numerator = 0; >> ? ? ? ? ? ? ? ? ? ? ? ?dec_denominator = 1; >> ? ? ? ? ? ? ? ?} else { >> ? ? ? ? ? ? ? ? ? ? ? ?// ... conversion happens here ... >> ? ? ? ? ? ? ? ?} >> >> ? ? ? ? ? ? ? ?this( dec_numerator, dec_denominator ); >> ? ? ? ? ? ?} >> >> ? ? ? ? ? The Inches(double decimal) constructor demonstrates the new >> grammar by declaring local variables and performing calculations upon >> the input parameter before calling another constructor via this(). >> This example is important because the conversion from a decimal >> fraction to a numerator and denominator produces two results from one >> input. >> >> ? ? DETAILS >> >> ? ? SPECIFICATION: The grammar is extended to allow declaration of >> local variables and statements involving only local variables, >> parameters, static fields and static methods to occur before the >> super() or this() constructor is called. >> >> ? ? COMPILATION: Unknown impact. >> >> ? ? TESTING: No special testing requirements are required for this >> extension. Simple unit tests should be able to exercise all of >> ? ? ? ?the required behaviour. >> >> ? ? LIBRARY SUPPORT: None. >> >> ? ? REFLECTIVE APIS: Calling constructors via reflection as an >> alternative to explicit calls to this() or super() constructors is not >> currently supported and this change does not impact that. >> >> ? ? OTHER CHANGES: No changes are likely needed to JNI, Javadoc or >> JPDA. >> >> ? ? MIGRATION: Most source changes to use this feature would be >> manually performed as they likely entail the introduction of new local >> variables to hold intermediate results before super() or this() is >> called. New constructors could be provided to take the place of static >> factory methods and the methods deprecated and replaced with one >> statement bodies consisting of "return new Foo()" with matching params >> to their own. >> >> ? ? COMPATIBILITY >> >> ? ? BREAKING CHANGES: I believe this change is 100% backwards >> compatible for source code as it does not restrict or change the >> meaning of any existing statements. >> >> ? ? EXISTING PROGRAMS: As all of the changes are captured within the >> constructor method it is unlikely existing programs would be >> ? ? ? ?impacted by this change. >> >> ? ? REFERENCES >> >> ? ? EXISTING BUGS: None known. >> >> ? ? URL FOR PROTOTYPE (optional): None available. >> >> >> > From markmahieu at googlemail.com Sun Mar 22 18:14:43 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 23 Mar 2009 01:14:43 +0000 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> Message-ID: 2009/3/23 Jeremy Manson > > Also, it seems to me that you would want to be careful about access to > fields of the parent object before the invocation of super(). > > Jeremy > Yes, which implies no calls to other instance methods, or to static methods passing 'this' as an argument etc. Maybe a simple rule to build upon would be to say that anything before the call to this() or super() is effectively in a static context (ie no references to instance members, or to this/super, are allowed). There'd be more to it than that though. Also (Mike) there's at least one existing bug entry for this: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093999 Mark From markmahieu at googlemail.com Sun Mar 22 18:20:55 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 23 Mar 2009 01:20:55 +0000 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> Message-ID: 2009/3/23 Jeremy Manson > > For example, now that this() and super() can come in the middle of a > constructor, are the semantics implicitly changed so that you can > catch exceptions thrown by this() and super()? Does that mean that > objects can now be seen as partially initialized in sub-constructors? > Ha, there's a bug entry for that one too: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4879515 Mark From develop4lasu at gmail.com Sun Mar 22 18:25:26 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 02:25:26 +0100 Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> <05C1E4C5-B65B-4800-A14D-FB274257E0E2@zwitserloot.com> <28bca0ff0903221707gc2cb032la8ec17c4e547df35@mail.gmail.com> Message-ID: <28bca0ff0903221825v184d7471o5f46d10dee1bdf64@mail.gmail.com> 2009/3/23 Reinier Zwitserloot : > If your goal is to find a way to eliminate the builder pattern - good luck. > I don't think any proposal other than the builder pattern can replace the > builder pattern. Even python and friends have rare usage of the builder > pattern. > > This proposal has named parameters, defaults, and allows shuffling order. > What more could you possibly ?want out of a proposal to make direct method > invocation easier when there are many parameters? > > ?--Reinier Zwitserloot > I need ask you about something. Where do you see problem: - when creating such method invocation? - reading such invocation? - while refactoring? My conclusions: - default values are quite good if blank === default, and even better if blank === null === default - reordering parameters is wrong path, will create more confusion: 9 parameters mean 9! = 362880 combinations o.O - having named parameters is OK, but not in given form: method(Some some){ call(some = ?New?,...); } 'some' is parameter in call or variable from current block. Maybe IDE (with compiler) should create proper signature( and re-check it): method(Some some){ call( /** some =*/ ?New? ,... ); } or method(Some some){ call( ?New? //* some ,1 //* length ,... ); } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sun Mar 22 18:38:10 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 02:38:10 +0100 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> Message-ID: <28bca0ff0903221838k665a6e5bl66a36ba82762116@mail.gmail.com> 2009/3/23 Mark Mahieu : > 2009/3/23 Jeremy Manson >> >> For example, now that this() and super() can come in the middle of a >> constructor, are the semantics implicitly changed so that you can >> catch exceptions thrown by this() and super()? ?Does that mean that >> objects can now be seen as partially initialized in sub-constructors? >> > > Ha, there's a bug entry for that one too: > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4879515 > > Mark > > this() super() work 100% correctly now days. But maybe the thing you need is not this 'weird' behavior of constructor. Consider new kind of method 'initializer': - Can be executed only in constructors. - Can assign value to final fields, only condition is to assign it always. class Sample{ final Foo foo; final Bar bar; public Sample(FooBuilder foo, Bar bar){ initFoo(foo); // compiler known that foo is assigned this.bar = bar.copy(); } public Sample(FooBuilder foo, BarBuilder bar){ initFoo(foo); // compiler known that foo is assigned initBar(bar); // compiler know that bar is assigned } public Sample(Foo foo, BarBuilder bar){ this.foo = foo.copy(); initBar(bar); // compiler know that bar is assigned } initializer void initFoo(FooBuilder foo){ //operations to create foo // we have foo this.foo = foo; } initializer void initBar(BarBuilder bar){ //operations to create bar // we have bar this. bar = bar; } } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From markmahieu at googlemail.com Sun Mar 22 18:50:36 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 23 Mar 2009 01:50:36 +0000 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <28bca0ff0903221838k665a6e5bl66a36ba82762116@mail.gmail.com> References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> <28bca0ff0903221838k665a6e5bl66a36ba82762116@mail.gmail.com> Message-ID: Marek, Other than being able to give a name to your 'initializers', I'm not sure what you're gaining with that compared to what's already supported, eg: class Foo { private final int i; public Foo() { this(42); } private Foo(int j) { i = j; } } Regards, Mark 2009/3/23 Marek Kozie? > 2009/3/23 Mark Mahieu : > > 2009/3/23 Jeremy Manson > >> > >> For example, now that this() and super() can come in the middle of a > >> constructor, are the semantics implicitly changed so that you can > >> catch exceptions thrown by this() and super()? Does that mean that > >> objects can now be seen as partially initialized in sub-constructors? > >> > > > > Ha, there's a bug entry for that one too: > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4879515 > > > > Mark > > > > > > this() super() work 100% correctly now days. > > But maybe the thing you need is not this 'weird' behavior of constructor. > > Consider new kind of method 'initializer': > - Can be executed only in constructors. > - Can assign value to final fields, only condition is to assign it always. > > > > class Sample{ > final Foo foo; > final Bar bar; > > public Sample(FooBuilder foo, Bar bar){ > initFoo(foo); // compiler known that foo is assigned > this.bar = bar.copy(); > } > > public Sample(FooBuilder foo, BarBuilder bar){ > initFoo(foo); // compiler known that foo is assigned > initBar(bar); // compiler know that bar is assigned > } > > public Sample(Foo foo, BarBuilder bar){ > this.foo = foo.copy(); > initBar(bar); // compiler know that bar is assigned > } > > initializer void initFoo(FooBuilder foo){ > //operations to create foo > // we have foo > this.foo = foo; > } > > initializer void initBar(BarBuilder bar){ > //operations to create bar > // we have bar > this. bar = bar; > } > > } > > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From tim at peierls.net Sun Mar 22 19:31:43 2009 From: tim at peierls.net (Tim Peierls) Date: Sun, 22 Mar 2009 22:31:43 -0400 Subject: Glue classes proposal 0.9 In-Reply-To: <28bca0ff0903221627l1a0715d7xac0170de6ef3da8a@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <49C5A253.5000304@sun.com> <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> <63b4e4050903221529o6c4d4f55kc6562451d36bcded@mail.gmail.com> <28bca0ff0903221627l1a0715d7xac0170de6ef3da8a@mail.gmail.com> Message-ID: <63b4e4050903221931j358d283ei6301db71270b1e68@mail.gmail.com> On Sun, Mar 22, 2009 at 7:27 PM, Marek Kozie? wrote: > >> Let's say, we write sample program doing something... > >> Part 1 (we have already some glue classes defined) > > > > I [Tim] couldn't get past this point. What's a glue class? > > At start, think about it as classes responsible for adding new methods to > existing types. > I'm completely baffled by all of this. --tim From Mike.Duigou at Sun.COM Sun Mar 22 21:30:01 2009 From: Mike.Duigou at Sun.COM (Mike Duigou) Date: Sun, 22 Mar 2009 21:30:01 -0700 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> Message-ID: <805D1335-2F96-462E-8E1C-F32686592BE5@Sun.COM> On Mar 22, 2009, at 6:14 PM, Mark Mahieu wrote: > 2009/3/23 Jeremy Manson Also, it seems to > me that you would want to be careful about access to > fields of the parent object before the invocation of super(). > > Jeremy > > Yes, which implies no calls to other instance methods, or to static > methods passing 'this' as an argument etc. Maybe a simple rule to > build upon would be to say that anything before the call to this() > or super() is effectively in a static context (ie no references to > instance members, or to this/super, are allowed). There'd be more > to it than that though. Your clarification is correct. Before the explicit call to super() or this() no reference to instance fields or methods is allowed because the object hasn't been created yet. The case where no explicit call to super/this() is made is a little harder because an implicit call to the no params super() method needs to be inserted before the first reference to an instance field or method in order to construct the object. > Also (Mike) there's at least one existing bug entry for this: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093999 Hmmm, thanks! That should have been easy to find. Perhaps I searched only open bugs. Mike From Mike.Duigou at Sun.COM Sun Mar 22 21:39:03 2009 From: Mike.Duigou at Sun.COM (Mike Duigou) Date: Sun, 22 Mar 2009 21:39:03 -0700 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> <1631da7d0903221807v12d5c692n1075e9e1fc321b2d@mail.gmail.com> Message-ID: <5CDC0D77-1E87-4AAE-BD84-051362613315@Sun.COM> On Mar 22, 2009, at 6:07 PM, Jeremy Manson wrote: > Also, you probably need to state that super will now be inserted as > the first thing that happens in a constructor only when static > analysis determines that there are no calls to super() or this() in > the code. > > One of the benefits of super() being the first thing called in a > constructor was that a subclass could never see a partially > initialized version of its super-class stuff. With that in mind, what > are the new semantics like? My intention was not to not change initialization sematics. Since no access is allowed to any instance methods or fields before the super() the object need not be constructed until the super() call is actually made. > For example, now that this() and super() can come in the middle of a > constructor, are the semantics implicitly changed so that you can > catch exceptions thrown by this() and super()? Does that mean that > objects can now be seen as partially initialized in sub-constructors? > > In the same vein, is there any desire to prevent code from accessing > fields / methods of superclasses before super() is invoked? > I don't wish to change the object initialization semantics at all. No access to instance fields or methods is allowed before an explicit super()/this() call and if there is no explicit super() then an implicit super() is added before the first time "this" is needed to access either field or method. Sorry if that wasn't clear. Changing the initialization semantics to make partially constructed objects visible would make an unholy mess that I can't imagine would ever be worthwhile. > Jeremy > > On Sun, Mar 22, 2009 at 5:49 PM, Jeremy Manson > wrote: >> It seems to me that you might need more semantics. For example, the >> specification should probably work with the definite assignment rules >> to make sure that the calls to super / this, if present, both >> definitely happen and only happen exactly once per constructor. Here >> are a couple of constructors for class Foo that should probably >> result >> in compilation errors: >> >> Foo() { >> if (something) { >> super(blah) >> } >> } >> Foo() { >> super(blah); >> super(blah); >> } >> >> Also, it seems to me that you would want to be careful about access >> to >> fields of the parent object before the invocation of super(). >> >> Jeremy >> >> On Sun, Mar 22, 2009 at 3:55 PM, Mike Duigou >> wrote: >>> AUTHOR(S): Mike Duigou >>> >>> OVERVIEW >>> >>> FEATURE SUMMARY: Currently, if present, a call to another >>> constructer via super() or this() must be the first statement of a >>> constructor. This proposal would loosen the restrictions on calls to >>> super() and this () to allow local variable declaration and several >>> types of statements to appear before the call to super() or this(). >>> >>> MAJOR ADVANTAGE: This proposal is most useful when the >>> constructor parameters must be mutated before calling the other >>> super() or this() constructor. >>> >>> MAJOR BENEFIT: This proposal may allow for simpler, easier to >>> understand constructions in the calling of super() and this() >>> constructors. It also eliminates the need for some static factory >>> methods which are currently used to work around this problem. The >>> resulting code is more uniform in the use of constructors to create >>> objects. >>> >>> MAJOR DISADVANTAGE: This is a change to the Java language >>> grammar >>> and will require changes to compilers, static analysis tools and any >>> other uses that parse Java source code. >>> >>> ALTERNATIVES: The common alternatives when the input parameters >>> cannot be easily mutated into the required parameters for calling >>> another constructor are to provide a static factory method that does >>> the work instead of a constructor. Private varargs constructors that >>> understand a specific order of parameters passed are also used. >>> >>> EXAMPLES >>> >>> Show us the code! >>> >>> SIMPLE EXAMPLE: >>> >>> /** >>> * presents a measurement in fractional inches. >>> */ >>> public class Inches { >>> private final int numerator; >>> >>> private final int denominator; >>> >>> public Inches( int numerator, int denominator ) { >>> this.numerator = numerator; >>> this.denominator = denominator; >>> } >>> >>> public Inches( int whole, int numerator, int >>> denominator ) { >>> // simple this() call >>> this( whole * denominator + numerator, >>> denominator ); >>> } >>> >>> /** >>> * A private constructor for the unpleasant technique of >>> using var args to pass >>> * constructor parameters. >>> */ >>> private Inches( int ... params ) { >>> this(params[0], params[1]); >>> } >>> >>> /** >>> * Makes use of a static method to transform decimal >>> into >>> numerator and denominator >>> * which are then passed to the private varargs >>> constructor. >>> */ >>> public Inches( float decimal ) { >>> this(convert(decimal)); >>> } >>> >>> /** >>> * produces a length 2 int array with the numerator at >>> index 0 and >>> the >>> * denominator at index 1 >>> */ >>> private static int[] convert(float decimal) { >>> int[] result = new int[2]; // [0] numerator, [1] >>> denominator >>> >>> // ... conversion happens here ... >>> >>> return result; >>> } >>> >>> /** >>> * Static factory method which does the conversion and >>> returns >>> * a new Inch object >>> */ >>> public static Inches toInches(double) { >>> int dec_numerator; >>> int dec_denominator; >>> >>> // ... conversion happens here ... >>> >>> return new Inches( dec_numerator, dec_denominator ); >>> } >>> >>> /** >>> * Converts a decimal fraction measurement in inches to >>> it's closest fractional representation. >>> * Note : accuracy is limited to 1/1024th. >>> */ >>> public Inches( double decimal ) { >>> int dec_numerator; // not allowed by Java 6 >>> grammar >>> int dec_denominator; >>> >>> if( Math.abs(decimal) < (1.0 / 1024) ) { >>> dec_numerator = 0; >>> dec_denominator = 1; >>> } else { >>> // ... conversion happens here ... >>> } >>> >>> this( dec_numerator, dec_denominator ); >>> } >>> >>> The Inches(double decimal) constructor demonstrates the >>> new >>> grammar by declaring local variables and performing calculations >>> upon >>> the input parameter before calling another constructor via this(). >>> This example is important because the conversion from a decimal >>> fraction to a numerator and denominator produces two results from >>> one >>> input. >>> >>> DETAILS >>> >>> SPECIFICATION: The grammar is extended to allow declaration of >>> local variables and statements involving only local variables, >>> parameters, static fields and static methods to occur before the >>> super() or this() constructor is called. >>> >>> COMPILATION: Unknown impact. >>> >>> TESTING: No special testing requirements are required for this >>> extension. Simple unit tests should be able to exercise all of >>> the required behaviour. >>> >>> LIBRARY SUPPORT: None. >>> >>> REFLECTIVE APIS: Calling constructors via reflection as an >>> alternative to explicit calls to this() or super() constructors is >>> not >>> currently supported and this change does not impact that. >>> >>> OTHER CHANGES: No changes are likely needed to JNI, Javadoc or >>> JPDA. >>> >>> MIGRATION: Most source changes to use this feature would be >>> manually performed as they likely entail the introduction of new >>> local >>> variables to hold intermediate results before super() or this() is >>> called. New constructors could be provided to take the place of >>> static >>> factory methods and the methods deprecated and replaced with one >>> statement bodies consisting of "return new Foo()" with matching >>> params >>> to their own. >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: I believe this change is 100% backwards >>> compatible for source code as it does not restrict or change the >>> meaning of any existing statements. >>> >>> EXISTING PROGRAMS: As all of the changes are captured within the >>> constructor method it is unlikely existing programs would be >>> impacted by this change. >>> >>> REFERENCES >>> >>> EXISTING BUGS: None known. >>> >>> URL FOR PROTOTYPE (optional): None available. >>> >>> >>> >> -- Mike Duigou Senior Staff Engineer APS CSG CTO AD Sun Microsystems Inc. From jeremy.manson at gmail.com Sun Mar 22 22:10:51 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Sun, 22 Mar 2009 22:10:51 -0700 Subject: Glue classes proposal 0.9 In-Reply-To: <63b4e4050903221931j358d283ei6301db71270b1e68@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <49C5A253.5000304@sun.com> <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> <63b4e4050903221529o6c4d4f55kc6562451d36bcded@mail.gmail.com> <28bca0ff0903221627l1a0715d7xac0170de6ef3da8a@mail.gmail.com> <63b4e4050903221931j358d283ei6301db71270b1e68@mail.gmail.com> Message-ID: <1631da7d0903222210h290a650apa02cdd7d5e864a57@mail.gmail.com> I believe that what Marek is trying to do is to introduce a feature that allows you to add (or glue) methods to existing classes. You could have, for example: // Glue class to add sorting to Lists class Sort glue(List) { void sort(List l) { // sorts the argument } } And then later say: List list = new ArrayList(); // adds elements to list list..sort(); // The ".." notation invokes Sort.sort() on list. It seems like rather a large change to me, and is along the same lines as some other proposals that have been rejected as out of scope. But perhaps Joe thinks otherwise. Jeremy 2009/3/22 Tim Peierls : > On Sun, Mar 22, 2009 at 7:27 PM, Marek Kozie? wrote: > >> >> Let's say, we write sample program doing something... >> >> Part 1 (we have already some glue classes defined) >> > >> > I [Tim] couldn't get past this point. What's a glue class? >> >> At start, think about it as classes responsible for adding new methods to >> existing types. >> > > I'm completely baffled by all of this. > > --tim > > From Joe.Darcy at Sun.COM Sun Mar 22 22:44:20 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 22 Mar 2009 22:44:20 -0700 Subject: Proposal: Access to Generic Type Parameters at Compile-Time In-Reply-To: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> References: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> Message-ID: <49C721B4.1010703@sun.com> David Walend wrote: > I've been hesitating to submit this proposal because I have seen so > few other people push generics as hard as I do. However, the > discussion around method and field literals -- and adding type > parameters to Field and Method -- may make it more relevant than I > first thought. > > My test for reflection APIs is using the API to convert between a > class in memory and bytes in a stream. One common corner case is > converting Map. I often create a simple class for the > chore. If Field becomes parameterized, I'll be using > Field> in that class, and will perhaps be creating > specialized classes for different Keys and Values. If the Key or Value > types take parameters, the generics will be three layers deep. > > Type parameters on methods that return types with their own type > parameters invites developers to wade into the depths of layered > generics. This proposal addresses one of the associated pain points. > > I've attempted to write a spec section which I hope is clear. I'm not > sure it's wrong. > > What do you think? > > Dave > > David Walend > david at walend.net > > --- > > Access to Generic Type Parameters at Compile-Time > > AUTHOR: David Walend > > OVERVIEW > > FEATURE SUMMARY: > > This feature allows a developer to gain dot access to the type > parameters of type parameters in classes and interfaces, similar to > accessing encapsulated fields in the class, but only in source code. > For example, given Digraph, one could declare > Subgraph extends > Digraph. > > MAJOR ADVANTAGE: This change will simplify the use of layered generics > and opens the door to richer general purpose code. > > MAJOR BENEFIT: This change transfers the rote work of resolving > specified types from the developer to the compiler. Given the > mechanical nature of the task, that is where the work belongs. > > MAJOR DISADVANTAGE: Generics in Java are already complex; the Java > Generics FAQ is very large. This change will make it slightly longer, > and require developers to learn one more (relatively intuitive) > detail. > > ALTERNATIVES: > > 1) Do nothing. > > 2) Full reification, if done well, would provide similar compile-time > language-level access beyond the type specifiers. (This option is one > of the case examples of things too large for project coin.) > > 3) Diminish generics' prominent position in Java by removing the > compile-time warnings. > > 4) Remove generics from Java. > > EXAMPLES: > > My examples are directed graph examples from the JDiraph project on > java.net. The semiring (advanced) example was inspired by Cormen, > Leiserson and Rivest, 26.4. I show what the code looks like in JDK5 > first, then with the access to generic type parameters proposed. > > --- > > SIMPLE EXAMPLE: Given interface Digraph, define Paths > through the Digraph, a Digraph representing a probalistic transitions > in the dialog, and an instance of Path that represents a conversation. > > JDK5 Syntax -- three type specifiers, one of which requires the > developer to match the first two by hand: > > interface Path> > extends Digraph > { > Node getHead(); > ... > } > [snip] When I see a Java type declared to have more than two type parameters my initial reaction is usually "this type isn't using the best decomposition of the problem space." -Joe From Joe.Darcy at Sun.COM Sun Mar 22 23:25:56 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 22 Mar 2009 23:25:56 -0700 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <805D1335-2F96-462E-8E1C-F32686592BE5@Sun.COM> References: <1631da7d0903221749j4502ea61s7247dd219e14ffc6@mail.gmail.com> <805D1335-2F96-462E-8E1C-F32686592BE5@Sun.COM> Message-ID: <49C72B74.5070900@sun.com> Hello. Mike Duigou wrote: > On Mar 22, 2009, at 6:14 PM, Mark Mahieu wrote: > > >> 2009/3/23 Jeremy Manson Also, it seems to >> me that you would want to be careful about access to >> fields of the parent object before the invocation of super(). >> >> Jeremy >> >> Yes, which implies no calls to other instance methods, or to static >> methods passing 'this' as an argument etc. Maybe a simple rule to >> build upon would be to say that anything before the call to this() >> or super() is effectively in a static context (ie no references to >> instance members, or to this/super, are allowed). There'd be more >> to it than that though. >> > > Your clarification is correct. Before the explicit call to super() or > this() no reference to instance fields or methods is allowed because > the object hasn't been created yet. The case where no explicit call to > super/this() is made is a little harder because an implicit call to > the no params super() method needs to be inserted before the first > reference to an instance field or method in order to construct the > object. > > >> Also (Mike) there's at least one existing bug entry for this: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093999 >> > > Hmmm, thanks! That should have been easy to find. Perhaps I searched > only open bugs. > While I've certainly chafed at the "must call super first rules," I don't think they are a severe enough annoyance to need addressing by Project Coin. Additionally, a proposal on this topic should address the sort of points already raised by Jeremy as well as the issues listed in bug 4093999. -Joe From Joe.Darcy at Sun.COM Sun Mar 22 23:43:59 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 22 Mar 2009 23:43:59 -0700 Subject: Glue classes proposal 0.9 In-Reply-To: <1631da7d0903222210h290a650apa02cdd7d5e864a57@mail.gmail.com> References: <28bca0ff0903200735w572ebd73n39289e0757ad428c@mail.gmail.com> <49C5A253.5000304@sun.com> <28bca0ff0903221510h18ca7058w4c0ed35fb3f8ea3b@mail.gmail.com> <63b4e4050903221529o6c4d4f55kc6562451d36bcded@mail.gmail.com> <28bca0ff0903221627l1a0715d7xac0170de6ef3da8a@mail.gmail.com> <63b4e4050903221931j358d283ei6301db71270b1e68@mail.gmail.com> <1631da7d0903222210h290a650apa02cdd7d5e864a57@mail.gmail.com> Message-ID: <49C72FAF.2090208@sun.com> Jeremy Manson wrote: > I believe that what Marek is trying to do is to introduce a feature > that allows you to add (or glue) methods to existing classes. You > could have, for example: > > // Glue class to add sorting to Lists > class Sort glue(List) { > void sort(List l) { > // sorts the argument > } > } > > And then later say: > > List list = new ArrayList(); > // adds elements to list > list..sort(); // The ".." notation invokes Sort.sort() on list. > > It seems like rather a large change to me, and is along the same lines > as some other proposals that have been rejected as out of scope. But > perhaps Joe thinks otherwise > I remain perplexed by the impenetrable text of the proposal. If the feature is as you've described, it is too large to be a coin. -Joe From rssh at gradsoft.com.ua Sun Mar 22 23:55:09 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 23 Mar 2009 08:55:09 +0200 (EET) Subject: PRE-PROPOSAL: Named method parameters with defaults. In-Reply-To: <28bca0ff0903221825v184d7471o5f46d10dee1bdf64@mail.gmail.com> References: <4ce75f920903220635y576e03d9l3b44f95299b035ba@mail.gmail.com> <2A8FBE31-E894-4EA6-AB62-68957AA82510@zwitserloot.com> <4ce75f920903221528n4adb927ap4c0b4fa840aede9b@mail.gmail.com> <28bca0ff0903221636j6d0d780he6d2baf8bf6e430b@mail.gmail.com> <05C1E4C5-B65B-4800-A14D-FB274257E0E2@zwitserloot.com> <28bca0ff0903221707gc2cb032la8ec17c4e547df35@mail.gmail.com> <28bca0ff0903221825v184d7471o5f46d10dee1bdf64@mail.gmail.com> Message-ID: <9654ee8de26de5ba922494d39c289bb0.squirrel@wmail.gradsoft.ua> > - reordering parameters is wrong path, will create more confusion: 9 > parameters mean 9! = 362880 combinations o.O > What (?) !!! 9! have nothing with task to find correct ordering of named parameters. When name of parameters is known (they are already known during named call), than substitution is performed by perform 9 searches among parameter names. From cadenza at paradise.net.nz Mon Mar 23 01:10:42 2009 From: cadenza at paradise.net.nz (Bruce Chapman & Barbara Carey) Date: Mon, 23 Mar 2009 21:10:42 +1300 Subject: Proposal: Access to Generic Type Parameters at Compile-Time In-Reply-To: <49C721B4.1010703@sun.com> References: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> <49C721B4.1010703@sun.com> Message-ID: <49C74402.4070603@paradise.net.nz> I concur with Joe here. I have seen some code with many redundant generic type parameters. Unfortunately the tools like findbugs, checkstyle and PMD that we'd expect to point out other oversights don't do a very good job in this regard. Bruce Joseph D. Darcy wrote: > David Walend wrote: > > [snip] > > When I see a Java type declared to have more than two type parameters my > initial reaction is usually "this type isn't using the best > decomposition of the problem space." > > -Joe > From howard.lovatt at iee.org Mon Mar 23 02:13:33 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Mon, 23 Mar 2009 20:13:33 +1100 Subject: Loosen Constructor super()/this() call restrictions Message-ID: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> A few notes: 1. It is useful to be able to initialise fields before super is called, so that super can call instance methods defined in the derived class. This is what inner class do for their outer pointer. 2. You will need definite assignment, could be as simple as no super call inside a block (if, for, etc.) and only one call to super 3. You shouldn't be able to access super fields or any instance methods before super. -- Howard. From develop4lasu at gmail.com Mon Mar 23 02:56:49 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 10:56:49 +0100 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> References: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> Message-ID: <28bca0ff0903230256p48b36533n77a148232743d28e@mail.gmail.com> 2009/3/23 Howard Lovatt : > A few notes: > > 3. You shouldn't be able to access super fields or any instance > methods before super. > > ?-- Howard. > > Can you ensure that ? class A { private Bar bar; public A(Bar bar) { setBar(bar); } protected void setBar(Bar bar) { this.bar = bar; } } class B extends A { private Bar bar; private Foo foo; public B(Bar bar, Foo foo) { super(bar); this.foo = foo; } protected void setBar(Bar bar) { this.bar = bar; this.foo = bar.foo; } } Will code have same effect when constructor will be : public B(Bar bar, Foo foo) { this.foo = foo; super(bar); } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Mon Mar 23 11:33:27 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Mar 2009 19:33:27 +0100 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <49C7D0EB.1020807@gmail.com> References: <64C260CE-3CC3-43ED-914D-CB6BD77FBAB5@zwitserloot.com> <49C09189.9020005@sun.com> <49C7D0EB.1020807@gmail.com> Message-ID: <73BEACAB-ADBE-44A3-8B2E-24A0017BC188@zwitserloot.com> Kevin: The C# yield keyword does the exact same thing as was proposed for java - it creates an inner class. This is what was meant by: Adds all the intricacies of closures: Variables have to be final, and any attempts to throw an exception inside such a construct all of a sudden is no longer allowed (because the pseudo-interface you're implementing doesn't allow it either - and more specifically, because you could hand off your iterable and an entirely different code block could be throwing them). This is very confusing if you don't understand the intricacies of anonymous inner classes. At least *actual* anonymous inner classes have a very specific syntax which allows someone not familiar with them to read up. Trying to solve these problems gives you about as much difficulty as the various closure proposals floating around. Certainly doable, but not within the scope of project coin. Hence my suggestion to add them as a non-lazy list generator, which avoids all of those problems. We can always add a lazy form later, with the same syntax but for one minor difference (E.g. by employing different brackets or adding a context sensitive keyword or some such). --Reinier Zwitserloot On Mar 23, 2009, at 19:11, Kevin Krouse wrote: > > Joseph D. Darcy wrote: >> >> Reinier Zwitserloot wrote: >> >>> Ah, list comprehensions. I forgot them on my list. They aren't >>> closures, but you can do quite a few closure use-cases with them, >>> and >>> are a lot easier to understand. The draft proposal looks good (but >>> is >>> incomplete; it doesn't mention any JLS chapters, for example), but >>> there's one big issue it doesn't mention: If the list comprehensions >>> return Iterables, then the generating expression, as well as the >>> filter expressions, are effectively 'closures' and get all the >>> complications that stem from this. For example, you would not be >>> able >>> to use non-final variables in there, unless we change the rules >>> regarding usage of non-finals in 'closures', which involves a >>> significant change for the JVM (it has to declare that variable on >>> the >>> heap and not on the stack). >>> >>> Generating the entire list on the spot has none of those issues, and >>> turns the entire proposal into syntactic sugar + a new utility class >>> in the spirit of Collections and Arrays, named 'Iterables'. That's >>> all. >>> >>> Joe: If a list comprehension proposal is written that involves >>> (extensive) syntax sugar + 1 new class file and nothing else, would >>> they have a chance? >>> >>> >> I would be doubtful such a change would be within scope. >> >> -Joe >> >> > Is it too large for coin because of the syntax changes? Would > something more like C# yield return/break be more acceptable since > it looks more like a plain 'ol Java method? See Raymond Chen's > explanation of the transformation performed for yield which doesn't > require final variables or closures: http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx > > To me, it seems on the same level of size as the JDK 5 for-each loop > which was considered a small change. > > Kevin From i30817 at gmail.com Mon Mar 23 12:33:57 2009 From: i30817 at gmail.com (Paulo Levi) Date: Mon, 23 Mar 2009 19:33:57 +0000 Subject: Fwd: Anyone ever considered named tuples? In-Reply-To: <212322090903231232p13d833aalf82c5e9a3cb1ff91@mail.gmail.com> References: <212322090903211707w71c42bf0hb6aa046a2ad92aef@mail.gmail.com> <28bca0ff0903221626g4662f8b3g673134ee5f87622d@mail.gmail.com> <212322090903231232p13d833aalf82c5e9a3cb1ff91@mail.gmail.com> Message-ID: <212322090903231233p614c3cbahdcbd4df31e5ad9f6@mail.gmail.com> ---------- Forwarded message ---------- From: Paulo Levi Date: Mon, Mar 23, 2009 at 7:32 PM Subject: Re: Anyone ever considered named tuples? To: Marek Kozie? I don't think that maps or arrays are a good way to get effect. I'm saying that's how people get the effect without thinking about it too much. Also Neil, i thought "structural types" were a general abstraction of tuples. Much more powerful i agree, especially if they can be used as method arguments. This is how i get the effect when i want to, but meaningless names make me not use it. Also the places where they might be used are often better off refactored - one return value is always best, expect in performance critical iterations: package util; import java.io.IOException; import java.io.Serializable; /** * Type safe, inmutable, tuple classes * can be serialized with xmlencoder (>=1.6) * or objectoutputstream. * * Whenever you need to create public api, * it is best not to use these classes since the * given names (first, second, etc) are not descriptive. * @author i30817 */ public final class Tuples { private Tuples() { } public static T1 createSingleton(X target) { return new T1(target); } public static T2 createPair(X target1, Y target2) { return new T2(target1, target2); } public static T3 createTriple(X target1, Y target2, Z target3) { return new T3(target1, target2, target3); } public static T4 createQuadruple(W target1, X target2, Y target3, Z target4) { return new T4(target1, target2, target3, target4); } public static final class T1 implements Serializable { private static final long serialVersionUID = 362498860763181265L; private X first; //@java.beans.ConstructorProperties({"first"}) private T1(X first) { this.first = first; } public X getFirst() { return first; } @Override public String toString() { return "(" + first.toString() + ")"; } @SuppressWarnings(value = "unchecked") @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final T1 other = (T1) obj; if (this.first != other.first && (this.first == null || !this.first.equals(other.first))) { return false; } return true; } @Override public int hashCode() { int hash = 5; hash = 97 * hash + (this.first != null ? this.first.hashCode() : 0); return hash; } private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeObject(first); } @SuppressWarnings(value = "unchecked") private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { first = (X) in.readObject(); } } public static final class T2 implements Serializable { private static final long serialVersionUID = 463498820763161265L; private X first; private Y second; //@java.beans.ConstructorProperties({"first","second"}) private T2(X first, Y second) { this.first = first; this.second = second; } public X getFirst() { return first; } public Y getSecond() { return second; } @Override public String toString() { return "(" + first.toString() + ", " + second.toString() + ")"; } @SuppressWarnings(value = "unchecked") @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final T2 other = (T2) obj; if (this.first != other.first && (this.first == null || !this.first.equals(other.first))) { return false; } if (this.second != other.second && (this.second == null || !this.second.equals(other.second))) { return false; } return true; } @Override public int hashCode() { int hash = 3; hash = 67 * hash + (this.first != null ? this.first.hashCode() : 0); hash = 67 * hash + (this.second != null ? this.second.hashCode() : 0); return hash; } private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeObject(first); out.writeObject(second); } @SuppressWarnings(value = "unchecked") private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { first = (X) in.readObject(); second = (Y) in.readObject(); } } public static final class T3 implements Serializable { private static final long serialVersionUID = 162498830763481765L; private X first; private Y second; private Z third; //@java.beans.ConstructorProperties({"first","second","third"}) private T3(X first, Y second, Z third) { this.first = first; this.second = second; this.third = third; } public X getFirst() { return first; } public Y getSecond() { return second; } public Z getThird() { return third; } @Override public String toString() { return "(" + first.toString() + ", " + second.toString() + ", " + third.toString() + ")"; } @SuppressWarnings(value = "unchecked") @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final T3 other = (T3) obj; if (this.first != other.first && (this.first == null || !this.first.equals(other.first))) { return false; } if (this.second != other.second && (this.second == null || !this.second.equals(other.second))) { return false; } if (this.third != other.third && (this.third == null || !this.third.equals(other.third))) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 71 * hash + (this.first != null ? this.first.hashCode() : 0); hash = 71 * hash + (this.second != null ? this.second.hashCode() : 0); hash = 71 * hash + (this.third != null ? this.third.hashCode() : 0); return hash; } private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeObject(first); out.writeObject(second); out.writeObject(third); } @SuppressWarnings(value = "unchecked") private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { first = (X) in.readObject(); second = (Y) in.readObject(); third = (Z) in.readObject(); } } public static final class T4 implements Serializable { private static final long serialVersionUID = 162498830763581765L; private W first; private X second; private Y third; private Z fourth; //@java.beans.ConstructorProperties({"first","second","third","fourth"}) private T4(W first, X second, Y third, Z fourth) { this.first = first; this.second = second; this.third = third; this.fourth = fourth; } public W getFirst() { return first; } public X getSecond() { return second; } public Y getThird() { return third; } public Z getFourth() { return fourth; } @Override public String toString() { return "(" + first.toString() + ", " + second.toString() + ", " + third.toString() + ", " + fourth.toString() + ")"; } @SuppressWarnings(value = "unchecked") @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final T4 other = (T4) obj; if (this.first != other.first && (this.first == null || !this.first.equals(other.first))) { return false; } if (this.second != other.second && (this.second == null || !this.second.equals(other.second))) { return false; } if (this.third != other.third && (this.third == null || !this.third.equals(other.third))) { return false; } if (this.fourth != other.fourth && (this.fourth == null || !this.fourth.equals(other.fourth))) { return false; } return true; } @Override public int hashCode() { int hash = 5; hash = 29 * hash + (this.first != null ? this.first.hashCode() : 0); hash = 29 * hash + (this.second != null ? this.second.hashCode() : 0); hash = 29 * hash + (this.third != null ? this.third.hashCode() : 0); hash = 29 * hash + (this.fourth != null ? this.fourth.hashCode() : 0); return hash; } private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.writeObject(first); out.writeObject(second); out.writeObject(third); out.writeObject(fourth); } @SuppressWarnings(value = "unchecked") private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { first = (W) in.readObject(); second = (X) in.readObject(); third = (Y) in.readObject(); fourth = (Z) in.readObject(); } } } From jl0235 at yahoo.com Mon Mar 23 12:40:50 2009 From: jl0235 at yahoo.com (james lowden) Date: Mon, 23 Mar 2009 12:40:50 -0700 (PDT) Subject: Proposal: Simplified syntax for dealing with parameterized types. Message-ID: <172662.40997.qm@web63703.mail.re1.yahoo.com> Proposal: Simplified syntax for dealing with parameterized types. AUTHOR(S): J. Lowden VERSION: 1.0 Initial version. OVERVIEW FEATURE SUMMARY: Declaring and instantiating parameterized types can be verbose (resulting in expressions like "HashMap " being repeated throughtout one's code) and, due to the erasure-based implementation of generics in Java, not necessarily type-safe. The code snippet below illustrates both: HashMap a = new HashMap (); HashMap b = new HashMap (); b.put ("foo", new JFrame ()); a = b; // this is semantically wrong, but compiles In this case, the parameterization language ("") is repeated twice, which quickly becomes annoying if one is using a large number of String-to-String hashes. More dangerously, despite "a" having been declared as a HashMap , it is possible to use it as a reference to a non-parameterized HashMap which may contain objects of unexpected and semantically incorrect types. One way around this problem is by subclassing the parameterized type, as in: public class StringyMap extends HashMap { } The above example then becomes: StringyMap a = new StringyMap (); HashMap b = new HashMap (); b.put ("foo", new JFrame ()); a = b; // this now causes a compiler error This both removes the repetition and causes the type-unsafe assignments statement to generate a compiler error. However, since simply extending a class causes the loss of all but the default constructor, in order to make StringyMap as useful as HashMap , we really need to do this: public class StringyMap extends HashMap { public StringyMap () { } public StringyMap (int initialCapacity) { super (initialCapacity); } public StringyMap (int initialCapacity, float loadFactor) { super (initialCapacity, loadFactor); } public StringyMap (Map m) { super (m); } } This is an annoying heap of boilerplate code, especially seeing that verbosity was one of the issues we were trying to address. Therefore, the new syntax being proposed is something along the lines of: public class X = Y ; which would be exactly equivalent to: public class X extends Y { // constructors } with constructors matching the signatures of the superclass constructors automatically generated that simply pass all the parameters along to the superclass constructor. This could also be done with interfaces. Since interfaces do not support constructors, the mapping is simpler, as we simply leave the automatic constructor creation out: public interface X = Y ; is equivalent to: public interface X extends Y {} Java currently requires each top-level public class or interface to be declared in its own source file. When working with multiple parameterized types, this could result in a large number of one-line source files that may be inconvenient to deal with. Therefore, I also propose the creation of an optional special source file in each package that can be used to contain multiple such type definitions. This file would be named something like "param-types.java" (the specific name doesn't matter as long as it is A) standardized and B) not a legal Java identifier, so we avoid collisions), and all public classes or interfaces defined in it would be compiled as though they were top-level class files in the given package. The "param-types.java" file would be restricted to containing classes/interfaces defined using the new syntax described above; this file is intended as a convenience mechanism to support the features described above, not a mechanism for cramming all of one's code into one hideously-long source file. Although not a principal goal of this proposal, this also provides an easy mechanism for enforcing type safety between two types that have the same parameters but are not intended to be interconvertible. For example: public interface ListOfThingsToNameTheBaby = List ; public interface ListOfAnnoyingInternetAcronyms = List ; ListOfThingsToNameTheBaby a; ListOfAnnoyingInternetAcronyms b; a = b; // raises a compiler error, since these are not assignable Note that there is potential for confusion if the two types were actually meant to be interconverible (i.e., ListOfNamesForBabies and ListOfThingsToNameTheBaby). MAJOR ADVANTAGE: It becomes easier and more elegant to create reusable, robust parameterized types. MAJOR BENEFIT: Readability of code that makes extensive use of parameterized types is improved. Although the general erasure-related issues with type-safety of generics are not eliminated, this provides a straightforward mechanism for working with more robust parameterized types. MAJOR DISADVANTAGE: Programmers (especially those working on distributed projects) may inadvertantly end up defining two types meant to be "the same thing" that are not mutually assignable, as in: public class ListOfNamesForBabies = ArrayList ; public class ListOfThingsToNameTheBaby = ArrayList ; ListOfNamesForBabies a; ListOfThingsToNameTheBaby b; a = b; // does not compile Note that this is only a problem in cases where the types are intended to be equivalent; see the ListOfAnnoyingInternetAcronyms/ListOfThingsToNameTheBaby example above. ALTERNATIVES: Write strings the old way by using concatenations or using builders. EXAMPLES SIMPLE EXAMPLE: --- creating a file named StringyMap.java in package blah package blah; // various import statements public class StringyMap = HashMap ; --- is equivalent to what would currently result from the following: package blah; // various import statements public class StringyMap extends HashMap { public StringyMap () { } public StringyMap (int initialCapacity) { super (initialCapacity); } public StringyMap (int initialCapacity, float loadFactor) { super (initialCapacity, loadFactor); } public StringyMap (Map m) { super (m); } } ADVANCED EXAMPLE: --- creating a file named param-types.java in package blah package blah; // various import statements public class StringyMap = HashMap ; public interface ListOfNames = List ; --- is equivalent to what would currently result from defining the StringyMap class in the previous example --- as well as the following: package blah; // various import statements public interface ListOfNames extends List {} DETAILS SPECIFICATION: The new syntax can be handled entirely via compiler modifications. Since this proposal consists entirely of syntactic sugar atop the existing type system and uses a syntax that currently has no meaning in Java, it should not have any affect on the meaning of any current feature of the Java Programming Language. COMPILATION: Compilation of this new feature would consist of de-sugaring two new types of declarations. For interfaces, the following: [modifier_list] interface [name] = [superinterface] ; is de-sugared to: [modifier_list] interface [name] extends [superinterface] {} Classes are a bit more complex: [modifier_list] class [name] = [superclass] ; is de-sugared to: [modifier_list] class [name] extends [superclass] { [constructors] } Where the [constructors] block consists of one "wrapped" constructor for each public or protected constructor in the superclass. Thus, for each such constructor in the superclass: [public/protected] [superclass] ([constructor_args. . .]); A "wrapper" constructor would be generated as follows: [public/protected] [name] ([constructor_args. . .]) { super ([constructor_args. . .]); } Finally, when resolving dependencies, if the compiler doesn't find a class or source file for a top-level class in the expected location, the compiler would examine "param-types.java" in the package-appropriate directory to see if it is defined there. Only classes and interfaces defined using the syntax described here are permitted in the "param-types.java"; any "traditional" class or interface definition in this file results in a compiler error. TESTING: This feature can be tested in the same manner as any other form of class or interface declaration. LIBRARY SUPPORT: None required. REFLECTIVE APIS: This should be automatic, as the current reflective APIs will correctly identify the class or interface. OTHER CHANGES: None. MIGRATION: Replace current use of parameterized types where feasible. COMPATIBILITY BREAKING CHANGES: None. The proposed syntax currently causes compiler errors. EXISTING PROGRAMS: No changes. REFERENCES EXISTING BUGS: None that I am aware of. URL FOR PROTOTYPE (optional): None thus far; work-in-progress. From reinier at zwitserloot.com Mon Mar 23 13:16:04 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Mar 2009 21:16:04 +0100 Subject: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <172662.40997.qm@web63703.mail.re1.yahoo.com> References: <172662.40997.qm@web63703.mail.re1.yahoo.com> Message-ID: There are many more annoying issues with subtypes, most notably regarding behaviour of .equals(), and the the way one person's MapStringString isn't compatible with another's MapStringString, eventhough they are both really meant as just 'Map'. Your solution to this problem seems extremely overengineered, while the end-result is a patchy hack at best. Just allowing Map map = new HashMap<>(); - an idea that's been floated many times before, is something I'd strongly prefer, and it's much simpler. --Reinier Zwitserloot On Mar 23, 2009, at 20:40, james lowden wrote: > > Proposal: Simplified syntax for dealing with parameterized types. > > AUTHOR(S): > > J. Lowden > > VERSION: > > 1.0 Initial version. > > > OVERVIEW > > FEATURE SUMMARY: > > Declaring and instantiating parameterized types can be verbose > (resulting in expressions like "HashMap " being > repeated throughtout one's code) and, due to the erasure-based > implementation of generics in Java, not necessarily type-safe. The > code snippet below illustrates both: > > > HashMap a = new HashMap (); > HashMap b = new HashMap (); > b.put ("foo", new JFrame ()); > a = b; // this is semantically wrong, but compiles > > > In this case, the parameterization language ("") is > repeated twice, which quickly becomes annoying if one is using a > large number of String-to-String hashes. More dangerously, despite > "a" having been declared as a HashMap , it is > possible to use it as a reference to a non-parameterized HashMap > which may contain objects of unexpected and semantically incorrect > types. One way around this problem is by subclassing the > parameterized type, as in: > > > public class StringyMap extends HashMap { > } > > > The above example then becomes: > > > StringyMap a = new StringyMap (); > HashMap b = new HashMap (); > b.put ("foo", new JFrame ()); > a = b; // this now causes a compiler error > > > This both removes the repetition and causes the type-unsafe > assignments statement to generate a compiler error. However, since > simply extending a class causes the loss of all but the default > constructor, in order to make StringyMap as useful as HashMap > , we really need to do this: > > > public class StringyMap extends HashMap { > > public StringyMap () { > } > > public StringyMap (int initialCapacity) { > super (initialCapacity); > } > > public StringyMap (int initialCapacity, float loadFactor) { > super (initialCapacity, loadFactor); > } > > public StringyMap (Map m) { > super (m); > } > > } > > > This is an annoying heap of boilerplate code, especially seeing that > verbosity was one of the issues we were trying to address. > Therefore, the new syntax being proposed is something along the > lines of: > > public class X = Y ; > > which would be exactly equivalent to: > > public class X extends Y { > > // constructors > > } > > with constructors matching the signatures of the superclass > constructors automatically generated that simply pass all the > parameters along to the superclass constructor. > > This could also be done with interfaces. Since interfaces do not > support constructors, the mapping is simpler, as we simply leave the > automatic constructor creation out: > > public interface X = Y ; > > is equivalent to: > > public interface X extends Y {} > > > Java currently requires each top-level public class or interface to > be declared in its own source file. When working with multiple > parameterized types, this could result in a large number of one-line > source files that may be inconvenient to deal with. Therefore, I > also propose the creation of an optional special source file in each > package that can be used to contain multiple such type definitions. > This file would be named something like "param-types.java" (the > specific name doesn't matter as long as it is A) standardized and B) > not a legal Java identifier, so we avoid collisions), and all public > classes or interfaces defined in it would be compiled as though they > were top-level class files in the given package. The "param- > types.java" file would be restricted to containing classes/ > interfaces defined using the new syntax described above; this file > is intended as a convenience mechanism to support the features > described above, not a mechanism for > cramming all of one's code into one hideously-long source file. > > Although not a principal goal of this proposal, this also provides > an easy mechanism for enforcing type safety between two types that > have the same parameters but are not intended to be > interconvertible. For example: > > public interface ListOfThingsToNameTheBaby = List ; > public interface ListOfAnnoyingInternetAcronyms = List ; > > ListOfThingsToNameTheBaby a; > ListOfAnnoyingInternetAcronyms b; > > a = b; // raises a compiler error, since these are not assignable > > > Note that there is potential for confusion if the two types were > actually meant to be interconverible (i.e., ListOfNamesForBabies and > ListOfThingsToNameTheBaby). > > > MAJOR ADVANTAGE: > > It becomes easier and more elegant to create reusable, robust > parameterized types. > > > MAJOR BENEFIT: > > Readability of code that makes extensive use of parameterized types > is improved. Although the general erasure-related issues with type- > safety of generics are not eliminated, this provides a > straightforward mechanism for working with more robust parameterized > types. > > > MAJOR DISADVANTAGE: > > Programmers (especially those working on distributed projects) may > inadvertantly end up defining two types meant to be "the same thing" > that are not mutually assignable, as in: > > public class ListOfNamesForBabies = ArrayList ; > public class ListOfThingsToNameTheBaby = ArrayList ; > > ListOfNamesForBabies a; > ListOfThingsToNameTheBaby b; > > a = b; // does not compile > > > Note that this is only a problem in cases where the types are > intended to be equivalent; see the ListOfAnnoyingInternetAcronyms/ > ListOfThingsToNameTheBaby example above. > > > ALTERNATIVES: > > Write strings the old way by using concatenations or using builders. > > > EXAMPLES > > SIMPLE EXAMPLE: > > --- creating a file named StringyMap.java in package blah > > package blah; > > // various import statements > > public class StringyMap = HashMap ; > > > --- is equivalent to what would currently result from the following: > > package blah; > > // various import statements > > public class StringyMap extends HashMap { > > public StringyMap () { > } > > public StringyMap (int initialCapacity) { > super (initialCapacity); > } > > public StringyMap (int initialCapacity, float loadFactor) { > super (initialCapacity, loadFactor); > } > > public StringyMap (Map m) { > super (m); > } > > } > > ADVANCED EXAMPLE: > > --- creating a file named param-types.java in package blah > > package blah; > > // various import statements > > public class StringyMap = HashMap ; > public interface ListOfNames = List ; > > --- is equivalent to what would currently result from defining the > StringyMap class in the previous example > --- as well as the following: > > package blah; > > // various import statements > > public interface ListOfNames extends List {} > > > DETAILS > > SPECIFICATION: > > The new syntax can be handled entirely via compiler modifications. > Since this proposal consists entirely of syntactic sugar atop the > existing type system and uses a syntax that currently has no meaning > in Java, it should not have any affect on the meaning of any current > feature of the Java Programming Language. > > > COMPILATION: > > Compilation of this new feature would consist of de-sugaring two new > types of declarations. For interfaces, the following: > > [modifier_list] interface [name] = [superinterface] > ; > > is de-sugared to: > > [modifier_list] interface [name] extends [superinterface] > {} > > > Classes are a bit more complex: > > [modifier_list] class [name] = [superclass] ; > > is de-sugared to: > > [modifier_list] class [name] extends [superclass] > { > > [constructors] > > } > > Where the [constructors] block consists of one "wrapped" constructor > for each public or protected constructor in the superclass. Thus, > for each such constructor in the superclass: > > [public/protected] [superclass] ([constructor_args. . .]); > > A "wrapper" constructor would be generated as follows: > > [public/protected] [name] ([constructor_args. . .]) { > super ([constructor_args. . .]); > } > > > Finally, when resolving dependencies, if the compiler doesn't find a > class or source file for a top-level class in the expected location, > the compiler would examine "param-types.java" in the package- > appropriate directory to see if it is defined there. Only classes > and interfaces defined using the syntax described here are permitted > in the "param-types.java"; any "traditional" class or interface > definition in this file results in a compiler error. > > > TESTING: > > This feature can be tested in the same manner as any other form of > class or interface declaration. > > LIBRARY SUPPORT: > > None required. > > REFLECTIVE APIS: > > This should be automatic, as the current reflective APIs will > correctly identify the class or interface. > > OTHER CHANGES: > > None. > > MIGRATION: > > Replace current use of parameterized types where feasible. > > > COMPATIBILITY > > BREAKING CHANGES: > > None. The proposed syntax currently causes compiler errors. > > EXISTING PROGRAMS: > > No changes. > > > REFERENCES > > EXISTING BUGS: > > None that I am aware of. > > URL FOR PROTOTYPE (optional): > > None thus far; work-in-progress. > > > > From brucechapman at paradise.net.nz Mon Mar 23 13:17:59 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Tue, 24 Mar 2009 09:17:59 +1300 (NZDT) Subject: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <172662.40997.qm@web63703.mail.re1.yahoo.com> References: <172662.40997.qm@web63703.mail.re1.yahoo.com> Message-ID: <1237839479.49c7ee77a4889@www.paradise.net.nz> Quoting james lowden : > ALTERNATIVES: > Write strings the old way by using concatenations or using builders.> Seems somewhat out of place. From reinier at zwitserloot.com Mon Mar 23 13:18:24 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Mar 2009 21:18:24 +0100 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: <49C7E9BA.60207@gmail.com> References: <64C260CE-3CC3-43ED-914D-CB6BD77FBAB5@zwitserloot.com> <49C09189.9020005@sun.com> <49C7D0EB.1020807@gmail.com> <73BEACAB-ADBE-44A3-8B2E-24A0017BC188@zwitserloot.com> <49C7E9BA.60207@gmail.com> Message-ID: If you copy the variables, then change them later, people are going to be rightly confused about why the comprehension still appears to read an old version. Also, that still does not solve the checked exceptions issue, either. Its possible there's an easy answer here, but considering that everyone and their dog has submitted a closure proposal of some flavour or other, I kind of doubt there is one. --Reinier Zwitserloot On Mar 23, 2009, at 20:57, Kevin Krouse wrote: > I may have read the generated code wrong, but doesn't the C# > translated source just copy the method parameters and locals to the > generated class? Only member fields referenced by the method need > to be final, right? > > Kevin > > Reinier Zwitserloot wrote: >> >> Kevin: The C# yield keyword does the exact same thing as was >> proposed for java - it creates an inner class. This is what was >> meant by: Adds all the intricacies of closures: Variables have to >> be final, and any attempts to throw an exception inside such a >> construct all of a sudden is no longer allowed (because the pseudo- >> interface you're implementing doesn't allow it either - and more >> specifically, because you could hand off your iterable and an >> entirely different code block could be throwing them). This is very >> confusing if you don't understand the intricacies of anonymous >> inner classes. At least *actual* anonymous inner classes have a >> very specific syntax which allows someone not familiar with them to >> read up. >> >> Trying to solve these problems gives you about as much difficulty >> as the various closure proposals floating around. Certainly doable, >> but not within the scope of project coin. >> >> Hence my suggestion to add them as a non-lazy list generator, which >> avoids all of those problems. We can always add a lazy form later, >> with the same syntax but for one minor difference (E.g. by >> employing different brackets or adding a context sensitive keyword >> or some such). >> >> --Reinier Zwitserloot >> >> >> >> On Mar 23, 2009, at 19:11, Kevin Krouse wrote: >> >>> >>> Joseph D. Darcy wrote: >>>> >>>> Reinier Zwitserloot wrote: >>>> >>>>> Ah, list comprehensions. I forgot them on my list. They aren't >>>>> closures, but you can do quite a few closure use-cases with >>>>> them, and >>>>> are a lot easier to understand. The draft proposal looks good >>>>> (but is >>>>> incomplete; it doesn't mention any JLS chapters, for example), but >>>>> there's one big issue it doesn't mention: If the list >>>>> comprehensions >>>>> return Iterables, then the generating expression, as well as the >>>>> filter expressions, are effectively 'closures' and get all the >>>>> complications that stem from this. For example, you would not be >>>>> able >>>>> to use non-final variables in there, unless we change the rules >>>>> regarding usage of non-finals in 'closures', which involves a >>>>> significant change for the JVM (it has to declare that variable >>>>> on the >>>>> heap and not on the stack). >>>>> >>>>> Generating the entire list on the spot has none of those issues, >>>>> and >>>>> turns the entire proposal into syntactic sugar + a new utility >>>>> class >>>>> in the spirit of Collections and Arrays, named 'Iterables'. >>>>> That's all. >>>>> >>>>> Joe: If a list comprehension proposal is written that involves >>>>> (extensive) syntax sugar + 1 new class file and nothing else, >>>>> would >>>>> they have a chance? >>>>> >>>>> >>>> I would be doubtful such a change would be within scope. >>>> >>>> -Joe >>>> >>>> >>> Is it too large for coin because of the syntax changes? Would >>> something more like C# yield return/break be more acceptable since >>> it looks more like a plain 'ol Java method? See Raymond Chen's >>> explanation of the transformation performed for yield which >>> doesn't require final variables or closures: http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx >>> >>> To me, it seems on the same level of size as the JDK 5 for-each >>> loop which was considered a small change. >>> >>> Kevin >> From markmahieu at googlemail.com Mon Mar 23 13:21:16 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 23 Mar 2009 20:21:16 +0000 Subject: ACCEPTABLE?: List Comprehensions? In-Reply-To: References: <64C260CE-3CC3-43ED-914D-CB6BD77FBAB5@zwitserloot.com> <49C09189.9020005@sun.com> <49C7D0EB.1020807@gmail.com> <73BEACAB-ADBE-44A3-8B2E-24A0017BC188@zwitserloot.com> <49C7E9BA.60207@gmail.com> Message-ID: 2009/3/23 Reinier Zwitserloot > Also, that still does not solve the checked exceptions issue, either. > Its possible there's an easy answer here, but considering that > everyone and their dog has submitted a closure proposal of some > flavour or other, I kind of doubt there is one. My dog and I were going to submit one, but we couldn't agree on the syntax... Mark From jl0235 at yahoo.com Mon Mar 23 13:22:49 2009 From: jl0235 at yahoo.com (james lowden) Date: Mon, 23 Mar 2009 13:22:49 -0700 (PDT) Subject: Proposal: Simplified syntax for dealing with parameterized types (correction to ALTERNATIVES section) In-Reply-To: <1237839479.49c7ee77a4889@www.paradise.net.nz> Message-ID: <86480.18026.qm@web63701.mail.re1.yahoo.com> Proposal: Simplified syntax for declaring with parameterized types. AUTHOR(S): J. Lowden VERSION: 1.0 Initial version. OVERVIEW FEATURE SUMMARY: Declaring and instantiating parameterized types can be verbose (resulting in expressions like "HashMap " being repeated throughtout one's code) and, due to the erasure-based implementation of generics in Java, not necessarily type-safe. The code snippet below illustrates both: HashMap a = new HashMap (); HashMap b = new HashMap (); b.put ("foo", new JFrame ()); a = b; // this is semantically wrong, but compiles In this case, the parameterization language ("") is repeated twice, which quickly becomes annoying if one is using a large number of String-to-String hashes. More dangerously, despite "a" having been declared as a HashMap , it is possible to use it as a reference to a non-parameterized HashMap which may contain objects of unexpected and semantically incorrect types. One way around this problem is by subclassing the parameterized type, as in: public class StringyMap extends HashMap { } The above example then becomes: StringyMap a = new StringyMap (); HashMap b = new HashMap (); b.put ("foo", new JFrame ()); a = b; // this now causes a compiler error This both removes the repetition and causes the type-unsafe assignments statement to generate a compiler error. However, since simply extending a class causes the loss of all but the default constructor, in order to make StringyMap as useful as HashMap , we really need to do this: public class StringyMap extends HashMap { public StringyMap () { } public StringyMap (int initialCapacity) { super (initialCapacity); } public StringyMap (int initialCapacity, float loadFactor) { super (initialCapacity, loadFactor); } public StringyMap (Map m) { super (m); } } This is an annoying heap of boilerplate code, especially seeing that verbosity was one of the issues we were trying to address. Therefore, the new syntax being proposed is something along the lines of: public class X = Y ; which would be exactly equivalent to: public class X extends Y { // constructors } with constructors matching the signatures of the superclass constructors automatically generated that simply pass all the parameters along to the superclass constructor. This could also be done with interfaces. Since interfaces do not support constructors, the mapping is simpler, as we simply leave the automatic constructor creation out: public interface X = Y ; is equivalent to: public interface X extends Y {} Java currently requires each top-level public class or interface to be declared in its own source file. When working with multiple parameterized types, this could result in a large number of one-line source files that may be inconvenient to deal with. Therefore, I also propose the creation of an optional special source file in each package that can be used to contain multiple such type definitions. This file would be named something like "param-types.java" (the specific name doesn't matter as long as it is A) standardized and B) not a legal Java identifier, so we avoid collisions), and all public classes or interfaces defined in it would be compiled as though they were top-level class files in the given package. The "param-types.java" file would be restricted to containing classes/interfaces defined using the new syntax described above; this file is intended as a convenience mechanism to support the features described above, not a mechanism for cramming all of one's code into one hideously-long source file. Although not a principal goal of this proposal, this also provides an easy mechanism for enforcing type safety between two types that have the same parameters but are not intended to be interconvertible. For example: public interface ListOfThingsToNameTheBaby = List ; public interface ListOfAnnoyingInternetAcronyms = List ; ListOfThingsToNameTheBaby a; ListOfAnnoyingInternetAcronyms b; a = b; // raises a compiler error, since these are not assignable Note that there is potential for confusion if the two types were actually meant to be interconverible (i.e., ListOfNamesForBabies and ListOfThingsToNameTheBaby). MAJOR ADVANTAGE: It becomes easier and more elegant to create reusable, robust parameterized types. MAJOR BENEFIT: Readability of code that makes extensive use of parameterized types is improved. Although the general erasure-related issues with type-safety of generics are not eliminated, this provides a straightforward mechanism for working with more robust parameterized types. MAJOR DISADVANTAGE: Programmers (especially those working on distributed projects) may inadvertantly end up defining two types meant to be "the same thing" that are not mutually assignable, as in: public class ListOfNamesForBabies = ArrayList ; public class ListOfThingsToNameTheBaby = ArrayList ; ListOfNamesForBabies a; ListOfThingsToNameTheBaby b; a = b; // does not compile Note that this is only a problem in cases where the types are intended to be equivalent; see the ListOfAnnoyingInternetAcronyms/ListOfThingsToNameTheBaby example above. ALTERNATIVES: Reification of generics combined with some kind of syntax to avoid repetition of the type parameters would be ideal, but out of the scope of "small language changes". EXAMPLES SIMPLE EXAMPLE: --- creating a file named StringyMap.java in package blah package blah; // various import statements public class StringyMap = HashMap ; --- is equivalent to what would currently result from the following: package blah; // various import statements public class StringyMap extends HashMap { public StringyMap () { } public StringyMap (int initialCapacity) { super (initialCapacity); } public StringyMap (int initialCapacity, float loadFactor) { super (initialCapacity, loadFactor); } public StringyMap (Map m) { super (m); } } ADVANCED EXAMPLE: --- creating a file named param-types.java in package blah package blah; // various import statements public class StringyMap = HashMap ; public interface ListOfNames = List ; --- is equivalent to what would currently result from defining the StringyMap class in the previous example --- as well as the following: package blah; // various import statements public interface ListOfNames extends List {} DETAILS SPECIFICATION: The new syntax can be handled entirely via compiler modifications. Since this proposal consists entirely of syntactic sugar atop the existing type system and uses a syntax that currently has no meaning in Java, it should not have any affect on the meaning of any current feature of the Java Programming Language. COMPILATION: Compilation of this new feature would consist of de-sugaring two new types of declarations. For interfaces, the following: [modifier_list] interface [name] = [superinterface] ; is de-sugared to: [modifier_list] interface [name] extends [superinterface] {} Classes are a bit more complex: [modifier_list] class [name] = [superclass] ; is de-sugared to: [modifier_list] class [name] extends [superclass] { [constructors] } Where the [constructors] block consists of one "wrapped" constructor for each public or protected constructor in the superclass. Thus, for each such constructor in the superclass: [public/protected] [superclass] ([constructor_args. . .]); A "wrapper" constructor would be generated as follows: [public/protected] [name] ([constructor_args. . .]) { super ([constructor_args. . .]); } Finally, when resolving dependencies, if the compiler doesn't find a class or source file for a top-level class in the expected location, the compiler would examine "param-types.java" in the package-appropriate directory to see if it is defined there. Only classes and interfaces defined using the syntax described here are permitted in the "param-types.java"; any "traditional" class or interface definition in this file results in a compiler error. TESTING: This feature can be tested in the same manner as any other form of class or interface declaration. LIBRARY SUPPORT: None required. REFLECTIVE APIS: This should be automatic, as the current reflective APIs will correctly identify the class or interface. OTHER CHANGES: None. MIGRATION: Replace current use of parameterized types where feasible. COMPATIBILITY BREAKING CHANGES: None. The proposed syntax currently causes compiler errors. EXISTING PROGRAMS: No changes. REFERENCES EXISTING BUGS: None that I am aware of. URL FOR PROTOTYPE (optional): None thus far; work-in-progress. --- On Mon, 3/23/09, brucechapman at paradise.net.nz wrote: > From: brucechapman at paradise.net.nz > Subject: Re: Proposal: Simplified syntax for dealing with parameterized types. > To: jl0235 at yahoo.com, "james lowden" > Cc: coin-dev at openjdk.java.net > Date: Monday, March 23, 2009, 3:17 PM > Quoting james lowden : > > > ALTERNATIVES: > > > Write strings the old way by using concatenations or > using builders.> > > Seems somewhat out of place. From jl0235 at yahoo.com Mon Mar 23 13:38:34 2009 From: jl0235 at yahoo.com (james lowden) Date: Mon, 23 Mar 2009 13:38:34 -0700 (PDT) Subject: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: Message-ID: <662164.26492.qm@web63701.mail.re1.yahoo.com> Yeah, the "Map map = new HashMap<>();" is a lot simpler (and something I've wanted. . .); I'd actually like to see both that and the ideas I've suggested implemented. . . I may be attempting to kill multiple birds with one stone here; part of it is removing repitition from code, which the previously-floated proposal addresses. The other thing I'm trying to do is provide an "easier" way to use parameterized types in a type-safe fashion, without (unfortunately, in my mind) providing some kind of reification. I'm thinking of two different kinds of "type safety". One is making it harder to "break" the parameterized type (by, for example, setting a HashMap reference to a plain HashMap); the subclassing provides this. The other feature I'm looking for is some kind of differentiation-of-intent; Java already has this in the case of enums (i.e., any given four-value enum is in some sense "equivalent" to any other, as they are both internally represented by one of four integer values, but you can't interconvert); I think something similar would be useful in cases like Collections (every List is not necessarily intended to be the same thing); the syntactic sugar for subclassing would allow this. --- On Mon, 3/23/09, Reinier Zwitserloot wrote: > From: Reinier Zwitserloot > Subject: Re: Proposal: Simplified syntax for dealing with parameterized types. > To: jl0235 at yahoo.com > Cc: coin-dev at openjdk.java.net > Date: Monday, March 23, 2009, 3:16 PM > There are many more annoying issues with subtypes, most > notably regarding behaviour of .equals(), and the the way > one person's MapStringString isn't compatible with > another's MapStringString, eventhough they are both > really meant as just 'Map'. > > Your solution to this problem seems extremely > overengineered, while the end-result is a patchy hack at > best. > > Just allowing Map map = new > HashMap<>(); - an idea that's been floated many > times before, is something I'd strongly prefer, and > it's much simpler. > > --Reinier Zwitserloot > > > > On Mar 23, 2009, at 20:40, james lowden wrote: > > > > > Proposal: Simplified syntax for dealing with > parameterized types. > > > > AUTHOR(S): > > > > J. Lowden > > > > VERSION: > > > > 1.0 Initial version. > > > > > > OVERVIEW > > > > FEATURE SUMMARY: > > > > Declaring and instantiating parameterized types can be > verbose (resulting in expressions like "HashMap > " being repeated throughtout > one's code) and, due to the erasure-based implementation > of generics in Java, not necessarily type-safe. The code > snippet below illustrates both: > > > > > > HashMap a = new HashMap > (); > > HashMap b = new HashMap (); > > b.put ("foo", new JFrame ()); > > a = b; // this is semantically wrong, but compiles > > > > > > In this case, the parameterization language > ("") is repeated twice, > which quickly becomes annoying if one is using a large > number of String-to-String hashes. More dangerously, > despite "a" having been declared as a HashMap > , it is possible to use it as a > reference to a non-parameterized HashMap which may contain > objects of unexpected and semantically incorrect types. One > way around this problem is by subclassing the parameterized > type, as in: > > > > > > public class StringyMap extends HashMap String> { > > } > > > > > > The above example then becomes: > > > > > > StringyMap a = new StringyMap (); > > HashMap b = new HashMap (); > > b.put ("foo", new JFrame ()); > > a = b; // this now causes a compiler error > > > > > > This both removes the repetition and causes the > type-unsafe assignments statement to generate a compiler > error. However, since simply extending a class causes the > loss of all but the default constructor, in order to make > StringyMap as useful as HashMap , we > really need to do this: > > > > > > public class StringyMap extends HashMap String> { > > > > public StringyMap () { > > } > > > > public StringyMap (int initialCapacity) { > > super (initialCapacity); > > } > > > > public StringyMap (int initialCapacity, float > loadFactor) { > > super (initialCapacity, loadFactor); > > } > > > > public StringyMap (Map m) { > > super (m); > > } > > > > } > > > > > > This is an annoying heap of boilerplate code, > especially seeing that verbosity was one of the issues we > were trying to address. Therefore, the new syntax being > proposed is something along the lines of: > > > > public class X = Y ; > > > > which would be exactly equivalent to: > > > > public class X extends Y parameters> { > > > > // constructors > > > > } > > > > with constructors matching the signatures of the > superclass constructors automatically generated that simply > pass all the parameters along to the superclass constructor. > > > > This could also be done with interfaces. Since > interfaces do not support constructors, the mapping is > simpler, as we simply leave the automatic constructor > creation out: > > > > public interface X = Y parameters>; > > > > is equivalent to: > > > > public interface X extends Y parameters> {} > > > > > > Java currently requires each top-level public class or > interface to be declared in its own source file. When > working with multiple parameterized types, this could result > in a large number of one-line source files that may be > inconvenient to deal with. Therefore, I also propose the > creation of an optional special source file in each package > that can be used to contain multiple such type definitions. > This file would be named something like > "param-types.java" (the specific name doesn't > matter as long as it is A) standardized and B) not a legal > Java identifier, so we avoid collisions), and all public > classes or interfaces defined in it would be compiled as > though they were top-level class files in the given package. > The "param-types.java" file would be restricted > to containing classes/interfaces defined using the new > syntax described above; this file is intended as a > convenience mechanism to support the features described > above, not a mechanism for > > cramming all of one's code into one hideously-long > source file. > > > > Although not a principal goal of this proposal, this > also provides an easy mechanism for enforcing type safety > between two types that have the same parameters but are not > intended to be interconvertible. For example: > > > > public interface ListOfThingsToNameTheBaby = List > ; > > public interface ListOfAnnoyingInternetAcronyms = List > ; > > > > ListOfThingsToNameTheBaby a; > > ListOfAnnoyingInternetAcronyms b; > > > > a = b; // raises a compiler error, since these are not > assignable > > > > > > Note that there is potential for confusion if the two > types were actually meant to be interconverible (i.e., > ListOfNamesForBabies and ListOfThingsToNameTheBaby). > > > > > > MAJOR ADVANTAGE: > > > > It becomes easier and more elegant to create reusable, > robust parameterized types. > > > > > > MAJOR BENEFIT: > > > > Readability of code that makes extensive use of > parameterized types is improved. Although the general > erasure-related issues with type-safety of generics are not > eliminated, this provides a straightforward mechanism for > working with more robust parameterized types. > > > > > > MAJOR DISADVANTAGE: > > > > Programmers (especially those working on distributed > projects) may inadvertantly end up defining two types meant > to be "the same thing" that are not mutually > assignable, as in: > > > > public class ListOfNamesForBabies = ArrayList > ; > > public class ListOfThingsToNameTheBaby = ArrayList > ; > > > > ListOfNamesForBabies a; > > ListOfThingsToNameTheBaby b; > > > > a = b; // does not compile > > > > > > Note that this is only a problem in cases where the > types are intended to be equivalent; see the > ListOfAnnoyingInternetAcronyms/ListOfThingsToNameTheBaby > example above. > > > > > > ALTERNATIVES: > > > > Write strings the old way by using concatenations or > using builders. > > > > > > EXAMPLES > > > > SIMPLE EXAMPLE: > > > > --- creating a file named StringyMap.java in package > blah > > > > package blah; > > > > // various import statements > > > > public class StringyMap = HashMap String>; > > > > > > --- is equivalent to what would currently result from > the following: > > > > package blah; > > > > // various import statements > > > > public class StringyMap extends HashMap String> { > > > > public StringyMap () { > > } > > > > public StringyMap (int initialCapacity) { > > super (initialCapacity); > > } > > > > public StringyMap (int initialCapacity, float > loadFactor) { > > super (initialCapacity, loadFactor); > > } > > > > public StringyMap (Map m) { > > super (m); > > } > > > > } > > > > ADVANCED EXAMPLE: > > > > --- creating a file named param-types.java in package > blah > > > > package blah; > > > > // various import statements > > > > public class StringyMap = HashMap String>; > > public interface ListOfNames = List ; > > > > --- is equivalent to what would currently result from > defining the StringyMap class in the previous example > > --- as well as the following: > > > > package blah; > > > > // various import statements > > > > public interface ListOfNames extends List > {} > > > > > > DETAILS > > > > SPECIFICATION: > > > > The new syntax can be handled entirely via compiler > modifications. Since this proposal consists entirely of > syntactic sugar atop the existing type system and uses a > syntax that currently has no meaning in Java, it should not > have any affect on the meaning of any current feature of the > Java Programming Language. > > > > > > COMPILATION: > > > > Compilation of this new feature would consist of > de-sugaring two new types of declarations. For interfaces, > the following: > > > > [modifier_list] interface [name] = [superinterface] > ; > > > > is de-sugared to: > > > > [modifier_list] interface [name] extends > [superinterface] {} > > > > > > Classes are a bit more complex: > > > > [modifier_list] class [name] = [superclass] > ; > > > > is de-sugared to: > > > > [modifier_list] class [name] extends [superclass] > { > > > > [constructors] > > > > } > > > > Where the [constructors] block consists of one > "wrapped" constructor for each public or protected > constructor in the superclass. Thus, for each such > constructor in the superclass: > > > > [public/protected] [superclass] ([constructor_args. . > .]); > > > > A "wrapper" constructor would be generated > as follows: > > > > [public/protected] [name] ([constructor_args. . .]) { > > super ([constructor_args. . .]); > > } > > > > > > Finally, when resolving dependencies, if the compiler > doesn't find a class or source file for a top-level > class in the expected location, the compiler would examine > "param-types.java" in the package-appropriate > directory to see if it is defined there. Only classes and > interfaces defined using the syntax described here are > permitted in the "param-types.java"; any > "traditional" class or interface definition in > this file results in a compiler error. > > > > > > TESTING: > > > > This feature can be tested in the same manner as any > other form of class or interface declaration. > > > > LIBRARY SUPPORT: > > > > None required. > > > > REFLECTIVE APIS: > > > > This should be automatic, as the current reflective > APIs will correctly identify the class or interface. > > > > OTHER CHANGES: > > > > None. > > > > MIGRATION: > > > > Replace current use of parameterized types where > feasible. > > > > > > COMPATIBILITY > > > > BREAKING CHANGES: > > > > None. The proposed syntax currently causes compiler > errors. > > > > EXISTING PROGRAMS: > > > > No changes. > > > > > > REFERENCES > > > > EXISTING BUGS: > > > > None that I am aware of. > > > > URL FOR PROTOTYPE (optional): > > > > None thus far; work-in-progress. > > > > > > > > From rssh at gradsoft.com.ua Mon Mar 23 14:12:01 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 23 Mar 2009 23:12:01 +0200 (EET) Subject: [Where is type inherence ?] Re: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <172662.40997.qm@web63703.mail.re1.yahoo.com> References: <172662.40997.qm@web63703.mail.re1.yahoo.com> Message-ID: <47245b94ef68b1abb844e6bd401d71e1.squirrel@wmail.gradsoft.ua> Just my 2 cents: I think, that if we move in this direction, than constructor type inference must be on first place, simplified constructors syntax - second, all other like this proposal - third. Otherwise set of language features will be unbalanced. BTW, are type inference proposal was submitted ? May be somebody have plans to do this ? Or exists some consensus that this is not in project coin ? Some links: http://gafter.blogspot.com/2007/07/constructor-type-inference.html // Neal, what you think now ? Exists implementation http://weblogs.java.net/blog/forax/archive/2006/12/call_me_santa.html It was in Java 7 wish list. http://blogs.sun.com/ahe/entry/java_se_7_wish_list From develop4lasu at gmail.com Mon Mar 23 14:29:38 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 23 Mar 2009 22:29:38 +0100 Subject: [Where is type inherence ?] Re: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <47245b94ef68b1abb844e6bd401d71e1.squirrel@wmail.gradsoft.ua> References: <172662.40997.qm@web63703.mail.re1.yahoo.com> <47245b94ef68b1abb844e6bd401d71e1.squirrel@wmail.gradsoft.ua> Message-ID: <28bca0ff0903231429w718c73f1gee6eaea611511778@mail.gmail.com> 2009/3/23 : > [snip] > > Some links: > http://gafter.blogspot.com/2007/07/constructor-type-inference.html > // Neal, what you think now ? > > Exists implementation > http://weblogs.java.net/blog/forax/archive/2006/12/call_me_santa.html > > It was in Java 7 wish list. > http://blogs.sun.com/ahe/entry/java_se_7_wish_list > > As I see it's quite common for people to look for values support in Java ( final without type / := operator ). I do not know why Joe is against. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Mon Mar 23 14:43:59 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Mon, 23 Mar 2009 22:43:59 +0100 Subject: Tiny update to Improved Exception Handling: @SuppressWarnings Message-ID: If the suggestion to remove the requirement that catch blocks are reachable is accepted, I suggest such code should still generate a warning. You can put @SuppressWarnings on the exception block, like so: try { int x = 5 + 5; } catch ( @SuppressWarnings("unreachable") IOException iDontOccurInTryBlock) { //whatever } Perhaps the notion that the compiler will presume that annotation is referring to the catch block should be added to the proposal. --Reinier Zwitserloot (on behalf of Roel Spilker, who came up with this). From brucechapman at paradise.net.nz Mon Mar 23 14:46:48 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Tue, 24 Mar 2009 10:46:48 +1300 (NZDT) Subject: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <172662.40997.qm@web63703.mail.re1.yahoo.com> References: <172662.40997.qm@web63703.mail.re1.yahoo.com> Message-ID: <1237844808.49c80348272fe@www.paradise.net.nz> Quoting james lowden : > > Proposal: Simplified syntax for dealing with parameterized types. > > AUTHOR(S): > - snip- > [modifier_list] interface [name] = [superinterface] .>; > > is de-sugared to: > > [modifier_list] interface [name] extends [superinterface] > {} > > > Classes are a bit more complex: > > [modifier_list] class [name] = [superclass] ; > > is de-sugared to: > > [modifier_list] class [name] extends [superclass] > { > > [constructors] > > } > my 2 cents: The interface case is trivial and offers little or no value in terms of added expressiveness other than an alternative syntax consistent with the class case, which is more than enough value IFF the class case can be justified. The class case can be achieved using a custom annotation, and an AnnotationProcessor to generate the code. Such a solution would be nicer if annotation values could include type literals, but can still be done nice enough to be "adequate for purpose" (IMHO) without them. The annotations could be placed in package-info.java giving you much of the advantage of your param-types.java file. So a proposal for type literals and type literals as annotation values would make this proposal redundant, and enable solutions to similar (and not so similar) needs as well. However good this proposal is, type literals as annotation values is even better, because it leverages existing mechanisms to allow developers to solve many problems themselves, as opposed to having the compiler solve one problem. Bruce From neal at gafter.com Mon Mar 23 14:51:21 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 23 Mar 2009 14:51:21 -0700 Subject: [Where is type inherence ?] Re: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <47245b94ef68b1abb844e6bd401d71e1.squirrel@wmail.gradsoft.ua> References: <172662.40997.qm@web63703.mail.re1.yahoo.com> <47245b94ef68b1abb844e6bd401d71e1.squirrel@wmail.gradsoft.ua> Message-ID: <15e8b9d20903231451t1dadee42x2e349ae1e44f117d@mail.gmail.com> On Mon, Mar 23, 2009 at 2:12 PM, wrote: > BTW, are type inference proposal was submitted ? > May be somebody have plans to ?do this ? > Or exists some consensus that this is not in project coin ? > > Some links: > http://gafter.blogspot.com/2007/07/constructor-type-inference.html > // Neal, what you think now ? Joe Darcy and Jeremy Manson are working on a detailed proposal. I still think it's a good idea. > Exists implementation > http://weblogs.java.net/blog/forax/archive/2006/12/call_me_santa.html That's a different approach to shorten some of the same use cases. For those who aren't aware, R?mi was looking at using "final" instead of a type on the variable declaration. See the discussion and comments on my blog post for opinions about the two alternatives. R?mi's approach is much simpler (which is a good thing), and has the advantage that it is usable when the right-hand-side is something other than just a constructor invocation. On the other hand, the constructor-type-inference approach is useful in a few contexts where the object creation appears somewhere other than directly on the right-hand-side of an assignment. If I were to write up the approach R?mi implemented, the disadvantages section would read "This is a departure from Java's previous philosophy that all named entities should be given an explicit type. Theoretically, it is possible to intentionally write difficult-to-understand code by using this construct where the types of the intermediate results are not clear from context. In addition, this creates language support for an idiom that departs from the advice in Effective Java (2nd edition) Item 52 (use interface types for variable declarations): local code might unintentionally depend on features of the implementation class rather than the abstract type. On the other hand, a few years of experience with this change in a Java-like language has yielded virtually uniform positive feedback, suggesting that these are not problems in practice." From i30817 at gmail.com Mon Mar 23 15:28:55 2009 From: i30817 at gmail.com (Paulo Levi) Date: Mon, 23 Mar 2009 22:28:55 +0000 Subject: Anyone ever considered named tuples? Message-ID: <212322090903231528m2cf069c6lc6089730f564397e@mail.gmail.com> "Actually, you could create this quite simply without changing the type system by allowing a simpler syntax to create POJOs. Something like: public data class Person { String name; int age; boolean male; } which would be compiled to a method with those fields as private final, 1 constructor (would dovetail nicely with the 'named' suggestion), 3 public getters named according to javabean semantics (getName, getAge, isMale), a toString, an equals, a hashCode, and a clone method. You can add more methods to it if you want to, and even replace the auto-generated ones (if its already there, it won't be autogenerated). --Reinier Zwitserloot" I don't think this is enough, simply because the main annoyance for these data objects is the typesystem pollution with methodless(oo-less) objects. If we had structural typing, yes, i'd shup up in a instant, and just use the yet another data container since i wouldn't have to extract the data before passing it to a library, but if we aren't going to get it (oh it would be soooo cool), i prefer we got a minimal, classless - typeless outside the parameters - way to declare data objects that libraries could use. A swissland of data objects. I know I'm being contradictory. For one I'd not like names at class level (as a library creator to avoid having to create yet another data container and as a library user to have to assimilate the data object) but on another hand, i'd like at least token self documenting semantic meaning as a library user - given by the library code. For instance: List<(String parentDirectory, String file)> getChildrenBindingToPosixMethod(File parent) From howard.lovatt at iee.org Mon Mar 23 15:33:31 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Tue, 24 Mar 2009 09:33:31 +1100 Subject: Proposal: Simplified syntax for dealing with parameterized types (correction to ALTERNATIVES section) Message-ID: <3dd3f56a0903231533q5cd6365dqaf15c6978cc2794e@mail.gmail.com> Hi, There is a lot to like with proposal since class StringList = ArrayList would both shorten declarations and would partially reify the generic class. However there is a problem touched on in the proposal namely class MyStringList = List then StringList sl = ...; MyStringList msl ...; sl = msl; // Error. This problem is worse than suggested in the proposal, consider alternate implementations of the same interface: class StringList = List; class ArrayStringList = ArrayList; StringList sl = new ArrayList(); // Error I think to make this workable you need to either: 1. change the mechanism so that the interface and abstract class version is simply a shorthand and does not create a new class or type (i.e. simply a type alias), or 2. alternatively just drop the interface/abstract class bit altogether and say the new mechanism can only be applied to non-abstract classes. -- Howard. From develop4lasu at gmail.com Mon Mar 23 17:04:13 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 24 Mar 2009 01:04:13 +0100 Subject: I need your opinion... In-Reply-To: <28bca0ff0903220348vf914ba9jc326ee17083b7c10@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <49C5A096.8010706@sun.com> <28bca0ff0903220348vf914ba9jc326ee17083b7c10@mail.gmail.com> Message-ID: <28bca0ff0903231704i168831c0kc31ff1c4a8c92015@mail.gmail.com> I'll try compare: - 'final' without type - Type inference - consider(::) operator (for values) Let's assume final field is just named 'value'. 1) Type inference It's nothing new that such code will be hard to read, and depending from implementation it will create lots bugs. This can be really hard to real as well. Here we need read 5th line to understand first. 0| addone(x) { 1| val result; /*inferred-type result */ 2| val result2; /*inferred-type result #2 */ 3| val boo = foo.getSome().getContext(); // boo is Boo> 4| 5| result = x+1; 6| result2 = x+1.0; /* this line won't work (in the proposed language) */ 7| boo = current,get(result); 8| return result; 9| } What more we need analyse returned types to be sure that new value is correct to assign: 3rd line need to be analysed just to say if 7th is correct. All those make Type inference really hard to read. 2) ':=' operator for values & consider '::' operator. they are one and the same, just :: is easier to read and do not need so many brackets. (last := arraylist.get(( size := arraylist.size() )-1 ) ).getIdentificator().getName(); reading order(eyes): -> -> -> <- <- <- <- <- -> -> -> -> -> -> -> <- <- <- <- <- <- <- <- -> -> -> -> -> -> -> -> -> -> -> -> arraylist.get( arraylist.size()::size -1 )::last .getIdentificator().getName(); reading order(eyes): -> -> -> -> -> <- <- <- <- <- <- <- <- -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> Both make some problems in if-s .... if ( ( a ) && ( c.getD::d ==5 )) // people expect for : ( c.getD::d ==5 ) to be not executed if ( a ) is true. 3) 'final' without type It's clear and do not create more interactions (only one is intersection) But it need forget keyword, because people used to write 1 variable rather than 3 values, so amount of used names need to be decreased. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Mon Mar 23 18:16:48 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 23 Mar 2009 18:16:48 -0700 Subject: Proposal: Simplified syntax for dealing with parameterized types. In-Reply-To: <662164.26492.qm@web63701.mail.re1.yahoo.com> References: <662164.26492.qm@web63701.mail.re1.yahoo.com> Message-ID: <49C83480.7080906@sun.com> james lowden wrote: > Yeah, the "Map map = new HashMap<>();" is a lot simpler (and something I've wanted. . .); I'd actually like to see both that and the ideas I've suggested implemented. . . > Yes, Jeremy sent around a proposal for that in the first days of the call for proposals; a revised is in the works. > I may be attempting to kill multiple birds with one stone here; part of it is removing repitition from code, which the previously-floated proposal addresses. The other thing I'm trying to do is provide an "easier" way to use parameterized types in a type-safe fashion, without (unfortunately, in my mind) providing some kind of reification. > > I'm thinking of two different kinds of "type safety". One is making it harder to "break" the parameterized type (by, for example, setting a HashMap reference to a plain HashMap); the subclassing provides this. > The concerns you have with converting to/from rawtypes could be handled with either new lint flags to the compiler or annotation processors to reject such conversions. > The other feature I'm looking for is some kind of differentiation-of-intent; Declaring a new type strikes me as a fine way to indicate differentiation of intent :-) Therefore, combined with the shorter declaration syntax and the ability to cause compilation errors for raw types without change the language, I don't see a strong motivation for this change. > Java already has this in the case of enums (i.e., any given four-value enum is in some sense "equivalent" to any other, as they are both internally represented by one of four integer values, but you can't interconvert); In their serial form, enums are represented by their names, not their ordinal values. Also, enums can and do define type-specific behavior. Therefore, all enums with the same number of constants are not semantically equivalent. -Joe From lk at teamten.com Mon Mar 23 18:24:28 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Mon, 23 Mar 2009 18:24:28 -0700 Subject: Anyone ever considered named tuples? In-Reply-To: <212322090903231528m2cf069c6lc6089730f564397e@mail.gmail.com> References: <212322090903231528m2cf069c6lc6089730f564397e@mail.gmail.com> Message-ID: <997cab100903231824g1151d3e2o282c01df362a9636@mail.gmail.com> On Mon, Mar 23, 2009 at 3:28 PM, Paulo Levi wrote: > i'd like at least token self documenting semantic meaning as a library > user - given by the library code. > For instance: > List<(String parentDirectory, String file)> > getChildrenBindingToPosixMethod(File parent) One of the advantages of using named types is that it gives you a place to write documentation. Where would you document the meaning of "parentDirectory" and "file"? Can either be null? Does parentDirectory include the final slash? I don't think your example above is very self-documenting when you consider the subtle questions a user might have about the list contents. You could put it in the javadoc for getChildrenBindingToPosixMethod(), but surely several methods will eventually want to return or take that list or one of its elements, and you don't want to duplicate that documentation. Giving that tuple a name gives you a place to document it, and it later encourages you to document it when the javadoc page is bare. What you call typesystem pollution, I call javadoc richness. Lawrence From r.spilker at gmail.com Tue Mar 24 01:38:16 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Tue, 24 Mar 2009 09:38:16 +0100 Subject: Tiny update to Improved Exception Handling: @SuppressWarnings In-Reply-To: References: Message-ID: I prefer catch (@SuppressWarnings("unthrown") IOException e) {} On Mon, Mar 23, 2009 at 10:43 PM, Reinier Zwitserloot < reinier at zwitserloot.com> wrote: > If the suggestion to remove the requirement that catch blocks are > reachable is accepted, I suggest such code should still generate a > warning. You can put @SuppressWarnings on the exception block, like so: > > try { > int x = 5 + 5; > } catch ( @SuppressWarnings("unreachable") IOException > iDontOccurInTryBlock) { > //whatever > } > > > Perhaps the notion that the compiler will presume that annotation is > referring to the catch block should be added to the proposal. > > > --Reinier Zwitserloot (on behalf of Roel Spilker, who came up with > this). > > > > > From david at walend.net Tue Mar 24 05:41:25 2009 From: david at walend.net (David Walend) Date: Tue, 24 Mar 2009 08:41:25 -0400 Subject: Proposal: Access to Generic Type Parameters at Compile-Time In-Reply-To: <49C721B4.1010703@sun.com> References: <3F974753-0D66-4D25-A670-E1F0D442F9A0@walend.net> <49C721B4.1010703@sun.com> Message-ID: On Mar 23, 2009, at 1:44 AM, Joseph D. Darcy wrote: > David Walend wrote: >> [snip] >> >> JDK5 Syntax -- three type specifiers, one of which requires the >> developer to match the first two by hand: >> >> interface Path> >> extends Digraph >> { >> Node getHead(); >> ... >> } >> > > [snip] > > When I see a Java type declared to have more than two type > parameters my initial reaction is usually "this type isn't using the > best decomposition of the problem space." > I agree. It's even worse when the type parameters layer on top of each other. These type parameters take effort to understand because they provide no guidance to what is important. They are frustrating to drag through the code to the compiler. When someone makes the effort to force a system to work, whatever clarity could exist gets lost in the noise of the resulting nested angle brackets. The entire complexity of the problem is exposed in one declaration. I have no doubt in my mind that a Path through a Digraph exists within my mental context of that Digraph. The Path should use the same types as the Digraph it traverses. It doesn't follow just any series of alternating Nodes and Edges. Further, the Digraph should dictate types to Paths for the Nodes and Edges when the Path is declared. Part of the problem space is the tools available to solve the problem. I mapped "dictating types" to generic type parameters, which resulted in ugly, complex code. JDK5 generics provide two approaches when generics begin to get complex: layered generics and wildcards. We are already discussing layered generics. Wildcards work well when the type doesn't matter -- when encapsulation and invisibility are total. I found now way to use wildcards to say that two wildcard symbols must be the same. JDK5 generics provides the two extremes of completely hidden and completely exposed complexity, with no middle ground. Java class structures provide a much richer set of options for member variables and methods. Some details of a member variable's lifecycle can be specified with final, transient and volatile. More importantly, a member variable's accessibility can be public, protected, default or private. One model of this proposal is that, before erasure, the type parameters exist as final variables with the same visibility as the declaration that contains them. When a method has an unwieldy number of parameters, we'll often refactor the code by creating a parameter object -- a class to contain and replace all the parameters. A parameter object's members exploit the final and accessibility keywords to act as a container of the complexity. When the code is compiled, type parameters are encapsulated but unaccessible; JDK5 generics provide no access to type parameters declared somewhere else. Implementing this proposal would give us that access. In that sense, Semiring can play the role of a parameter object for the type parameters that describe the problem domain. This proposal would allow Path to be much cleaner -- just one type parameter: interface Path Dave David Walend david at walend.net From rssh at gradsoft.com.ua Tue Mar 24 06:06:21 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 24 Mar 2009 15:06:21 +0200 (EET) Subject: PROPOSAL: Compiletime information access Message-ID: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> AUTHOR: Ruslan Shevchenko OVERVIEW: FEATURE SUMMARY: Add API to access compile-time context of current compiled element from programs and annotation processors. MAJOR ADVANTAGE: Now compile time properties are unaccessible for programmer. This meaning that some functionality (such as access to location of file and line) is accessible only from debug version of program with technique, which is not officially supported, some (such as access to time of compilation or to binding context of current program location) is not avaible at all. MAJOR DISADVANTAGE Inaccurate usage of this feature can cause producing of unmaintable code. ALTERNATIVES: External preprocessing of java sources. EXAMPLES SIMPLE EXAMPLE: Example 1 if (traceCondigion) { log.trace(Compiletime.getFileName()+":"+ Compiletime.getLineNumber()); } Example 2 if (system.currentTimeMillis() - Compiletime.getTimeMillis() > 86400) { System.out.println("This file was compiled more than day ago"); } Example 3 System.out.println("Superprogram by AAA AC, version:"+ Compiletime.exec("svnversion")); ADVANCED EXAMPLE: Example 1 // assuming that multiline strings are implemented: int a=0; int b=1; Binding bindings = Compiletime.getInstance().getCurrentBindings(); ScriptEngine velocity = ScriptEngineManager.get("velocity"); try { String fname = Compiletime.getFileName(); int line = Compiletime.getLineNumber(); String s = velocity.eval(""" #if ($a==$b) Something interesting here may be, Are you know that value of b is $b ? #else no mistics here. #end """, bindings); } catch (ScriptException ex){ Sytem.err.println("error in inline velocity in "+fname+", " "line "+line+1+ex.getLineNumber()); } Example 2 boolean isDemo = (Compiletime.eval(Properties.class, "getProperty","is.demo")!=null); if (!isDemo) { String key = (String)Compiletime.eval(GenerateUniqueKey.class, "generate"); LoadNotDemoClass(); } DETAILS: Add to Java Library pseudo-objects java.lang.Compiletime with access to compile-time properties and next signature: public class Compiletime { /** * get filename of compiled call. * in case of generated source and avaible JSR-45 SMAP file * return file name of translated-source. **/ public static String getFileName(); /** * get line number of compiled call. * in case of generated source and avaible JSR-45 SMAP file * return line number in translated-source. **/ public static int getLineNumber(); /** * get class name where this call is placed. * in case of generated source and avaible JSR-45 SMAP file * return class name in translated-source. **/ public static int getClassName(); /** * get method name where this call is placed. * in case of generated source and avaible JSR-45 SMAP file * return method name in translated-source. **/ public static int getMethodName(); /** * generate JSR223 bindings for given names in current compilation *context. *Names array must be empty or consists from string literals. **/ public static Bindings getBindings(String ... names) /** * get time of compilation in miliseconds. **/ public static long getTimeMillis(); /** * Execute os command in compile-time. *@command - must be a string literal or result of call of Compiletime * method, otherwise compile-time error is thrown **/ public static String exec(String command) /** * call java class at compile-time. *During processing this directive, compiler will *1. determinate, if class available in user path. *2. determinate, if exists method with appropriative number and types * of parameters. *3. If such method is static - call one, otherwise * 3.1 if class have default constructor - create instance of object * (otherwise throw compile-time error) * 3.2. Call methid with new-created instance. * 3.3. If method return some result - substitute output to result, * on exception throw compile-time error. *@param classLiteral - must be a class literal for object to call. *@param methodName - must be a string literal with name of method to call. *@param parameters - parameters of method to call. Must be a literals, or * calls of Compiletime methods. **/ public static Object eval(Class classLiteral, String methodName, Object .. params); } COMPILATION: During compilation calls to compile time are changed to generation of appriative constant expressions. String x = Compiletime.getFileName(); changed to String x = "com/mycompany/package/MyClass.java"; int x = Compiletime.getLinNumber(); changed to int x = 33; String x = getClassName() changed to String x = "com.mycompany.package.MyClass"; class X { int p1; String p2; ... public void doSomething(int x, int y) { int local = x+y; Bindings bindings = Compiletime.getBindings(); evalSomeScript(bindings); } } will translated to class X { int p1; String p2; ... public void doSomething(int x, int y) { int local = x+y; SimpleBinding binding=(SimpleBinging uniqueName= new SimpleBinding(); uniqueName.put("this",this); uniqueName.put("p1",p1); uniqueName.put("p2",p2); uniqueName.put("x",x); uniqueName.put("y",y); uniqueName.put("local",local); uniqueName ); evalSomeScript(bindings); } } (assuming that Block Expressions for Java will be avaible. If not - it will be necessory create own implementation of Bindings as part of library). exec will be changed to Sting literal, with result of execution, i. e. on Unix String compiledBy = Compiletime.eval("whoami"); whill be translated to 'rssh' At last eval call is translated to - appropriative literal, if result of eval is primitive type or boxed primitivew type. - Call of code to unserialize constant byte array, which as serialized during compilation or throw compile-time error is object is not primitive type and not implements Serializable. JLS changes: current scope of JLS is not touched. Btw, may be add to JLS chapter with name 'Compilation process' where describe: - high level description of transforming source code to JVM classes. - process of automatic loading of annotation processors and when ones are used. - this API. TESTING: Special cases are: * compability with JSR45 * testing of exec function is LIBRARY SUPPORT: None, or adding two classes (for Bindings implementation with filling in constructor and Unserializing Object utility) in depends of avaibility of block expressions for Java (May be exists sence add methods for retrieveing source location (i.e. file name and line number retrieving) to javax.lang.model.element.Element to support better diagnostics. REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4411102 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6439965 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4649007 IMPLEMENTATION URL (optional) None yet. From Ruslan.Lazukov at digia.com Tue Mar 24 07:13:13 2009 From: Ruslan.Lazukov at digia.com (Ruslan) Date: Tue, 24 Mar 2009 17:13:13 +0300 Subject: Small property support. In-Reply-To: <49C10BC1.1000604@fh-landshut.de> References: <49C0E891.7000901@digia.com> <200903181340.52296.david.goodenough@linkchoose.co.uk> <49C0FC1F.2010002@digia.com> <200903181405.52957.david.goodenough@linkchoose.co.uk> <49C103FA.909@digia.com> <49C10BC1.1000604@fh-landshut.de> Message-ID: <49C8EA79.5030500@digia.com> Hello. It was a joke :) but every joke have it's serious side. So i will answer on serious side. I will be happy to use your tine property support. But it creates more problems than my proposal. Without "property" keyword - it can be unclear why in one place @Get @Set private int i; create both getter and setter, and in another only one of them. Java is very good because it is readable. This issue appear because in first class imported annotations are: java.property.Set and java.property.Get And in another class java.property.Set and some.other.package.Get Same thing is with arrow (->) and point (.). With arrow i can easily understand can some code throw exception (because getter/setter can throw exceptions). And with point i can not. With point you can not access getter and variable at the same place: private property int i; public void foo2() { int j = this.i; j = getI(); } public void foo2() { int j = this.i; j = this->i; } So arrow should be in this proposal. And at the end: it's much more harder to write getter function with using of Java annotations right now. So for you proposal necessary to change annotations too. BR, Ruslan. PS i would like to have any type of property support faster than in 5 years. 5 years - time before java 8 will be released... may be ;) Michael Bien ?????: > I would even start smaller, should I call it tiny property support? ;) > > @get @set > private int i; > > would tell the compiler to generate getter setter and property change > listener methods for the field 'i'. No additonal keywords and no > arrow(->) syntax required. > > Writing the property 'i' in the bean would cause a compiler warning, > reading would be fine. Calling setters would be the preferred way to > modify properties from inside or outside the bean. > > I know Annotations are not intended to change the meaning of a field or > its behaviour. But this is rather a shortcut to the bean pattern than > the usual language change proposal. > > I see it rather as temporary and probably even as smallest possible > property feature instead of a final solution. JDK8 could add real first > class properties without conflicts with this proposal (again its just > the bean pattern), you could even keep the Annotations it wouldn't hurt. > > no changes to javadoc, compiler etc. > > what do you think? Should I try to file a proposal or do you already > spot show stoppers? > > best regards, > > Michael Bien > > Ruslan wrote: > >> Hello. >> >> David Goodenough wrote: >> >> >>> On Wednesday 18 March 2009, Ruslan wrote: >>> >>> >>> >>>> Hello. >>>> >>>> Yes, i have read it. >>>> But we are trying to fix different things: >>>> - You are trying to get rid of strings in "Beans Binding of JPA Criteria >>>> API" >>>> >>>> >>>> >>> As a matter of interest, how would I pass a property reference using >>> your proposal? >>> >>> >>> >> My proposal have another goal. Goal is to have synthetic sugar like >> for-each for property. >> And in my case there is not property reference, so you can not pass it. >> >> Property references can be added at next release (5 years later ;) ). >> >> >> >> >>>> - And my point is to make property code readable and get rid of >>>> getters/setters when use Dependency Injection. >>>> >>>> >>>> >>> For simple getters and setters, my proposal does actually get rid of >>> getters and setters, in that the Property object will do the work for you >>> using the Field get and set (and some snake oil to handle >>> PropertyChangeSupport). >>> >>> >>> >> Yes, that is true. And my proposal are not using Property or Field. It's >> like macros for property get/set generation. >> >> >>> David >>> >>> >>> >> PS my goal is to avoid situation like this: >> private int i; >> >> public String getI() { >> return Integer.toString(i); >> } >> >> public void setI(long i) { >> this.i = (int)i; >> } >> >> What is the type of property 'i' ? >> >> private int i; >> >> public int getJ() { >> return i; >> } >> >> public void setI(int i) { >> this.i = i; >> } >> >> IS everyone see that there is not getter for 'i' - we have getter for >> 'j'. But compiler will not fix this error, because it is a logical >> error, not language. >> >> >> Ruslan. From vilya.harvey at gmail.com Tue Mar 24 07:38:31 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 24 Mar 2009 14:38:31 +0000 Subject: PROPOSAL: Compiletime information access In-Reply-To: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> Message-ID: <6aef848f0903240738x4e24b53bv2c0c18394cfb9acb@mail.gmail.com> Wouldn't this effectively kill off jikes, or any other compiler that wasn't itself implemented in Java? Regardless of that, there's some potentially big problems with this that I don't see addressed in the proposal. Consider the code snippet below: import java.text.MessageFormat; import java.util.Date; class Bad { private static final String HELLO = "Hello #{0} at {1,time} on {1,date}!"; public void myMethod(int i) { System.out.println(MessageFormat.format(HELLO, i, new Date())); } public static void main(String[] args) { for (int i = 0; i < 10; ++i) Compiletime.eval(getClass(), "myMethod", i); } } Although it looks like valid Java, it contains a lot of bugs: - The arguments to Compiletime.eval (getClass() and i) aren't available until runtime. - "myMethod" can't be called because we haven't compiled it's class yet. - MessageFormat.format relies on the current locale, which may be different at compile time to run time. - Compiletime.eval will only be called once, although it looks like it should be called 10 times; then at runtime the program will iterate 10 times over an empty loop and exit. The main problem is the execution of arbitrary Java code at compile time. The code can contain dependencies on things which haven't been compiled yet, or libraries which are dynamically loaded at runtime; worse, it may depend on an environment which may be different between compile time and runtime (quite likely when developing J2EE apps, for example). It also raises the questions around verification (how do you verify classes that you are evaluating during compilation?) and security (what security model does it operate under?). The other problem with the proposal is the Compiletime.exec() method. Allowing arbitrary commands to be executed introduces serious security implications to the compilation step. Currently, at least, you can compile code without having to worry about those. Finally, because it looks like ordinary Java code it's easy to confuse the two, leading to mistakes like the loop body in the example. In my opinion, this is more suited to a separate preprocessor. A quick google found a few of those already available. Vil. 2009/3/24 > > AUTHOR: Ruslan Shevchenko > > OVERVIEW: > > FEATURE SUMMARY: > > Add API to access compile-time context of current compiled element from > programs and annotation processors. > > MAJOR ADVANTAGE: > > Now compile time properties are unaccessible for programmer. This meaning > that some functionality (such as access to location of file and line) is > accessible only from debug version of program with technique, which is not > officially supported, some (such as access to time of compilation or > to binding context of current program location) is not avaible at all. > > MAJOR DISADVANTAGE > > Inaccurate usage of this feature can cause producing of unmaintable code. > > ALTERNATIVES: > > External preprocessing of java sources. > > EXAMPLES > > SIMPLE EXAMPLE: > > Example 1 > > if (traceCondigion) { > log.trace(Compiletime.getFileName()+":"+ > Compiletime.getLineNumber()); > } > > Example 2 > > if (system.currentTimeMillis() - Compiletime.getTimeMillis() > 86400) { > System.out.println("This file was compiled more than day ago"); > } > > Example 3 > > System.out.println("Superprogram by AAA AC, version:"+ > Compiletime.exec("svnversion")); > > ADVANCED EXAMPLE: > > Example 1 > // assuming that multiline strings are implemented: > > int a=0; > int b=1; > Binding bindings = Compiletime.getInstance().getCurrentBindings(); > ScriptEngine velocity = ScriptEngineManager.get("velocity"); > try { > String fname = Compiletime.getFileName(); > int line = Compiletime.getLineNumber(); > String s = velocity.eval(""" > #if ($a==$b) > Something interesting here may be, > Are you know that value of b is $b ? > #else > no mistics here. > #end > """, > bindings); > } catch (ScriptException ex){ > Sytem.err.println("error in inline velocity in "+fname+", " > "line "+line+1+ex.getLineNumber()); > } > > > Example 2 > > boolean isDemo = (Compiletime.eval(Properties.class, > "getProperty","is.demo")!=null); > > if (!isDemo) { > String key = (String)Compiletime.eval(GenerateUniqueKey.class, > "generate"); > LoadNotDemoClass(); > } > > > DETAILS: > > > > Add to Java Library pseudo-objects java.lang.Compiletime with access to > compile-time properties and next signature: > > public class Compiletime > { > /** > * get filename of compiled call. > * in case of generated source and avaible JSR-45 SMAP file > * return file name of translated-source. > **/ > public static String getFileName(); > > /** > * get line number of compiled call. > * in case of generated source and avaible JSR-45 SMAP file > * return line number in translated-source. > **/ > public static int getLineNumber(); > > /** > * get class name where this call is placed. > * in case of generated source and avaible JSR-45 SMAP file > * return class name in translated-source. > **/ > public static int getClassName(); > > /** > * get method name where this call is placed. > * in case of generated source and avaible JSR-45 SMAP file > * return method name in translated-source. > **/ > public static int getMethodName(); > > > /** > * generate JSR223 bindings for given names in current compilation > *context. > *Names array must be empty or consists from string literals. > **/ > public static Bindings getBindings(String ... names) > > > /** > * get time of compilation in miliseconds. > **/ > public static long getTimeMillis(); > > /** > * Execute os command in compile-time. > *@command - must be a string literal or result of call of Compiletime > * method, otherwise compile-time error is thrown > **/ > public static String exec(String command) > /** > * call java class at compile-time. > *During processing this directive, compiler will > *1. determinate, if class available in user path. > *2. determinate, if exists method with appropriative number and types > * of parameters. > *3. If such method is static - call one, otherwise > * 3.1 if class have default constructor - create instance of object > * (otherwise throw compile-time error) > * 3.2. Call methid with new-created instance. > * 3.3. If method return some result - substitute output to result, > * on exception throw compile-time error. > *@param classLiteral - must be a class literal for object to call. > *@param methodName - must be a string literal with name of method to > call. > *@param parameters - parameters of method to call. Must be a literals, > or > * calls of Compiletime methods. > **/ > public static Object eval(Class classLiteral, String methodName, > Object .. params); > > } > > > > COMPILATION: > > During compilation calls to compile time are changed to generation of > appriative constant expressions. > > String x = Compiletime.getFileName(); > changed to > String x = "com/mycompany/package/MyClass.java"; > > int x = Compiletime.getLinNumber(); > changed to > int x = 33; > > String x = getClassName() > changed to > String x = "com.mycompany.package.MyClass"; > > > class X > { > int p1; > String p2; > > ... > public void doSomething(int x, int y) > { > int local = x+y; > Bindings bindings = Compiletime.getBindings(); > evalSomeScript(bindings); > } > > } > > > will translated to > > class X > { > int p1; > String p2; > ... > > public void doSomething(int x, int y) > { > int local = x+y; > SimpleBinding binding=(SimpleBinging uniqueName= new SimpleBinding(); > uniqueName.put("this",this); > uniqueName.put("p1",p1); > uniqueName.put("p2",p2); > uniqueName.put("x",x); > uniqueName.put("y",y); > uniqueName.put("local",local); > uniqueName ); > evalSomeScript(bindings); > } > > > } > > (assuming that Block Expressions for Java will be avaible. If not - it > will be necessory create own implementation of Bindings as part of > library). > > exec will be changed to Sting literal, with result of execution, i. e. > on Unix > String compiledBy = Compiletime.eval("whoami"); > whill be translated to 'rssh' > > At last eval call is translated to > - appropriative literal, if result of eval is primitive type or boxed > primitivew type. > - Call of code to unserialize constant byte array, which as serialized > during compilation > or throw compile-time error is object is not primitive type and not > implements Serializable. > > JLS changes: current scope of JLS is not touched. > > Btw, may be add to JLS chapter with name 'Compilation process' where > describe: > - high level description of transforming source code to JVM classes. > - process of automatic loading of annotation processors and when ones are > used. > - this API. > > > TESTING: > > Special cases are: > * compability with JSR45 > * testing of exec function is > > LIBRARY SUPPORT: > None, or adding two classes (for Bindings implementation with filling in > constructor and Unserializing Object utility) in depends of avaibility > of block expressions for Java > > (May be exists sence add methods for retrieveing source location (i.e. > file > name and line number retrieving) to javax.lang.model.element.Element to > support better diagnostics. > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > None > > REFERENCES > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4411102 > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6439965 > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4649007 > > IMPLEMENTATION URL (optional) > > None yet. > > > > > > > From jl0235 at yahoo.com Tue Mar 24 07:50:33 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 07:50:33 -0700 (PDT) Subject: Proposal: Simplified syntax for dealing with parameterized types (correction to ALTERNATIVES section) In-Reply-To: <3dd3f56a0903231533q5cd6365dqaf15c6978cc2794e@mail.gmail.com> Message-ID: <365917.25119.qm@web63706.mail.re1.yahoo.com> I see what you're saying. . . there's no way, having made StringList a subinterface of List, to then have it be an ArrayList (or whatever concrete implementation is desired). Based on this, and the general triviality of the interface case, I'm thinking that using the syntax for interfaces (or abstract classes) is probably a lot of confusion for minimal/no gain, and am tempted to simply remove it from the proposal. (Alternately, as you mentioned, we could use it as an alias, but then we have an identifier such as "StringList" floating around the code which isn't *actually* a class or interface or anything after compilation, which results in different reflective behaviors for the class and interface case, which could be messy.) -JL --- On Mon, 3/23/09, Howard Lovatt wrote: > From: Howard Lovatt > Subject: Proposal: Simplified syntax for dealing with parameterized types (correction to ALTERNATIVES section) > To: coin-dev at openjdk.java.net > Date: Monday, March 23, 2009, 5:33 PM > Hi, > > There is a lot to like with proposal since class StringList > = > ArrayList would both shorten declarations and > would partially > reify the generic class. However there is a problem touched > on in the > proposal namely class MyStringList = List > then StringList sl = > ...; MyStringList msl ...; sl = msl; // Error. This problem > is worse > than suggested in the proposal, consider alternate > implementations of > the same interface: > > class StringList = List; > class ArrayStringList = ArrayList; > > StringList sl = new ArrayList(); // Error > > I think to make this workable you need to either: > > 1. change the mechanism so that the interface and abstract > class > version is simply a shorthand and does not create a new > class or type > (i.e. simply a type alias), or > > 2. alternatively just drop the interface/abstract class bit > altogether > and say the new mechanism can only be applied to > non-abstract classes. > > > -- Howard. From rssh at gradsoft.com.ua Tue Mar 24 08:02:07 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 24 Mar 2009 17:02:07 +0200 (EET) Subject: PROPOSAL: Compiletime information access In-Reply-To: <6aef848f0903240738x4e24b53bv2c0c18394cfb9acb@mail.gmail.com> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <6aef848f0903240738x4e24b53bv2c0c18394cfb9acb@mail.gmail.com> Message-ID: <7bc7a3eea212b409e97a78f9e9c4cac0.squirrel@wmail.gradsoft.ua> > Wouldn't this effectively kill off jikes, or any other compiler that > wasn't > itself implemented in Java? > I think any compiler can load or spawn external JVM, if needed. > Regardless of that, there's some potentially big problems with this that I > don't see addressed in the proposal. Consider the code snippet below: > > import java.text.MessageFormat; > import java.util.Date; > > class Bad { > private static final String HELLO = "Hello #{0} at {1,time} on > {1,date}!"; > > public void myMethod(int i) { > System.out.println(MessageFormat.format(HELLO, i, new Date())); > } > > public static void main(String[] args) { > for (int i = 0; i < 10; ++i) > Compiletime.eval(getClass(), "myMethod", i); > } > } > > Although it looks like valid Java, it contains a lot of bugs: > > - The arguments to Compiletime.eval (getClass() and i) aren't available > until runtime. Yes, it was Compile-Time error. > - "myMethod" can't be called because we haven't compiled it's class > yet. Or, thenks, I forgott sentence: 'Class, avaible in user classpath durong compilation time'. (I. e. I mean call classes from classpath, not sourcepath) > - MessageFormat.format relies on the current locale, which may be > different at compile time to run time. Yes. And the same with AnnotationProcessing (which can be called in compile-time now). > - Compiletime.eval will only be called once, although it looks like it > should be called 10 times; then at runtime the program will iterate 10 > times > over an empty loop and exit. > No. Compile-time error on supplying 'i' will be thrown, because parameters of Compiletime.eval() must be literal or result of compile-time call. I.e. Compiletime.eval() is also constant expression. > > The main problem is the execution of arbitrary Java code at compile time. > The code can contain dependencies on things which haven't been compiled > yet, > or libraries which are dynamically loaded at runtime; worse, it may depend Yes, I forgott to write sentence, that classes must be avaible at user classpath before start of compilation. > on an environment which may be different between compile time and runtime > (quite likely when developing J2EE apps, for example). It also raises the > questions around verification (how do you verify classes that you are They will be disappeared at all. > evaluating during compilation?) and security (what security model does it > operate under?). > Security model of java compiler. We already have al this potential problems with annotations processing, where any java code can be auto-discovered and run. And practice shows that this is not the biggest problem of language. > The other problem with the proposal is the Compiletime.exec() method. > Allowing arbitrary commands to be executed introduces serious security > implications to the compilation step. Currently, at least, you can compile Are you know, that you can execute arbitrary command during compilation in current javac compiler by call System.exec from auto discovered annotation processor ? So, nothing new here. > code without having to worry about those. > Possibility to write unmaintainable code exists. But if think in such way, than creation of turing-complete programming language was fatal security error ;) > Finally, because it looks like ordinary Java code it's easy to confuse the > two, leading to mistakes like the loop body in the example. > > In my opinion, this is more suited to a separate preprocessor. A quick > google found a few of those already available. > > Vil. > > > 2009/3/24 > >> >> AUTHOR: Ruslan Shevchenko >> >> OVERVIEW: >> >> FEATURE SUMMARY: >> >> Add API to access compile-time context of current compiled element >> from >> programs and annotation processors. >> >> MAJOR ADVANTAGE: >> >> Now compile time properties are unaccessible for programmer. This >> meaning >> that some functionality (such as access to location of file and line) >> is >> accessible only from debug version of program with technique, which is >> not >> officially supported, some (such as access to time of compilation or >> to binding context of current program location) is not avaible at all. >> >> MAJOR DISADVANTAGE >> >> Inaccurate usage of this feature can cause producing of unmaintable >> code. >> >> ALTERNATIVES: >> >> External preprocessing of java sources. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> >> Example 1 >> >> if (traceCondigion) { >> log.trace(Compiletime.getFileName()+":"+ >> Compiletime.getLineNumber()); >> } >> >> Example 2 >> >> if (system.currentTimeMillis() - Compiletime.getTimeMillis() > 86400) { >> System.out.println("This file was compiled more than day ago"); >> } >> >> Example 3 >> >> System.out.println("Superprogram by AAA AC, version:"+ >> Compiletime.exec("svnversion")); >> >> ADVANCED EXAMPLE: >> >> Example 1 >> // assuming that multiline strings are implemented: >> >> int a=0; >> int b=1; >> Binding bindings = Compiletime.getInstance().getCurrentBindings(); >> ScriptEngine velocity = ScriptEngineManager.get("velocity"); >> try { >> String fname = Compiletime.getFileName(); >> int line = Compiletime.getLineNumber(); >> String s = velocity.eval(""" >> #if ($a==$b) >> Something interesting here may be, >> Are you know that value of b is $b ? >> #else >> no mistics here. >> #end >> """, >> bindings); >> } catch (ScriptException ex){ >> Sytem.err.println("error in inline velocity in "+fname+", " >> "line "+line+1+ex.getLineNumber()); >> } >> >> >> Example 2 >> >> boolean isDemo = (Compiletime.eval(Properties.class, >> "getProperty","is.demo")!=null); >> >> if (!isDemo) { >> String key = (String)Compiletime.eval(GenerateUniqueKey.class, >> "generate"); >> LoadNotDemoClass(); >> } >> >> >> DETAILS: >> >> >> >> Add to Java Library pseudo-objects java.lang.Compiletime with access to >> compile-time properties and next signature: >> >> public class Compiletime >> { >> /** >> * get filename of compiled call. >> * in case of generated source and avaible JSR-45 SMAP file >> * return file name of translated-source. >> **/ >> public static String getFileName(); >> >> /** >> * get line number of compiled call. >> * in case of generated source and avaible JSR-45 SMAP file >> * return line number in translated-source. >> **/ >> public static int getLineNumber(); >> >> /** >> * get class name where this call is placed. >> * in case of generated source and avaible JSR-45 SMAP file >> * return class name in translated-source. >> **/ >> public static int getClassName(); >> >> /** >> * get method name where this call is placed. >> * in case of generated source and avaible JSR-45 SMAP file >> * return method name in translated-source. >> **/ >> public static int getMethodName(); >> >> >> /** >> * generate JSR223 bindings for given names in current compilation >> *context. >> *Names array must be empty or consists from string literals. >> **/ >> public static Bindings getBindings(String ... names) >> >> >> /** >> * get time of compilation in miliseconds. >> **/ >> public static long getTimeMillis(); >> >> /** >> * Execute os command in compile-time. >> *@command - must be a string literal or result of call of Compiletime >> * method, otherwise compile-time error is thrown >> **/ >> public static String exec(String command) >> /** >> * call java class at compile-time. >> *During processing this directive, compiler will >> *1. determinate, if class available in user path. >> *2. determinate, if exists method with appropriative number and types >> * of parameters. >> *3. If such method is static - call one, otherwise >> * 3.1 if class have default constructor - create instance of object >> * (otherwise throw compile-time error) >> * 3.2. Call methid with new-created instance. >> * 3.3. If method return some result - substitute output to result, >> * on exception throw compile-time error. >> *@param classLiteral - must be a class literal for object to call. >> *@param methodName - must be a string literal with name of method to >> call. >> *@param parameters - parameters of method to call. Must be a >> literals, >> or >> * calls of Compiletime methods. >> **/ >> public static Object eval(Class classLiteral, String methodName, >> Object .. params); >> >> } >> >> >> >> COMPILATION: >> >> During compilation calls to compile time are changed to generation of >> appriative constant expressions. >> >> String x = Compiletime.getFileName(); >> changed to >> String x = "com/mycompany/package/MyClass.java"; >> >> int x = Compiletime.getLinNumber(); >> changed to >> int x = 33; >> >> String x = getClassName() >> changed to >> String x = "com.mycompany.package.MyClass"; >> >> >> class X >> { >> int p1; >> String p2; >> >> ... >> public void doSomething(int x, int y) >> { >> int local = x+y; >> Bindings bindings = Compiletime.getBindings(); >> evalSomeScript(bindings); >> } >> >> } >> >> >> will translated to >> >> class X >> { >> int p1; >> String p2; >> ... >> >> public void doSomething(int x, int y) >> { >> int local = x+y; >> SimpleBinding binding=(SimpleBinging uniqueName= new SimpleBinding(); >> uniqueName.put("this",this); >> uniqueName.put("p1",p1); >> uniqueName.put("p2",p2); >> uniqueName.put("x",x); >> uniqueName.put("y",y); >> uniqueName.put("local",local); >> uniqueName ); >> evalSomeScript(bindings); >> } >> >> >> } >> >> (assuming that Block Expressions for Java will be avaible. If not - it >> will be necessory create own implementation of Bindings as part of >> library). >> >> exec will be changed to Sting literal, with result of execution, i. e. >> on Unix >> String compiledBy = Compiletime.eval("whoami"); >> whill be translated to 'rssh' >> >> At last eval call is translated to >> - appropriative literal, if result of eval is primitive type or boxed >> primitivew type. >> - Call of code to unserialize constant byte array, which as serialized >> during compilation >> or throw compile-time error is object is not primitive type and not >> implements Serializable. >> >> JLS changes: current scope of JLS is not touched. >> >> Btw, may be add to JLS chapter with name 'Compilation process' where >> describe: >> - high level description of transforming source code to JVM classes. >> - process of automatic loading of annotation processors and when ones >> are >> used. >> - this API. >> >> >> TESTING: >> >> Special cases are: >> * compability with JSR45 >> * testing of exec function is >> >> LIBRARY SUPPORT: >> None, or adding two classes (for Bindings implementation with filling >> in >> constructor and Unserializing Object utility) in depends of avaibility >> of block expressions for Java >> >> (May be exists sence add methods for retrieveing source location (i.e. >> file >> name and line number retrieving) to javax.lang.model.element.Element to >> support better diagnostics. >> >> REFLECTIVE APIS: None >> >> OTHER CHANGES: None >> >> MIGRATION: None >> >> COMPABILITY >> None >> >> REFERENCES >> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4411102 >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6439965 >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4649007 >> >> IMPLEMENTATION URL (optional) >> >> None yet. >> >> >> >> >> >> >> > From j16sdiz at gmail.com Tue Mar 24 08:50:19 2009 From: j16sdiz at gmail.com (Daniel Cheng) Date: Tue, 24 Mar 2009 23:50:19 +0800 Subject: Proposal: @Unloadable Class defination Message-ID: AUTHOR(S): Daniel Cheng (aka SDiZ) OVERVIEW Introduce a @Unloadable annotation to allow a class to be unloaded even if the ClassLoader is still accessible. FEATURE SUMMARY: Introduce a @Unloadable annotation to allow a class to be unloaded even if the ClassLoader is still accessible. This allow opt-in Classes to be optionally unloaded in memory constrained environment. MAJOR ADVANTAGE: Developer may define some class as @Unloadable can be unloaded when needed. MAJOR BENEFIT: Currently, VM are not allow to unload Class with reachable ClassLoader, this is required for "static variable" to be keep. But this means Class have to keep in memory even if the class is rarely used. Sometimes, the value static variable can be recreated at any time, MAJOR DISADVANTAGE: Not I am aware of. Note: This proposal only relax the language specification level to allow VM to unload class annotated with @Unloadable. The VM changes are optional, and is not expect in JDK7. ALTERNATIVES: Use micro-ClassLoader for classes. This is very hard to done right. EXAMPLES SIMPLE EXAMPLE: @Unloadable class A {} ADVANCED EXAMPLE: @Unloadable class { ? static int i = 0; ? static int get() ?{ ? ? ? ?return i++; ? ?// the value of get() may reset to zero, if the class have been reloaded. ? } } DETAILS SPECIFICATION: JLS (3rd Ed.) Section - 12.7 Unloading of Classes and Interfaces Original text: ----------------- An implementation of the Java programming language may unload classes. A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector as discussed in ?12.6. Classes and interfaces loaded by the bootstrap loader may not be unloaded. Here is the rationale for the rule given in the previous paragraph: [...] ----------------- New text: ----------------- An implementation of the Java programming language may unload classes. A class or interface may be unloaded if and only if: ? ? 1) ?its defining class loader may be reclaimed by the garbage collector as discussed in ?12.6; or ? ? 2) ?it is annotated with @Unloadable annotation (?9.6) Classes and interfaces loaded by the bootstrap loader may not be unloaded. Here is the rationale for the rule given in the previous paragraph: [...] The @Unloadable annotation allow trading the preserve of static variable with memory footprint. ----------------- No changes in VM Spec needed. COMPILATION: (nil) TESTING: see the ADVANCED EXAMPLE above LIBRARY SUPPORT: new annotation @java.lang.Unloadable REFLECTIVE APIS: (nil) OTHER CHANGES: (nil) MIGRATION: (nil) COMPATIBILITY BREAKING CHANGES: (nil) EXISTING PROGRAMS (nil) REFERENCES EXISTING BUGS: (nil) From rssh at gradsoft.com.ua Tue Mar 24 08:52:34 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 24 Mar 2009 17:52:34 +0200 (EET) Subject: PROPOSAL: Compiletime information access In-Reply-To: <7bc7a3eea212b409e97a78f9e9c4cac0.squirrel@wmail.gradsoft.ua> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <6aef848f0903240738x4e24b53bv2c0c18394cfb9acb@mail.gmail.com> <7bc7a3eea212b409e97a78f9e9c4cac0.squirrel@wmail.gradsoft.ua> Message-ID: <2bf6a832cbe067fab93aa0b7e6fd266f.squirrel@wmail.gradsoft.ua> > >> - "myMethod" can't be called because we haven't compiled it's class >> yet. > > Or, thenks, I forgott sentence: 'Class, avaible in user classpath durong > compilation time'. > No, I'm not forgott this: *During processing this directive, compiler will *1. determinate, if class available in user path. How to write this better ? .. MB Determinate, if called class in available in user classpath before running of compiler ? Is this enough ? From jl0235 at yahoo.com Tue Mar 24 09:35:30 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 09:35:30 -0700 (PDT) Subject: Proposal: Large arrays Message-ID: <774923.96230.qm@web63701.mail.re1.yahoo.com> Proposal: Large arrays AUTHOR(S): J. Lowden VERSION: 1.0 Initial version. OVERVIEW FEATURE SUMMARY: Java arrays are accessed via 32-bit ints, resulting in a maximum theoretical array size of 2147483647 elements. While this is enough for most uses, some applications that need to handle large sequential data sets in memory would benefit from the ability to work with arrays indexed using 64-bit indices. As "simply" changing the current array syntax to use longs as indices rather than ints would have the potential to break a large amount of existing code, I'm not proposing doing any such thing. Instead, I'd like to see a separate but parallel array feature for creating and accessing both types of arrays. A rather boring example, which simply fills a byte array with hexadecimal "FF" values, is shown below: //int-indexed array byte [] foo = new byte [200000]; for (int i = 0; i < foo.length; i++) foo [i] = (byte) 0xff; //long-indexed array byte [[]] foo2 = new byte [[20000000000L]]; for (long i = 0; i < foo2.length; i++) foo2 [i] = (byte) 0xff; Syntax for declaration, instantation, instanceof and casting would use doubled square brackets to differentiate it from current array access. Single brackets can still be used for access/mutation as the compiler should have sufficient information to decide whether it can treat a specific reference as an int-indexed or long-indexed ("large") array. The length field would be a long rather than an int. Like standard arrays, large arrays would derive directly from java.lang.Object. MAJOR ADVANTAGE: Java gains the ability to easily work with large sequential data sets. MAJOR BENEFIT: Declaring extremely large arrays simply isn't possible right now; in cases where such a structure is desirable, something has to be hacked together. For applications dealing with large data sets, the current upper limit on array size is constricting, and will only grow more so as 64-bit systems continue to become more common and RAM less expensive. MAJOR DISADVANTAGE: This can't be implemented well solely via a compiler patch; existing VMs would likely need to be changed to support this concept natively; new VM instructions parallel to the existing array instructions would likely be required. Also, a class parallel to java.util.Arrays for performing standard operations on large arrays would likely be desirable (although presumably fairly simple to implement.) ALTERNATIVES: Build your own class for storing long-indexes sequences, possibly as an array-or-arrays. EXAMPLES SIMPLE EXAMPLE: // calculate the first 3 billion fibonacci numbers and store them in an array long [[]] fib = new long [[3000000000L]]; fib [0] = 0; fib [1] = 0; for (long i = 2; i < fib.length; i++) fib [i] = fib [i - 1] + fib [i - 2]; ADVANCED EXAMPLE: // this doesn't really do anything particular useful, but does serve to show how casting and instanceof are handled byte [] foo = new byte [400000]; byte [[]] blah = new byte [[40000000000L]]; Object temp = Math.random () < 0.5 ? foo : blah; if (foo instanceof byte [[]]) System.out.println (((byte [[]]) foo).length); else System.out.println (((byte []) foo).length); DETAILS SPECIFICATION: Syntax-wise, the following expressions become legal: SomeType [[]] foo; // declares foo as a long-indexed "large" array of SomeType, // where sometype is either a primitive or reference type foo = new SomeType [[some_long_value]]; // instantiates a large array of length // some_long_value, which is either a long // or some type that can upconvert or unbox // to a long long some_long = foo.length; // large arrays will have a "length" field, which is // a long indicating the number of elements in the array foo instanceof SomeType [[]] // returns true if foo is a large array // of SomeType, false otherwise (SomeType [[]]) foo // casts foo to a large array of SomeType. If foo isn't // a large array of SomeType or a subclass of SomeType, // throws a ClassCastException Large arrays are not castable or assignable to or from int-indexed arrays of the same element type. int [[]] p = new int [40000]; // compiler error int [] p = new int [[760000]]; // compiler error int [] foo = (int []) (new int [[4040404040L]]); // throws ClassCastException int [[]] foo = (int [[]]) (new int [4040]); // throws ClassCastException Canonical class names for large arrays would be generated in a similar fashion to those for standard arrays, but using the opposite square bracket. The following table shows some examples. declared type class name int [[]] ]I int [[]][[]] ]]I Object [[]] ]Ljava.lang.Object; The same set of indicator character (i.e., 'I' for int, 'L' for reference types, etc.) as are currently used for arrays would be used for large arrays. A set of additional VM instructions parallel to the current array instructions would be added to support this feature. The following table shows the current instruction, the proposed instruction for large arrays, and any semantic differences (reference http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html): array instruction proposed instruction differences aaload lxaaload index value becomes a long aastore lxaastore index value becomes a long anewarray lxanewarray count value becomes a long arraylength lxarraylength return value becomes a long baload lxbaload index value becomes a long bastore lxbastore index value becomes a long caload lxcaload index value becomes a long castore lxcastore index value becomes a long daload lxdaload index value becomes a long dastore lxdastore index value becomes a long faload lxfaload index value becomes a long fastore lxfastore index value becomes a long iaload lxiaload index value becomes a long iastore lxiastore index value becomes a long laload lxlaload index value becomes a long lastore lxlastore index value becomes a long multianewarray lxmultianewarray countN values become longs newarray lxnewarray count value becomes a long saload lxsaload index value becomes a long sastore lxsastore index value becomes a long COMPILATION: Compilation would be parallel to the present mechanism for compiling arrays, but would output the lx* VM instructions listed above for large arrays instead of the current array instructions. TESTING: Any test sufficient to test support for current arrays should work for this as well. LIBRARY SUPPORT: It would probably be desirable to create large array versions of the various java.util.Arrays methods, whether that be done by adding methods to the existing java.util.Arrays class or putting them somewhere new. At some point in the future, large java.util.List might be a desirable library feature, but that is beyond the scope of this proposal. REFLECTIVE APIS: An additional class (LargeArray or something of that sort) would need to be added to the java.lang.reflect package. This would have a similar set of methods and constructors to java.lang.reflect.Array, but with long "index" and "length" parameters where appropriate. OTHER CHANGES: VM needs to support the above-listed large array instructions. MIGRATION: Existing "hacks" to provide this kind of behavior could be replaced with large arrays. COMPATIBILITY BREAKING CHANGES: None. This feature simple doesn't exist; the proposed declaration/instantation syntax currently results in a compiler error. EXISTING PROGRAMS: No changes. REFERENCES EXISTING BUGS: 4880587 (64-Bit indexing for arrays) URL FOR PROTOTYPE (optional): None. From reinier at zwitserloot.com Tue Mar 24 09:53:22 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 24 Mar 2009 17:53:22 +0100 Subject: Proposal: Large arrays In-Reply-To: <774923.96230.qm@web63701.mail.re1.yahoo.com> References: <774923.96230.qm@web63701.mail.re1.yahoo.com> Message-ID: <24798D3F-A40A-4CCD-ADEA-26AD0455944B@zwitserloot.com> This change has serious impact on the JVM, and the language support for java is clearly a patchy hack: The 'best' solution (however unattainable that may be) is to just ensure that arrays can be long- indexed, and forego the double bracket notation. You also forgot to mention you need rather a lot of work in the reflection API, because you're introducing a new magic type here (there are the primitives, arrays, and objects. You're adding a new one: large arrays). I'm opposed to any solution where a clearly superior one that is similar is obvious, and not clearly impossible to implement (even if it will be implemented in java8 or beyond). If your proposal was somehow compatible with such a future, that'd be okay, I guess, but it isn't: If this double-bracket feature is added, then the extra type will never go away. If you're willing to eat up 20 of the precious opcode space, you can instead propose something that is much simpler for all involved: Any attempt to use arrays with a long instead of an int will work fine, it'll just use a different opcodes. Internally, there are such things as large arrays, but you can index into them using an int, and you can index into a plain array with a long (with the usual result if your long has a non-zero upper int: AIOOBException). For most other things including reflection, there is no discernable difference between large and non-large arrays. You can't grow arrays, so I don't really understand why you'd want a distinction in the first place. That's just implementation detail leaking through. --Reinier Zwitserloot On Mar 24, 2009, at 17:35, james lowden wrote: > > Proposal: Large arrays > > AUTHOR(S): > > J. Lowden > > VERSION: > > 1.0 Initial version. > > > OVERVIEW > > FEATURE SUMMARY: > > Java arrays are accessed via 32-bit ints, resulting in a maximum > theoretical array size of 2147483647 elements. While > > this is enough for most uses, some applications that need to handle > large sequential data sets in memory would benefit > > from the ability to work with arrays indexed using 64-bit indices. > As "simply" changing the current array syntax to use > > longs as indices rather than ints would have the potential to break > a large amount of existing code, I'm not proposing > > doing any such thing. Instead, I'd like to see a separate but > parallel array feature for creating and accessing both > > types of arrays. A rather boring example, which simply fills a byte > array with hexadecimal "FF" values, is shown below: > > //int-indexed array > byte [] foo = new byte [200000]; > for (int i = 0; i < foo.length; i++) > foo [i] = (byte) 0xff; > > //long-indexed array > byte [[]] foo2 = new byte [[20000000000L]]; > for (long i = 0; i < foo2.length; i++) > foo2 [i] = (byte) 0xff; > > Syntax for declaration, instantation, instanceof and casting would > use doubled square brackets to differentiate it from > > current array access. Single brackets can still be used for access/ > mutation as the compiler should have sufficient > > information to decide whether it can treat a specific reference as > an int-indexed or long-indexed ("large") array. The length field > would be a long rather than an int. Like standard arrays, large > arrays would derive directly from > > java.lang.Object. > > > MAJOR ADVANTAGE: > > Java gains the ability to easily work with large sequential data sets. > > > MAJOR BENEFIT: > > Declaring extremely large arrays simply isn't possible right now; in > cases where such a structure is desirable, something > > has to be hacked together. For applications dealing with large data > sets, the current upper limit on array size is constricting, and > will only grow more so as 64-bit systems continue to become more > common and RAM less expensive. > > > MAJOR DISADVANTAGE: > > This can't be implemented well solely via a compiler patch; existing > VMs would likely need to be changed to support this > > concept natively; new VM instructions parallel to the existing array > instructions would likely be required. Also, a class > > parallel to java.util.Arrays for performing standard operations on > large arrays would likely be desirable (although > > presumably fairly simple to implement.) > > > ALTERNATIVES: > > Build your own class for storing long-indexes sequences, possibly as > an array-or-arrays. > > > EXAMPLES > > SIMPLE EXAMPLE: > > // calculate the first 3 billion fibonacci numbers and store them in > an array > > long [[]] fib = new long [[3000000000L]]; > fib [0] = 0; > fib [1] = 0; > for (long i = 2; i < fib.length; i++) > fib [i] = fib [i - 1] + fib [i - 2]; > > > ADVANCED EXAMPLE: > > // this doesn't really do anything particular useful, but does serve > to show how casting and instanceof are handled > byte [] foo = new byte [400000]; > byte [[]] blah = new byte [[40000000000L]]; > Object temp = Math.random () < 0.5 ? foo : blah; > if (foo instanceof byte [[]]) > System.out.println (((byte [[]]) foo).length); > else > System.out.println (((byte []) foo).length); > > > DETAILS > > SPECIFICATION: > > Syntax-wise, the following expressions become legal: > > SomeType [[]] foo; // declares foo as a long-indexed "large" > array of SomeType, > // where sometype is either a primitive or reference type > > foo = new SomeType [[some_long_value]]; // instantiates a large > array of length > // some_long_value, which is either a long > // or some type that can upconvert or unbox > // to a long > > long some_long = foo.length; // large arrays will have a "length" > field, which is > // a long indicating the number of elements in the array > > foo instanceof SomeType [[]] // returns true if foo is a large array > // of SomeType, false otherwise > > (SomeType [[]]) foo // casts foo to a large array of SomeType. > If foo isn't > // a large array of SomeType or a subclass of SomeType, > // throws a ClassCastException > > > Large arrays are not castable or assignable to or from int-indexed > arrays of the same element type. > > int [[]] p = new int [40000]; // compiler error > int [] p = new int [[760000]]; // compiler error > int [] foo = (int []) (new int [[4040404040L]]); // throws > ClassCastException > int [[]] foo = (int [[]]) (new int [4040]); // throws > ClassCastException > > > Canonical class names for large arrays would be generated in a > similar fashion to those for standard arrays, but > > using the opposite square bracket. The following table shows some > examples. > > declared type class name > int [[]] ]I > int [[]][[]] ]]I > Object [[]] ]Ljava.lang.Object; > > > The same set of indicator character (i.e., 'I' for int, 'L' for > reference types, etc.) as are currently used for arrays > > would be used for large arrays. > > A set of additional VM instructions parallel to the current array > instructions would be added to support this feature. > > The following table shows the current instruction, the proposed > instruction for large arrays, and any semantic > > differences (reference http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html) > : > > array instruction proposed instruction differences > aaload lxaaload index value becomes a long > aastore lxaastore index value becomes a long > anewarray lxanewarray count value becomes a long > arraylength lxarraylength return value becomes a long > baload lxbaload index value becomes a long > bastore lxbastore index value becomes a long > caload lxcaload index value becomes a long > castore lxcastore index value becomes a long > daload lxdaload index value becomes a long > dastore lxdastore index value becomes a long > faload lxfaload index value becomes a long > fastore lxfastore index value becomes a long > iaload lxiaload index value becomes a long > iastore lxiastore index value becomes a long > laload lxlaload index value becomes a long > lastore lxlastore index value becomes a long > multianewarray lxmultianewarray countN values become longs > newarray lxnewarray count value becomes a long > saload lxsaload index value becomes a long > sastore lxsastore index value becomes a long > > > COMPILATION: > > Compilation would be parallel to the present mechanism for compiling > arrays, but would output the lx* VM instructions listed above for > large arrays instead of the current array instructions. > > TESTING: > > Any test sufficient to test support for current arrays should work > for this as well. > > LIBRARY SUPPORT: > > It would probably be desirable to create large array versions of the > various java.util.Arrays methods, whether that be done by adding > methods to the existing java.util.Arrays class or putting them > somewhere new. At some point in the future, large java.util.List > might be a desirable library feature, but that is beyond the scope > of this proposal. > > REFLECTIVE APIS: > > An additional class (LargeArray or something of that sort) would > need to be added to the java.lang.reflect package. This would have > a similar set of methods and constructors to > java.lang.reflect.Array, but with long "index" and "length" > parameters where appropriate. > > OTHER CHANGES: > > VM needs to support the above-listed large array instructions. > > > MIGRATION: > > Existing "hacks" to provide this kind of behavior could be replaced > with large arrays. > > > COMPATIBILITY > > BREAKING CHANGES: > > None. This feature simple doesn't exist; the proposed declaration/ > instantation syntax currently results in a compiler error. > > > EXISTING PROGRAMS: > > No changes. > > > REFERENCES > > EXISTING BUGS: > > 4880587 (64-Bit indexing for arrays) > > > URL FOR PROTOTYPE (optional): > > None. > > > > From Joe.Darcy at Sun.COM Tue Mar 24 10:04:14 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 10:04:14 -0700 Subject: PROPOSAL: Compiletime information access In-Reply-To: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> Message-ID: <49C9128E.80701@sun.com> rssh at gradsoft.com.ua wrote: > AUTHOR: Ruslan Shevchenko > > OVERVIEW: > > FEATURE SUMMARY: > > Add API to access compile-time context of current compiled element from > programs and annotation processors. > > MAJOR ADVANTAGE: > > Now compile time properties are unaccessible for programmer. This meaning > No, this flavor information has been officially accessible for programmers using Java SE 6 compilers, which are required to support annotation processing and the JSR 199 tools API. See the javax.annotation.processing and javax.tools packages, which use javax.lang.model. The view of a type provided by JSR 269 annotation processing is read-only, but much of the effect of modifying the file can be had by either generating subclasses or the superclass of the type in question. These APIs don't provide a direct notion of location, but the Messager accepts the model of a program element to emit location information. -Joe From jl0235 at yahoo.com Tue Mar 24 10:05:26 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 10:05:26 -0700 (PDT) Subject: Proposal: Large arrays In-Reply-To: <774923.96230.qm@web63701.mail.re1.yahoo.com> Message-ID: <645278.85964.qm@web63702.mail.re1.yahoo.com> Not terribly relevant to the content of the proposal, but the fibonacci example should read: long [[]] fib = new long [[3000000000L]]; fib [0] = 1; fib [1] = 1; for (long i = 2; i < fib.length; i++) fib [i] = fib [i - 1] + fib [i - 2]; --- On Tue, 3/24/09, james lowden wrote: > From: james lowden > Subject: Proposal: Large arrays > To: coin-dev at openjdk.java.net > Date: Tuesday, March 24, 2009, 11:35 AM > Proposal: Large arrays > > AUTHOR(S): > > J. Lowden > > VERSION: > > 1.0 Initial version. > > > OVERVIEW > > FEATURE SUMMARY: > > Java arrays are accessed via 32-bit ints, resulting in a > maximum theoretical array size of 2147483647 elements. > While > > this is enough for most uses, some applications that need > to handle large sequential data sets in memory would benefit > > > from the ability to work with arrays indexed using 64-bit > indices. As "simply" changing the current array > syntax to use > > longs as indices rather than ints would have the potential > to break a large amount of existing code, I'm not > proposing > > doing any such thing. Instead, I'd like to see a > separate but parallel array feature for creating and > accessing both > > types of arrays. A rather boring example, which simply > fills a byte array with hexadecimal "FF" values, > is shown below: > > //int-indexed array > byte [] foo = new byte [200000]; > for (int i = 0; i < foo.length; i++) > foo [i] = (byte) 0xff; > > //long-indexed array > byte [[]] foo2 = new byte [[20000000000L]]; > for (long i = 0; i < foo2.length; i++) > foo2 [i] = (byte) 0xff; > > Syntax for declaration, instantation, instanceof and > casting would use doubled square brackets to differentiate > it from > > current array access. Single brackets can still be used > for access/mutation as the compiler should have sufficient > > information to decide whether it can treat a specific > reference as an int-indexed or long-indexed > ("large") array. The length field would be a long > rather than an int. Like standard arrays, large arrays > would derive directly from > > java.lang.Object. > > > MAJOR ADVANTAGE: > > Java gains the ability to easily work with large sequential > data sets. > > > MAJOR BENEFIT: > > Declaring extremely large arrays simply isn't possible > right now; in cases where such a structure is desirable, > something > > has to be hacked together. For applications dealing with > large data sets, the current upper limit on array size is > constricting, and will only grow more so as 64-bit systems > continue to become more common and RAM less expensive. > > > MAJOR DISADVANTAGE: > > This can't be implemented well solely via a compiler > patch; existing VMs would likely need to be changed to > support this > > concept natively; new VM instructions parallel to the > existing array instructions would likely be required. Also, > a class > > parallel to java.util.Arrays for performing standard > operations on large arrays would likely be desirable > (although > > presumably fairly simple to implement.) > > > ALTERNATIVES: > > Build your own class for storing long-indexes sequences, > possibly as an array-or-arrays. > > > EXAMPLES > > SIMPLE EXAMPLE: > > // calculate the first 3 billion fibonacci numbers and > store them in an array > > long [[]] fib = new long [[3000000000L]]; > fib [0] = 0; > fib [1] = 0; > for (long i = 2; i < fib.length; i++) > fib [i] = fib [i - 1] + fib [i - 2]; > > > ADVANCED EXAMPLE: > > // this doesn't really do anything particular useful, > but does serve to show how casting and instanceof are > handled > byte [] foo = new byte [400000]; > byte [[]] blah = new byte [[40000000000L]]; > Object temp = Math.random () < 0.5 ? foo : blah; > if (foo instanceof byte [[]]) > System.out.println (((byte [[]]) foo).length); > else > System.out.println (((byte []) foo).length); > > > DETAILS > > SPECIFICATION: > > Syntax-wise, the following expressions become legal: > > SomeType [[]] foo; // declares foo as a long-indexed > "large" array of SomeType, > // where sometype is either a primitive or reference > type > > foo = new SomeType [[some_long_value]]; // instantiates a > large array of length > // some_long_value, which is either a long > // or some type that can upconvert or unbox > // to a long > > long some_long = foo.length; // large arrays will have a > "length" field, which is > // a long indicating the number of elements in the > array > > foo instanceof SomeType [[]] // returns true if foo is a > large array > // of SomeType, false otherwise > > (SomeType [[]]) foo // casts foo to a large array of > SomeType. If foo isn't > // a large array of SomeType or a subclass of SomeType, > // throws a ClassCastException > > > Large arrays are not castable or assignable to or from > int-indexed arrays of the same element type. > > int [[]] p = new int [40000]; // compiler error > int [] p = new int [[760000]]; // compiler error > int [] foo = (int []) (new int [[4040404040L]]); // throws > ClassCastException > int [[]] foo = (int [[]]) (new int [4040]); // throws > ClassCastException > > > Canonical class names for large arrays would be generated > in a similar fashion to those for standard arrays, but > > using the opposite square bracket. The following table > shows some examples. > > declared type class name > int [[]] ]I > int [[]][[]] ]]I > Object [[]] ]Ljava.lang.Object; > > > The same set of indicator character (i.e., 'I' for > int, 'L' for reference types, etc.) as are currently > used for arrays > > would be used for large arrays. > > A set of additional VM instructions parallel to the current > array instructions would be added to support this feature. > > The following table shows the current instruction, the > proposed instruction for large arrays, and any semantic > > differences (reference > http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html): > > array instruction proposed instruction differences > aaload lxaaload index value > becomes a long > aastore lxaastore index value > becomes a long > anewarray lxanewarray count value > becomes a long > arraylength lxarraylength return value > becomes a long > baload lxbaload index value > becomes a long > bastore lxbastore index value > becomes a long > caload lxcaload index value > becomes a long > castore lxcastore index value > becomes a long > daload lxdaload index value > becomes a long > dastore lxdastore index value > becomes a long > faload lxfaload index value > becomes a long > fastore lxfastore index value > becomes a long > iaload lxiaload index value > becomes a long > iastore lxiastore index value > becomes a long > laload lxlaload index value > becomes a long > lastore lxlastore index value > becomes a long > multianewarray lxmultianewarray countN values > become longs > newarray lxnewarray count value > becomes a long > saload lxsaload index value > becomes a long > sastore lxsastore index value > becomes a long > > > COMPILATION: > > Compilation would be parallel to the present mechanism for > compiling arrays, but would output the lx* VM instructions > listed above for large arrays instead of the current array > instructions. > > TESTING: > > Any test sufficient to test support for current arrays > should work for this as well. > > LIBRARY SUPPORT: > > It would probably be desirable to create large array > versions of the various java.util.Arrays methods, whether > that be done by adding methods to the existing > java.util.Arrays class or putting them somewhere new. At > some point in the future, large java.util.List > might be a desirable library feature, but that is beyond the > scope of this proposal. > > REFLECTIVE APIS: > > An additional class (LargeArray or something of that sort) > would need to be added to the java.lang.reflect package. > This would have a similar set of methods and constructors to > java.lang.reflect.Array, but with long "index" and > "length" parameters where appropriate. > > OTHER CHANGES: > > VM needs to support the above-listed large array > instructions. > > > MIGRATION: > > Existing "hacks" to provide this kind of behavior > could be replaced with large arrays. > > > COMPATIBILITY > > BREAKING CHANGES: > > None. This feature simple doesn't exist; the proposed > declaration/instantation syntax currently results in a > compiler error. > > > EXISTING PROGRAMS: > > No changes. > > > REFERENCES > > EXISTING BUGS: > > 4880587 (64-Bit indexing for arrays) > > > URL FOR PROTOTYPE (optional): > > None. From alexandre.makarenko at sgcib.com Tue Mar 24 06:14:35 2009 From: alexandre.makarenko at sgcib.com (Alexandre MAKARENKO) Date: Tue, 24 Mar 2009 14:14:35 +0100 Subject: Naked dot - accessing object fields through unqualified "." [C1] Message-ID: Naked dot AUTHOR(S): MAKARENKO Alexandre OVERVIEW FEATURE SUMMARY: Accessing object fields through unqualified "." MAJOR ADVANTAGE: Obsoletes attribute naming conventions. MAJOR BENEFIT: Makes Java programs visually more readable and eventually less error-prone (see ?Strict mode? in details). To avoid name collisions and make source codes more maintainable developers either hold with a convention for attribute names or prefix members by ?this.? when refer to. Any naming convention, since not a part of the language, offers only a weak distinction between local variable and object field. Moreover it introduces extra characters and makes the source code not very natural. Using ?this.? is absolutely safe but makes the source code too much heavy. Assessing object fields through unqualified ?.? may be an elegant trade-off between readability and strictness. MAJOR DISADVANTAGE: May look assemblish. ALTERNATIVES: Use "this.aField" or m_aField, or _aField, or any other naming convention to distinguish between local variables and object fields. EXAMPLES public class Point { public Point( double x, double y ) { .x = x; // compiles like this.x = x; .y = y; // compiles like this.y = y; } private double x, y; } DETAILS SPECIFICATION: During the name lookup process a package-less ?.? will be considered as ?this.?. So that ?.fieldName? will be equivalent to ?this.fieldName?. COMPILATION: The compiler detects unqualified dots and (if not a start of floating point value) inserts an imaginary ?this?. TESTING: Not relevant LIBRARY SUPPORT: Not relevant. REFLECTIVE APIS: Not relevant OTHER CHANGES: Not relevant MIGRATION: Weak mode (default). Attribute name look-up is carried out as it is mentioned in the current language specification. For example public class Point { ... public move( double dx, double dy ) { .x += dx; // resolves .x to this.x y += dy; // resolves y to this.y } private double x, y; } Strict mode (optional). For enterprises who would like to enforce in-house coding styles, there may be a kind of -XStrictMemberAccess compiler option. In this case the unqualified attribute references will fail to compile. For example public class Point { ... public move( double dx, double dy ) { .x += dx; // only local and static variables may // be referred to without ?.? y += dy; // compile time error: unknown y } private double x, y; } COMPATIBILITY Ascending source level compatibility (in Weak mode) with existing Java programs. Absolute binary compatibility with all existing Java software. Disassemblers may produce both ?this.? and ?.? (since they are equivalent). REFERENCES None ************************************************************************* This message and any attachments (the "message") are confidential, intended solely for the addressee(s), and may contain legally privileged information. Any unauthorised use or dissemination is prohibited. E-mails are susceptible to alteration. Neither SOCIETE GENERALE nor any of its subsidiaries or affiliates shall be liable for the message if altered, changed or falsified. ************ Ce message et toutes les pieces jointes (ci-apres le "message") sont confidentiels et susceptibles de contenir des informations couvertes par le secret professionnel. Ce message est etabli a l'intention exclusive de ses destinataires. Toute utilisation ou diffusion non autorisee est interdite. Tout message electronique est susceptible d'alteration. La SOCIETE GENERALE et ses filiales declinent toute responsabilite au titre de ce message s'il a ete altere, deforme ou falsifie. ************************************************************************* From j16sdiz at gmail.com Tue Mar 24 08:47:59 2009 From: j16sdiz at gmail.com (Daniel Cheng) Date: Tue, 24 Mar 2009 23:47:59 +0800 Subject: @Unloadable Class defination Message-ID: AUTHOR(S): Daniel Cheng (aka SDiZ) OVERVIEW Introduce a @Unloadable annotation to allow a class to be unloaded even if the ClassLoader is still accessible. FEATURE SUMMARY: Introduce a @Unloadable annotation to allow a class to be unloaded even if the ClassLoader is still accessible. This allow opt-in Classes to be optionally unloaded in memory constrained environment. MAJOR ADVANTAGE: Developer may define some class as @Unloadable can be unloaded when needed. MAJOR BENEFIT: Currently, VM are not allow to unload Class with reachable ClassLoader, this is required for "static variable" to be keep. But this means Class have to keep in memory even if the class is rarely used. Sometimes, the value static variable can be recreated at any time, MAJOR DISADVANTAGE: Not I am aware of. Note: This proposal only relax the language specification level to allow VM to unload class annotated with @Unloadable. The VM changes are optional, and is not expect in JDK7. ALTERNATIVES: Use micro-ClassLoader for classes. This is very hard to done right. EXAMPLES SIMPLE EXAMPLE: @Unloadable class A {} ADVANCED EXAMPLE: @Unloadable class { static int i = 0; static int get() { return i++; // the value of get() may reset to zero, if the class have been reloaded. } } DETAILS SPECIFICATION: JLS (3rd Ed.) Section - 12.7 Unloading of Classes and Interfaces Original text: ----------------- An implementation of the Java programming language may unload classes. A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector as discussed in ?12.6. Classes and interfaces loaded by the bootstrap loader may not be unloaded. Here is the rationale for the rule given in the previous paragraph: [...] ----------------- New text: ----------------- An implementation of the Java programming language may unload classes. A class or interface may be unloaded if and only if: 1) its defining class loader may be reclaimed by the garbage collector as discussed in ?12.6; or 2) it is annotated with @Unloadable annotation (?9.6) Classes and interfaces loaded by the bootstrap loader may not be unloaded. Here is the rationale for the rule given in the previous paragraph: [...] The @Unloadable annotation allow trading the preserve of static variable with memory footprint. ----------------- No changes in VM Spec needed. COMPILATION: (nil) TESTING: see the ADVANCED EXAMPLE above LIBRARY SUPPORT: new annotation @java.lang.Unloadable REFLECTIVE APIS: (nil) OTHER CHANGES: (nil) MIGRATION: (nil) COMPATIBILITY BREAKING CHANGES: (nil) EXISTING PROGRAMS (nil) REFERENCES EXISTING BUGS: (nil) From Joe.Darcy at Sun.COM Tue Mar 24 10:16:38 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 10:16:38 -0700 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: References: Message-ID: <49C91576.1010706@sun.com> Alexandre MAKARENKO wrote: > Naked dot > > AUTHOR(S): MAKARENKO Alexandre > OVERVIEW > FEATURE SUMMARY: Accessing object fields through unqualified "." > > MAJOR ADVANTAGE: Obsoletes attribute naming conventions. > > MAJOR BENEFIT: Makes Java programs visually more readable and eventually > less error-prone (see ?Strict mode? in details). > > To avoid name collisions and make source codes more maintainable > developers either hold with a convention for attribute names or prefix > members by ?this.? when refer to. Any naming convention, since not a part > of the language, offers only a weak distinction between local variable and > object field. Moreover it introduces extra characters and makes the source > code not very natural. Using ?this.? is absolutely safe but makes the > source code too much heavy. > Assessing object fields through unqualified ?.? may be an elegant > trade-off between readability and strictness. > > MAJOR DISADVANTAGE: May look assemblish. > > ALTERNATIVES: > Use "this.aField" or m_aField, or _aField, or any other naming convention > to distinguish between local variables and object fields. > > EXAMPLES > public class Point > { > public Point( double x, double y ) > { > .x = x; // compiles like this.x = x; > .y = y; // compiles like this.y = y; > } > private double x, y; > } > I don't think being about to elide "this" in such situations would be very helpful; at least having to write out "this.x" gives some clear indication you aren't assigning x to itself! -Joe From rssh at gradsoft.com.ua Tue Mar 24 10:22:16 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 24 Mar 2009 19:22:16 +0200 (EET) Subject: PROPOSAL: Compiletime information access In-Reply-To: <49C9128E.80701@sun.com> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <49C9128E.80701@sun.com> Message-ID: <5ba57ef8c9162404dd97143689f05b27.squirrel@wmail.gradsoft.ua> > rssh at gradsoft.com.ua wrote: >> AUTHOR: Ruslan Shevchenko >> >> OVERVIEW: >> >> FEATURE SUMMARY: >> >> Add API to access compile-time context of current compiled element >> from >> programs and annotation processors. >> >> MAJOR ADVANTAGE: >> >> Now compile time properties are unaccessible for programmer. This >> meaning >> > > No, this flavor information has been officially accessible for > programmers using Java SE 6 compilers, which are required to support > annotation processing and the JSR 199 tools API. See the > javax.annotation.processing and javax.tools packages, which use > javax.lang.model. > > The view of a type provided by JSR 269 annotation processing is > read-only, but much of the effect of modifying the file can be had by > either generating subclasses or the superclass of the type in question. > > These APIs don't provide a direct notion of location, but the Messager > accepts the model of a program element to emit location information. > > -Joe > Thanks for clarify; actually only fileName, lineNumber, className, methodName and bindings can't be build with annotation processors. (all those require context of location inside class be available). So, this can be rewritten as: Now compile time properties which depends from local compilation context (i.e. source location and variable bindings) are unaccessible for programmer. Yet one question to community - may be better left in proposal only methods, which provide information, unaccessible from annotations (getFileName(); getLineIndex(); getClassName(); getMethodName(); getBindings()) and others (exec and eval) left to annotation processors, which can be easy constructed ? From belingueres at gmail.com Tue Mar 24 10:32:54 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 24 Mar 2009 14:32:54 -0300 Subject: Some corner cases of overloading to consider Message-ID: Hi, This is a document I prepared to show some uses of overloading that IMO may well be candidate for the compiler to show a Warning (maybe when using an Xlint option), instead of silently compile. If there is enough interest, I could prepare a more formal proposal for the issues here presented. Regards, Gabriel 1) Calling an overloaded method where the actual parameter is a final variable Example: class A {} class B extends A {} public class OverloadingTest { public void method(A a) { System.out.println("method(A)"); } public void method(B b) { System.out.println("method(B)"); } public static void main(String[] args) { OverloadingTest o = new OverloadingTest(); A p = new B(); o.method(p); // call method(A) o.method(new B()); // call method(B) final A p2 = new B(); o.method(p2); // call method(A) } } The 3rd. call to the overloaded method is calling method(A) which is correct because the compile time type of variable p2 is A. However, since the p2 variable is declared as a final variable, it means that it can not change its runtime type, but since p2 is actually a B, and the runtime type can never change, why it is not treated in a similar way to o.method(new B())? This might be a sign that the programmer made a mistake, and the compiler should emit a Warning indicating so. How to disambiguate: a) cast to a more specific type: final A p2 = new B(); o.method((B)p2); b) removing the final modifier, indicating that this specific variable can change its runtime type in its lifetime, and should call method(A), as current overloading rules: A p2 = new B(); o.method(p2); c) keeping the final modifier, but changing the compile time type to B, indicating that it should call method(B), as current overloading rules: final B p2 = new B(); o.method(p2); or final A p2 = new A(); o.method(p2); 1.1) Dealing with blank final declarations Example: final A a; ... if (someCondition) { ... a = new A(); ... } else { ... a = new B(); ... } ... method(a); There is no obvious way of detecting the issue here (without a flow analysis at least). So a safest thing can be to emit the warning anyway, so the programmer could refactor to something like this: ... if (someCondition) { ... final A a = new A(); ... method(a); ... } else { ... final B b = new B(); ... method(b); ... } 1.2) dealing with the conditional ? operator Seems counter intuitive that if o.method(new B()); calls method(B), the following two will call method(A): o.method((false) ? new A() : new B()); o.method((false) ? (A)null : new B()); and the following will call method(B): o.method((false) ? null : new B()); // prints method(B) This is because of the resulting expression type produced by the ? operator. IMO, then conditional operator ? result should be considered as if assigned to a final variable: example: o.method((condition) ? expressionReturningA : expressionReturningB); should produce the same semantics as: final A a; if (condition) a = expressionReturningA; else a = expressionReturningB; o.method(a); which would show a Warning since a final variable is present (as in the previous section.) What happens when one of the 2nd or 3rd operand of ? is null? o.method((condition) ? null : expressionReturningB); IMO this case should not show a Warning, since both operands resolve to call method(B) (because calling o.method(null) would resolve to the most specific type) In the third example the second operand is null, so the resulting type is B (because of the third rule of the ? operand definition), BUT when applying the 2) rule, a warning is emitted. Specifically, IMO currently using the ? operator as a expression for an overloaded method should be avoided if possible, given that the current definition of the ? operator has only one type (which is dependent of the 2nd and 3rd operand). Instead, when detecting the ? operator as a parameter of an overloaded method, BOTH the 2nd and 3rd operand types should reduce to a type which uniquely identify only one possible method to call. 2) Calling a method which actual parameter is a null literal Example (from book Java Puzzlers): public class Confusing { private Confusing(Object o) { System.out.println("Object"); } private Confusing(double[] dArray) { System.out.println("double array"); } public static void main(String[] args) { new Confusing(null); } } this compiles without warning, but because the null literal has no defined compile time type IMO it is ambiguous. A cast should be used to disambiguate, otherwise a Warning should be emitted by the compiler. 3) Calling a method which actual parameter can be autoboxed/unboxed Example: public class OverloadPrimitiveTest { public void method(int a) { System.out.println("method(int)"); } public void method(Integer b) { System.out.println("method(Integer)"); } public static void main(String[] args) { OverloadPrimitiveTest o = new OverloadPrimitiveTest(); o.method(1); // call method(int) o.method(new Integer(1)); // call method(Integer) o.method((short) 1); // call method(int) o.method(null); // call method(Integer) o.method((true) ? 1: new Integer(2)); // call method(int), ambiguous } } This is similar to what was described in point 1.2), only the ? operator's are of types which can be autoboxed/unoboxed to produce the other type. Again it is counter intuitive and a Warning should be emitted. It can be detected using the same rule for the ? operator given in 1.2), which take into account both operand types to determine if it uniquely identify the overloaded method to call. In this case, the 2nd operand type is int, and the 3rd operand type is Integer, which both are valid argument types for the same overloaded method. Another solution for detection could be just emit a warning when the compiler encounters that both method(int) and method(Integer) are identified for calling, regardless of if the current parameter type used in the method call is boxed or primitive. 4) Calling a method with generic argument Example: public class GenericOverloadTest { public void method(T t) { System.out.println("method(T)"); } public void method(int n) { System.out.println("method(int)"); } public static void main(String[] args) { GenericOverloadTest o = new GenericOverloadTest(); o.method(1); // call method(int) o.method(new Integer(1)); // call method(T) o.method((short) 1); // call method(int) o.method(null); // call method(T) o.method((true) ? 1: new Integer(2)); // call method(int), ambiguous } } This is similar to 3) but here the overloaded method is dependent of the generic type that was used. A Warning should be emitted too. From Joe.Darcy at Sun.COM Tue Mar 24 10:39:07 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 10:39:07 -0700 Subject: Proposal: @Unloadable Class defination In-Reply-To: References: Message-ID: <49C91ABB.4070801@sun.com> Daniel Cheng wrote: > AUTHOR(S): Daniel Cheng (aka SDiZ) > > OVERVIEW > > Introduce a @Unloadable annotation to allow a class to be unloaded > even if the ClassLoader is still accessible. > > FEATURE SUMMARY: > > Introduce a @Unloadable annotation to allow a class to be unloaded > even if the ClassLoader is still accessible. This allow opt-in Classes > to be optionally unloaded in memory constrained environment. > What would that mean exactly to all those poor objects on the heap needing that classloader? When could this unloading occur, anytime, never? A related issue is being able to call close on a ClassLoader, a capability added to URLClassLoader in JDK 7: http://blogs.sun.com/CoreJavaTechTips/entry/closing_a_urlclassloader -Joe From jeremy.manson at gmail.com Tue Mar 24 10:49:22 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 24 Mar 2009 10:49:22 -0700 Subject: Proposal: Large arrays In-Reply-To: <774923.96230.qm@web63701.mail.re1.yahoo.com> References: <774923.96230.qm@web63701.mail.re1.yahoo.com> Message-ID: <1631da7d0903241049h375d7344x6cfa76de17d4142d@mail.gmail.com> This is actually a pretty big change. I doubt they will let you do bytecode changes. Also, library changes would include everything that touches an array, like all of the Collections.toArray classes. Also, as part of such a change, collections would need to add support for more than 2^31-1 elements, and NIO Buffers would, too. Instead of bytecode changes, this could be implemented as an array of arrays for the moment (even though that is kind of ugly). That's not to say that I don't wish that this existed, though. Jeremy On Tue, Mar 24, 2009 at 9:35 AM, james lowden wrote: > > Proposal: Large arrays > > AUTHOR(S): > > J. Lowden > > VERSION: > > 1.0 ? ?Initial version. > > > OVERVIEW > > FEATURE SUMMARY: > > Java arrays are accessed via 32-bit ints, resulting in a maximum theoretical array size of 2147483647 elements. ?While > > this is enough for most uses, some applications that need to handle large sequential data sets in memory would benefit > > from the ability to work with arrays indexed using 64-bit indices. ?As "simply" changing the current array syntax to use > > longs as indices rather than ints would have the potential to break a large amount of existing code, I'm not proposing > > doing any such thing. ?Instead, I'd like to see a separate but parallel array feature for creating and accessing both > > types of arrays. ?A rather boring example, which simply fills a byte array with hexadecimal "FF" values, is shown below: > > //int-indexed array > byte [] foo = new byte [200000]; > for (int i = 0; i < foo.length; i++) > ?foo [i] = (byte) 0xff; > > //long-indexed array > byte [[]] foo2 = new byte [[20000000000L]]; > for (long i = 0; i < foo2.length; i++) > ?foo2 [i] = (byte) 0xff; > > Syntax for declaration, instantation, instanceof and casting would use doubled square brackets to differentiate it from > > current array access. ?Single brackets can still be used for access/mutation as the compiler should have sufficient > > information to decide whether it can treat a specific reference as an int-indexed or long-indexed ("large") array. ?The length field would be a long rather than an int. ?Like standard arrays, large arrays would derive directly from > > java.lang.Object. > > > MAJOR ADVANTAGE: > > Java gains the ability to easily work with large sequential data sets. > > > MAJOR BENEFIT: > > Declaring extremely large arrays simply isn't possible right now; in cases where such a structure is desirable, something > > has to be hacked together. ?For applications dealing with large data sets, the current upper limit on array size is constricting, and will only grow more so as 64-bit systems continue to become more common and RAM less expensive. > > > MAJOR DISADVANTAGE: > > This can't be implemented well solely via a compiler patch; existing VMs would likely need to be changed to support this > > concept natively; new VM instructions parallel to the existing array instructions would likely be required. ?Also, a class > > parallel to java.util.Arrays for performing standard operations on large arrays would likely be desirable (although > > presumably fairly simple to implement.) > > > ALTERNATIVES: > > Build your own class for storing long-indexes sequences, possibly as an array-or-arrays. > > > EXAMPLES > > SIMPLE EXAMPLE: > > // calculate the first 3 billion fibonacci numbers and store them in an array > > long [[]] fib = new long [[3000000000L]]; > fib [0] = 0; > fib [1] = 0; > for (long i = 2; i < fib.length; i++) > ?fib [i] = fib [i - 1] + fib [i - 2]; > > > ADVANCED EXAMPLE: > > // this doesn't really do anything particular useful, but does serve to show how casting and instanceof are handled > byte [] foo = new byte [400000]; > byte [[]] blah = new byte [[40000000000L]]; > Object temp = Math.random () < 0.5 ? foo : blah; > if (foo instanceof byte [[]]) > ?System.out.println (((byte [[]]) foo).length); > else > ?System.out.println (((byte []) foo).length); > > > DETAILS > > SPECIFICATION: > > Syntax-wise, the following expressions become legal: > > SomeType [[]] foo; ? ?// declares foo as a long-indexed "large" array of SomeType, > ? ? ? ? ? ? ? ? ? ? ? ?// where sometype is either a primitive or reference type > > foo = new SomeType [[some_long_value]]; ? // instantiates a large array of length > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// some_long_value, which is either a long > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// or some type that can upconvert or unbox > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// to a long > > long some_long = foo.length; ? // large arrays will have a "length" field, which is > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// a long indicating the number of elements in the array > > foo instanceof SomeType [[]] ? // returns true if foo is a large array > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// of SomeType, false otherwise > > (SomeType [[]]) foo ? ?// casts foo to a large array of SomeType. ?If foo isn't > ? ? ? ? ? ? ? ? ? ? ? ?// a large array of SomeType or a subclass of SomeType, > ? ? ? ? ? ? ? ? ? ? ? ?// throws a ClassCastException > > > Large arrays are not castable or assignable to or from int-indexed arrays of the same element type. > > int [[]] p = new int [40000]; // compiler error > int [] p = new int [[760000]]; // compiler error > int [] foo = (int []) (new int [[4040404040L]]); // throws ClassCastException > int [[]] foo = (int [[]]) (new int [4040]); // throws ClassCastException > > > Canonical class names for large arrays would be generated in a similar fashion to those for standard arrays, but > > using the opposite square bracket. ?The following table shows some examples. > > declared type ? ? class name > int [[]] ? ? ? ? ?]I > int [[]][[]] ? ? ?]]I > Object [[]] ? ? ? ]Ljava.lang.Object; > > > The same set of indicator character (i.e., 'I' for int, 'L' for reference types, etc.) as are currently used for arrays > > would be used for large arrays. > > A set of additional VM instructions parallel to the current array instructions would be added to support this feature. > > The following table shows the current instruction, the proposed instruction for large arrays, and any semantic > > differences (reference http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html): > > array instruction ? proposed instruction ? differences > aaload ? ? ? ? ? ? ?lxaaload ? ? ? ? ? ? ? index value becomes a long > aastore ? ? ? ? ? ? lxaastore ? ? ? ? ? ? ?index value becomes a long > anewarray ? ? ? ? ? lxanewarray ? ? ? ? ? ?count value becomes a long > arraylength ? ? ? ? lxarraylength ? ? ? ? ?return value becomes a long > baload ? ? ? ? ? ? ?lxbaload ? ? ? ? ? ? ? index value becomes a long > bastore ? ? ? ? ? ? lxbastore ? ? ? ? ? ? ?index value becomes a long > caload ? ? ? ? ? ? ?lxcaload ? ? ? ? ? ? ? index value becomes a long > castore ? ? ? ? ? ? lxcastore ? ? ? ? ? ? ?index value becomes a long > daload ? ? ? ? ? ? ?lxdaload ? ? ? ? ? ? ? index value becomes a long > dastore ? ? ? ? ? ? lxdastore ? ? ? ? ? ? ?index value becomes a long > faload ? ? ? ? ? ? ?lxfaload ? ? ? ? ? ? ? index value becomes a long > fastore ? ? ? ? ? ? lxfastore ? ? ? ? ? ? ?index value becomes a long > iaload ? ? ? ? ? ? ?lxiaload ? ? ? ? ? ? ? index value becomes a long > iastore ? ? ? ? ? ? lxiastore ? ? ? ? ? ? ?index value becomes a long > laload ? ? ? ? ? ? ?lxlaload ? ? ? ? ? ? ? index value becomes a long > lastore ? ? ? ? ? ? lxlastore ? ? ? ? ? ? ?index value becomes a long > multianewarray ? ? ?lxmultianewarray ? ? ? countN values become longs > newarray ? ? ? ? ? ?lxnewarray ? ? ? ? ? ? count value becomes a long > saload ? ? ? ? ? ? ?lxsaload ? ? ? ? ? ? ? index value becomes a long > sastore ? ? ? ? ? ? lxsastore ? ? ? ? ? ? ?index value becomes a long > > > COMPILATION: > > Compilation would be parallel to the present mechanism for compiling arrays, but would output the lx* VM instructions listed above for large arrays instead of the current array instructions. > > TESTING: > > Any test sufficient to test support for current arrays should work for this as well. > > LIBRARY SUPPORT: > > It would probably be desirable to create large array versions of the various java.util.Arrays methods, whether that be done by adding methods to the existing java.util.Arrays class or putting them somewhere new. ?At some point in the future, large java.util.List might be a desirable library feature, but that is beyond the scope of this proposal. > > REFLECTIVE APIS: > > An additional class (LargeArray or something of that sort) would need to be added to the java.lang.reflect package. ?This would have a similar set of methods and constructors to java.lang.reflect.Array, but with long "index" and "length" parameters where appropriate. > > OTHER CHANGES: > > VM needs to support the above-listed large array instructions. > > > MIGRATION: > > Existing "hacks" to provide this kind of behavior could be replaced with large arrays. > > > COMPATIBILITY > > BREAKING CHANGES: > > None. This feature simple doesn't exist; the proposed declaration/instantation syntax currently results in a compiler error. > > > EXISTING PROGRAMS: > > No changes. > > > REFERENCES > > EXISTING BUGS: > > 4880587 (64-Bit indexing for arrays) > > > URL FOR PROTOTYPE (optional): > > None. > > > > > From Joe.Darcy at Sun.COM Tue Mar 24 10:52:56 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 10:52:56 -0700 Subject: Proposal: Large arrays In-Reply-To: <774923.96230.qm@web63701.mail.re1.yahoo.com> References: <774923.96230.qm@web63701.mail.re1.yahoo.com> Message-ID: <49C91DF8.8060304@sun.com> james lowden wrote: > Proposal: Large arrays > > AUTHOR(S): > > J. Lowden > > VERSION: > > 1.0 Initial version. > > > OVERVIEW > > FEATURE SUMMARY: > > Java arrays are accessed via 32-bit ints, resulting in a maximum theoretical array size of 2147483647 elements. While > > this is enough for most uses, some applications that need to handle large sequential data sets in memory would benefit > > from the ability to work with arrays indexed using 64-bit indices. As "simply" changing the current array syntax to use > > longs as indices rather than ints would have the potential to break a large amount of existing code, I don't think the source compatibility impact is that large actually. Let's say *all* arrays can potentially be 64-bit now. The existing code that uses an int expression to index into the array will still index into the same element and negative indexes will still cause an exception. Now, how should the length field be set? I'd guess it should saturate to Integer.MAX_VALUE for oversize arrays and a new "long size()" method could be added to return the full length. The JVM would need to be modified to handle the long indexes of course; perhaps the wide bytecode prefix could be put to use here. [snip] > ALTERNATIVES: > > Build your own class for storing long-indexes sequences, possibly as an array-or-arrays. > This would be eased if the bracket operator could be used for user-defined types too since today functionally an array is just a fixed-length map from int to some other type. -Joe From jl0235 at yahoo.com Tue Mar 24 10:54:55 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 10:54:55 -0700 (PDT) Subject: Proposal: Large arrays Message-ID: <808065.43390.qm@web63707.mail.re1.yahoo.com> Ideally, I would like to see the ability to declare and manipulate arrays with long indicies exactly the same way that we currently do with ints. Unfortunately, this introduces the need to have the standard array's length field become a long, which immediately breaks a whole lot of existing code; thus I went with proposing a totally new array type. -JL- --- On Tue, 3/24/09, Reinier Zwitserloot wrote: > From: Reinier Zwitserloot > Subject: Re: Proposal: Large arrays > To: jl0235 at yahoo.com > Cc: coin-dev at openjdk.java.net > Date: Tuesday, March 24, 2009, 11:53 AM > This change has serious impact on the JVM, and the language > support for java is clearly a patchy hack: The > 'best' solution (however unattainable that may be) > is to just ensure that arrays can be long-indexed, and > forego the double bracket notation. You also forgot to > mention you need rather a lot of work in the reflection API, > because you're introducing a new magic type here (there > are the primitives, arrays, and objects. You're adding a > new one: large arrays). > > > I'm opposed to any solution where a clearly superior > one that is similar is obvious, and not clearly impossible > to implement (even if it will be implemented in java8 or > beyond). If your proposal was somehow compatible with such a > future, that'd be okay, I guess, but it isn't: If > this double-bracket feature is added, then the extra type > will never go away. > > > If you're willing to eat up 20 of the precious opcode > space, you can instead propose something that is much > simpler for all involved: > > Any attempt to use arrays with a long instead of an int > will work fine, it'll just use a different opcodes. > Internally, there are such things as large arrays, but you > can index into them using an int, and you can index into a > plain array with a long (with the usual result if your long > has a non-zero upper int: AIOOBException). For most other > things including reflection, there is no discernable > difference between large and non-large arrays. You can't > grow arrays, so I don't really understand why you'd > want a distinction in the first place. That's just > implementation detail leaking through. > > --Reinier Zwitserloot > > > > On Mar 24, 2009, at 17:35, james lowden wrote: > > > > > Proposal: Large arrays > > > > AUTHOR(S): > > > > J. Lowden > > > > VERSION: > > > > 1.0 Initial version. > > > > > > OVERVIEW > > > > FEATURE SUMMARY: > > > > Java arrays are accessed via 32-bit ints, resulting in > a maximum theoretical array size of 2147483647 elements. > While > > > > this is enough for most uses, some applications that > need to handle large sequential data sets in memory would > benefit > > > > from the ability to work with arrays indexed using > 64-bit indices. As "simply" changing the current > array syntax to use > > > > longs as indices rather than ints would have the > potential to break a large amount of existing code, I'm > not proposing > > > > doing any such thing. Instead, I'd like to see a > separate but parallel array feature for creating and > accessing both > > > > types of arrays. A rather boring example, which > simply fills a byte array with hexadecimal "FF" > values, is shown below: > > > > //int-indexed array > > byte [] foo = new byte [200000]; > > for (int i = 0; i < foo.length; i++) > > foo [i] = (byte) 0xff; > > > > //long-indexed array > > byte [[]] foo2 = new byte [[20000000000L]]; > > for (long i = 0; i < foo2.length; i++) > > foo2 [i] = (byte) 0xff; > > > > Syntax for declaration, instantation, instanceof and > casting would use doubled square brackets to differentiate > it from > > > > current array access. Single brackets can still be > used for access/mutation as the compiler should have > sufficient > > > > information to decide whether it can treat a specific > reference as an int-indexed or long-indexed > ("large") array. The length field would be a long > rather than an int. Like standard arrays, large arrays > would derive directly from > > > > java.lang.Object. > > > > > > MAJOR ADVANTAGE: > > > > Java gains the ability to easily work with large > sequential data sets. > > > > > > MAJOR BENEFIT: > > > > Declaring extremely large arrays simply isn't > possible right now; in cases where such a structure is > desirable, something > > > > has to be hacked together. For applications dealing > with large data sets, the current upper limit on array size > is constricting, and will only grow more so as 64-bit > systems continue to become more common and RAM less > expensive. > > > > > > MAJOR DISADVANTAGE: > > > > This can't be implemented well solely via a > compiler patch; existing VMs would likely need to be changed > to support this > > > > concept natively; new VM instructions parallel to the > existing array instructions would likely be required. Also, > a class > > > > parallel to java.util.Arrays for performing standard > operations on large arrays would likely be desirable > (although > > > > presumably fairly simple to implement.) > > > > > > ALTERNATIVES: > > > > Build your own class for storing long-indexes > sequences, possibly as an array-or-arrays. > > > > > > EXAMPLES > > > > SIMPLE EXAMPLE: > > > > // calculate the first 3 billion fibonacci numbers and > store them in an array > > > > long [[]] fib = new long [[3000000000L]]; > > fib [0] = 0; > > fib [1] = 0; > > for (long i = 2; i < fib.length; i++) > > fib [i] = fib [i - 1] + fib [i - 2]; > > > > > > ADVANCED EXAMPLE: > > > > // this doesn't really do anything particular > useful, but does serve to show how casting and instanceof > are handled > > byte [] foo = new byte [400000]; > > byte [[]] blah = new byte [[40000000000L]]; > > Object temp = Math.random () < 0.5 ? foo : blah; > > if (foo instanceof byte [[]]) > > System.out.println (((byte [[]]) foo).length); > > else > > System.out.println (((byte []) foo).length); > > > > > > DETAILS > > > > SPECIFICATION: > > > > Syntax-wise, the following expressions become legal: > > > > SomeType [[]] foo; // declares foo as a > long-indexed "large" array of SomeType, > > // where sometype is either a primitive or > reference type > > > > foo = new SomeType [[some_long_value]]; // > instantiates a large array of length > > // some_long_value, which is either a long > > // or some type that can upconvert or unbox > > // to a long > > > > long some_long = foo.length; // large arrays will > have a "length" field, which is > > // a long indicating the number of elements in the > array > > > > foo instanceof SomeType [[]] // returns true if foo > is a large array > > // of SomeType, false otherwise > > > > (SomeType [[]]) foo // casts foo to a large array > of SomeType. If foo isn't > > // a large array of SomeType or a subclass of > SomeType, > > // throws a ClassCastException > > > > > > Large arrays are not castable or assignable to or from > int-indexed arrays of the same element type. > > > > int [[]] p = new int [40000]; // compiler error > > int [] p = new int [[760000]]; // compiler error > > int [] foo = (int []) (new int [[4040404040L]]); // > throws ClassCastException > > int [[]] foo = (int [[]]) (new int [4040]); // throws > ClassCastException > > > > > > Canonical class names for large arrays would be > generated in a similar fashion to those for standard arrays, > but > > > > using the opposite square bracket. The following > table shows some examples. > > > > declared type class name > > int [[]] ]I > > int [[]][[]] ]]I > > Object [[]] ]Ljava.lang.Object; > > > > > > The same set of indicator character (i.e., 'I' > for int, 'L' for reference types, etc.) as are > currently used for arrays > > > > would be used for large arrays. > > > > A set of additional VM instructions parallel to the > current array instructions would be added to support this > feature. > > > > The following table shows the current instruction, the > proposed instruction for large arrays, and any semantic > > > > differences (reference > http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html): > > > > array instruction proposed instruction differences > > aaload lxaaload index value > becomes a long > > aastore lxaastore index value > becomes a long > > anewarray lxanewarray count value > becomes a long > > arraylength lxarraylength return > value becomes a long > > baload lxbaload index value > becomes a long > > bastore lxbastore index value > becomes a long > > caload lxcaload index value > becomes a long > > castore lxcastore index value > becomes a long > > daload lxdaload index value > becomes a long > > dastore lxdastore index value > becomes a long > > faload lxfaload index value > becomes a long > > fastore lxfastore index value > becomes a long > > iaload lxiaload index value > becomes a long > > iastore lxiastore index value > becomes a long > > laload lxlaload index value > becomes a long > > lastore lxlastore index value > becomes a long > > multianewarray lxmultianewarray countN > values become longs > > newarray lxnewarray count value > becomes a long > > saload lxsaload index value > becomes a long > > sastore lxsastore index value > becomes a long > > > > > > COMPILATION: > > > > Compilation would be parallel to the present mechanism > for compiling arrays, but would output the lx* VM > instructions listed above for large arrays instead of the > current array instructions. > > > > TESTING: > > > > Any test sufficient to test support for current arrays > should work for this as well. > > > > LIBRARY SUPPORT: > > > > It would probably be desirable to create large array > versions of the various java.util.Arrays methods, whether > that be done by adding methods to the existing > java.util.Arrays class or putting them somewhere new. At > some point in the future, large java.util.List > might be a desirable library feature, but that is beyond the > scope of this proposal. > > > > REFLECTIVE APIS: > > > > An additional class (LargeArray or something of that > sort) would need to be added to the java.lang.reflect > package. This would have a similar set of methods and > constructors to java.lang.reflect.Array, but with long > "index" and "length" parameters where > appropriate. > > > > OTHER CHANGES: > > > > VM needs to support the above-listed large array > instructions. > > > > > > MIGRATION: > > > > Existing "hacks" to provide this kind of > behavior could be replaced with large arrays. > > > > > > COMPATIBILITY > > > > BREAKING CHANGES: > > > > None. This feature simple doesn't exist; the > proposed declaration/instantation syntax currently results > in a compiler error. > > > > > > EXISTING PROGRAMS: > > > > No changes. > > > > > > REFERENCES > > > > EXISTING BUGS: > > > > 4880587 (64-Bit indexing for arrays) > > > > > > URL FOR PROTOTYPE (optional): > > > > None. > > > > > > > > From Thomas.Hawtin at Sun.COM Tue Mar 24 11:01:03 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Tue, 24 Mar 2009 18:01:03 +0000 Subject: Proposal: Large arrays In-Reply-To: <1631da7d0903241049h375d7344x6cfa76de17d4142d@mail.gmail.com> References: <774923.96230.qm@web63701.mail.re1.yahoo.com> <1631da7d0903241049h375d7344x6cfa76de17d4142d@mail.gmail.com> Message-ID: <49C91FDF.7000404@sun.com> Jeremy Manson wrote: > Instead of bytecode changes, this could be implemented as an array of > arrays for the moment (even though that is kind of ugly). Without a language change it could be implemented as classes (one class per primitive + one for references). With intrinsics this could be made as fast as if it were a language change (although class files would be larger). Tom Hawtin From jl0235 at yahoo.com Tue Mar 24 11:03:02 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 11:03:02 -0700 (PDT) Subject: Proposal: Large arrays In-Reply-To: <49C91DF8.8060304@sun.com> Message-ID: <248872.90823.qm@web63703.mail.re1.yahoo.com> > I don't think the source compatibility impact is that > large actually. Let's say *all* arrays can potentially > be 64-bit now. The existing code that uses an int > expression to index into the array will still index into the > same element and negative indexes will still cause an > exception. Now, how should the length field be set? > I'd guess it should saturate to Integer.MAX_VALUE for > oversize arrays and a new "long size()" method > could be added to return the full length. This I'd actually prefer over what I proposed (and, based on the response so far and the previous bug, what others would probably like as well); my main concern was not breaking the int "length" field; I'd slightly prefer the long size to be a field rather than a method, but that may just be due to that being how I'm used to obtaining the array size; if there's a compelling reason to use a method rather than a field for this, I'd be curious to hear it. > The JVM would need to be modified to handle the long > indexes of course; perhaps the wide bytecode prefix could be > put to use here. Looking at wide, it looks like applying it to the existing array instructions would be an option; I would favor that approach over my original idea, which chews up a whole slew of opcodes. I'll probably stew on the various suggestions for a while, and send out a revised version of the proposal. -JL- From jjb at google.com Tue Mar 24 11:03:29 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 24 Mar 2009 11:03:29 -0700 Subject: Proposal: Large arrays In-Reply-To: <49C91DF8.8060304@sun.com> References: <774923.96230.qm@web63701.mail.re1.yahoo.com> <49C91DF8.8060304@sun.com> Message-ID: <17b2302a0903241103h7feedadeh64fca20d8bc89f22@mail.gmail.com> Much as like the idea of 63-bit addressable arrays (hell even 32 would be nice, as opposed to the 31 we have now), I believe the source impact is large. Consider our old friend Arrays.binarySearch: public static int *binarySearch*(char[] a, char key) Searches the specified array of chars for the specified value using the binary search algorithm. The array must be sorted (as by the sort(char[])method) prior to making this call. If it is not sorted, the results are undefined. If the array contains multiple elements with the specified value, there is no guarantee which one will be found. *Parameters:*a - the array to be searchedkey - the value to be searched for *Returns:*index of the search key, if it is contained in the array; otherwise, (-(*insertion point*) - 1). The *insertion point* is defined as the point at which the key would be inserted into the array: the index of the first element greater than the key, or a.length if all elements in the array are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found. I don't see how we could change the return value to long--it's binary incompatible. That means we need a second version of the call that can tolerate big arrays, and people have to remember to call it. And what do we do if the original version is given an array that's longer than Integer.MAX_VALUE locations? I suppose we have to throw an IllegalArgumentException. So how much damage will this cause to the libraries? How many methods will need twins that tolerate large arrays? How much damage will it cause to user code? I don't think these are easy questions to answer. Josh On Tue, Mar 24, 2009 at 10:52 AM, Joseph D. Darcy wrote: > james lowden wrote: > > Proposal: Large arrays > > > > AUTHOR(S): > > > > J. Lowden > > > > VERSION: > > > > 1.0 Initial version. > > > > > > OVERVIEW > > > > FEATURE SUMMARY: > > > > Java arrays are accessed via 32-bit ints, resulting in a maximum > theoretical array size of 2147483647 elements. While > > > > this is enough for most uses, some applications that need to handle large > sequential data sets in memory would benefit > > > > from the ability to work with arrays indexed using 64-bit indices. As > "simply" changing the current array syntax to use > > > > longs as indices rather than ints would have the potential to break a > large amount of existing code, > > I don't think the source compatibility impact is that large actually. > Let's say *all* arrays can potentially be 64-bit now. The existing code > that uses an int expression to index into the array will still index > into the same element and negative indexes will still cause an > exception. Now, how should the length field be set? I'd guess it > should saturate to Integer.MAX_VALUE for oversize arrays and a new "long > size()" method could be added to return the full length. > > The JVM would need to be modified to handle the long indexes of course; > perhaps the wide bytecode prefix could be put to use here. > > [snip] > > > ALTERNATIVES: > > > > Build your own class for storing long-indexes sequences, possibly as an > array-or-arrays. > > > > This would be eased if the bracket operator could be used for > user-defined types too since today functionally an array is just a > fixed-length map from int to some other type. > > -Joe > > > From Joe.Darcy at Sun.COM Tue Mar 24 11:07:12 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 11:07:12 -0700 Subject: Proposal: Large arrays In-Reply-To: <248872.90823.qm@web63703.mail.re1.yahoo.com> References: <248872.90823.qm@web63703.mail.re1.yahoo.com> Message-ID: <49C92150.7070704@sun.com> james lowden wrote: >> I don't think the source compatibility impact is that >> large actually. Let's say *all* arrays can potentially >> be 64-bit now. The existing code that uses an int >> expression to index into the array will still index into the >> same element and negative indexes will still cause an >> exception. Now, how should the length field be set? >> I'd guess it should saturate to Integer.MAX_VALUE for >> oversize arrays and a new "long size()" method >> could be added to return the full length. >> > > This I'd actually prefer over what I proposed (and, based on the response so far and the previous bug, what others would probably like as well); my main concern was not breaking the int "length" field; I'd slightly prefer the long size to be a field rather than a method, but that may just be due to that being how I'm used to obtaining the array size; if there's a compelling reason to use a method rather than a field for this, I'd be curious to hear it. > Methods should generally be preferred to fields. A method named "size" is used in Collections. -Joe From jl0235 at yahoo.com Tue Mar 24 11:24:20 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 11:24:20 -0700 (PDT) Subject: Proposal: Large arrays In-Reply-To: <17b2302a0903241103h7feedadeh64fca20d8bc89f22@mail.gmail.com> Message-ID: <794079.35699.qm@web63702.mail.re1.yahoo.com> My (rough) thoughts on this: There are going to be a few different levels of difficulty as regards dealing with existing array API. The easiest case is methods like the one-argument Arrays.sort. The signature doesn't need to change to support this, and no duplicate public method is necessary; the implementation needs to change to check the size as a long, and that's about it. Next are methods like the multi-argument Arrays.sort and Arrays.fill that take in indices. We can't change the existing methods to take in longs without breaking existing code, but we can just add a parallel method that takes in longs and it's pretty transparent to the caller; either way, you're passing in an array and indices. The binarySearch is nastier as you can't (easily) create or call two methods with the same parameters but different return types. My preference would be to create new parallel methods (call it logNSearch or something?) and leave the old ones there for extant code but deprecate them, so that if I try and use an int-only binary search, my code still compiles but the compiler yells at me and encourages me to change it. If the old binary search is called on an array too big for it to handle, throw IllegalArgumentException (or maybe ArrayIndexOutOfBoundsException, although that's not *quite* in line with the current meaning of the ArrayIndexOutOfBoundsException) or maybe some new exception type like ArraySizeException or EpicArrayFailException or something. The case that really worries me, actually, is collections, as we can't retrofit interfaces, and java.util.Collection is built around an int size. We could maybe extend Collection, Set, List, Map, etc. with some new interface that defines long-based size/indexing methods and retroactively apply this to the concrete implementations like ArrayList, HashMap, etc., and deprecate the current Collection.size (). It's definitely a hairy problem, but I think it's one that the language is going to have to deal with sooner or later--I'm currently hackishly using two-dimensional arrays in cases where my array might need to be outside of the current limits, but this results in ugly code and incurs some performance penalties. -JL- --- On Tue, 3/24/09, Joshua Bloch wrote: > From: Joshua Bloch > Subject: Re: Proposal: Large arrays > To: "Joseph D. Darcy" > Cc: jl0235 at yahoo.com, coin-dev at openjdk.java.net > Date: Tuesday, March 24, 2009, 1:03 PM > Much as like the idea of 63-bit addressable arrays (hell > even 32 would be > nice, as opposed to the 31 we have now), I believe the > source impact is > large. Consider our old friend Arrays.binarySearch: > > public static int *binarySearch*(char[] a, > char key) > > Searches the specified array of chars for the specified > value using the > binary search algorithm. The array must be sorted (as by > the > sort(char[])method) > prior to making this call. If it is not sorted, the results > are > undefined. If the array contains multiple elements with the > specified value, > there is no guarantee which one will be found. > > *Parameters:*a - the array to be searchedkey - the value to > be searched for > *Returns:*index of the search key, if it is contained in > the array; > otherwise, (-(*insertion point*) - 1). The *insertion > point* is defined as > the point at which the key would be inserted into the > array: the index of > the first element greater than the key, or a.length if all > elements in the > array are less than the specified key. Note that this > guarantees that the > return value will be >= 0 if and only if the key is > found. I don't see how > we could change the return value to long--it's binary > incompatible. That > means we need a second version of the call that can > tolerate big arrays, and > people have to remember to call it. > > And what do we do if the original version is given an array > that's longer > than Integer.MAX_VALUE locations? I suppose we have to > throw an > IllegalArgumentException. So how much damage will this > cause to the > libraries? How many methods will need twins that tolerate > large arrays? > How much damage will it cause to user code? I don't > think these are easy > questions to answer. > > Josh > > > > > On Tue, Mar 24, 2009 at 10:52 AM, Joseph D. Darcy > wrote: > > > james lowden wrote: > > > Proposal: Large arrays > > > > > > AUTHOR(S): > > > > > > J. Lowden > > > > > > VERSION: > > > > > > 1.0 Initial version. > > > > > > > > > OVERVIEW > > > > > > FEATURE SUMMARY: > > > > > > Java arrays are accessed via 32-bit ints, > resulting in a maximum > > theoretical array size of 2147483647 elements. While > > > > > > this is enough for most uses, some applications > that need to handle large > > sequential data sets in memory would benefit > > > > > > from the ability to work with arrays indexed > using 64-bit indices. As > > "simply" changing the current array syntax > to use > > > > > > longs as indices rather than ints would have the > potential to break a > > large amount of existing code, > > > > I don't think the source compatibility impact is > that large actually. > > Let's say *all* arrays can potentially be 64-bit > now. The existing code > > that uses an int expression to index into the array > will still index > > into the same element and negative indexes will still > cause an > > exception. Now, how should the length field be set? > I'd guess it > > should saturate to Integer.MAX_VALUE for oversize > arrays and a new "long > > size()" method could be added to return the full > length. > > > > The JVM would need to be modified to handle the long > indexes of course; > > perhaps the wide bytecode prefix could be put to use > here. > > > > [snip] > > > > > ALTERNATIVES: > > > > > > Build your own class for storing long-indexes > sequences, possibly as an > > array-or-arrays. > > > > > > > This would be eased if the bracket operator could be > used for > > user-defined types too since today functionally an > array is just a > > fixed-length map from int to some other type. > > > > -Joe > > > > > > From jl0235 at yahoo.com Tue Mar 24 12:02:22 2009 From: jl0235 at yahoo.com (james lowden) Date: Tue, 24 Mar 2009 12:02:22 -0700 (PDT) Subject: Proposal: Large arrays (take two) Message-ID: <896901.15341.qm@web63708.mail.re1.yahoo.com> Proposal: Large arrays AUTHOR(S): J. Lowden VERSION: 1.1 Revised to remove distinction between classic/new arrays OVERVIEW FEATURE SUMMARY: Java arrays are accessed via 32-bit ints, resulting in a maximum theoretical array size of 2147483647 elements. While this is enough for most uses, some applications that need to handle large sequential data sets in memory would benefit from the ability to work with arrays indexed using 64-bit indices. I propose an extension to current array syntax to allow longs to be used as array indices and sizes. For example, int [] foo = new int [3000000000L]; foo [2999999999L] = 500; does not currently compile, but would under this proposal result in an array of length 3000000000. Currently, the length of the array is accessed via a length field, which is an int. Instead of changing this to a long, which would potentially break a lot of extant code, I propose deprecating the length field and adding a size() method to arrays, which returns a long indicating the actual size. Checking the original length field would behave as expected for arrays of less than 2^31 elements, and would return Integer.MAX_VALUE for all larger arrays. MAJOR ADVANTAGE: Java gains the ability to easily work with large sequential data sets. MAJOR BENEFIT: Declaring extremely large arrays simply isn't possible right now; in cases where such a structure is desirable, something has to be hacked together. For applications dealing with large data sets, the current upper limit on array size is constricting, and will only grow more so as 64-bit systems continue to become more common and RAM less expensive. MAJOR DISADVANTAGE: This can't be implemented well solely via a compiler patch; existing VMs would likely need to be changed to support this concept natively; new VM instructions would likely be required. Modifications to array-oriented library code such as java.util.Arrays and the collections API would also be highly desirable in order to make this change useful. ALTERNATIVES: Build your own class for storing long-indexes sequences, possibly as an array-or-arrays. EXAMPLES SIMPLE EXAMPLE: // calculate the first 3 billion fibonacci numbers and store them in an array // this doesn't *actually* work, as the 3 billionth fibonacci number is way // way too big to store in any java primitive type long [] fib = new long [3000000000L]; fib [0] = 1; fib [1] = 1; long length = fib.size (); for (long i = 2; i < length; i++) fib [i] = fib [i - 1] + fib [i - 2]; DETAILS SPECIFICATION: Syntax-wise, the following expressions become legal: foo = new SomeType [some_long_value]; // instantiates an array of length // some_long_value, which is either a long // or some type that can upconvert or unbox // to a long long some_long = foo.size (); // arrays will have a "size" method, which returns // a long indicating the number of elements in the array At the VM level, we could use the "wide" instruction in combination with the current group of array instructions to provide instructions for access to and manipulation of long-indexed arrays. The existing int-indexed array instructions would continue to behave as expected, operating on the first 2^31 - 1 elements of arrays, with the exception of "arraylength" which would, in the case of an array with more than 2^31 - 1 elements, return Integer.MAX_VALUE. COMPILATION: Compilation of array operations would be changed to call the new "wide" + array_instruction VM instructions for all array access. TESTING: Any test sufficient to test support for current arrays should work for this as well. The previous sentence may be hopelessly naive. LIBRARY SUPPORT: Existing array APIs would have to be modified to support this change. In particular, the methods of java.util.Arrays would have to be altered to work with long-indexed arrays. I propose using the following pattern for such changes (both in java.util.Arrays and elsewhere where applicable): 1) If the method neither takes in nor returns an int representing an array length or array index, it retains its current public signature and the implementation is changed to work with large arrays. 2) If the method takes in at least one int parameter representing a array length or array index but does not return such an int, a parallel version will need to be created that takes in long parameters instead of ints. The implementation of the original version may also need to be altered to work with large arrays. 3) If the method returns an int representing an array length or index, it should be modified to work as expected with arrays that are within current size limits and break as cleanly as possible for larger arrays. It should also be deprecated in favor of an equivalent method that returns a long and operates properly on large arrays. Additionally, there are extant interfaces (java.util.Collection) that are often used in tandem with arrays where it might be beneficial to make parellel changes. Collection, for example, has a size () method that returns an int. It isn't possible to change this to return a long, or add an alternate size method that returns a long, without breaking every extant implementation of this interface. I'm thinking that the best non-breaking way to handle this would be to create a new subinterface of Collection that defined a new getSize () method that returned a long, and deprecate the extant size () method. The existing collection implementations could then be retrofit to implement the new interface without breaking code that was dependent on the current implementation of Collection. Alternately, a completely new collections library (javax.collections or something) could be built based on 64-bit sizes, possibly incorporating other features that haven't been added to Collections over the years out of backward compatibility concerns. REFLECTIVE APIS: java.lang.reflect.Array would need additional getXXX (Object array, long index) methods parallel to the current getXXX (Object array, int index) methods--the current getXXX methods would still work. Additional newInstance methods taking in long sizes would also be required. The current getLength () methods would be deprecated in favor of a new getSize () method returning a long. OTHER CHANGES: VM needs to support large arrays. MIGRATION: Existing "hacks" to provide this kind of behavior could be replaced with large arrays. COMPATIBILITY BREAKING CHANGES: Existing code that wasn't expecting a large array that was passed an array with 2^31 or more elements would only "see" the first 2^31 - 1 elements. EXISTING PROGRAMS: No changes. REFERENCES EXISTING BUGS: 4880587 (64-Bit indexing for arrays) URL FOR PROTOTYPE (optional): None. From mark at talios.com Tue Mar 24 12:07:49 2009 From: mark at talios.com (Mark Derricutt) Date: Wed, 25 Mar 2009 08:07:49 +1300 Subject: Proposal idea - generators Message-ID: Hi all, This isn't an actual proposal, but more a proposal idea that hopefully someone could run with. I was thinking about all the closures issues and looking at a lot of my code where I'm using closure like patterns and started thinking what would really make things easier for me would be some form of yield/generators api to give me a cleaner way of making Iterable's that could be used in the JDK5 for loop. The usage I'd like would be something like: for ( User user : allUsersList) { if (user.isActive()) yield user; } Effectively I could see this as being like comparing an XML pull parser to SAX. The problem I have is I can't think of a suitable way of expressing, or implementing this in java, unless I split the code into another thread that sleeps between the yield calling back to the iterable next() call which is nasty as I could see a lot of thread leakage there. Has anyone looked at, or already written some form of generator proposal? ...and then Buffy staked Edward. The End. From fw at deneb.enyo.de Tue Mar 24 12:50:38 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Tue, 24 Mar 2009 20:50:38 +0100 Subject: Proposal: @Unloadable Class defination In-Reply-To: <49C91ABB.4070801@sun.com> (Joseph D. Darcy's message of "Tue, 24 Mar 2009 10:39:07 -0700") References: <49C91ABB.4070801@sun.com> Message-ID: <87skl2em41.fsf@mid.deneb.enyo.de> * Joseph D. Darcy: > What would that mean exactly to all those poor objects on the heap > needing that classloader? I suppose the idea is that the classes can be garbage-collected once all the objects referencing it are gone. If they are needed again, they are reloaded and re-initialized, receiving a different identity. It might be possible to implement this in the present JDK 7, using a custom class loader which turns those annoated classes into anonymous classes. From akuhn at iam.unibe.ch Tue Mar 24 13:06:07 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Tue, 24 Mar 2009 21:06:07 +0100 Subject: (update) Use "default" keyword for default visibility In-Reply-To: <49C6AF16.5090803@sun.com> References: <8EAFB4E0-5A40-4E09-810B-803BAE598335@iam.unibe.ch> <49AD1C0B.3070907@joda.org> <43577BD5-8BD8-45F0-B190-EB04FBB283C3@iam.unibe.ch> <49AF0E94.6000206@sun.com> <49C6AF16.5090803@sun.com> Message-ID: <25FACF8D-7D0F-4683-B82F-D9E8E18284B6@iam.unibe.ch> On Mar 22, 2009, at 22:35 , Joseph D. Darcy wrote: > Joseph D. Darcy wrote: >> Hello. >> >> While the lack of an explicit name for the default accessibility in >> Java has slightly annoyed me at times over the years, I don't think >> it in isolation is such a troublesome issue that a language change >> is warranted. >> > > I've conferred with Alex on this request. Since the JSR 294 expert > group is working on adding a "module" accessibility level to the > language, that group is in a good position to weigh the pros and > cons of adding an explicit "package" modifier at the same time, a > change they are considering. Therefore, Project Coin should defer > the decision on an explicit package modifier to the JSR 294 expert > group. Okay with me. When I see the innovative ideas submitted since my proposal, which was a among the very first ones, I'd prefer manpower to be invested on those anyway. There are more valuable coins than my geeky obsession with fixing asymmetries in the language definition :) cheers, AA From Thomas.Hawtin at Sun.COM Tue Mar 24 13:07:28 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Tue, 24 Mar 2009 20:07:28 +0000 Subject: Proposal: @Unloadable Class defination In-Reply-To: References: Message-ID: <49C93D80.3080901@sun.com> Daniel Cheng wrote: > MAJOR ADVANTAGE: > > Developer may define some class as @Unloadable can be unloaded when needed. > > MAJOR BENEFIT: > > Currently, VM are not allow to unload Class with reachable > ClassLoader, this is required for "static variable" to be keep. But > this means Class have to keep in memory even if the class is rarely > used. Sometimes, the value static variable can be recreated at any > time, I'm not entirely sure what you intend this to be used for. Do you want normal pieces of application code unloaded? Do you want large blobs of static data to be unloaded? In which case don't you want more fine control over that? Do you want small pieces of generated code to be unloaded? Perhaps individual class loaders are more appropriate. Tom Hawtin From howard.lovatt at gmail.com Tue Mar 24 13:07:28 2009 From: howard.lovatt at gmail.com (Howard Lovatt) Date: Wed, 25 Mar 2009 07:07:28 +1100 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <28bca0ff0903230256p48b36533n77a148232743d28e@mail.gmail.com> References: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> <28bca0ff0903230256p48b36533n77a148232743d28e@mail.gmail.com> Message-ID: I don't get the example. Is class B meant to be Bar? Can you clarify? -- Howard. On 23/03/2009, at 8:56 PM, Marek Kozie? wrote: > 2009/3/23 Howard Lovatt : >> A few notes: >> >> 3. You shouldn't be able to access super fields or any instance >> methods before super. >> >> -- Howard. >> >> > > Can you ensure that ? > > > > class A { > private Bar bar; > > public A(Bar bar) { > setBar(bar); > } > > protected void setBar(Bar bar) { > this.bar = bar; > } > } > > class B extends A { > private Bar bar; > private Foo foo; > > public B(Bar bar, Foo foo) { > super(bar); > this.foo = foo; > } > > protected void setBar(Bar bar) { > this.bar = bar; > this.foo = bar.foo; > } > } > > Will code have same effect when constructor will be : > public B(Bar bar, Foo foo) { > this.foo = foo; > super(bar); > } > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit http://www.messagelabs.com/email > ______________________________________________________________________ From phil.swenson at gmail.com Tue Mar 24 14:21:36 2009 From: phil.swenson at gmail.com (phil swenson) Date: Tue, 24 Mar 2009 15:21:36 -0600 Subject: Compiler flag to turn off checked exceptions Message-ID: Not sure if this is a Project Coin thing, but has anyone thought about a compiler flag to turn off checked exceptions? I'm sure everyone knows the arguments against checked exceptions, I'd love to have the ability to just turn them off so I don't have to wrap them in RuntimeExceptions. Not sure what the implications of this are..... thoughts? From reinier at zwitserloot.com Tue Mar 24 14:38:31 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 24 Mar 2009 22:38:31 +0100 Subject: Proposal: Large arrays In-Reply-To: <248872.90823.qm@web63703.mail.re1.yahoo.com> References: <248872.90823.qm@web63703.mail.re1.yahoo.com> Message-ID: <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> Arrays are extremely ugly. They don't follow java's usual semantics at all; they have a read-only field, which java normally doesn't have. I don't actually consider 'length' a field at all. "length" just happens to be java's first context sensitive keyword. They don't have a sensible toString(), which is, well, "stupid" is being too kind, really. Their type system is broken (covariance, which is wrong, see generics), with a patchy runtime hack to make sure you can't actually crash the JVM with it. They are extremely hard to use because they don't grow on demand, and they have 0 useful methods, though some of them have been squirreled away in java.util.Arrays. I'd be more supportive of a proposal that excises the blight of arrays from java altogether. Or, perhaps somewhat more realistically, a retrofit to move arrays into the proper collections API, where they have a bunch of useful methods, .length becomes deprecated and .size() is preferred instead, they are instanceof List, and at the very least have halfway sensible hashCode(), equals(), and toString() implementations. The point of this rant: I actually laughed when I read "Is there a compelling reason for [length] to use a method rather than a field"? Anything done with arays is beyond salvation in the ugliness department. I think josh's point that existing APIs that deal with arrays are not going to handle this correctly is a very good one, and making overloaded methods (a 'large array' twin) can't be the right answer either: A properly implemented library would then have 3 methods that do the exact same thing - one for arrays, one for large arrays, and one for lists... and while we're at it, at some future point, undoubtedly one for large lists as well. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 24, 2009, at 19:03, james lowden wrote: > >> I don't think the source compatibility impact is that >> large actually. Let's say *all* arrays can potentially >> be 64-bit now. The existing code that uses an int >> expression to index into the array will still index into the >> same element and negative indexes will still cause an >> exception. Now, how should the length field be set? >> I'd guess it should saturate to Integer.MAX_VALUE for >> oversize arrays and a new "long size()" method >> could be added to return the full length. > > This I'd actually prefer over what I proposed (and, based on the > response so far and the previous bug, what others would probably > like as well); my main concern was not breaking the int "length" > field; I'd slightly prefer the long size to be a field rather than a > method, but that may just be due to that being how I'm used to > obtaining the array size; if there's a compelling reason to use a > method rather than a field for this, I'd be curious to hear it. > >> The JVM would need to be modified to handle the long >> indexes of course; perhaps the wide bytecode prefix could be >> put to use here. > > Looking at wide, it looks like applying it to the existing array > instructions would be an option; I would favor that approach over my > original idea, which chews up a whole slew of opcodes. > > I'll probably stew on the various suggestions for a while, and send > out a revised version of the proposal. > > -JL- > > > > From Joe.Darcy at Sun.COM Tue Mar 24 14:55:51 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 24 Mar 2009 14:55:51 -0700 Subject: Compiler flag to turn off checked exceptions In-Reply-To: References: Message-ID: <49C956E7.5000004@sun.com> On 03/24/09 02:21 PM, phil swenson wrote: > Not sure if this is a Project Coin thing, but has anyone thought about > a compiler flag to turn off checked exceptions? I'm sure everyone > knows the arguments against checked exceptions, I'd love to have the > ability to just turn them off so I don't have to wrap them in > RuntimeExceptions. > > Not sure what the implications of this are..... > > thoughts? > > From the proposal form on the Project Coin homepage: > The proposal must not remove existing features of the language; for > example, "Get rid of checked exceptions" would not be considered. http://openjdk.java.net/projects/coin/ -Joe From Joe.Darcy at Sun.COM Tue Mar 24 14:58:11 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 24 Mar 2009 14:58:11 -0700 Subject: Proposal: Large arrays In-Reply-To: <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> References: <248872.90823.qm@web63703.mail.re1.yahoo.com> <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> Message-ID: <49C95773.6020902@sun.com> On 03/24/09 02:38 PM, Reinier Zwitserloot wrote: > Arrays are extremely ugly. They don't follow java's usual semantics at > all; they have a read-only field, which java normally doesn't have. I > don't actually consider 'length' a field at all. "length" just happens > to be java's first context sensitive keyword. They don't have a > sensible toString(), which is, well, "stupid" is being too kind, > really. Their type system is broken (covariance, which is wrong, see > generics), with a patchy runtime hack to make sure you can't actually > crash the JVM with it. They are extremely hard to use because they > don't grow on demand, and they have 0 useful methods, though some of > them have been squirreled away in java.util.Arrays. > ... which is generally why I favor letting collection-like types use the bracket notation to get and set elements. That would eliminate the syntactically advantages of arrays. -Joe From rssh at gradsoft.com.ua Tue Mar 24 15:06:04 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 00:06:04 +0200 (EET) Subject: Proposal: Large arrays In-Reply-To: <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> References: <248872.90823.qm@web63703.mail.re1.yahoo.com> <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> Message-ID: <566c0772d7feaf216f3a6bc631ea96a3.squirrel@wmail.gradsoft.ua> > Arrays are extremely ugly. They don't follow java's usual semantics at > all; they have a read-only field, which java normally doesn't have. I Just note: low-level mechanisms are always 'ugly' from high=level point of view. And you can't live without low-level mechanisms at all, because method calls and checks for auto extending have cost. For example, I one time implemented term representation as plain arrays and as array-list in implementation of term rewriting system: hight-level constructs was near 60% slowly. I. e. role of arrays in java is not for end-user application programmer (for near 90 % of code collections is better) but for building of high-level library constructions. From Joe.Darcy at Sun.COM Tue Mar 24 15:17:44 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 24 Mar 2009 15:17:44 -0700 Subject: PROPOSAL: Method and Field Literals In-Reply-To: References: Message-ID: <49C95C08.3060906@sun.com> Hello. Jesse Wilson wrote: > Rich text (preferred) here: > http://docs.google.com/View?docID=dhfm3hw2_62dxg677jn > > Proposal: Method and Field Literals > > AUTHOR(S): > Jesse Wilson > > OVERVIEW > > FEATURE SUMMARY: > Add syntax for method and field literals. Enables compile-time > checking of member references and avoids an impossible checked > exception. While this proposal would certainly address a pain-point when using reflective frameworks, I don't think it would directly benefit the masses of Java programmers. Regards, -Joe From Joe.Darcy at Sun.COM Tue Mar 24 15:24:53 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 24 Mar 2009 15:24:53 -0700 Subject: For further consideration... Message-ID: <49C95DB5.6020202@sun.com> Greetings. In the first three weeks of Project Coin over two dozen proposals have been sent to the mailing list for evaluation. The proposals have ranged the gamut from new kinds of expressions, to new statements forms, to improved generics support. Thanks to everyone who has sent in interesting, thoughtful proposals and contributed to informative discussions on the list! While there is a bit less than a week left in the call for proposals period, there has been enough discussion on the list to winnow the slate of proposals sent in so far to those that merit further consideration for possible inclusion in the platform. First, Bruce Chapman's proposal to extend the scope of imports to include package annotations will be implemented under JLS maintenance so further action is unnecessary on this matter as part of Project Coin. Second, since the JSR 294 expert group is discussing adding a module level of accessibility to the language, the decision of whether or not to include Adrian Kuhn's proposal of letting "package" explicitly name the default accessibility level will be deferred to that body. Working with Alex, I reviewed the remaining proposals. Sun believes that the following proposals are small enough, have favorable estimated reward to effort ratios, and advance the stated criteria of making things programmers do everyday easier or supporting platform changes in JDK 7: * Strings in switch, Joe Darcy * Improved Exception Handling for Java, Neal Gafter * Automatic Resource Management, Josh Bloch * Improved Type Inference for Generic Instance Creation, Jeremy Manson * Elvis and Other Null-Safe Operators, Written by Neal Gafter and submitted by Stephen Colebourne * Simplified Varargs Method Invocation, Bob Lee As this is just an initial cut and the proposals are not yet in a form suitable for direct inclusion in the JLS, work should continue to refine these proposed specifications and preferably also to produce prototype implementations to allow a more thorough evaluation of the utility and scope of the changes. The email list should focus on improving the selected proposals and on getting any remaining new proposals submitted; continued discussion of the other proposals is discouraged. The final list of small language changes will be determined after the call for proposals is over so proposals sent in this week are certainly still in the running! The final list will only have around five items so it is possible not all the changes above will be on the eventual final list. -Joe From markmahieu at googlemail.com Tue Mar 24 15:20:57 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 24 Mar 2009 22:20:57 +0000 Subject: Proposal: Large arrays In-Reply-To: <49C95773.6020902@sun.com> References: <248872.90823.qm@web63703.mail.re1.yahoo.com> <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> <49C95773.6020902@sun.com> Message-ID: 2009/3/24 Joe Darcy > > > ... which is generally why I favor letting collection-like types use the > bracket notation to get and set elements. +1 > That would eliminate the > syntactically advantages of arrays. Except, possibly, for 'adding' elements to them, which in many cases just looks like: fooArray[i++] = foo; Collections could conceivably go even cuter though: fooList += foo; and fooList -= foo; Mark From phil.swenson at gmail.com Tue Mar 24 15:24:53 2009 From: phil.swenson at gmail.com (phil swenson) Date: Tue, 24 Mar 2009 16:24:53 -0600 Subject: Compiler flag to turn off checked exceptions In-Reply-To: <49C956E7.5000004@sun.com> References: <49C956E7.5000004@sun.com> Message-ID: I wasn't suggesting "removing" a feature, just disabling one via a compiler flag. But I guess it's a no-go. On Tue, Mar 24, 2009 at 3:55 PM, Joe Darcy wrote: > On 03/24/09 02:21 PM, phil swenson wrote: >> >> Not sure if this is a Project Coin thing, but has anyone thought about >> a compiler flag to turn off checked exceptions? ?I'm sure everyone >> knows the arguments against checked exceptions, I'd love to have the >> ability to just turn them off so I don't have to wrap them in >> RuntimeExceptions. >> >> Not sure what the implications of this are..... >> >> thoughts? >> >> > > From the proposal form on the Project Coin homepage: >> >> The proposal must not remove existing features of the language; for >> example, "Get rid of checked exceptions" would not be considered. > > http://openjdk.java.net/projects/coin/ > > -Joe > From jeremy.manson at gmail.com Tue Mar 24 15:30:23 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 24 Mar 2009 15:30:23 -0700 Subject: For further consideration... In-Reply-To: <49C95DB5.6020202@sun.com> References: <49C95DB5.6020202@sun.com> Message-ID: <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> Joe, Is it all the Elvis operators, or just ?: ? Jeremy On Tue, Mar 24, 2009 at 3:24 PM, Joe Darcy wrote: > Greetings. > > In the first three weeks ?of Project Coin over two dozen proposals have > been sent to the mailing list for evaluation. The proposals have ranged > the gamut from new kinds of expressions, to new statements forms, to > improved generics support. ?Thanks to everyone who has sent in > interesting, thoughtful proposals and contributed to informative > discussions on the list! > > While there is a bit less than a week left in the call for proposals > period, there has been enough discussion on the list to winnow the slate > of proposals sent in so far to those that merit further consideration > for possible inclusion in the platform. > > First, Bruce Chapman's proposal to extend the scope of imports to > include package annotations will be implemented under JLS maintenance so > further action is unnecessary on this matter as part of Project Coin. > Second, since the JSR 294 expert group is discussing adding a module > level of accessibility to the language, the decision of whether or not > to include Adrian Kuhn's proposal of letting "package" explicitly name > the default accessibility level will be deferred to that body. ?Working > with Alex, I reviewed the remaining proposals. ?Sun believes that the > following proposals are small enough, have favorable estimated reward to > effort ratios, and advance the stated criteria of making things > programmers do everyday easier or supporting platform changes in JDK 7: > > ? ? * Strings in switch, Joe Darcy > ? ? * Improved Exception Handling for Java, Neal Gafter > ? ? * Automatic Resource Management, Josh Bloch > ? ? * Improved Type Inference for Generic Instance Creation, > ? ? ? Jeremy Manson > ? ? * Elvis and Other Null-Safe Operators, > ? ? ? Written by Neal Gafter and submitted by Stephen Colebourne > ? ? * Simplified Varargs Method Invocation, Bob Lee > > As this is just an initial cut and the proposals are not yet in a form > suitable for direct inclusion in the JLS, work should continue to refine > these proposed specifications and preferably also to produce prototype > implementations to allow a more thorough evaluation of the utility and > scope of the changes. ?The email list should focus on improving the > selected proposals and on getting any remaining new proposals submitted; > continued discussion of the other proposals is discouraged. > > The final list of small language changes will be determined after the > call for proposals is over so proposals sent in this week are certainly > still in the running! ?The final list will only have around five items > so it is possible not all the changes above will be on the eventual > final list. > > -Joe > > > From rssh at gradsoft.com.ua Tue Mar 24 15:55:18 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 00:55:18 +0200 (EET) Subject: For further consideration... In-Reply-To: <49C95DB5.6020202@sun.com> References: <49C95DB5.6020202@sun.com> Message-ID: > > * Strings in switch, Joe Darcy > * Improved Exception Handling for Java, Neal Gafter > * Automatic Resource Management, Josh Bloch > * Improved Type Inference for Generic Instance Creation, > Jeremy Manson > * Elvis and Other Null-Safe Operators, > Written by Neal Gafter and submitted by Stephen Colebourne > * Simplified Varargs Method Invocation, Bob Lee > ...... > scope of the changes. The email list should focus on improving the > selected proposals and on getting any remaining new proposals submitted; > continued discussion of the other proposals is discouraged. > > The final list of small language changes will be determined after the > call for proposals is over so proposals sent in this week are certainly > still in the running! So, as I understood: - work for improving enhanced strings literals proposal will be useless, it's finally rejected in project coin (?),[ so will wait for java 7.1 or later with them] - improving proposal about access to compile-time information about local context can have some sence (?) For other proposals which are not accepted and interesting for me: Are exists change that naming parameters proposal will be in short list ? From vilya.harvey at gmail.com Tue Mar 24 16:12:56 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 24 Mar 2009 23:12:56 +0000 Subject: PROPOSAL: Compiletime information access In-Reply-To: <7bc7a3eea212b409e97a78f9e9c4cac0.squirrel@wmail.gradsoft.ua> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <6aef848f0903240738x4e24b53bv2c0c18394cfb9acb@mail.gmail.com> <7bc7a3eea212b409e97a78f9e9c4cac0.squirrel@wmail.gradsoft.ua> Message-ID: <6aef848f0903241612v512d76ccl64a2e0ed7226a0fc@mail.gmail.com> 2009/3/24 > > evaluating during compilation?) and security (what security model does it > > operate under?). > > > > Security model of java compiler. We already have al this potential > problems > with annotations processing, where any java code can be auto-discovered and > run. And practice shows that this is not the biggest problem of language. > Good point, I forgot about the annotation processor. The difference is that use of annotations is syntactically distinct from regular Java code, whereas the Compiletime class in your examples is not. I think this could lead to confusion, but maybe that's just me. Possibility to write unmaintainable code exists. > > But if think in such way, than creation of turing-complete programming > language was fatal security error ;) > I like it! :-) Vil. From Joe.Darcy at Sun.COM Tue Mar 24 16:17:11 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 16:17:11 -0700 Subject: For further consideration... In-Reply-To: References: <49C95DB5.6020202@sun.com> Message-ID: <49C969F7.7070209@sun.com> rssh at gradsoft.com.ua wrote: >> * Strings in switch, Joe Darcy >> * Improved Exception Handling for Java, Neal Gafter >> * Automatic Resource Management, Josh Bloch >> * Improved Type Inference for Generic Instance Creation, >> Jeremy Manson >> * Elvis and Other Null-Safe Operators, >> Written by Neal Gafter and submitted by Stephen Colebourne >> * Simplified Varargs Method Invocation, Bob Lee >> >> > ...... > >> scope of the changes. The email list should focus on improving the >> selected proposals and on getting any remaining new proposals submitted; >> continued discussion of the other proposals is discouraged. >> >> The final list of small language changes will be determined after the >> call for proposals is over so proposals sent in this week are certainly >> still in the running! >> > > So, as I understood: > - work for improving enhanced strings literals proposal will be useless, > it's finally rejected in project coin (?),[ so will wait for java 7.1 or > later with them] > Correct; enhanced strings literals will not be one of the final language change selections of Project Coin. > - improving proposal about access to compile-time information about > local context can have some sence (?) > Given the existing capabilities of annotation processors, I don't think the proposed API is necessary or desirable. > For other proposals which are not accepted and interesting for me: > Are exists change that naming parameters proposal will be in short list ? > Method resolution is one of the most complicated aspects of the Java Language Specification; adding another wrinkle to the selection process is quite a tricky undertaking. I don't think that change as a good cost/benefit trade off. -Joe From Joe.Darcy at Sun.COM Tue Mar 24 16:18:26 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 24 Mar 2009 16:18:26 -0700 Subject: For further consideration... In-Reply-To: <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> References: <49C95DB5.6020202@sun.com> <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> Message-ID: <49C96A42.9050805@sun.com> Jeremy Manson wrote: > Joe, > > Is it all the Elvis operators, or just ?: ? > The more modest version is more likely to get in. -Joe From vilya.harvey at gmail.com Tue Mar 24 16:31:49 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 24 Mar 2009 23:31:49 +0000 Subject: Any interest in raw strings? Message-ID: <6aef848f0903241631x5a38a26dqbcf9107d3027b0f7@mail.gmail.com> Hi all, I don't think I've seen a proposal for raw strings - string literals which ignore escape sequences - yet. Would there be enough interest to write this up as a proposal? The idea is stolen shamelessly from Python, where you can write a raw string as r"[\n\r\t]" and it's equivalent to the normal string "[\\n\\r\\t]" (i.e. you don't need to double the backslash in a raw string, it's just treated like any other character). This is most useful when writing regular expressions; in fact, it may *only* be useful then. But for that one case it is extremely handy. Any opinions? Vil. From rssh at gradsoft.com.ua Tue Mar 24 16:38:11 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 01:38:11 +0200 (EET) Subject: Compile-time Access to local context: ver 1.1 Message-ID: <09241845bdfea4370bcf2e0b920c9c87.squirrel@wmail.gradsoft.ua> Already rejected, but to "finish gelshtat." Sorry, OVERVIEW: FEATURE SUMMARY: Add API to access compile-time local context of currenct compiled element from programs. MAJOR ADVANTAGE: Now compile time properties of local context are unaccessible for programmer. This meaning that some functionality (such as access to location of file and line) is accessible only from debug version of program with technique, which is not officially supported, some (such as binding context in current location) is not available at all. some (such as time of compilation) can be accessibla via annotation processor, but direct access is more natural. MAJOR DISADVANTAGE Inaccurate usage of this feature can cause producing of unmaintable code. ALTERNATIVES: External preprocessing of java sources. EXAMPLES SIMPLE EXAMPLE: Example 1 if (traceCondigion) { log.trace(Compiletime.getFileName()+":"+ Compiletime.getLineNumber()); } Example 2 if (system.currentTimeMillis() - Compiletime.getTimeMillis() > 86400) { System.out.println("This file was compiled more than day ago"); } ADVANCED EXAMPLE: Example 1 // assuming that multiline strings are implemented: int a=0; int b=1; Binding bindings = Compiletime.getInstance().getCurrentBindings(); ScriptEngine velocity = ScriptEngineManager.get("velocity"); try { String fname = Compiletime.getFileName(); int line = Compiletime.getLineNumber(); String s = velocity.eval(""" #if ($a==$b) Something interesting here may be, Are you know that value of b is $b ? #else no mistics here. #end """, bindings); } catch (ScriptException ex){ Sytem.err.println("error in inline velocity in "+fname+", " "line "+line+1+ex.getLineNumber()); } DETAILS: Add to Java Library pseudo-objects java.lang.Compiletime with access to compile-time properties and next signature: public class Compiletime { /** * get filename of compiled call. * in case of generated source and avaible JSR-45 SMAP file * return file name of translated-source. **/ public static String getFileName(); /** * get line number of compiled call. * in case of generated source and avaible JSR-45 SMAP file * return line number in translated-source. **/ public static int getLineNumber(); /** * get class name where this call is placed. * in case of generated source and avaible JSR-45 SMAP file * return class name in translated-source. **/ public static int getClassName(); /** * get method name where this call is placed. * in case of generated source and avaible JSR-45 SMAP file * return method name in translated-source. **/ public static int getMethodName(); /** * generate JSR223 bindings for given names in current compilation *context. *Names array must be empty or consists from string literals. **/ public static Bindings getBindings(String ... names) /** * get time of compilation in miliseconds. **/ public static long getTimeMillis(); } COMPILATION: During compilation calls to compile time are changed to generation of appriative constant expressions. String x = Compiletime.getFileName(); changed to String x = "com/mycompany/package/MyClass.java"; int x = Compiletime.getLinNumber(); changed to int x = 33; String x = getClassName() changed to String x = "com.mycompany.package.MyClass"; class X { int p1; String p2; ... public void doSomething(int x, int y) { int local = x+y; Bindings bindings = Compiletime.getBindings(); evalSomeScript(bindings); } } will translated to will translated to class X { int p1; String p2; ... public void doSomething(int x, int y) { int local = x+y; Binding binding=(new CompileTime.Binding().build( "this",this, "p1",p1, "p2",p2, "x",x, "y",y "local",local)); evalSomeScript(bindings); } } JLS changes: current scope of JLS is not touched. Btw, may be add to JLS chapter with name 'Compilation process' where describe: - high level description of transforming source code to JVM classes. - process of automatic loading of annotation processors and when ones are used. - this API. TESTING: Special cases are: * compability with JSR45 LIBRARY SUPPORT: Adding one classes for Compiletime.Bindings implementation to standart library. REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4411102 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6439965 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4649007 IMPLEMENTATION URL (optional) None. From rssh at gradsoft.com.ua Tue Mar 24 16:43:46 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 01:43:46 +0200 (EET) Subject: Any interest in raw strings? In-Reply-To: <6aef848f0903241631x5a38a26dqbcf9107d3027b0f7@mail.gmail.com> References: <6aef848f0903241631x5a38a26dqbcf9107d3027b0f7@mail.gmail.com> Message-ID: <9df7013b651580a5faaf0b913f1f178b.squirrel@wmail.gradsoft.ua> > Hi all, > > I don't think I've seen a proposal for raw strings - string literals which > ignore escape sequences - yet. Would there be enough interest to write > this > up as a proposal? > > The idea is stolen shamelessly from Python, where you can write a raw > string > as r"[\n\r\t]" and it's equivalent to the normal string "[\\n\\r\\t]" > (i.e. > you don't need to double the backslash in a raw string, it's just treated > like any other character). This is most useful when writing regular > expressions; in fact, it may *only* be useful then. But for that one case > it > is extremely handy. > > Any opinions? > It was part of my enhanched string proposal http://redmine.gradsoft.ua/wiki/java7stringliterals If creating new proposal only for unescaped strings (without multiline) can help (ask Darcy) -- than submit one. It woud be better than nothing. > Vil. > > From vilya.harvey at gmail.com Tue Mar 24 16:58:29 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 24 Mar 2009 23:58:29 +0000 Subject: Any interest in raw strings? In-Reply-To: <9df7013b651580a5faaf0b913f1f178b.squirrel@wmail.gradsoft.ua> References: <6aef848f0903241631x5a38a26dqbcf9107d3027b0f7@mail.gmail.com> <9df7013b651580a5faaf0b913f1f178b.squirrel@wmail.gradsoft.ua> Message-ID: <6aef848f0903241658q612a587ep5d8e85b8ea2597e@mail.gmail.com> Ah, I had a feeling I might have missed something. It looks like you've already covered everything I wanted to write up and more! I think multiline strings would be a useful addition too; it seems a shame that it won't be included in the Coin changes. Cheers, Vil. 2009/3/24 > > Hi all, > > > > I don't think I've seen a proposal for raw strings - string literals > which > > ignore escape sequences - yet. Would there be enough interest to write > > this > > up as a proposal? > > > > The idea is stolen shamelessly from Python, where you can write a raw > > string > > as r"[\n\r\t]" and it's equivalent to the normal string "[\\n\\r\\t]" > > (i.e. > > you don't need to double the backslash in a raw string, it's just treated > > like any other character). This is most useful when writing regular > > expressions; in fact, it may *only* be useful then. But for that one case > > it > > is extremely handy. > > > > Any opinions? > > > > It was part of my enhanched string proposal > http://redmine.gradsoft.ua/wiki/java7stringliterals > > If creating new proposal only for unescaped strings (without multiline) > can help (ask Darcy) -- than submit one. It woud be better than nothing. > > > Vil. > > > > > > > From markmahieu at googlemail.com Tue Mar 24 18:07:25 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 25 Mar 2009 01:07:25 +0000 Subject: PROPOSAL: Auto-assignment Parameters Message-ID: HTML version + prototype available at http://slm888.com/javac Auto-assignment Parameters v0.1 AUTHOR(S): Mark Mahieu OVERVIEW FEATURE SUMMARY: Should be suitable as a summary in a language tutorial. An additional form of constructor parameter which provides automatic assignment of the parameter's value to an instance field. These parameters are implicitly declared as final to prevent unintentional assignments to the wrong variable in the constructor body. MAJOR ADVANTAGE: What makes the proposal a favorable change? Reduces the likelihood of some common coding errors relating to assignment of fields in a constructor, including those where: * a field is assigned to itself * the parameter is assigned instead of the field * the assignment to the field is missing entirely These and other errors are often caused by typos or code refactoring. MAJOR BENEFIT: Why is the platform better if the proposal is adopted? A programmer's intent is more clearly expressed for the extremely common case of assigning a constructor parameter directly to an instance field with the same name. MAJOR DISADVANTAGE: There is always a cost. As with any sugar which enables a more concise way of expressing an existing idiom, programmers may be tempted to use it even when the original form would be more appropriate. ALTERNATIVES: Can the benefits and advantages be had some way without a language change? IDEs and tools such as FindBugs are good at warning about the kind of errors mentioned above, however since the code in question is usually still valid to the compiler, they are limited in what action they can take by default. A language change can combine the ability to avoid these errors entirely with a more expressive idiom, resulting in an increased signal to noise ratio for readers of that code. EXAMPLES SIMPLE EXAMPLE: Show the simplest possible program utilizing the new feature. class C { int i; C(int this.i) {} } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. class Proposal { private final String name; private final String author; private boolean suitableForCoin; private Integer score; public Proposal(String this.name, String this.author, boolean this.suitableForCoin, int this.score) { if (name.equals(?Auto-assignment Parameters?)) { suitableForCoin = true; // final so compile-time error } } // rest of class ... } 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. The syntactic grammar is modified to include auto-assignment parameters for constructors: ConstructorDeclaratorRest: ConstructorParameters [throws QualifiedIdentifierList] MethodBody ConstructorParameters: ( [ConstructorParameterDecls] ) ConstructorParameterDecls: [final] [Annotations] Type ConstructorParameterDeclsRest ConstructorParameterDeclsRest: ConstructorParameterId [ , ConstructorParameterDecls] ... ConstructorParameterId ConstructorParameterId: VariableDeclaratorId this . VariableDeclaratorId super . VariableDeclaratorId An auto-assignment parameter is a formal parameter (JLSv3 ?8.4.1) which specifies an instance field instead of an identifier. Its value is automatically assigned to the specified field. It may only be used in a constructor. The automatic assignment takes place after any explicit or implicit invocation of another constructor, and before any statements in the body of the constructor. A constructor which declares n auto-assignment parameters will perform n such automatic assignments, in the order that the parameters are declared. The parameter has the same name (JLSv3 ?6.2) as the field to which it is assigned; replacing each auto-assignment parameter with a normal formal parameter with the same name would yield a constructor with an identical signature. As with a normal parameter, the parameter's name is entered into the scope of the constructor body (JLSv3 ?6.3), and therefore shadows the field (JLSv3 ?6.3.1) within that scope. It is a compile-time error if the field is not accessible from the constructor in which the parameter appears. It is a compile-time error if the declared type of the parameter is not assignment compatible (JLSv3 ?5.2) with the field to which it is automatically assigned. If an unboxing conversion is required by an automatic assignment, any NullPointerException thrown as a result (JLSv3 ?5.1.8) will contain the name of the field on which the conversion failed, which may be retrieved by calling getMessage() on the exception. Auto-assignment parameters are implicitly final, and follow the standard rules for final variables (JLSv3 ?4.12.4). Explicitly declaring an auto-assignment parameter as final has no effect, and does not cause a compilation error. Auto-assignment parameters follow the standard definite assignment rules for formal parameters (JLSv3 ?16.3). An auto-assignment parameter may be annotated. If an auto-assignment parameter is the last parameter in the list, and refers to a field of array type, it may be a variable arity parameter. 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! Desugaring of the following class: class Foo { int value; Foo(Integer this.value) { System.out.println(value); } } would result in (unboxing desugaring omitted): class Foo { int value; Foo(final Integer value) { super(); if (value == null) throw new NullPointerException("value"); this.value = value; System.out.println(value); } } No changes to the classfile format are required. Tools which consume class files see the constructor signature as though it had been written using normal formal parameters. TESTING: How can the feature be tested? An initial set of jtreg tests is included in the prototype. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No 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. com.sun.source.tree.VariableTree would require an additional method which returns the auto-assigned field. 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 MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. Assignment statements in constructors for which all of the following are true can be considered suitable for conversion: * the lhs of the assignment is a non-static field * the rhs is a parameter with the same name as the field * there are no other assignments to the parameter anywhere in the constructor * there are no assignments to, or other uses of the field before the assignment statement in question (including invoked constructors) Such statements can be converted by: 1) replacing the parameter with an auto-assignment parameter (prefixing the existing parameter's identifier with 'this.'), and 2) removing the assignment statement COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. No 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 semantics of existing class files and legal source files are unchanged by this feature. REFERENCES EXISTING BUGS: Please include a list of any existing Sun bug ids related to this proposal. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 (uses a 'setter' method rather than a constructor in its example) FindBugs bug patterns - http://findbugs.sourceforge.net/bugDescriptions.html * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) * Self comparison of field with itself (SA_FIELD_SELF_COMPARISON) * Nonsensical self computation involving a field (e.g., x & x) (SA_FIELD_SELF_COMPUTATION) * Self assignment of local variable (SA_LOCAL_SELF_ASSIGNMENT) * Nonsensical self computation involving a variable (e.g., x & x) (SA_LOCAL_SELF_COMPUTATION) * Uninitialized read of field in constructor (UR_UNINIT_READ) * Unwritten field (UWF_UNWRITTEN_FIELD) * Dead store to local variable (DLS_DEAD_LOCAL_STORE) * Dead store of null to local variable (DLS_DEAD_LOCAL_STORE_OF_NULL) URL FOR PROTOTYPE (optional): http://slm888.com/javac DESIGN ALTERNATIVES: The following variations have been explored and are worth mentioning: * Allow auto-assignment parameters on all non-abstract methods. This may be especially useful on the extremely common 'setter' methods in 'value object' classes. * Remove the requirement for (or even disallow) the type to be specified on auto-assignment parameters. Experimentation with this idea suggests that it may work quite well for constructors, further emphasising the difference in intent and semantics from those of normal parameters. However, it may not work so well in combination with auto-assignment parameters on all non-abstract methods, and requires a change to the order in which javac compiles classes (can still pass jtreg tests). * Allow an alternative name to be specified. This adds additional complexity to support a fractional percentage of cases, which could continue to use the existing coding pattern. From rssh at gradsoft.com.ua Tue Mar 24 18:22:25 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 03:22:25 +0200 (EET) Subject: REQUEST: better empty catch in better exception handling Message-ID: Yet one problem with extension handler: rare we need catch exception but do nothibg in catch statement. (i. e. do not log) Example is code like next snipset: try { something=searchFirst(condition); }catch(NotFoundException ex){ // do nothing. search better } if (something!=null) { try { something=searchSecond(condition); }catch(NotFoundException ex){ // do nothing. search better } } >From other side, we prefer do not have in codebase code with empty exception handling and use special tools to detect empty catch braclets and warn about ones. For now, we use ';' to mark, that this empty catch is really empty catch and not error or unfinished refactoring. I.e.: if (something!=null) { try { something=searchSecond(condition); }catch(NotFoundException ex){ // do nothing. search better ; // ';' tell javachecker do not complain about empty catch. } } But this is ugly. Of course, is simple use annotation @SuppressWarning("empty-catch") but javac compiler does not warn about empty catch-s. So, question to community: is it possible to extend exception handling proposal by adding optional conventions - warn about empty catch-s - specify rare cases, when empty catch is really needed. ? For example, this can be @EmptyCatch annotation, which mark catch block empty. i.e. try { }catch(@EmptyCatch NotFound | FoundNotAsILike ex ){ } and effective do nothing. From reinier at zwitserloot.com Tue Mar 24 18:25:17 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 02:25:17 +0100 Subject: Proposal: Large arrays In-Reply-To: References: <248872.90823.qm@web63703.mail.re1.yahoo.com> <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> <49C95773.6020902@sun.com> Message-ID: <26EC18B2-0D21-4F99-BE79-D719F839550E@zwitserloot.com> Far too cute; I think: fooArray.add(foo); is superior to all of: fooArray[fooArray.length] = foo; fooList += foo; fooList -= foo; Note also that fooArray[length+1] can't be made threadsafe, and the pseudo-addition/substraction is exactly the kind of example people who oppose operator overloading use - it's that offensive to some. Access and setting is a decent addition, but not something I usually do with my lists (I iterate them instead). I'd use comprehensions more. Not against it either, just saying 'meh' to the idea. --Reinier Zwitserloot On Mar 24, 2009, at 23:20, Mark Mahieu wrote: > 2009/3/24 Joe Darcy >> >> >> ... which is generally why I favor letting collection-like types >> use the >> bracket notation to get and set elements. > > > +1 > > >> That would eliminate the >> syntactically advantages of arrays. > > > Except, possibly, for 'adding' elements to them, which in many cases > just > looks like: > > fooArray[i++] = foo; > > Collections could conceivably go even cuter though: > > fooList += foo; > > and > > fooList -= foo; > > > > Mark > From reinier at zwitserloot.com Tue Mar 24 18:31:44 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 02:31:44 +0100 Subject: Any interest in raw strings? In-Reply-To: <6aef848f0903241658q612a587ep5d8e85b8ea2597e@mail.gmail.com> References: <6aef848f0903241631x5a38a26dqbcf9107d3027b0f7@mail.gmail.com> <9df7013b651580a5faaf0b913f1f178b.squirrel@wmail.gradsoft.ua> <6aef848f0903241658q612a587ep5d8e85b8ea2597e@mail.gmail.com> Message-ID: <3113C08A-DAA7-4638-8F18-340F3C2D338B@zwitserloot.com> Because raw strings are only used for regexps (it's so bad that people think the 'r' in python's raw string syntax stands for regexp and not raw), I suggested a while ago, on a different forum, to support regexp literals, which would even get the benefit of compile-time checking the regexp (there are a few things which are neccessarily a bad reg- exp, such as mismatched parentheses), and possibly the compile-time generation of the regexp literal to a regexp Thompson's tree, which takes relatively long to build, but once built, can parse any string through the regexp in O(n), where n is the length of the string. Back then there were some admittedly rare use-cases for raw strings (including concatenating a regexp with a variable, which you couldn't do with regexp literals), but there was no consensus on whether raw strings, or regexp literals (or possibly both) were a good idea. I'd love me some raw (and multiline) strings, but this stuff is a bit too tricky to sort out now, a month or two before java7RC1. --Reinier Zwitserloot On Mar 25, 2009, at 00:58, Vilya Harvey wrote: > Ah, I had a feeling I might have missed something. It looks like > you've > already covered everything I wanted to write up and more! I think > multiline > strings would be a useful addition too; it seems a shame that it > won't be > included in the Coin changes. > > Cheers, > Vil. > > > 2009/3/24 > >>> Hi all, >>> >>> I don't think I've seen a proposal for raw strings - string literals >> which >>> ignore escape sequences - yet. Would there be enough interest to >>> write >>> this >>> up as a proposal? >>> >>> The idea is stolen shamelessly from Python, where you can write a >>> raw >>> string >>> as r"[\n\r\t]" and it's equivalent to the normal string "[\\n\\r\ >>> \t]" >>> (i.e. >>> you don't need to double the backslash in a raw string, it's just >>> treated >>> like any other character). This is most useful when writing regular >>> expressions; in fact, it may *only* be useful then. But for that >>> one case >>> it >>> is extremely handy. >>> >>> Any opinions? >>> >> >> It was part of my enhanched string proposal >> http://redmine.gradsoft.ua/wiki/java7stringliterals >> >> If creating new proposal only for unescaped strings (without >> multiline) >> can help (ask Darcy) -- than submit one. It woud be better than >> nothing. >> >>> Vil. >>> >>> >> >> >> > From reinier at zwitserloot.com Tue Mar 24 18:34:34 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 02:34:34 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: Message-ID: I like where this is going, but I'd rather see a bigger setup for auto- POJO classes. I proposed this before and in most java circles (outside of coin-dev!), this idea was considered very useful: public data class Foo { private final int x; private final int y; private final String foo; } The above class would auto-generate the getters, a constructor, hashCode, equals, and toString. You can add methods to it if you want, and if you define a method that would usually be auto-generated, it isn't auto-generated. So, if you need to do some extra processing before returning 'foo' via the getter, go right ahead. You can even add this later without breaking your API's compatibility. --Reinier Zwitserloot On Mar 25, 2009, at 02:07, Mark Mahieu wrote: > HTML version + prototype available at http://slm888.com/javac > > > > Auto-assignment Parameters v0.1 > > > AUTHOR(S): > > Mark Mahieu > > > OVERVIEW > > FEATURE SUMMARY: Should be suitable as a summary in a language > tutorial. > > An additional form of constructor parameter which provides automatic > assignment of the parameter's value to an instance field. These > parameters > are implicitly declared as final to prevent unintentional > assignments to the > wrong variable in the constructor body. > > > MAJOR ADVANTAGE: What makes the proposal a favorable change? > > Reduces the likelihood of some common coding errors relating to > assignment > of fields in a constructor, including those where: > > * a field is assigned to itself > * the parameter is assigned instead of the field > * the assignment to the field is missing entirely > > These and other errors are often caused by typos or code refactoring. > > > MAJOR BENEFIT: Why is the platform better if the proposal is adopted? > > A programmer's intent is more clearly expressed for the extremely > common > case of assigning a constructor parameter directly to an instance > field with > the same name. > > > MAJOR DISADVANTAGE: There is always a cost. > > As with any sugar which enables a more concise way of expressing an > existing > idiom, programmers may be tempted to use it even when the original > form > would be more appropriate. > > > ALTERNATIVES: Can the benefits and advantages be had some way > without a > language change? > > IDEs and tools such as FindBugs are good at warning about the kind > of errors > mentioned above, however since the code in question is usually still > valid > to the compiler, they are limited in what action they can take by > default. > > A language change can combine the ability to avoid these errors > entirely > with a more expressive idiom, resulting in an increased signal to > noise > ratio for readers of that code. > > > > EXAMPLES > > SIMPLE EXAMPLE: Show the simplest possible program utilizing the new > feature. > > class C { > int i; > C(int this.i) {} > } > > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > > class Proposal { > > private final String name; > private final String author; > private boolean suitableForCoin; > private Integer score; > > public Proposal(String this.name, > String this.author, > boolean this.suitableForCoin, > int this.score) { > > if (name.equals(?Auto-assignment Parameters?)) { > suitableForCoin = true; // final so compile-time error > } > } > > // rest of class ... > } > > > > 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. > > The syntactic grammar is modified to include auto-assignment > parameters for > constructors: > > ConstructorDeclaratorRest: > ConstructorParameters [throws QualifiedIdentifierList] > MethodBody > > ConstructorParameters: > ( [ConstructorParameterDecls] ) > > ConstructorParameterDecls: > [final] [Annotations] Type > ConstructorParameterDeclsRest > > ConstructorParameterDeclsRest: > ConstructorParameterId [ , ConstructorParameterDecls] > ... ConstructorParameterId > > ConstructorParameterId: > VariableDeclaratorId > this . VariableDeclaratorId > super . VariableDeclaratorId > > An auto-assignment parameter is a formal parameter (JLSv3 ?8.4.1) > which > specifies an instance field instead of an identifier. Its value is > automatically assigned to the specified field. It may only be used > in a > constructor. > > The automatic assignment takes place after any explicit or implicit > invocation of another constructor, and before any statements in the > body of > the constructor. A constructor which declares n auto-assignment > parameters > will perform n such automatic assignments, in the order that the > parameters > are declared. > > The parameter has the same name (JLSv3 ?6.2) as the field to which > it is > assigned; replacing each auto-assignment parameter with a normal > formal > parameter with the same name would yield a constructor with an > identical > signature. As with a normal parameter, the parameter's name is > entered into > the scope of the constructor body (JLSv3 ?6.3), and therefore > shadows the > field (JLSv3 ?6.3.1) within that scope. > > It is a compile-time error if the field is not accessible from the > constructor in which the parameter appears. > > It is a compile-time error if the declared type of the parameter is > not > assignment compatible (JLSv3 ?5.2) with the field to which it is > automatically assigned. > > If an unboxing conversion is required by an automatic assignment, any > NullPointerException thrown as a result (JLSv3 ?5.1.8) will contain > the name > of the field on which the conversion failed, which may be retrieved by > calling getMessage() on the exception. > > Auto-assignment parameters are implicitly final, and follow the > standard > rules for final variables (JLSv3 ?4.12.4). Explicitly declaring an > auto-assignment parameter as final has no effect, and does not cause a > compilation error. > > Auto-assignment parameters follow the standard definite assignment > rules for > formal parameters (JLSv3 ?16.3). > > An auto-assignment parameter may be annotated. > > If an auto-assignment parameter is the last parameter in the list, and > refers to a field of array type, it may be a variable arity parameter. > > > > 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! > > Desugaring of the following class: > > class Foo { > int value; > Foo(Integer this.value) { > System.out.println(value); > } > } > > would result in (unboxing desugaring omitted): > > class Foo { > int value; > Foo(final Integer value) { > super(); > if (value == null) > throw new NullPointerException("value"); > this.value = value; > System.out.println(value); > } > } > > No changes to the classfile format are required. Tools which > consume class > files see the constructor signature as though it had been written > using > normal formal parameters. > > > TESTING: How can the feature be tested? > > An initial set of jtreg tests is included in the prototype. > > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > > No > > > 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. > > com.sun.source.tree.VariableTree would require an additional method > which > returns the auto-assigned field. > > > 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 > > > MIGRATION: Sketch how a code base could be converted, manually or > automatically, to use the new feature. > > Assignment statements in constructors for which all of the following > are > true can be considered suitable for conversion: > * the lhs of the assignment is a non-static field > * the rhs is a parameter with the same name as the field > * there are no other assignments to the parameter anywhere in the > constructor > * there are no assignments to, or other uses of the field before > the > assignment statement in question (including invoked constructors) > > Such statements can be converted by: > 1) replacing the parameter with an auto-assignment parameter > (prefixing > the existing parameter's identifier with 'this.'), and > 2) removing the assignment statement > > > > COMPATIBILITY > > BREAKING CHANGES: Are any previously valid programs now invalid? If > so, list > one. > > No > > > 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 semantics of existing class files and legal source files are > unchanged > by this feature. > > > > REFERENCES > > EXISTING BUGS: Please include a list of any existing Sun bug ids > related to > this proposal. > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 > (uses a 'setter' method rather than a constructor in its example) > > FindBugs bug patterns - http://findbugs.sourceforge.net/bugDescriptions.html > * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) > * Self comparison of field with itself (SA_FIELD_SELF_COMPARISON) > * Nonsensical self computation involving a field (e.g., x & x) > (SA_FIELD_SELF_COMPUTATION) > * Self assignment of local variable (SA_LOCAL_SELF_ASSIGNMENT) > * Nonsensical self computation involving a variable (e.g., x & x) > (SA_LOCAL_SELF_COMPUTATION) > * Uninitialized read of field in constructor (UR_UNINIT_READ) > * Unwritten field (UWF_UNWRITTEN_FIELD) > * Dead store to local variable (DLS_DEAD_LOCAL_STORE) > * Dead store of null to local variable (DLS_DEAD_LOCAL_STORE_OF_NULL) > > > > URL FOR PROTOTYPE (optional): > > http://slm888.com/javac > > > > DESIGN ALTERNATIVES: > > The following variations have been explored and are worth mentioning: > > * Allow auto-assignment parameters on all non-abstract methods. > This may be especially useful on the extremely common 'setter' > methods > in 'value object' classes. > > * Remove the requirement for (or even disallow) the type to be > specified on > auto-assignment parameters. > Experimentation with this idea suggests that it may work quite > well for > constructors, further emphasising the difference in intent and > semantics > from those of normal parameters. However, it may not work so well in > combination with auto-assignment parameters on all non-abstract > methods, and > requires a change to the order in which javac compiles classes (can > still > pass jtreg tests). > > * Allow an alternative name to be specified. > This adds additional complexity to support a fractional > percentage of > cases, which could continue to use the existing coding pattern. > From markmahieu at googlemail.com Tue Mar 24 19:20:14 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 25 Mar 2009 02:20:14 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: Message-ID: 2009/3/25 Reinier Zwitserloot > I like where this is going, but I'd rather see a bigger setup for auto-POJO > classes. I don't think the two approaches conflict. One of the sneaky aims of auto-assignment parameters is to encourage people to write classes with decent constructors (by making it a bit easier to do so) - such that an instance will only be in a valid state when the constructor finishes. An approach such as the one you suggest (if and when there's an opportunity to add it to the language) could then generate getters, but no setters, which is complementary in my view. Mark From javalists at cbfiddle.com Tue Mar 24 20:16:50 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Tue, 24 Mar 2009 20:16:50 -0700 (PDT) Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions Message-ID: <56957.69.239.104.86.1237951010.squirrel@69.239.104.86> Unchecked Exceptions as Subclasses of Checked Exceptions AUTHOR: Alan Snyder OVERVIEW FEATURE SUMMARY: This proposal would allow the definition of an unchecked exception class that extends a checked exception class. MAJOR ADVANTAGE: Unchecked exception classes are useful when an exception must be thrown through an existing interface that does not declare any checked exceptions or an appropriate checked exception. If one can define both an unchecked exception class and a corresponding checked exception class such that the unchecked exception class extends the checked exception class, then the unchecked exception will be caught by a try statement that catches the checked exception. MAJOR BENEFIT: Programs do not have to explictly catch both the unchecked and checked exceptions. Most developers need only be aware of the checked exception. MAJOR DISADVANTAGE: A new marker interface (or equivalent) must be defined and the definition of unchecked exceptions changed. ALTERNATIVES: The alternative is to always explicitly catch both the unchecked and checked exceptions, which introduces a likely source of programming errors. EXAMPLE: This proposal uses a marker interface as an alternative way (besides subclassing RuntimeException and Error) of indicating that an exception class defines an unchecked exception. The following would define a checked exception and an unchecked exception that extends the checked exception: public class TheCheckedException extends Exception {}; public class TheUncheckedException extends TheCheckedException implements UncheckedException {}; There is no advanced usage. DETAILS SPECIFICATION: The JLS would be changed to add one more way to define an unchecked exception. JLS 11.2 The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes. would become The unchecked exceptions classes are the class RuntimeException and its subclasses, the class Error and its subclasses, and those subclasses of Exception that implement the UncheckedException interface. All other exception classes are checked exception classes. JLS 11.5 The subclasses of Exception other than RuntimeException are all checked exception classes. would become The subclasses of Exception other than RuntimeException are checked exception classes, unless they implement the UncheckedException interface. The marker interface UncheckedException would have to be defined in some java package, with java.lang being the obvious choice. COMPILATION: The compiler would have to be extended to recognize the new category of unchecked exceptions. I'm not aware of other changes. COMPATIBILITY The major compatibility issue arises from the introduction of a new name in the class name space. That could potentially cause a program to fail to compile if it imported a class with the name UncheckedException using a wild card import statement. There could also be programs that examine the class hierarchy using reflection that would not recognize some exception classes as being unchecked. From jeremy.manson at gmail.com Tue Mar 24 22:21:15 2009 From: jeremy.manson at gmail.com (Jeremy Manson) Date: Tue, 24 Mar 2009 22:21:15 -0700 Subject: REQUEST: better empty catch in better exception handling In-Reply-To: References: Message-ID: <1631da7d0903242221i790dc1a2xb35c99c27632d672@mail.gmail.com> Do people do empty catch blocks by mistake? They always think it is right, even if it isn't. I just imagine people sprinkling this annotation everywhere and not getting anything out of it. Jeremy On Tue, Mar 24, 2009 at 6:22 PM, wrote: > > ?Yet one problem with extension handler: rare we need catch exception but do > nothibg in catch statement. (i. e. do not log) > Example is code like next snipset: > > try { > ?something=searchFirst(condition); > }catch(NotFoundException ex){ > ?// do nothing. search better > } > > if (something!=null) { > ?try { > ?something=searchSecond(condition); > ?}catch(NotFoundException ex){ > ?// do nothing. search better > ?} > } > > >From other side, we prefer do not have in codebase code with empty > exception handling and use special tools to detect empty catch braclets > and warn about ones. > ?For now, ? we use ';' to mark, that this empty catch is really empty > catch and not error or unfinished refactoring. I.e.: > > if (something!=null) { > ?try { > ?something=searchSecond(condition); > ?}catch(NotFoundException ex){ > ?// do nothing. search better > ?; ?// ';' tell javachecker do not complain about empty catch. > ?} > } > > > But this is ugly. > Of course, is simple use annotation > @SuppressWarning("empty-catch") ?but javac compiler does not warn about > empty catch-s. > > So, question to community: is it possible to extend exception handling > proposal by adding optional conventions > ?- warn about empty catch-s > ?- specify rare cases, when empty catch is really needed. ? > > For example, this can be @EmptyCatch annotation, which mark catch block > empty. i.e. > try { > > }catch(@EmptyCatch ?NotFound | FoundNotAsILike ex ){ > } > and effective do nothing. > > > > > > From rssh at gradsoft.com.ua Tue Mar 24 22:41:33 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 07:41:33 +0200 (EET) Subject: REQUEST: better empty catch in better exception handling In-Reply-To: <1631da7d0903242221i790dc1a2xb35c99c27632d672@mail.gmail.com> References: <1631da7d0903242221i790dc1a2xb35c99c27632d672@mail.gmail.com> Message-ID: <47aea8122a0a380a9bfacd4ae46e8739.squirrel@wmail.gradsoft.ua> > Do people do empty catch blocks by mistake? They always think it is > right, even if it isn't. I just imagine people sprinkling this > annotation everywhere and not getting anything out of it. > Yes, this is possible. But it's shows, that somebody at least seen this empty catch on exception, warned that empty catch are extremally rare and do decision: add exception handling code or such annotation. I. e. this is not ideal, but better than nothing. I'm afraid than more ambitious target (let's compiler automatically distinguish difference between empty catch block by mistake and by need) is too hard for solving during this week. > Jeremy > > On Tue, Mar 24, 2009 at 6:22 PM, wrote: >> >> ?Yet one problem with extension handler: rare we need catch exception >> but do >> nothibg in catch statement. (i. e. do not log) >> Example is code like next snipset: >> >> try { >> ?something=searchFirst(condition); >> }catch(NotFoundException ex){ >> ?// do nothing. search better >> } >> >> if (something!=null) { >> ?try { >> ?something=searchSecond(condition); >> ?}catch(NotFoundException ex){ >> ?// do nothing. search better >> ?} >> } >> >> >From other side, we prefer do not have in codebase code with empty >> exception handling and use special tools to detect empty catch braclets >> and warn about ones. >> ?For now, ? we use ';' to mark, that this empty catch is really empty >> catch and not error or unfinished refactoring. I.e.: >> >> if (something!=null) { >> ?try { >> ?something=searchSecond(condition); >> ?}catch(NotFoundException ex){ >> ?// do nothing. search better >> ?; ?// ';' tell javachecker do not complain about empty catch. >> ?} >> } >> >> >> But this is ugly. >> Of course, is simple use annotation >> @SuppressWarning("empty-catch") ?but javac compiler does not warn about >> empty catch-s. >> >> So, question to community: is it possible to extend exception handling >> proposal by adding optional conventions >> ?- warn about empty catch-s >> ?- specify rare cases, when empty catch is really needed. ? >> >> For example, this can be @EmptyCatch annotation, which mark catch block >> empty. i.e. >> try { >> >> }catch(@EmptyCatch ?NotFound | FoundNotAsILike ex ){ >> } >> and effective do nothing. >> >> >> >> >> >> > From noel at peralex.com Wed Mar 25 01:37:25 2009 From: noel at peralex.com (Noel Grandin) Date: Wed, 25 Mar 2009 10:37:25 +0200 Subject: Proposal: @Unloadable Class defination In-Reply-To: <49C93D80.3080901@sun.com> References: <49C93D80.3080901@sun.com> Message-ID: <49C9ED45.4000004@peralex.com> It seems that this use-case would be better solved by using WeakReferences and loading binary data using Class#getResource for any large static data that is easily regenerated. Regards, Noel. Tom Hawtin wrote: > Daniel Cheng wrote: > > >> MAJOR ADVANTAGE: >> >> Developer may define some class as @Unloadable can be unloaded when needed. >> >> MAJOR BENEFIT: >> >> Currently, VM are not allow to unload Class with reachable >> ClassLoader, this is required for "static variable" to be keep. But >> this means Class have to keep in memory even if the class is rarely >> used. Sometimes, the value static variable can be recreated at any >> time, >> > > I'm not entirely sure what you intend this to be used for. > > Do you want normal pieces of application code unloaded? > > Do you want large blobs of static data to be unloaded? In which case > don't you want more fine control over that? > > Do you want small pieces of generated code to be unloaded? Perhaps > individual class loaders are more appropriate. > > Tom Hawtin > > > Disclaimer: http://www.peralex.com/disclaimer.html From brucechapman at paradise.net.nz Wed Mar 25 01:43:47 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Wed, 25 Mar 2009 21:43:47 +1300 Subject: Unsigned byte sidestep - introduction Message-ID: <49C9EEC3.9020309@paradise.net.nz> Hello all, I am about to submit 3 proposals which are related. This email serves to background the 3 proposals The proposals are my best attempt at solving the no unsigned byte dilemma in a way that fits the existing language. After much thought I have identified two root issues which cause me to want unsigned byte. The proposals address these issues without actually add unsigned bytes. The first root issue is the lack of byte size literals, so byte literals must be formed by a narrowing conversion (cast) from an int literal. The cast in this case can increase the code by over 100% and is particularly onerous when populating byte arrays with fixed values, often during testing but in other cases as well. I have two competing proposals for byte (and short) integer literals with different advantages and disadvantages. These are mutually exclusive proposals (but under the coin rules they can't really refer to each other - hence this email). One of these has a nicer syntax at the expense of a more complex specification and narrower focus (it doesn't support decimal byte literals). The second root issue is the automatic widening conversion to int whenever a byte field or variable is used in an expression. It is not so much the widening, but the implicit sign extend which causes problems which bite when least expected. The third proposal adds an operator (cast like operator) to convert byte (and short) to int with zero extend to reduce the pain of the second issue. Here is an example showing some of the present traps. byte b = (byte)0x80; // cast needed because 0x80 is int and wont fit // in signed bit assert b == 0x80; // throw AssertionError because == causes the value // of b to be converted to int value 0xFFFFFF80 Here are the google doc references, I'll post content soon. Auto Typing Hexadecimal and Binary Integer Literals : 0hFF http://docs.google.com/Doc?id=dcvp3mkv_125ww5tct Byte and Short Integer Literals (new type suffixes) : 0xFFy http://docs.google.com/Doc?id=dcvp3mkv_0fvz5gx7b Unsigned Integer Widening Operator : (+) http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf Bruce From brucechapman at paradise.net.nz Wed Mar 25 01:57:24 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Wed, 25 Mar 2009 21:57:24 +1300 Subject: PROPOSAL Narrow Hexadecimal and Binary Integer Literals. Message-ID: <49C9F1F4.5050906@paradise.net.nz> Title Auto Typing Hexadecimal and Binary Integer Literals. latest html version at http://docs.google.com/Doc?id=dcvp3mkv_125ww5tct AUTHOR(S): Bruce Chapman OVERVIEW FEATURE SUMMARY: Introduce two new forms of integer literals, for hexadecimal and binary that are typed as the minimum width integer that can accomodate the value. MAJOR ADVANTAGE: Allows for binary literals and allows for byte size and short size hex literals with a concise syntax. byte[] stuff = { 0x00, 0x7F, (byte)0x80, (byte)0xFF}; can be recoded as byte[] ufum7 = { 0h00, 0h7F, 0h80, 0hFF }; MAJOR DISADVANTAGE: Introduces a second form of hexadecimal literal with overlapping functionality. ALTERNATIVES: Introduce a new new integer type literal suffix for byte and short, and a new syntax for binary integers. EXAMPLES SIMPLE EXAMPLE: byte[] utf8bom7 = { 0hEF, 0hBB, 0b10111111 }; ADVANCED EXAMPLE: byte[] buffer = ...; if(buffer[i] == 0hBB) { ... } DETAILS SPECIFICATION: JSL Section 3.10.1 needs considerable rewrite An integer literal may be expressed in decimal (base 10), hexadecimal (base 16)(two ways), or octal (base 8), or binary (base 2): IntegerLiteral: FixedIntegerLiteral NarrowIntegerLiteral FixedIntegerLiteral: DecimalIntegerLiteral HexIntegerLiteral OctalIntegerLiteral NarrowIntegerLiteral: NarrowHexIntegerLiteral NarrowBinaryIntegerLiteral DecimalIntegerLiteral: DecimalNumeral IntegerTypeSuffixopt HexIntegerLiteral: HexNumeral IntegerTypeSuffixopt OctalIntegerLiteral: OctalNumeral IntegerTypeSuffixopt IntegerTypeSuffix: one of l L NarrowHexIntegerLiteral: 0 h HexDigits 0 H HexDigits NarrowBinaryIntegerLiteral: 0 b BinaryDigits 0 B BinaryDigits BinaryDigits: BinaryDigit BinaryDigit BinaryDigits BinaryDigit: one of 0 1 An fixed integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (?4.2.1). The suffix L is preferred, because the letter l (ell) is often hard to distinguish from the digit 1 (one). A narrow integer literal has the smallest integer type able to accomodate the number of HexDigits or BinaryDigits specified, including leading zeros. For 1 or 2 HexDigits and for 1 through 8 binary digits the type is byte. For 3 or 4 Hex digits or from 9 through 16 binary digits the type is short. For 5 through 8 hex digits and for 17 through 32 binary digits the type is integer and for 9 through 16 hex digits and 33 through 64 binary digits the type is long. A compile time error occurs if more than 16 hex digits or 64 binary digits are specified. Narrow integer literals may not use an Integer type suffix, their type is determined by the number of digits. A decimal numeral is either the single ASCII character 0, representing the integer zero, or consists of an ASCII digit from 1 to 9, optionally followed by one or more ASCII digits from 0 to 9, representing a positive integer: DecimalNumeral: 0 NonZeroDigit Digitsopt Digits: Digit Digits Digit Digit: 0 NonZeroDigit NonZeroDigit: one of 1 2 3 4 5 6 7 8 9 A hexadecimal numeral consists of the leading ASCII characters 0x or 0X followed by one or more ASCII hexadecimal digits and can represent a positive, zero, or negative integer. Hexadecimal digits with values 10 through 15 are represented by the ASCII letters a through f or A through F, respectively; each letter used as a hexadecimal digit may be uppercase or lowercase. HexNumeral: 0 x HexDigits 0 X HexDigits HexDigits: HexDigit HexDigit HexDigits COMPILATION: Two new forms of Integer literal need to be processed in scanner, and the sizing algorithm applied. TESTING: Exercise and check types and values of various narrow integer literals. LIBRARY SUPPORT: No library support required. REFLECTIVE APIS: None OTHER CHANGES: None - but it might be nice if the javadoc tool remembered the number base of Integer constants for constant fields and displayed them in that same base in the Constant Field Values list. MIGRATION: COMPATIBILITY BREAKING CHANGES: None EXISTING PROGRAMS: None REFERENCES EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 http://forums.sun.com/thread.jspa?forumID=316&messageID=2239381&threadID=480508 URL FOR PROTOTYPE (optional): None From brucechapman at paradise.net.nz Wed Mar 25 01:59:43 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Wed, 25 Mar 2009 21:59:43 +1300 Subject: PROPOSAL: Byte and Short Integer Literal Suffixes Message-ID: <49C9F27F.7090006@paradise.net.nz> TITLE: Byte and Short Integer Literal Suffixes latest html version at http://docs.google.com/Doc?docid=dcvp3mkv_0fvz5gx7b&hl AUTHOR(S): Bruce Chapman OVERVIEW Problems occur when trying to create literal byte values for known bit patterns because byte is signed therefore 0x80 thru 0xFF are not valid byte values. Working with bytes (binary files, network communications) can be simplified by allowing byte size integer literals (and short for consistency). Specifically allow hexadecimal byte literals, others for completeness. FEATURE SUMMARY: Allow byte and short integer literals by introducing 4 new integer type suffixes 'y' & 'Y' for bytes, 's' & 'S' for shorts. MAJOR ADVANTAGE: Somewhat reduces the pain resulting from byte being a signed type, removes the need to downcast integer literals to byte or short. MAJOR BENEFIT: Why is the platform better if the proposal is adopted? cruddy code like byte[] stuff = { 0x00, 0x7F, (byte)0x80, (byte)0xFF}; can be recoded as byte[] ufum7 = { 0x00y, 0x7Fy, 0x80y, 0xFFy }; MAJOR DISADVANTAGE: Some familiarisation curve required before the syntax stops looking slightly odd. Would prefer to but cannot use 'B' as Integral type suffix because it is a hexadecimal digit, 'Y' can be used but is slightly esoteric, but probably no more so than 'X' for hexadecimal prefix. ALTERNATIVES: An alternative language change would be to have hexadecimal integer literals that are typed according to the number of digits. EXAMPLES Show us the code! SIMPLE EXAMPLE: byte[] utf8bom7 = { 0xEFy, 0xBBy, 0xBFy }; ADVANCED EXAMPLE: byte[] buffer = ...; if(buffer[i] == 0xBBy) { // never equal with 0xBB ... } DETAILS SPECIFICATION: "3.10.1 Integer literals" is amended as follows - additions in bold. IntegerTypeSuffix: one of l L y Y s S An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell), of type short if it is suffixed with an ASCII letter S or s and of type byte if it is suffixed with an ASCII letter Y or y; otherwise it is of type int (?4.2.1). For long literals the suffix L is preferred, because the letter l (ell) is often hard to distinguish from the digit 1 (one). and at the end of 3.10.1 add A compile-time error occurs if a decimal literal of type short is larger than 32767 (215), or if the literal 32767 appears anywhere other than as the operand of the unary - operator, or if a hexadecimal or octal short literal does not fit in 16 bits. A compile-time error occurs if a decimal literal of type byte is larger than 128 (27), or if the literal 128 appears anywhere other than as the operand of the unary - operator, or if a hexadecimal or octal byte literal does not fit in 8 bits. 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! TESTING: How can the feature be tested? LIBRARY SUPPORT: No library support required. 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. 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. MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. 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? REFERENCES EXISTING BUGS: Please include a list of any existing Sun bug ids related to this proposal. URL FOR PROTOTYPE (optional): From brucechapman at paradise.net.nz Wed Mar 25 02:02:06 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Wed, 25 Mar 2009 22:02:06 +1300 Subject: PROPOSAL: Unsigned Integer Widening Operator Message-ID: <49C9F30E.2020008@paradise.net.nz> Title Unsigned Integer Widening Operator latest html version at http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf&hl AUTHOR(S): Bruce Chapman OVERVIEW FEATURE SUMMARY: Add an unsigned widening operator to convert bytes (in particular), shorts, and chars (for completeness) to int while avoiding sign extension. MAJOR ADVANTAGE: Byte manipulation code becomes littered with (b & 0xFF) expressions in order to reverse the sign extension that occurs when a byte field or variable or array access appears on either side of an operator and is thus subject to widening conversion with its implicit sign extension. This masking with 0xFF can detract from the clarity of the code by masking the actual algorithm. It is the Java Language's rules and not the algorithm itself that demand this masking operation which can appear to be a redundant operation to the uninitiated. It is highly intentional that the new operator (+) can be read as a cast to a positive. MAJOR DISADVANTAGE: A new operator. ALTERNATIVES: explicit masking. If java.nio.ByteBuffer was extensible (it isn't) unsigned get and set methods could be added to hide the masking in an API. Extension methods could be employed to that end if they were implemented. EXAMPLES SIMPLE EXAMPLE: byte[] buffer = ...; int idx=...; int length=...; int value=0; for(int i = idx; i < idx + length; i++) { value = (value << 8) | (buffer[i] & 0xff); } can be recoded as for(int i = idx; i < idx + length; i++) { value = (value << 8) | (+)buffer[i]; } ADVANCED EXAMPLE: private int getBerValueLength(byte[] contents, int idx) { if((contents[idx] & 0x80) == 0) return contents[idx]; int lenlen = (+)contents[idx] ^ 0x80; // invert high bit which = 1 int result=0; for(int i = idx+1; i < idx + 1 + lenlen; i++ ) { result = (result << 8) | (+)contents[i]; } return result; } DETAILS SPECIFICATION: amend 15.15 The unary operators include +, -, ++, --, ~, !, unsigned integer widening operator and cast operators. add the following to the grammars in 15.15 The following productions from ?new section are repeated here for convenience: UnsignedWideningExpression: UnsignedIntegerWideningOperator UnaryExpression UnsignedIntegerWideningOperator: ( + ) Add a new section to 15 - between "15.15 Unary Expressions" and "15.16 Cast Expressions" would seem ideal in terms of context and precedence level. The unsigned integer widening operator is a unary operator which may be applied to expressions of type byte, short and char. It is a compile time error to apply this operator to other types. UnsignedWideningExpression: UnsignedIntegerWideningOperator UnaryExpression UnsignedIntegerWideningOperator: ( + ) The unsigned integer widening operator converts its operand to type int. Unary numeric promotion (?) is NOT performed on the operand. For a byte operand, the lower order 8 bits of the resultant have the same values as in the operand. For short and char operands, the resultant's lower order 16 bits have the same value as the operand's. The remaining high order bits are set to zero. This is effectively a zero extend widening conversion and is equivalent to the following expression for byte operand x, x & 0xFF and equivalent to the following for a short or char operand y y & 0xFFFF Other sections have lists of operators for which various things apply. Add to these as appropriate - yet to be determined. Note the specification above could also be ammended to allow the operator to zero extend an int to a long, however the utility value of this is uncertain. COMPILATION: Compilation may be equivalent to the masking operation above. Hotspot could detect the redundant sign extend followed by masking out the sign extended bits and remove both. If that were the case the operator could be applied to every access of a byte field, variable or array to indicate treatment as unsigned byte, with no cost. For a char, the operator is equivalent to a widening conversion to int. The new operator is permitted on a char expression because there is no reason to disallow it. However it would be equally effective if it did not apply to char. TESTING: There are no gnarly use cases, so testing is straight forward. It could be as simple as compiling and executing a main class with a handful of asserts. LIBRARY SUPPORT: No library support required. REFLECTIVE APIS: None OTHER CHANGES: none foreseen MIGRATION: COMPATIBILITY BREAKING CHANGES: None EXISTING PROGRAMS: Tools could detect the specific masking operations used to zero extend a previously sign extended byte or short, and replace that with the new operator. REFERENCES EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4186775 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4879804 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504839 URL FOR PROTOTYPE (optional): None From brucechapman at paradise.net.nz Wed Mar 25 02:07:38 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Wed, 25 Mar 2009 22:07:38 +1300 Subject: REQUEST: better empty catch in better exception handling In-Reply-To: References: Message-ID: <49C9F45A.1050300@paradise.net.nz> I think a better solution to this problem is to add a new method to Throwable thus public final void ignore() {} And then you can explicitly ignore an exception like this }catch(SomeException ex){ ex.ignore(); } I would hope that hotspot could inline that quite easily :) I intend to suggest this for the small API changes process which is coming soon. Bruce rssh at gradsoft.com.ua wrote: > Yet one problem with extension handler: rare we need catch exception but do > nothibg in catch statement. (i. e. do not log) > Example is code like next snipset: > > try { > something=searchFirst(condition); > }catch(NotFoundException ex){ > // do nothing. search better > } > > if (something!=null) { > try { > something=searchSecond(condition); > }catch(NotFoundException ex){ > // do nothing. search better > } > } > > >From other side, we prefer do not have in codebase code with empty > exception handling and use special tools to detect empty catch braclets > and warn about ones. > For now, we use ';' to mark, that this empty catch is really empty > catch and not error or unfinished refactoring. I.e.: > > if (something!=null) { > try { > something=searchSecond(condition); > }catch(NotFoundException ex){ > // do nothing. search better > ; // ';' tell javachecker do not complain about empty catch. > } > } > > > But this is ugly. > Of course, is simple use annotation > @SuppressWarning("empty-catch") but javac compiler does not warn about > empty catch-s. > > So, question to community: is it possible to extend exception handling > proposal by adding optional conventions > - warn about empty catch-s > - specify rare cases, when empty catch is really needed. ? > > For example, this can be @EmptyCatch annotation, which mark catch block > empty. i.e. > try { > > }catch(@EmptyCatch NotFound | FoundNotAsILike ex ){ > } > and effective do nothing. > > > > > > From rssh at gradsoft.com.ua Wed Mar 25 02:24:59 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 11:24:59 +0200 (EET) Subject: REQUEST: better empty catch in better exception handling In-Reply-To: <49C9F45A.1050300@paradise.net.nz> References: <49C9F45A.1050300@paradise.net.nz> Message-ID: <0b3736f57029140427c6bef691d94b90.squirrel@wmail.gradsoft.ua> > I think a better solution to this problem is to add a new method to > Throwable thus > > public final void ignore() {} > > And then you can explicitly ignore an exception like this > > }catch(SomeException ex){ > ex.ignore(); > } > > I would hope that hotspot could inline that quite easily :) > > I intend to suggest this for the small API changes process which is > coming soon. > Great ! > Bruce > > rssh at gradsoft.com.ua wrote: >> Yet one problem with extension handler: rare we need catch exception >> but do >> nothibg in catch statement. (i. e. do not log) >> Example is code like next snipset: >> >> try { >> something=searchFirst(condition); >> }catch(NotFoundException ex){ >> // do nothing. search better >> } >> >> if (something!=null) { >> try { >> something=searchSecond(condition); >> }catch(NotFoundException ex){ >> // do nothing. search better >> } >> } >> >> >From other side, we prefer do not have in codebase code with empty >> exception handling and use special tools to detect empty catch braclets >> and warn about ones. >> For now, we use ';' to mark, that this empty catch is really empty >> catch and not error or unfinished refactoring. I.e.: >> >> if (something!=null) { >> try { >> something=searchSecond(condition); >> }catch(NotFoundException ex){ >> // do nothing. search better >> ; // ';' tell javachecker do not complain about empty catch. >> } >> } >> >> >> But this is ugly. >> Of course, is simple use annotation >> @SuppressWarning("empty-catch") but javac compiler does not warn about >> empty catch-s. >> >> So, question to community: is it possible to extend exception handling >> proposal by adding optional conventions >> - warn about empty catch-s >> - specify rare cases, when empty catch is really needed. ? >> >> For example, this can be @EmptyCatch annotation, which mark catch block >> empty. i.e. >> try { >> >> }catch(@EmptyCatch NotFound | FoundNotAsILike ex ){ >> } >> and effective do nothing. >> >> >> >> >> >> > > From david.goodenough at linkchoose.co.uk Wed Mar 25 02:29:19 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Wed, 25 Mar 2009 09:29:19 +0000 Subject: For further consideration... In-Reply-To: <49C95DB5.6020202@sun.com> References: <49C95DB5.6020202@sun.com> Message-ID: <200903250929.20256.david.goodenough@linkchoose.co.uk> On Tuesday 24 March 2009, Joe Darcy wrote: > Greetings. > > In the first three weeks of Project Coin over two dozen proposals have > been sent to the mailing list for evaluation. The proposals have ranged > the gamut from new kinds of expressions, to new statements forms, to > improved generics support. Thanks to everyone who has sent in > interesting, thoughtful proposals and contributed to informative > discussions on the list! > > While there is a bit less than a week left in the call for proposals > period, there has been enough discussion on the list to winnow the slate > of proposals sent in so far to those that merit further consideration > for possible inclusion in the platform. > > First, Bruce Chapman's proposal to extend the scope of imports to > include package annotations will be implemented under JLS maintenance so > further action is unnecessary on this matter as part of Project Coin. > Second, since the JSR 294 expert group is discussing adding a module > level of accessibility to the language, the decision of whether or not > to include Adrian Kuhn's proposal of letting "package" explicitly name > the default accessibility level will be deferred to that body. Working > with Alex, I reviewed the remaining proposals. Sun believes that the > following proposals are small enough, have favorable estimated reward to > effort ratios, and advance the stated criteria of making things > programmers do everyday easier or supporting platform changes in JDK 7: > > * Strings in switch, Joe Darcy > * Improved Exception Handling for Java, Neal Gafter > * Automatic Resource Management, Josh Bloch > * Improved Type Inference for Generic Instance Creation, > Jeremy Manson > * Elvis and Other Null-Safe Operators, > Written by Neal Gafter and submitted by Stephen Colebourne > * Simplified Varargs Method Invocation, Bob Lee > > As this is just an initial cut and the proposals are not yet in a form > suitable for direct inclusion in the JLS, work should continue to refine > these proposed specifications and preferably also to produce prototype > implementations to allow a more thorough evaluation of the utility and > scope of the changes. The email list should focus on improving the > selected proposals and on getting any remaining new proposals submitted; > continued discussion of the other proposals is discouraged. > > The final list of small language changes will be determined after the > call for proposals is over so proposals sent in this week are certainly > still in the running! The final list will only have around five items > so it is possible not all the changes above will be on the eventual > final list. > > -Joe I realise that as you say the list is not final, but looking at the list of items my lightweight properties proposal is (at least to my eyes) considerably smaller than most of the provisional list. It is smaller in respect to all of the changes to the language, the changes to the library and the changes to the compiler. I realise that anything mentioning properties is mired in history and that there seems to be a "do it all or don't touch it" approach to the problem which is a problem because the result is that it will not happen for (to be realistic) at least 5 years. I also realise that the proposal is perhaps not written with detail updates to the JLS etc, but I have never been involved in such things and would hesitate to try to write them up properly. If this is needed then I am sure it can be done. I am more than happy to work with anyone prepared to give constructive help. I would therefore be interested to know why my proposal is not being considered. I believe I have shown need (BeanBindings, Criteria and PropertyChangeSupport uncheckable string literals for field names). It is also in the spirit of Java and one of great strengths (compiler/ide checkability). David From noel at peralex.com Wed Mar 25 03:30:43 2009 From: noel at peralex.com (Noel Grandin) Date: Wed, 25 Mar 2009 12:30:43 +0200 Subject: PROPOSAL: Unsigned Integer Widening Operator In-Reply-To: <49C9F30E.2020008@paradise.net.nz> References: <49C9F30E.2020008@paradise.net.nz> Message-ID: <49CA07D3.8090909@peralex.com> I would think that a utility class that performed widening operations, and maybe some other useful stuff would be preferable to extending the language/ Perhaps a BinaryMath class to live alongside java.lang.Math? Regards, Noel. Bruce Chapman wrote: > Title > Unsigned Integer Widening Operator > > latest html version at http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf&hl > > AUTHOR(S): Bruce Chapman > > OVERVIEW > > > > FEATURE SUMMARY: > Add an unsigned widening operator to convert bytes (in particular), > shorts, and chars (for completeness) to int while avoiding sign extension. > > > MAJOR ADVANTAGE: > > Byte manipulation code becomes littered with (b & 0xFF) expressions in > order to reverse the sign extension that occurs when a byte field or > variable or array access appears on either side of an operator and is > thus subject to widening conversion with its implicit sign extension. > This masking with 0xFF can detract from the clarity of the code by > masking the actual algorithm. It is the Java Language's rules and not > the algorithm itself that demand this masking operation which can appear > to be a redundant operation to the uninitiated. > > > It is highly intentional that the new operator (+) can be read as a cast > to a positive. > > > > MAJOR DISADVANTAGE: > A new operator. > > > ALTERNATIVES: > > explicit masking. If java.nio.ByteBuffer was extensible (it isn't) > unsigned get and set methods could be added to hide the masking in an > API. Extension methods could be employed to that end if they were > implemented. > > EXAMPLES > SIMPLE EXAMPLE: > > byte[] buffer = ...; int idx=...; int length=...; > > int value=0; > > for(int i = idx; i < idx + length; i++) { > value = (value << 8) | (buffer[i] & 0xff); > } > > can be recoded as > > > for(int i = idx; i < idx + length; i++) { > value = (value << 8) | (+)buffer[i]; > } > > > ADVANCED EXAMPLE: > > private int getBerValueLength(byte[] contents, int idx) { > if((contents[idx] & 0x80) == 0) return contents[idx]; > int lenlen = (+)contents[idx] ^ 0x80; // invert high bit which = 1 > int result=0; > for(int i = idx+1; i < idx + 1 + lenlen; i++ ) { > result = (result << 8) | (+)contents[i]; > } > return result; > } > > DETAILS > SPECIFICATION: > > amend 15.15 > > The unary operators include +, -, ++, --, ~, !, unsigned integer > widening operator and cast operators. > > > > add the following to the grammars in 15.15 > > > > The following productions from ?new section are repeated here for > convenience: > > > UnsignedWideningExpression: > > UnsignedIntegerWideningOperator UnaryExpression > > > UnsignedIntegerWideningOperator: > > ( + ) > > > > Add a new section to 15 - between "15.15 Unary Expressions" and "15.16 > Cast Expressions" would seem ideal in terms of context and precedence level. > > > The unsigned integer widening operator is a unary operator which may be > applied to expressions of type byte, short and char. It is a compile > time error to apply this operator to other types. > > > UnsignedWideningExpression: > > UnsignedIntegerWideningOperator UnaryExpression > > > UnsignedIntegerWideningOperator: > > ( + ) > > > The unsigned integer widening operator converts its operand to type int. > Unary numeric promotion (?) is NOT performed on the operand. For a byte > operand, the lower order 8 bits of the resultant have the same values as > in the operand. For short and char operands, the resultant's lower order > 16 bits have the same value as the operand's. The remaining high order > bits are set to zero. This is effectively a zero extend widening > conversion and is equivalent to the following expression for byte operand x, > > x & 0xFF > > and equivalent to the following for a short or char operand y > > y & 0xFFFF > > > Other sections have lists of operators for which various things apply. > Add to these as appropriate - yet to be determined. > > Note the specification above could also be ammended to allow the > operator to zero extend an int to a long, however the utility value of > this is uncertain. > COMPILATION: > > Compilation may be equivalent to the masking operation above. Hotspot > could detect the redundant sign extend followed by masking out the sign > extended bits and remove both. If that were the case the operator could > be applied to every access of a byte field, variable or array to > indicate treatment as unsigned byte, with no cost. > > > For a char, the operator is equivalent to a widening conversion to int. > The new operator is permitted on a char expression because there is no > reason to disallow it. However it would be equally effective if it did > not apply to char. > > > TESTING: > > There are no gnarly use cases, so testing is straight forward. It could > be as simple as compiling and executing a main class with a handful of > asserts. > > LIBRARY SUPPORT: > > No library support required. > > REFLECTIVE APIS: > > None > > OTHER CHANGES: > > none foreseen > > MIGRATION: > > COMPATIBILITY > BREAKING CHANGES: > > None > > EXISTING PROGRAMS: > > Tools could detect the specific masking operations used to zero extend a > previously sign extended byte or short, and replace that with the new > operator. > > REFERENCES > EXISTING BUGS: > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4186775 > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4879804 > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504839 > > > URL FOR PROTOTYPE (optional): > None > > > > Disclaimer: http://www.peralex.com/disclaimer.html From scolebourne at joda.org Wed Mar 25 03:41:59 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 10:41:59 +0000 Subject: Any interest in raw strings? In-Reply-To: <3113C08A-DAA7-4638-8F18-340F3C2D338B@zwitserloot.com> References: <6aef848f0903241631x5a38a26dqbcf9107d3027b0f7@mail.gmail.com> <9df7013b651580a5faaf0b913f1f178b.squirrel@wmail.gradsoft.ua> <6aef848f0903241658q612a587ep5d8e85b8ea2597e@mail.gmail.com> <3113C08A-DAA7-4638-8F18-340F3C2D338B@zwitserloot.com> Message-ID: <4b4f45e00903250341p127faa25y6b16b0e5830ac0d8@mail.gmail.com> Personally, I would say that raw strings (prefixed by r, not multiline) were a good candidate for a Coin. The change would seem relatively small, and they compile to a standard String instance. I wouldn't especially like to see RegExp strings, as it ties the compiler too closely to one specific library. Stephen 2009/3/25 Reinier Zwitserloot : > Because raw strings are only used for regexps (it's so bad that people > think the 'r' in python's raw string syntax stands for regexp and not > raw), I suggested a while ago, on a different forum, to support regexp > literals, which would even get the benefit of compile-time checking > the regexp (there are a few things which are neccessarily a bad reg- > exp, such as mismatched parentheses), and possibly the compile-time > generation of the regexp literal to a regexp Thompson's tree, which > takes relatively long to build, but once built, can parse any string > through the regexp in O(n), where n is the length of the string. > > Back then there were some admittedly rare use-cases for raw strings > (including concatenating a regexp with a variable, which you couldn't > do with regexp literals), but there was no consensus on whether raw > strings, or regexp literals (or possibly both) were a good idea. > > I'd love me some raw (and multiline) strings, but this stuff is a bit > too tricky to sort out now, a month or two before java7RC1. > > ?--Reinier Zwitserloot > > > > On Mar 25, 2009, at 00:58, Vilya Harvey wrote: > >> Ah, I had a feeling I might have missed something. It looks like >> you've >> already covered everything I wanted to write up and more! I think >> multiline >> strings would be a useful addition too; it seems a shame that it >> won't be >> included in the Coin changes. >> >> Cheers, >> Vil. >> >> >> 2009/3/24 >> >>>> Hi all, >>>> >>>> I don't think I've seen a proposal for raw strings - string literals >>> which >>>> ignore escape sequences - yet. Would there be enough interest to >>>> write >>>> this >>>> up as a proposal? >>>> >>>> The idea is stolen shamelessly from Python, where you can write a >>>> raw >>>> string >>>> as r"[\n\r\t]" and it's equivalent to the normal string "[\\n\\r\ >>>> \t]" >>>> (i.e. >>>> you don't need to double the backslash in a raw string, it's just >>>> treated >>>> like any other character). This is most useful when writing regular >>>> expressions; in fact, it may *only* be useful then. But for that >>>> one case >>>> it >>>> is extremely handy. >>>> >>>> Any opinions? >>>> >>> >>> It was part of my enhanched string proposal >>> ?http://redmine.gradsoft.ua/wiki/java7stringliterals >>> >>> If creating new proposal only for unescaped strings (without >>> multiline) >>> can help (ask Darcy) -- than submit one. It woud be better than >>> nothing. >>> >>>> Vil. >>>> >>>> >>> >>> >>> >> > > > From rssh at gradsoft.com.ua Wed Mar 25 04:23:45 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 13:23:45 +0200 (EET) Subject: PRE-PROPOSAL: Simple operator overloading. Message-ID: Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk Probably too big, but anyway. As I remember, alternative proposal (made [] and []= syntax sugar on well-known interfaces, as with for-each loop) still not submitted. If anybody want submit such proposal, then it is possible to reuse JLS-changed for 15.26.1 from there. OVERVIEW: FEATURE SUMMARY: Add possibility to overloaded common subset of java operators for own classes. MAJOR ADVANTAGE: In many cases (especially for Collections and own subtypes of numeric) using operator syntax is more clear and simple, than call by name of method. MAJOR DISADVANTAGE Inaccurate usage of this feature can cause producing of code which hard to read. Compiler is slightly complex then before. ALTERNATIVES: Live without operators as before. EXAMPLES SIMPLE EXAMPLE: Example 1 import javax.lang.Operator; public class Z3 { public Z3(int value) { this.value = (value%3); } public Z3(Z3 z3) { this.value = z3.value; } @Operator("+") public Z3 plus(Z3 x) { return new Z3(value + x.value); } @Operator("+=") public Z3 plusAssign(Z3 x) { value=((value+x.value)%3); } @Operator("-") public Z3 minus(Z3 x) { return new Z3(value-x.value); } @Operator("-=") public Z3 minusAssign(Z3 x) { value=((value-x.value)%3); } private int value; } Usage: Z3 z3 = new Z3(2); Z3 z4 = z3+z3; Example 2 public interface Named { public String getName(); } public class IndexedCollection { IndexedCollection(int capacity) { byNames=new T[capacity]; byNames=new TreeMap(); } @Operator("[]"); public T get(int i) { return byIndexes.get(i); } @Operator("[]"); public T get(String name) { return byNames.get(i); } } @Operator("[]="); public void set(int i, T t) { byIndexes[i]=t; byNames[t.getName()]=t; } private T[] byIndexes; private Map byNames_; } Usage: class NVPair extends Named { public NVPair(String name, Object value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } private String name; private String value; } IndexedCollection pairs = new IndexedCollection(10); pairs[0]=new NVPair("CISCO-AV-Pair","lcp:interface=1"); pairs[1]=new NVPair("X",4); pairs[2]=new NVPair("Y",5); NVPair pair1=pairs[1]; NVPair pair2=pairs["X"]; ADVANCED EXAMPLE: Nothing advanced here. All simple. DETAILS: Add to Java Library @Operator method annotation with next signature: package java.lang.Annotation @Documented @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface Operator { public String value(); } Add to JLS chapter 9.6.1.7 about Operator annotation: The annotation type annotation.Operator(v) is used to indicate, that annotated method can be shortcated as operator in program test. v is String, which can be one of: ( "[]", "[]=", "+", "-", "~", "!", "*", "/", "%", "+=", "-=", "*=", "/=", %= ) Signature of operator method must be compatible with signature of operator, which means that methods, annotated as binary operators must be nonstatic member functions with one argument; unary operators - as nonstatic member functions without arguments. To chapter 15.13, instead: The type of the array reference expression must be an array type (call it T[], an array whose components are of type T) or a compile-time error results. The type of the array reference expression must be an array type (call it T[], an array whose components are of type T) or type of class with methods, annotated by @Operator("[]") or @Operator("[]=") annotations(call one class array reference expression) or a compile-time error occurs. 15.13.1 Runtime Evaluation of Array Access Instead: An array access expression is evaluated using the following procedure: * First, the array reference expression is evaluated. If this evaluation completes abruptly, then the array access completes abruptly for the same reason and the index expression is not evaluated. * Otherwise, the index expression is evaluated. If this evaluation completes abruptly, then the array access completes abruptly for the same reason. * Otherwise, if the value of the array reference expression is null, then a NullPointerException is thrown. * Otherwise, the value of the array reference expression indeed refers to an array. If the value of the index expression is less than zero, or greater than or equal to the array's length, then an ArrayIndexOutOfBoundsException is thrown. * Otherwise, the result of the array access is the variable of type T, within the array, selected by the value of the index expression. (Note that this resulting variable, which is a component of the array, is never considered final, even if the array reference expression is a final variable.) An array access expression is evaluated using the following procedure: * First, the array reference expression is evaluated. If this evaluation completes abruptly, then the array access completes abruptly for the same reason and the index expression is not evaluated. * Otherwise, o if array reference is array + the index expression is evaluated. If this evaluation completes abruptly, then the array access completes abruptly for the same reason. + Otherwise, if the value of the array reference expression is null, then a NullPointerException is thrown. + Otherwise, the value of the array reference expression indeed refers to an array. If the value of the index expression is less than zero, or greater than or equal to the array's length, then an ArrayIndexOutOfBoundsException is thrown. + Otherwise, the result of the array access is the variable of type T, within the array, selected by the value of the index expression. (Note that this resulting variable, which is a component of the array, is never considered final, even if the array reference expression is a final variable. o if array reference is object + if exists method, annotated as @Operator("[]=") and if such expression is situated at the left part of plain assigment expression X=Y, than this subexpression does not evaluated itself, instead components of array access expression take part in process of assigment. + otherwise, if exists set of methods for such class, annotated by @Operator("[]"), than better candidate from set of appropriative annotated methods is called, as specified in 15.12 (Method Invocation Expression) except check for name of method step. 15.15.5 Bitwise Complement Operator ~ The type of the operand expression of the unary ~ operator must be a type that is convertible (§5.1.8) to a primitive integral type, or class, which have non-static member functions without arguments, annotated by @Operator("~") , or a compile-time error occurs. If operand expression is convertable to a primitive integram type, than * Unary numeric promotion (§) is performed on the operand. The type of the unary bitwise complement expression is the promoted type of the operand. * At run time, the value of the unary bitwise complement expression is the bitwise complement of the promoted value of the operand; note that, in all cases, ~x equals (-x)-1 Otherwise, if exists methods for operand class, annotated by @Operator("~"), than appropriative methods is called, as specified in 15.12 ( except check for name of method step) and result type is type of method invocaton. 15.15.6 Logical Complement Operator ! The type of the operand expression of the unary ! operator must be boolean or Boolean, or or class, which have non-static member functions without arguments, annotated by @Operator("!") , or a compile-time error occurs. When type of the operand expression is boolean or Boolean, than * type unary logical complement expression is boolean, * At run time, the operand is subject to unboxing conversion (§5.1.8) if necessary; the value of the unary logical complement expression is true if the (possibly converted) operand value is false and false if the (possibly converted) operand value is true When type of the operand expression is class, which have non-static member functions without arguments, annotated by @Operator("!") than expression is processed as invocation of appropriative method. 15.17 Multiplicative Operators The operators *, /, and % are called the multiplicative operators. They have the same precedence and are syntactically left-associative (they group left-to-right). MultiplicativeExpression: UnaryExpression MultiplicativeExpression * UnaryExpression MultiplicativeExpression / UnaryExpression MultiplicativeExpression % UnaryExpression The type of each of the operands of a multiplicative operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or type of first operand must be a class, which have non-static methods with one argument, annotated by @Operator("*" or "/" or "%"), or compile-time error occurs. In case of types, convertible to promitive numeric type: Binary numeric promotion is performed on the operands (§5.6.2). The type of a multiplicative expression is the promoted type of its operands. If this promoted type is int or long, then integer arithmetic is performed; if this promoted type is float or double, then floating-point arithmetic is performed. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13). Chapter 15.17.1, 15.17.2, 15.17.3 just rename to Primitive Numeric Multiplication Operator, Primitive Numeric Division Operator and Primitive Numeric Remind operator. Add 15.17.4 Multiplicative Operators for class with operator-annotated methods. In case when type of first operand is class with method, annotated by appropreative annotations, than expression is processed as invocation expression ($15.2) from set of appropriative annotated methods, with value of opeeand annotations instean name of methods. 15.18 Additive Operators The operators + and - are called the additive operators. They have the same precedence and are syntactically left-associative (they group left-to-right). AdditiveExpression: MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression If the type of either operand of a + operator is String, then the operation is string concatenation. Otherwise, the type of each of the operands of the + operator must be a type that is convertible (§5.1.8) to a primitive numeric type. In every case, the type of each of the operands of the binary - operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or a compile-time error occurs. Otheriwise, the type of first operand must be a class with nonstatic member function with one argument, annotated by @Operator("+" or "-") or compile-time error occurs. add 15.18.3 Additive Operators for class with operator-annotated methods: In case when type of first operand is class with method, annotated by appropreative annotations, than expression is processed as invocation expression from set of appropriative annotated methods. 15.26 There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a. AssignmentExpression: ConditionalExpression Assignment Assignment: LeftHandSide AssignmentOperator AssignmentExpression LeftHandSide: ExpressionName FieldAccess ArrayAccess AssignmentOperator: one of = *= /= %= += -= <<= >>= >>>= &= ^= |= The result of the first operand of an assignment operator must be a variable, or class array reference expression ($15.3), or a compile-time error occurs. Variable operand may be a named variable, such as a local variable or a field of the current object or class, or it may be a computed variable, as can result from a field access (§15.11) or an array access (§15.13). The type of the assignment expression is the type of the variable after capture conversion (§5.1.10). 15.26.1 Simple Assignment Operator = A compile-time error occurs when * left hand operand expression is a value and the type of the right-hand operand cannot be converted to the type of the variable by assignment conversion (§5.2) * left hand operand expression is class array reference expression and type of right-hand operator cannot be converted to the type of second argument for one of methods, annotated with @Operator("[]=") annotation. At run time, the expression is evaluated in one of three ways: * If the left-hand operand expression is a field access expression (§15.11) e.f, possibly enclosed in one or more pairs of parentheses, then: o First, the expression e is evaluated. If evaluation of e completes abruptly, the assignment expression completes abruptly for the same reason. o Next, the right hand operand is evaluated. If evaluation of the right hand expression completes abruptly, the assignment expression completes abruptly for the same reason. o Then, if the field denoted by e.f is not static and the result of the evaluation of e above is null, then a NullPointerException is thrown. o Otherwise, the variable denoted by e.f is assigned the value of the right hand operand as computed above. * If the left-hand operand is an array access expression (§15.13), possibly enclosed in one or more pairs of parentheses, then: * o If array reference expression is array type + First, the array reference subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no assignment occurs. + Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no assignment occurs. + Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs. + Otherwise, if the value of the array reference subexpression is null, no assignment occurs and a NullPointerException is thrown. + Otherwise, the value of the array reference subexpression indeed refers to an array. If the value of the index subexpression is less than zero, or greater than or equal to the length of the array, then no assignment occurs and an ArrayIndexOutOfBoundsException is thrown. + Otherwise, the value of the index subexpression is used to select a component of the array referred to by the value of the array reference subexpression. This component is a variable; call its type SC. Also, let TC be the type of the left-hand operand of the assignment operator as determined at compile time. + If TC is a primitive type, then SC is necessarily the same as TC. The value of the right-hand operand is converted to the type of the selected array component, is subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the array component. + If TC is a reference type, then SC may not be the same as TC, but rather a type that extends or implements TC. Let RC be the class of the object referred to by the value of the right-hand operand at run time. The compiler may be able to prove at compile time that the array component will be of type TC exactly (for example, TC might be final). But if the compiler cannot prove at compile time that the array component will be of type TC exactly, then a check must be performed at run time to ensure that the class RC is assignment compatible (§5.2) with the actual type SC of the array component. This check is similar to a narrowing cast (§5.5, §15.16), except that if the check fails, an ArrayStoreException is thrown rather than a ClassCastException. Therefore: # If class RC is not assignable to type SC, then no assignment occurs and an ArrayStoreException is thrown. + Otherwise, the reference value of the right-hand operand is stored into the selected array component. o If array reference expression is class reference expression ($15.13), than + First, the first operand of array reference expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no array assigmnent methods are called. + Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no array assignment methods are called. + Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no call of array assignment method occurs. + Otherwise, appropriateve method, annotated with @Operator("[]=") is called on first operand of array reference with index subexpression and righ hand operators as reference. * Otherwise, three steps are required: o First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs. o Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs. 15.16.2 Compound Assignment Operators A compound assignment expression of the form E1 op= E2 is when * type of E1 is Primitive Numeric Types or Booleans or String, then this is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once. * type of E1 is Class, which have methods m, annotated by @Operator("op="), than compound assignment evaluates exactly as invocation expression of appropriative methods, with method names. COMPILATION: During compilation overloaded operators will be translated to set of appropriative annotated methods. I.e. for Example 1 Z3 z3 = new Z3(2); Z3 z4 = z3+z3; which will be translated to: Z3 z3 = new Z3(2); Z3 z4 = Z3.plus(z3,z3); Example 2 IndexedCollection pairs = new IndexedCollection(10); pairs[0]=new NVPair("CISCO-AV-Pair","lcp:interface=1"); pairs[1]=new NVPair("X",4); pairs[2]=new NVPair("Y",5); NVPair pair1=pairs[1]; NVPair pair2=pairs["X"]; will be equal to: IndexedCollection pairs = new IndexedCollection(10); pairs.set(0,new NVPair("CISCO-AV-Pair","lcp:interface=1")); pairs.set(1,new NVPair("X",4)); pairs.set(2,new NVPair("Y",5)); NVPair pair1=pairs.get(1); NVPair pair2=pairs.get("X"); TESTING Provide usual set of tests. Nothing special LIBRARY SUPPORT: Annotate standard Collection classes; BigDecimal ans BigInteger. REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4905919 IMPLEMENTATION PROTOTYPE URL (no) From reinier at zwitserloot.com Wed Mar 25 04:32:11 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 12:32:11 +0100 Subject: Unsigned byte sidestep - introduction In-Reply-To: <49C9EEC3.9020309@paradise.net.nz> References: <49C9EEC3.9020309@paradise.net.nz> Message-ID: Combining 0hFF and the (+) cast seems nicer, somehow, than coming up with a bunch of new random letters for byte and short literals. --Reinier Zwitserloot On Mar 25, 2009, at 09:43, Bruce Chapman wrote: > Hello all, > > > I am about to submit 3 proposals which are related. > > This email serves to background the 3 proposals > > The proposals are my best attempt at solving the no unsigned byte > dilemma in a way that fits the existing language. > > After much thought I have identified two root issues which cause me to > want unsigned byte. > > > The proposals address these issues without actually add unsigned > bytes. > > The first root issue is the lack of byte size literals, so byte > literals > must be formed by a narrowing conversion (cast) from an int literal. > The > cast in this case can increase the code by over 100% and is > particularly > onerous when populating byte arrays with fixed values, often during > testing but in other cases as well. > > I have two competing proposals for byte (and short) integer literals > with different advantages and disadvantages. These are mutually > exclusive proposals (but under the coin rules they can't really > refer to > each other - hence this email). One of these has a nicer syntax at > the > expense of a more complex specification and narrower focus (it doesn't > support decimal byte literals). > > > The second root issue is the automatic widening conversion to int > whenever a byte field or variable is used in an expression. It is > not so > much the widening, but the implicit sign extend which causes problems > which bite when least expected. The third proposal adds an operator > (cast like operator) to convert byte (and short) to int with zero > extend > to reduce the pain of the second issue. > > Here is an example showing some of the present traps. > > byte b = (byte)0x80; // cast needed because 0x80 is int and wont fit > // in signed bit > assert b == 0x80; // throw AssertionError because == causes the value > // of b to be converted to int value 0xFFFFFF80 > > > > Here are the google doc references, I'll post content soon. > > Auto Typing Hexadecimal and Binary Integer Literals : 0hFF > http://docs.google.com/Doc?id=dcvp3mkv_125ww5tct > > Byte and Short Integer Literals (new type suffixes) : 0xFFy > http://docs.google.com/Doc?id=dcvp3mkv_0fvz5gx7b > > > Unsigned Integer Widening Operator : (+) > http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf > > > Bruce > From reinier at zwitserloot.com Wed Mar 25 04:39:26 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 12:39:26 +0100 Subject: PROPOSAL: Unsigned Integer Widening Operator In-Reply-To: <49CA07D3.8090909@peralex.com> References: <49C9F30E.2020008@paradise.net.nz> <49CA07D3.8090909@peralex.com> Message-ID: <021BD3C7-35AE-4E88-8FA0-31737B0DC8CE@zwitserloot.com> Noel, Bruce: Perhaps Noel has a point, here. imagine: public class ByteUtils { public int b2i(byte b) { return b & 0xFF; } } import static ByteUtils.b2i; results = (result << 8) | b2i(contents[i]); vs: results = (result << 8) | (+)contents[i]; The second bit is hardly better, and it suffers from cast ambiguity if you add more fluff to the expression. Once you also add parens to localize the cast like so: results = (result << 8) | ((+)contents[i]); The static import starts to win, in my book, and that's before considering the impact of a language change. did you not read Bruce's introduction to his three proposals? It provides some useful background information. If you've ever worked with bytes in java, you may remember that the main issue is crippling wordiness. A librar --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 25, 2009, at 11:30, Noel Grandin wrote: > > I would think that a utility class that performed widening operations, > and maybe some other useful stuff would be preferable to extending the > language/ > > Perhaps a BinaryMath class to live alongside java.lang.Math? > > Regards, Noel. > > Bruce Chapman wrote: >> Title >> Unsigned Integer Widening Operator >> >> latest html version at http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf&hl >> >> AUTHOR(S): Bruce Chapman >> >> OVERVIEW >> >> >> >> FEATURE SUMMARY: >> Add an unsigned widening operator to convert bytes (in particular), >> shorts, and chars (for completeness) to int while avoiding sign >> extension. >> >> >> MAJOR ADVANTAGE: >> >> Byte manipulation code becomes littered with (b & 0xFF) expressions >> in >> order to reverse the sign extension that occurs when a byte field or >> variable or array access appears on either side of an operator and is >> thus subject to widening conversion with its implicit sign extension. >> This masking with 0xFF can detract from the clarity of the code by >> masking the actual algorithm. It is the Java Language's rules and not >> the algorithm itself that demand this masking operation which can >> appear >> to be a redundant operation to the uninitiated. >> >> >> It is highly intentional that the new operator (+) can be read as a >> cast >> to a positive. >> >> >> >> MAJOR DISADVANTAGE: >> A new operator. >> >> >> ALTERNATIVES: >> >> explicit masking. If java.nio.ByteBuffer was extensible (it isn't) >> unsigned get and set methods could be added to hide the masking in an >> API. Extension methods could be employed to that end if they were >> implemented. >> >> EXAMPLES >> SIMPLE EXAMPLE: >> >> byte[] buffer = ...; int idx=...; int length=...; >> >> int value=0; >> >> for(int i = idx; i < idx + length; i++) { >> value = (value << 8) | (buffer[i] & 0xff); >> } >> >> can be recoded as >> >> >> for(int i = idx; i < idx + length; i++) { >> value = (value << 8) | (+)buffer[i]; >> } >> >> >> ADVANCED EXAMPLE: >> >> private int getBerValueLength(byte[] contents, int idx) { >> if((contents[idx] & 0x80) == 0) return contents[idx]; >> int lenlen = (+)contents[idx] ^ 0x80; // invert high bit >> which = 1 >> int result=0; >> for(int i = idx+1; i < idx + 1 + lenlen; i++ ) { >> result = (result << 8) | (+)contents[i]; >> } >> return result; >> } >> >> DETAILS >> SPECIFICATION: >> >> amend 15.15 >> >> The unary operators include +, -, ++, --, ~, !, unsigned integer >> widening operator and cast operators. >> >> >> >> add the following to the grammars in 15.15 >> >> >> >> The following productions from ?new section are repeated here for >> convenience: >> >> >> UnsignedWideningExpression: >> >> UnsignedIntegerWideningOperator UnaryExpression >> >> >> UnsignedIntegerWideningOperator: >> >> ( + ) >> >> >> >> Add a new section to 15 - between "15.15 Unary Expressions" and >> "15.16 >> Cast Expressions" would seem ideal in terms of context and >> precedence level. >> >> >> The unsigned integer widening operator is a unary operator which >> may be >> applied to expressions of type byte, short and char. It is a compile >> time error to apply this operator to other types. >> >> >> UnsignedWideningExpression: >> >> UnsignedIntegerWideningOperator UnaryExpression >> >> >> UnsignedIntegerWideningOperator: >> >> ( + ) >> >> >> The unsigned integer widening operator converts its operand to type >> int. >> Unary numeric promotion (?) is NOT performed on the operand. For a >> byte >> operand, the lower order 8 bits of the resultant have the same >> values as >> in the operand. For short and char operands, the resultant's lower >> order >> 16 bits have the same value as the operand's. The remaining high >> order >> bits are set to zero. This is effectively a zero extend widening >> conversion and is equivalent to the following expression for byte >> operand x, >> >> x & 0xFF >> >> and equivalent to the following for a short or char operand y >> >> y & 0xFFFF >> >> >> Other sections have lists of operators for which various things >> apply. >> Add to these as appropriate - yet to be determined. >> >> Note the specification above could also be ammended to allow the >> operator to zero extend an int to a long, however the utility value >> of >> this is uncertain. >> COMPILATION: >> >> Compilation may be equivalent to the masking operation above. >> Hotspot >> could detect the redundant sign extend followed by masking out the >> sign >> extended bits and remove both. If that were the case the operator >> could >> be applied to every access of a byte field, variable or array to >> indicate treatment as unsigned byte, with no cost. >> >> >> For a char, the operator is equivalent to a widening conversion to >> int. >> The new operator is permitted on a char expression because there is >> no >> reason to disallow it. However it would be equally effective if it >> did >> not apply to char. >> >> >> TESTING: >> >> There are no gnarly use cases, so testing is straight forward. It >> could >> be as simple as compiling and executing a main class with a handful >> of >> asserts. >> >> LIBRARY SUPPORT: >> >> No library support required. >> >> REFLECTIVE APIS: >> >> None >> >> OTHER CHANGES: >> >> none foreseen >> >> MIGRATION: >> >> COMPATIBILITY >> BREAKING CHANGES: >> >> None >> >> EXISTING PROGRAMS: >> >> Tools could detect the specific masking operations used to zero >> extend a >> previously sign extended byte or short, and replace that with the new >> operator. >> >> REFERENCES >> EXISTING BUGS: >> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4186775 >> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4879804 >> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504839 >> >> >> URL FOR PROTOTYPE (optional): >> None >> >> >> >> > > > Disclaimer: http://www.peralex.com/disclaimer.html > > > From vilya.harvey at gmail.com Wed Mar 25 05:03:37 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Wed, 25 Mar 2009 12:03:37 +0000 Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: References: Message-ID: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> I would love to see this, but I'd prefer it to be based on special interfaces rather than annotations. This would adhere to the principle, mentioned on this list a few times, that annotations shouldn't modify the results of the compiler. For example, if you implement the Addable (say) interface then your class can be used the '+' operator; or the Subtractable interface for the '-' operator. I'd imagine you would also want some grouping interfaces, to reduce the number of interface declarations required when overloading multiple operators (e.g. interface Artihmetic extends Addable, Subtractable etc.). Whatever form it takes though, it would be great to have this capability in Java! Vil. 2009/3/25 : > Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk > > Probably too big, but anyway. > > As I remember, alternative proposal (made [] and []= syntax sugar on > well-known interfaces, as with for-each loop) still not submitted. If > anybody want submit such proposal, then it is possible to reuse > JLS-changed for 15.26.1 from there. > > From rssh at gradsoft.com.ua Wed Mar 25 05:28:03 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 14:28:03 +0200 (EET) Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: <8c7af51a995e0f01ad22af82e75bd577.squirrel@wmail.gradsoft.ua> > I would love to see this, but I'd prefer it to be based on special > interfaces rather than annotations. This would adhere to the > principle, mentioned on this list a few times, that annotations > shouldn't modify the results of the compiler. > If you have some free time, I suggest you (or anybody in community) to initiate such proposal for one pair of operators (for example [] and []=). (Why only for one pair - because it would be small; build logical structure for all operators during 5 days is impossible. ). And well-narrowed proposal for array access, may be have some chance. Rules for array access (15.3) and assignment expression (15.26.1) can be copied from 'Simple Operator Overloading' near verbatim, just change existence of operator to existence of interface. > For example, if you implement the Addable (say) interface then your > class can be used the '+' operator; or the Subtractable interface for > the '-' operator. I'd imagine you would also want some grouping > interfaces, to reduce the number of interface declarations required > when overloading multiple operators (e.g. interface Artihmetic extends > Addable, Subtractable etc.). > > Whatever form it takes though, it would be great to have this > capability in Java! > > Vil. > > > 2009/3/25 : >> Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk >> >> Probably too big, but anyway. >> >> As I remember, alternative proposal (made [] and []= syntax sugar on >> well-known interfaces, as with for-each loop) still not submitted. If >> anybody want submit such proposal, then it is possible to reuse >> JLS-changed for 15.26.1 from there. >> >> > From jl0235 at yahoo.com Wed Mar 25 06:26:57 2009 From: jl0235 at yahoo.com (james lowden) Date: Wed, 25 Mar 2009 06:26:57 -0700 (PDT) Subject: Proposal: Simplified syntax for dealing with parameterized types (correction to ALTERNATIVES section) Message-ID: <617633.92842.qm@web63707.mail.re1.yahoo.com> I'm withdrawing this proposal in favor of Jeremy Manson's "Improved Type Inference for Generic Instance Creation", which addresses the repetitive aspects of generic code. I still have type safety concerns over generics, but my proposal didn't address that completely, and I'd rather see it dealt with via full reification in a future release. -JL- --- On Tue, 3/24/09, james lowden wrote: > From: james lowden > Subject: Re: Proposal: Simplified syntax for dealing with parameterized types (correction to ALTERNATIVES section) > To: coin-dev at openjdk.java.net > Date: Tuesday, March 24, 2009, 9:50 AM > I see what you're saying. . . there's no way, having > made StringList a subinterface of List, to > then have it be an ArrayList (or whatever concrete > implementation is desired). Based on this, and the general > triviality of the interface case, I'm thinking that > using the syntax for interfaces (or abstract classes) is > probably a lot of confusion for minimal/no gain, and am > tempted to simply remove it from the proposal. > > (Alternately, as you mentioned, we could use it as an > alias, but then we have an identifier such as > "StringList" floating around the code which > isn't *actually* a class or interface or anything after > compilation, which results in different reflective behaviors > for the class and interface case, which could be messy.) > > > -JL > > --- On Mon, 3/23/09, Howard Lovatt > wrote: > > > From: Howard Lovatt > > Subject: Proposal: Simplified syntax for dealing with > parameterized types (correction to ALTERNATIVES section) > > To: coin-dev at openjdk.java.net > > Date: Monday, March 23, 2009, 5:33 PM > > Hi, > > > > There is a lot to like with proposal since class > StringList > > = > > ArrayList would both shorten > declarations and > > would partially > > reify the generic class. However there is a problem > touched > > on in the > > proposal namely class MyStringList = > List > > then StringList sl = > > ...; MyStringList msl ...; sl = msl; // Error. This > problem > > is worse > > than suggested in the proposal, consider alternate > > implementations of > > the same interface: > > > > class StringList = List; > > class ArrayStringList = ArrayList; > > > > StringList sl = new ArrayList(); // Error > > > > I think to make this workable you need to either: > > > > 1. change the mechanism so that the interface and > abstract > > class > > version is simply a shorthand and does not create a > new > > class or type > > (i.e. simply a type alias), or > > > > 2. alternatively just drop the interface/abstract > class bit > > altogether > > and say the new mechanism can only be applied to > > non-abstract classes. > > > > > > -- Howard. From tim at peierls.net Wed Mar 25 06:33:50 2009 From: tim at peierls.net (Tim Peierls) Date: Wed, 25 Mar 2009 09:33:50 -0400 Subject: Proposal idea - generators In-Reply-To: References: Message-ID: <63b4e4050903250633hb3087a8vafdb59d54519947d@mail.gmail.com> My sense (bolstered by a quick Google code search) is that people have been coming up with this kind of functionality on their own as they encounter a need for it. Is it really something that needs special language support? Using another thread to do the generation is quite reasonable. You can build a nice coroutine-style facility with a pair of SynchronousQueues (or, more generally and flexibly, with TransferQueues, expected for Java 7; or maybe with Phasers). Using that as a building block you could then rewrite your example below as something like this: final List allUsersList = ...; Iterator userIterator = generatorToIterator(new Generator() { public void generate(Generation generation) { for (User user : allUsersList) { if (user.isActive()) generation.yield(user); } } }); // Now userIterator lazily produces active users. Getting this kind of thing right is hard enough that someone should propose putting a production version in the standard library, but I don't see the need for a language change. For your particular example, you could use Google Collections' Iterators.filter: Iterator userIterator = filter(allUsersList.iterator(), new Predicate() { public boolean apply(User user) { return user.isActive(); } }); That's not true generation, but I bet lazy filtering handles a lot of the common cases that people think they want generation for. --tim On Tue, Mar 24, 2009 at 3:07 PM, Mark Derricutt wrote: > Hi all, > > This isn't an actual proposal, but more a proposal idea that hopefully > someone could run with. I was thinking about all the closures issues > and looking at a lot of my code where I'm using closure like patterns > and started thinking what would really make things easier for me would > be some form of yield/generators api to give me a cleaner way of > making Iterable's that could be used in the JDK5 for loop. > > The usage I'd like would be something like: > > for ( User user : allUsersList) { > if (user.isActive()) yield user; > } > > Effectively I could see this as being like comparing an XML pull > parser to SAX. The problem I have is I can't think of a suitable way > of expressing, or implementing this in java, unless I split the code > into another thread that sleeps between the yield calling back to the > iterable next() call which is nasty as I could see a lot of thread > leakage there. > > Has anyone looked at, or already written some form of generator proposal? > > > ...and then Buffy staked Edward. The End. > > From jl0235 at yahoo.com Wed Mar 25 06:41:09 2009 From: jl0235 at yahoo.com (james lowden) Date: Wed, 25 Mar 2009 06:41:09 -0700 (PDT) Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: Message-ID: <999760.7333.qm@web63701.mail.re1.yahoo.com> I'd like to see both. Auto-getters/setters/equals/etc. would be really, really nice, but it would also be valuable to have a way of specifying a variety of different constructors to generate, which Mark's proposal would allow for. Example: public data class Foo { private final int x; private final int y; private final String foo; public Foo (this.x) {} public Foo (this.foo, this.y) {} } (I eliminated the types from the automagical constructors, as they can be inferred by the compiler.) This would generate all three getters and setters, equals (), hashcode (), a general constructor taking in all 3 fields, and two additional constructors, one taking in just int x, and one taking in both String foo and int y. Reinier--is there a copy of your original proposal for auto-POJOs somewhere? -JL- > From: Reinier Zwitserloot > Subject: Re: PROPOSAL: Auto-assignment Parameters > To: "Mark Mahieu" > Cc: coin-dev at openjdk.java.net > Date: Tuesday, March 24, 2009, 8:34 PM > I like where this is going, but I'd rather see a bigger > setup for auto- > POJO classes. I proposed this before and in most java > circles (outside > of coin-dev!), this idea was considered very useful: > > public data class Foo { > private final int x; > private final int y; > private final String foo; > } > > > The above class would auto-generate the getters, a > constructor, > hashCode, equals, and toString. You can add methods to it > if you want, > and if you define a method that would usually be > auto-generated, it > isn't auto-generated. So, if you need to do some extra > processing > before returning 'foo' via the getter, go right > ahead. You can even > add this later without breaking your API's > compatibility. > > --Reinier Zwitserloot > > > > On Mar 25, 2009, at 02:07, Mark Mahieu wrote: > > > HTML version + prototype available at > http://slm888.com/javac > > > > > > > > Auto-assignment Parameters v0.1 > > > > > > AUTHOR(S): > > > > Mark Mahieu > > > > > > OVERVIEW > > > > FEATURE SUMMARY: Should be suitable as a summary in a > language > > tutorial. > > > > An additional form of constructor parameter which > provides automatic > > assignment of the parameter's value to an instance > field. These > > parameters > > are implicitly declared as final to prevent > unintentional > > assignments to the > > wrong variable in the constructor body. > > > > > > MAJOR ADVANTAGE: What makes the proposal a favorable > change? > > > > Reduces the likelihood of some common coding errors > relating to > > assignment > > of fields in a constructor, including those where: > > > > * a field is assigned to itself > > * the parameter is assigned instead of the field > > * the assignment to the field is missing entirely > > > > These and other errors are often caused by typos or > code refactoring. > > > > > > MAJOR BENEFIT: Why is the platform better if the > proposal is adopted? > > > > A programmer's intent is more clearly expressed > for the extremely > > common > > case of assigning a constructor parameter directly to > an instance > > field with > > the same name. > > > > > > MAJOR DISADVANTAGE: There is always a cost. > > > > As with any sugar which enables a more concise way of > expressing an > > existing > > idiom, programmers may be tempted to use it even when > the original > > form > > would be more appropriate. > > > > > > ALTERNATIVES: Can the benefits and advantages be had > some way > > without a > > language change? > > > > IDEs and tools such as FindBugs are good at warning > about the kind > > of errors > > mentioned above, however since the code in question is > usually still > > valid > > to the compiler, they are limited in what action they > can take by > > default. > > > > A language change can combine the ability to avoid > these errors > > entirely > > with a more expressive idiom, resulting in an > increased signal to > > noise > > ratio for readers of that code. > > > > > > > > EXAMPLES > > > > SIMPLE EXAMPLE: Show the simplest possible program > utilizing the new > > feature. > > > > class C { > > int i; > > C(int this.i) {} > > } > > > > > > ADVANCED EXAMPLE: Show advanced usage(s) of the > feature. > > > > > > class Proposal { > > > > private final String name; > > private final String author; > > private boolean suitableForCoin; > > private Integer score; > > > > public Proposal(String this.name, > > String this.author, > > boolean this.suitableForCoin, > > int this.score) { > > > > if (name.equals(?Auto-assignment > Parameters?)) { > > suitableForCoin = true; // final so > compile-time error > > } > > } > > > > // rest of class ... > > } > > > > > > > > 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. > > > > The syntactic grammar is modified to include > auto-assignment > > parameters for > > constructors: > > > > ConstructorDeclaratorRest: > > ConstructorParameters [throws > QualifiedIdentifierList] > > MethodBody > > > > ConstructorParameters: > > ( [ConstructorParameterDecls] ) > > > > ConstructorParameterDecls: > > [final] [Annotations] Type > > ConstructorParameterDeclsRest > > > > ConstructorParameterDeclsRest: > > ConstructorParameterId [ , > ConstructorParameterDecls] > > ... ConstructorParameterId > > > > ConstructorParameterId: > > VariableDeclaratorId > > this . VariableDeclaratorId > > super . VariableDeclaratorId > > > > An auto-assignment parameter is a formal parameter > (JLSv3 ?8.4.1) > > which > > specifies an instance field instead of an identifier. > Its value is > > automatically assigned to the specified field. It may > only be used > > in a > > constructor. > > > > The automatic assignment takes place after any > explicit or implicit > > invocation of another constructor, and before any > statements in the > > body of > > the constructor. A constructor which declares n > auto-assignment > > parameters > > will perform n such automatic assignments, in the > order that the > > parameters > > are declared. > > > > The parameter has the same name (JLSv3 ?6.2) as the > field to which > > it is > > assigned; replacing each auto-assignment parameter > with a normal > > formal > > parameter with the same name would yield a constructor > with an > > identical > > signature. As with a normal parameter, the > parameter's name is > > entered into > > the scope of the constructor body (JLSv3 ?6.3), and > therefore > > shadows the > > field (JLSv3 ?6.3.1) within that scope. > > > > It is a compile-time error if the field is not > accessible from the > > constructor in which the parameter appears. > > > > It is a compile-time error if the declared type of the > parameter is > > not > > assignment compatible (JLSv3 ?5.2) with the field to > which it is > > automatically assigned. > > > > If an unboxing conversion is required by an automatic > assignment, any > > NullPointerException thrown as a result (JLSv3 > ?5.1.8) will contain > > the name > > of the field on which the conversion failed, which may > be retrieved by > > calling getMessage() on the exception. > > > > Auto-assignment parameters are implicitly final, and > follow the > > standard > > rules for final variables (JLSv3 ?4.12.4). > Explicitly declaring an > > auto-assignment parameter as final has no effect, and > does not cause a > > compilation error. > > > > Auto-assignment parameters follow the standard > definite assignment > > rules for > > formal parameters (JLSv3 ?16.3). > > > > An auto-assignment parameter may be annotated. > > > > If an auto-assignment parameter is the last parameter > in the list, and > > refers to a field of array type, it may be a variable > arity parameter. > > > > > > > > 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! > > > > Desugaring of the following class: > > > > class Foo { > > int value; > > Foo(Integer this.value) { > > System.out.println(value); > > } > > } > > > > would result in (unboxing desugaring omitted): > > > > class Foo { > > int value; > > Foo(final Integer value) { > > super(); > > if (value == null) > > throw new > NullPointerException("value"); > > this.value = value; > > System.out.println(value); > > } > > } > > > > No changes to the classfile format are required. > Tools which > > consume class > > files see the constructor signature as though it had > been written > > using > > normal formal parameters. > > > > > > TESTING: How can the feature be tested? > > > > An initial set of jtreg tests is included in the > prototype. > > > > > > LIBRARY SUPPORT: Are any supporting libraries needed > for the feature? > > > > No > > > > > > 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. > > > > com.sun.source.tree.VariableTree would require an > additional method > > which > > returns the auto-assigned field. > > > > > > 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 > > > > > > MIGRATION: Sketch how a code base could be converted, > manually or > > automatically, to use the new feature. > > > > Assignment statements in constructors for which all of > the following > > are > > true can be considered suitable for conversion: > > * the lhs of the assignment is a non-static field > > * the rhs is a parameter with the same name as the > field > > * there are no other assignments to the parameter > anywhere in the > > constructor > > * there are no assignments to, or other uses of > the field before > > the > > assignment statement in question (including invoked > constructors) > > > > Such statements can be converted by: > > 1) replacing the parameter with an auto-assignment > parameter > > (prefixing > > the existing parameter's identifier with > 'this.'), and > > 2) removing the assignment statement > > > > > > > > COMPATIBILITY > > > > BREAKING CHANGES: Are any previously valid programs > now invalid? If > > so, list > > one. > > > > No > > > > > > 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 semantics of existing class files and legal source > files are > > unchanged > > by this feature. > > > > > > > > REFERENCES > > > > EXISTING BUGS: Please include a list of any existing > Sun bug ids > > related to > > this proposal. > > > > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 > > (uses a 'setter' method rather than a > constructor in its example) > > > > FindBugs bug patterns - > http://findbugs.sourceforge.net/bugDescriptions.html > > * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) > > * Self comparison of field with itself > (SA_FIELD_SELF_COMPARISON) > > * Nonsensical self computation involving a field > (e.g., x & x) > > (SA_FIELD_SELF_COMPUTATION) > > * Self assignment of local variable > (SA_LOCAL_SELF_ASSIGNMENT) > > * Nonsensical self computation involving a variable > (e.g., x & x) > > (SA_LOCAL_SELF_COMPUTATION) > > * Uninitialized read of field in constructor > (UR_UNINIT_READ) > > * Unwritten field (UWF_UNWRITTEN_FIELD) > > * Dead store to local variable (DLS_DEAD_LOCAL_STORE) > > * Dead store of null to local variable > (DLS_DEAD_LOCAL_STORE_OF_NULL) > > > > > > > > URL FOR PROTOTYPE (optional): > > > > http://slm888.com/javac > > > > > > > > DESIGN ALTERNATIVES: > > > > The following variations have been explored and are > worth mentioning: > > > > * Allow auto-assignment parameters on all non-abstract > methods. > > This may be especially useful on the extremely > common 'setter' > > methods > > in 'value object' classes. > > > > * Remove the requirement for (or even disallow) the > type to be > > specified on > > auto-assignment parameters. > > Experimentation with this idea suggests that it may > work quite > > well for > > constructors, further emphasising the difference in > intent and > > semantics > > from those of normal parameters. However, it may not > work so well in > > combination with auto-assignment parameters on all > non-abstract > > methods, and > > requires a change to the order in which javac compiles > classes (can > > still > > pass jtreg tests). > > > > * Allow an alternative name to be specified. > > This adds additional complexity to support a > fractional > > percentage of > > cases, which could continue to use the existing coding > pattern. > > From neal at gafter.com Wed Mar 25 07:02:20 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 25 Mar 2009 07:02:20 -0700 Subject: Proposal idea - generators In-Reply-To: <63b4e4050903250633hb3087a8vafdb59d54519947d@mail.gmail.com> References: <63b4e4050903250633hb3087a8vafdb59d54519947d@mail.gmail.com> Message-ID: <15e8b9d20903250702y8e16d39gff01361e02bc99ea@mail.gmail.com> The problem with this approach is that, without cooperation from the client, the other thread can stick around for arbitrarily long, which is a severe resource leak. I wrote about this at . That's because the generating thread has no way of knowing when the client did a "break" from the loop. You can solve this if your language has support for an AutoCloseable interface, and the Iterator is closed at the end by the expansion of the for-each loop when the Iterator is a subtype of AutoCloseable. Unfortunately, the current ARM proposal does not do that. On Wed, Mar 25, 2009 at 6:33 AM, Tim Peierls wrote: > My sense (bolstered by a quick Google code search) is that people have been > coming up with this kind of functionality on their own as they encounter a > need for it. Is it really something that needs special language support? > Using another thread to do the generation is quite reasonable. You can build > a nice coroutine-style facility with a pair of SynchronousQueues (or, more > generally and flexibly, with TransferQueues, expected for Java 7; or maybe > with Phasers). Using that as a building block you could then rewrite your > example below as something like this: > > final List allUsersList = ...; > Iterator userIterator = generatorToIterator(new Generator() { > ? ?public void generate(Generation generation) { > ? ? ? ?for (User user : allUsersList) { > ? ? ? ? ? ?if (user.isActive()) generation.yield(user); > ? ? ? ?} > ? ?} > }); > // Now userIterator lazily produces active users. > > > Getting this kind of thing right is hard enough that someone should propose > putting a production version in the standard library, but I don't see the > need for a language change. > > For your particular example, you could use Google Collections' > Iterators.filter com.google.common.base.Predicate)>: > > Iterator userIterator = filter(allUsersList.iterator(), new > Predicate() { > ? ?public boolean apply(User user) { > return user.isActive(); > ? ?} > }); > > > That's not true generation, but I bet lazy filtering handles a lot of the > common cases that people think they want generation for. > > --tim > > > > On Tue, Mar 24, 2009 at 3:07 PM, Mark Derricutt wrote: > >> Hi all, >> >> This isn't an actual proposal, but more a proposal idea that hopefully >> someone could run with. ?I was thinking about all the closures issues >> and looking at a lot of my code where I'm using closure like patterns >> and started thinking what would really make things easier for me would >> be some form of yield/generators api to give me a cleaner way of >> making Iterable's that could be used in the JDK5 for loop. >> >> The usage I'd like would be something like: >> >> for ( User user : allUsersList) { >> ?if (user.isActive()) yield user; >> } >> >> Effectively I could see this as being like comparing an XML pull >> parser to SAX. ?The problem I have is I can't think of a suitable way >> of expressing, or implementing this in java, unless I split the code >> into another thread that sleeps between the yield calling back to the >> iterable next() call which is nasty as I could see a lot of thread >> leakage there. >> >> Has anyone looked at, or already written some form of generator proposal? >> >> >> ...and then Buffy staked Edward. ?The End. >> >> > > From tim at peierls.net Wed Mar 25 08:55:54 2009 From: tim at peierls.net (Tim Peierls) Date: Wed, 25 Mar 2009 11:55:54 -0400 Subject: Proposal idea - generators In-Reply-To: <15e8b9d20903250702y8e16d39gff01361e02bc99ea@mail.gmail.com> References: <63b4e4050903250633hb3087a8vafdb59d54519947d@mail.gmail.com> <15e8b9d20903250702y8e16d39gff01361e02bc99ea@mail.gmail.com> Message-ID: <63b4e4050903250855r217a38cek47a4a2f1796a3509@mail.gmail.com> I don't think Java needs language support for generators. --tim On Wed, Mar 25, 2009 at 10:02 AM, Neal Gafter wrote: > The problem with this approach is that, without cooperation from the > client, the other thread can stick around for arbitrarily long, which > is a severe resource leak. I wrote about this at > < > http://gafter.blogspot.com/2007/07/internal-versus-external-iterators.html > >. > That's because the generating thread has no way of knowing when the > client did a "break" from the loop. > > You can solve this if your language has support for an AutoCloseable > interface, and the Iterator is closed at the end by the expansion of > the for-each loop when the Iterator is a subtype of AutoCloseable. > Unfortunately, the current ARM proposal does not do that. > > On Wed, Mar 25, 2009 at 6:33 AM, Tim Peierls wrote: > > My sense (bolstered by a quick Google code search) is that people have > been > > coming up with this kind of functionality on their own as they encounter > a > > need for it. Is it really something that needs special language support? > > Using another thread to do the generation is quite reasonable. You can > build > > a nice coroutine-style facility with a pair of SynchronousQueues (or, > more > > generally and flexibly, with TransferQueues, expected for Java 7; or > maybe > > with Phasers). Using that as a building block you could then rewrite your > > example below as something like this: > > > > final List allUsersList = ...; > > Iterator userIterator = generatorToIterator(new Generator() { > > public void generate(Generation generation) { > > for (User user : allUsersList) { > > if (user.isActive()) generation.yield(user); > > } > > } > > }); > > // Now userIterator lazily produces active users. > > > > > > Getting this kind of thing right is hard enough that someone should > propose > > putting a production version in the standard library, but I don't see the > > need for a language change. > > > > For your particular example, you could use Google Collections' > > Iterators.filter< > http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterators.html#filter(java.util.Iterator > , > > com.google.common.base.Predicate)>: > > > > Iterator userIterator = filter(allUsersList.iterator(), new > > Predicate() { > > public boolean apply(User user) { > > return user.isActive(); > > } > > }); > > > > > > That's not true generation, but I bet lazy filtering handles a lot of the > > common cases that people think they want generation for. > > > > --tim > > > > > > > > On Tue, Mar 24, 2009 at 3:07 PM, Mark Derricutt wrote: > > > >> Hi all, > >> > >> This isn't an actual proposal, but more a proposal idea that hopefully > >> someone could run with. I was thinking about all the closures issues > >> and looking at a lot of my code where I'm using closure like patterns > >> and started thinking what would really make things easier for me would > >> be some form of yield/generators api to give me a cleaner way of > >> making Iterable's that could be used in the JDK5 for loop. > >> > >> The usage I'd like would be something like: > >> > >> for ( User user : allUsersList) { > >> if (user.isActive()) yield user; > >> } > >> > >> Effectively I could see this as being like comparing an XML pull > >> parser to SAX. The problem I have is I can't think of a suitable way > >> of expressing, or implementing this in java, unless I split the code > >> into another thread that sleeps between the yield calling back to the > >> iterable next() call which is nasty as I could see a lot of thread > >> leakage there. > >> > >> Has anyone looked at, or already written some form of generator > proposal? > >> > >> > >> ...and then Buffy staked Edward. The End. > >> > >> > > > > > From tim.keith at gmail.com Wed Mar 25 09:44:50 2009 From: tim.keith at gmail.com (Tim Keith) Date: Wed, 25 Mar 2009 09:44:50 -0700 Subject: For further consideration... In-Reply-To: <49C96A42.9050805@sun.com> References: <49C95DB5.6020202@sun.com> <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> <49C96A42.9050805@sun.com> Message-ID: I would like to suggest at least leaving out ?[] The example in the proposal is not very compelling: class Group { Person[] members; // null if no members } class Person { String name; // may be null } final String aMember = g?.members?[0]?.name ?: "nobody"; If members is null you get "nobody" but if members is empty (the logical way to signify "no members") you get ArrayIndexOutOfBoundsException. "array?[...]" is like saying: if array is null treat it like it's an infinitely long array of nulls. "object?.member" is like saying: if object it null, treat it like every field is null and every method returns null. The array analog to that should be that "array?.length" means array == null ? 0 : array.length -- Tim On Tue, Mar 24, 2009 at 4:18 PM, Joseph D. Darcy wrote: > Jeremy Manson wrote: > > Joe, > > > > Is it all the Elvis operators, or just ?: ? > > > > The more modest version is more likely to get in. > > -Joe > > > From neal at gafter.com Wed Mar 25 09:55:16 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 25 Mar 2009 09:55:16 -0700 Subject: Proposal idea - generators In-Reply-To: <63b4e4050903250855r217a38cek47a4a2f1796a3509@mail.gmail.com> References: <63b4e4050903250633hb3087a8vafdb59d54519947d@mail.gmail.com> <15e8b9d20903250702y8e16d39gff01361e02bc99ea@mail.gmail.com> <63b4e4050903250855r217a38cek47a4a2f1796a3509@mail.gmail.com> Message-ID: <15e8b9d20903250955q674272b7ydca6bba2f5d8c0ac@mail.gmail.com> For Java 7, I agree. Until the thread leakage problem I mentioned can be solved, I don't think it should be done in a standard library either. -Neal On Wed, Mar 25, 2009 at 8:55 AM, Tim Peierls wrote: > I don't think Java needs language support for generators. > --tim > > On Wed, Mar 25, 2009 at 10:02 AM, Neal Gafter wrote: >> >> The problem with this approach is that, without cooperation from the >> client, the other thread can stick around for arbitrarily long, which >> is a severe resource leak. ?I wrote about this at >> >> . >> ?That's because the generating thread has no way of knowing when the >> client did a "break" from the loop. >> >> You can solve this if your language has support for an AutoCloseable >> interface, and the Iterator is closed at the end by the expansion of >> the for-each loop when the Iterator is a subtype of AutoCloseable. >> Unfortunately, the current ARM proposal does not do that. >> >> On Wed, Mar 25, 2009 at 6:33 AM, Tim Peierls wrote: >> > My sense (bolstered by a quick Google code search) is that people have >> > been >> > coming up with this kind of functionality on their own as they encounter >> > a >> > need for it. Is it really something that needs special language support? >> > Using another thread to do the generation is quite reasonable. You can >> > build >> > a nice coroutine-style facility with a pair of SynchronousQueues (or, >> > more >> > generally and flexibly, with TransferQueues, expected for Java 7; or >> > maybe >> > with Phasers). Using that as a building block you could then rewrite >> > your >> > example below as something like this: >> > >> > final List allUsersList = ...; >> > Iterator userIterator = generatorToIterator(new Generator() >> > { >> > ? ?public void generate(Generation generation) { >> > ? ? ? ?for (User user : allUsersList) { >> > ? ? ? ? ? ?if (user.isActive()) generation.yield(user); >> > ? ? ? ?} >> > ? ?} >> > }); >> > // Now userIterator lazily produces active users. >> > >> > >> > Getting this kind of thing right is hard enough that someone should >> > propose >> > putting a production version in the standard library, but I don't see >> > the >> > need for a language change. >> > >> > For your particular example, you could use Google Collections' >> > >> > Iterators.filter> > com.google.common.base.Predicate)>: >> > >> > Iterator userIterator = filter(allUsersList.iterator(), new >> > Predicate() { >> > ? ?public boolean apply(User user) { >> > return user.isActive(); >> > ? ?} >> > }); >> > >> > >> > That's not true generation, but I bet lazy filtering handles a lot of >> > the >> > common cases that people think they want generation for. >> > >> > --tim >> > >> > >> > >> > On Tue, Mar 24, 2009 at 3:07 PM, Mark Derricutt wrote: >> > >> >> Hi all, >> >> >> >> This isn't an actual proposal, but more a proposal idea that hopefully >> >> someone could run with. ?I was thinking about all the closures issues >> >> and looking at a lot of my code where I'm using closure like patterns >> >> and started thinking what would really make things easier for me would >> >> be some form of yield/generators api to give me a cleaner way of >> >> making Iterable's that could be used in the JDK5 for loop. >> >> >> >> The usage I'd like would be something like: >> >> >> >> for ( User user : allUsersList) { >> >> ?if (user.isActive()) yield user; >> >> } >> >> >> >> Effectively I could see this as being like comparing an XML pull >> >> parser to SAX. ?The problem I have is I can't think of a suitable way >> >> of expressing, or implementing this in java, unless I split the code >> >> into another thread that sleeps between the yield calling back to the >> >> iterable next() call which is nasty as I could see a lot of thread >> >> leakage there. >> >> >> >> Has anyone looked at, or already written some form of generator >> >> proposal? >> >> >> >> >> >> ...and then Buffy staked Edward. ?The End. >> >> >> >> >> > >> > > > From reinier at zwitserloot.com Wed Mar 25 09:59:53 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 17:59:53 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <999760.7333.qm@web63701.mail.re1.yahoo.com> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> Message-ID: There's no reference for auto-POJOs anywhere, but this should allow you to write up all you need: 1. 'data' is a context sensitive keyword that is legal on classes. The 'data' keyword will add a number of members to the class. 2. For each field, a getter is generated, according to the beanspec (getFoo() or isFoo()). if the field is not final, a setter is generated, according to beanspec (setFoo()), and the field is considered a property of the data class, unless it is transient. If the field is public, the getter (and, if not final, the setter), is not generated. For all generated getters/setters, if the getter/setter is already in the class, or already defined (that is; not abstract) in any supertype, then the getter/setter is not generated. protected and visible package protected members from supertypes are also included both for generating setters/getters and for hashCode/equals/toString/ clone (upcoming). 3. hashCode() and equals(): Existence of the hashCode() or equals() method in any supertype is not relevant (obviously; all objects have them!) 3a. If only one of hashCode() or equals() is present, a warning is generated and neither hashCode() or equals() is auto-generated. The warning basically explains that overriding one but not the other is a bug. 3b. If both hashCode() and equals() are present, nothing happens. 3c. If neither is present, a hashCode() and equals() method are generated. These involve all properties (non-transient visible fields). equals() is defined by: 3c1: First check if the other object is of the exact same class as ourselves; if not, false. If null, false. 3c2: For each primitive property, check via == if they are equal. If any isn't, false. 3c3: For each object property, call its .equals(). If they aren't, false. 3c4: return true. for hashCode(), do whatever eclipse does out of the box to auto- generate hashCode() methods. It basically looks like: final int PRIME = 31; int result = 1; for ( each field ) result = result*31 + field.hashCode(); return result; Where hashCode() is generated in obvious fashion for all primitives (xor the upper and lower bits of longs together, convert floats and doubles to long/intbits and use that, chars/bytes/ints/shorts's hashCode is their own value, booleans are translated to 11/17. 'null' becomes 3. 4. *IF* all fields are private, and *IF* all fields are final, *AND* the class does not contain any explicit constructors, *AND* the class has a no-args super constructor, then a constructor is generated that includes all fields, in order of definition, which simply assigns them to the fields. visible properties from supertypes aren't included. 5. A toString() method is generated, if not already present in the type, which produces a string like so: "MyClassName [field1=value, field2=value]", for all properties. (so, non-visible fields from supertypes and transient fields are skipped). 6 (optional). Each generated member gets a @Generated annotation, which is a new annotation ( java.lang.annotations.Generated ). These are @Documented and @Retention.RUNTIME. Is it viable for coin? I'll write it up if so. --Reinier Zwitserloot On Mar 25, 2009, at 14:41, james lowden wrote: > > I'd like to see both. Auto-getters/setters/equals/etc. would be > really, really nice, but it would also be valuable to have a way of > specifying a variety of different constructors to generate, which > Mark's proposal would allow for. Example: > > public data class Foo { > private final int x; > private final int y; > private final String foo; > > public Foo (this.x) {} > > public Foo (this.foo, this.y) {} > } > > > (I eliminated the types from the automagical constructors, as they > can be inferred by the compiler.) > > This would generate all three getters and setters, equals (), > hashcode (), a general constructor taking in all 3 fields, and two > additional constructors, one taking in just int x, and one taking in > both String foo and int y. > > Reinier--is there a copy of your original proposal for auto-POJOs > somewhere? > > -JL- > > >> From: Reinier Zwitserloot >> Subject: Re: PROPOSAL: Auto-assignment Parameters >> To: "Mark Mahieu" >> Cc: coin-dev at openjdk.java.net >> Date: Tuesday, March 24, 2009, 8:34 PM >> I like where this is going, but I'd rather see a bigger >> setup for auto- >> POJO classes. I proposed this before and in most java >> circles (outside >> of coin-dev!), this idea was considered very useful: >> >> public data class Foo { >> private final int x; >> private final int y; >> private final String foo; >> } >> >> >> The above class would auto-generate the getters, a >> constructor, >> hashCode, equals, and toString. You can add methods to it >> if you want, >> and if you define a method that would usually be >> auto-generated, it >> isn't auto-generated. So, if you need to do some extra >> processing >> before returning 'foo' via the getter, go right >> ahead. You can even >> add this later without breaking your API's >> compatibility. >> >> --Reinier Zwitserloot >> >> >> >> On Mar 25, 2009, at 02:07, Mark Mahieu wrote: >> >>> HTML version + prototype available at >> http://slm888.com/javac >>> >>> >>> >>> Auto-assignment Parameters v0.1 >>> >>> >>> AUTHOR(S): >>> >>> Mark Mahieu >>> >>> >>> OVERVIEW >>> >>> FEATURE SUMMARY: Should be suitable as a summary in a >> language >>> tutorial. >>> >>> An additional form of constructor parameter which >> provides automatic >>> assignment of the parameter's value to an instance >> field. These >>> parameters >>> are implicitly declared as final to prevent >> unintentional >>> assignments to the >>> wrong variable in the constructor body. >>> >>> >>> MAJOR ADVANTAGE: What makes the proposal a favorable >> change? >>> >>> Reduces the likelihood of some common coding errors >> relating to >>> assignment >>> of fields in a constructor, including those where: >>> >>> * a field is assigned to itself >>> * the parameter is assigned instead of the field >>> * the assignment to the field is missing entirely >>> >>> These and other errors are often caused by typos or >> code refactoring. >>> >>> >>> MAJOR BENEFIT: Why is the platform better if the >> proposal is adopted? >>> >>> A programmer's intent is more clearly expressed >> for the extremely >>> common >>> case of assigning a constructor parameter directly to >> an instance >>> field with >>> the same name. >>> >>> >>> MAJOR DISADVANTAGE: There is always a cost. >>> >>> As with any sugar which enables a more concise way of >> expressing an >>> existing >>> idiom, programmers may be tempted to use it even when >> the original >>> form >>> would be more appropriate. >>> >>> >>> ALTERNATIVES: Can the benefits and advantages be had >> some way >>> without a >>> language change? >>> >>> IDEs and tools such as FindBugs are good at warning >> about the kind >>> of errors >>> mentioned above, however since the code in question is >> usually still >>> valid >>> to the compiler, they are limited in what action they >> can take by >>> default. >>> >>> A language change can combine the ability to avoid >> these errors >>> entirely >>> with a more expressive idiom, resulting in an >> increased signal to >>> noise >>> ratio for readers of that code. >>> >>> >>> >>> EXAMPLES >>> >>> SIMPLE EXAMPLE: Show the simplest possible program >> utilizing the new >>> feature. >>> >>> class C { >>> int i; >>> C(int this.i) {} >>> } >>> >>> >>> ADVANCED EXAMPLE: Show advanced usage(s) of the >> feature. >>> >>> >>> class Proposal { >>> >>> private final String name; >>> private final String author; >>> private boolean suitableForCoin; >>> private Integer score; >>> >>> public Proposal(String this.name, >>> String this.author, >>> boolean this.suitableForCoin, >>> int this.score) { >>> >>> if (name.equals(?Auto-assignment >> Parameters?)) { >>> suitableForCoin = true; // final so >> compile-time error >>> } >>> } >>> >>> // rest of class ... >>> } >>> >>> >>> >>> 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. >>> >>> The syntactic grammar is modified to include >> auto-assignment >>> parameters for >>> constructors: >>> >>> ConstructorDeclaratorRest: >>> ConstructorParameters [throws >> QualifiedIdentifierList] >>> MethodBody >>> >>> ConstructorParameters: >>> ( [ConstructorParameterDecls] ) >>> >>> ConstructorParameterDecls: >>> [final] [Annotations] Type >>> ConstructorParameterDeclsRest >>> >>> ConstructorParameterDeclsRest: >>> ConstructorParameterId [ , >> ConstructorParameterDecls] >>> ... ConstructorParameterId >>> >>> ConstructorParameterId: >>> VariableDeclaratorId >>> this . VariableDeclaratorId >>> super . VariableDeclaratorId >>> >>> An auto-assignment parameter is a formal parameter >> (JLSv3 ?8.4.1) >>> which >>> specifies an instance field instead of an identifier. >> Its value is >>> automatically assigned to the specified field. It may >> only be used >>> in a >>> constructor. >>> >>> The automatic assignment takes place after any >> explicit or implicit >>> invocation of another constructor, and before any >> statements in the >>> body of >>> the constructor. A constructor which declares n >> auto-assignment >>> parameters >>> will perform n such automatic assignments, in the >> order that the >>> parameters >>> are declared. >>> >>> The parameter has the same name (JLSv3 ?6.2) as the >> field to which >>> it is >>> assigned; replacing each auto-assignment parameter >> with a normal >>> formal >>> parameter with the same name would yield a constructor >> with an >>> identical >>> signature. As with a normal parameter, the >> parameter's name is >>> entered into >>> the scope of the constructor body (JLSv3 ?6.3), and >> therefore >>> shadows the >>> field (JLSv3 ?6.3.1) within that scope. >>> >>> It is a compile-time error if the field is not >> accessible from the >>> constructor in which the parameter appears. >>> >>> It is a compile-time error if the declared type of the >> parameter is >>> not >>> assignment compatible (JLSv3 ?5.2) with the field to >> which it is >>> automatically assigned. >>> >>> If an unboxing conversion is required by an automatic >> assignment, any >>> NullPointerException thrown as a result (JLSv3 >> ?5.1.8) will contain >>> the name >>> of the field on which the conversion failed, which may >> be retrieved by >>> calling getMessage() on the exception. >>> >>> Auto-assignment parameters are implicitly final, and >> follow the >>> standard >>> rules for final variables (JLSv3 ?4.12.4). >> Explicitly declaring an >>> auto-assignment parameter as final has no effect, and >> does not cause a >>> compilation error. >>> >>> Auto-assignment parameters follow the standard >> definite assignment >>> rules for >>> formal parameters (JLSv3 ?16.3). >>> >>> An auto-assignment parameter may be annotated. >>> >>> If an auto-assignment parameter is the last parameter >> in the list, and >>> refers to a field of array type, it may be a variable >> arity parameter. >>> >>> >>> >>> 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! >>> >>> Desugaring of the following class: >>> >>> class Foo { >>> int value; >>> Foo(Integer this.value) { >>> System.out.println(value); >>> } >>> } >>> >>> would result in (unboxing desugaring omitted): >>> >>> class Foo { >>> int value; >>> Foo(final Integer value) { >>> super(); >>> if (value == null) >>> throw new >> NullPointerException("value"); >>> this.value = value; >>> System.out.println(value); >>> } >>> } >>> >>> No changes to the classfile format are required. >> Tools which >>> consume class >>> files see the constructor signature as though it had >> been written >>> using >>> normal formal parameters. >>> >>> >>> TESTING: How can the feature be tested? >>> >>> An initial set of jtreg tests is included in the >> prototype. >>> >>> >>> LIBRARY SUPPORT: Are any supporting libraries needed >> for the feature? >>> >>> No >>> >>> >>> 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. >>> >>> com.sun.source.tree.VariableTree would require an >> additional method >>> which >>> returns the auto-assigned field. >>> >>> >>> 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 >>> >>> >>> MIGRATION: Sketch how a code base could be converted, >> manually or >>> automatically, to use the new feature. >>> >>> Assignment statements in constructors for which all of >> the following >>> are >>> true can be considered suitable for conversion: >>> * the lhs of the assignment is a non-static field >>> * the rhs is a parameter with the same name as the >> field >>> * there are no other assignments to the parameter >> anywhere in the >>> constructor >>> * there are no assignments to, or other uses of >> the field before >>> the >>> assignment statement in question (including invoked >> constructors) >>> >>> Such statements can be converted by: >>> 1) replacing the parameter with an auto-assignment >> parameter >>> (prefixing >>> the existing parameter's identifier with >> 'this.'), and >>> 2) removing the assignment statement >>> >>> >>> >>> COMPATIBILITY >>> >>> BREAKING CHANGES: Are any previously valid programs >> now invalid? If >>> so, list >>> one. >>> >>> No >>> >>> >>> 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 semantics of existing class files and legal source >> files are >>> unchanged >>> by this feature. >>> >>> >>> >>> REFERENCES >>> >>> EXISTING BUGS: Please include a list of any existing >> Sun bug ids >>> related to >>> this proposal. >>> >>> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 >>> (uses a 'setter' method rather than a >> constructor in its example) >>> >>> FindBugs bug patterns - >> http://findbugs.sourceforge.net/bugDescriptions.html >>> * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) >>> * Self comparison of field with itself >> (SA_FIELD_SELF_COMPARISON) >>> * Nonsensical self computation involving a field >> (e.g., x & x) >>> (SA_FIELD_SELF_COMPUTATION) >>> * Self assignment of local variable >> (SA_LOCAL_SELF_ASSIGNMENT) >>> * Nonsensical self computation involving a variable >> (e.g., x & x) >>> (SA_LOCAL_SELF_COMPUTATION) >>> * Uninitialized read of field in constructor >> (UR_UNINIT_READ) >>> * Unwritten field (UWF_UNWRITTEN_FIELD) >>> * Dead store to local variable (DLS_DEAD_LOCAL_STORE) >>> * Dead store of null to local variable >> (DLS_DEAD_LOCAL_STORE_OF_NULL) >>> >>> >>> >>> URL FOR PROTOTYPE (optional): >>> >>> http://slm888.com/javac >>> >>> >>> >>> DESIGN ALTERNATIVES: >>> >>> The following variations have been explored and are >> worth mentioning: >>> >>> * Allow auto-assignment parameters on all non-abstract >> methods. >>> This may be especially useful on the extremely >> common 'setter' >>> methods >>> in 'value object' classes. >>> >>> * Remove the requirement for (or even disallow) the >> type to be >>> specified on >>> auto-assignment parameters. >>> Experimentation with this idea suggests that it may >> work quite >>> well for >>> constructors, further emphasising the difference in >> intent and >>> semantics >>> from those of normal parameters. However, it may not >> work so well in >>> combination with auto-assignment parameters on all >> non-abstract >>> methods, and >>> requires a change to the order in which javac compiles >> classes (can >>> still >>> pass jtreg tests). >>> >>> * Allow an alternative name to be specified. >>> This adds additional complexity to support a >> fractional >>> percentage of >>> cases, which could continue to use the existing coding >> pattern. >>> > > > > From reinier at zwitserloot.com Wed Mar 25 10:04:08 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 18:04:08 +0100 Subject: For further consideration... In-Reply-To: References: <49C95DB5.6020202@sun.com> <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> <49C96A42.9050805@sun.com> Message-ID: Excellent point about the disconnection between x?[0] where x is null and x is the empty array. I agree: That shouldn't be in the elvis operators proposal. Arrays aren't nearly as common as member access anyway. --Reinier Zwitserloot On Mar 25, 2009, at 17:44, Tim Keith wrote: > I would like to suggest at least leaving out ?[] > > The example in the proposal is not very compelling: > class Group { > Person[] members; // null if no members > } > class Person { > String name; // may be null > } > final String aMember = g?.members?[0]?.name ?: "nobody"; > > If members is null you get "nobody" but if members is empty (the > logical way > to signify "no members") you get ArrayIndexOutOfBoundsException. > > "array?[...]" is like saying: if array is null treat it like it's an > infinitely > long array of nulls. > > "object?.member" is like saying: if object it null, treat it like > every > field > is null and every method returns null. > The array analog to that should be that "array?.length" means > array == null ? 0 : array.length > > -- Tim > > On Tue, Mar 24, 2009 at 4:18 PM, Joseph D. Darcy > wrote: > >> Jeremy Manson wrote: >>> Joe, >>> >>> Is it all the Elvis operators, or just ?: ? >>> >> >> The more modest version is more likely to get in. >> >> -Joe >> >> >> > From markmahieu at googlemail.com Wed Mar 25 10:33:51 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 25 Mar 2009 17:33:51 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <999760.7333.qm@web63701.mail.re1.yahoo.com> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> Message-ID: <68314A56-1F12-48E9-85C0-1F52BE8FB8E4@googlemail.com> Hi James, I looked into inferring the parameter types, and while it does work quite well for 'brain-dead' POJO classes, it was not so great when you actually want to put some real code in the constructor, for example to throw an exception if a parameter value is not valid. The auto-assignment proposal is very much aimed at helping programmers with code they actually have to *write* (and therefore read and maintain), rather than just generate. If it happens to help with the latter as well, that's great. Mark On 25 Mar 2009, at 13:41, james lowden wrote: > > I'd like to see both. Auto-getters/setters/equals/etc. would be > really, really nice, but it would also be valuable to have a way of > specifying a variety of different constructors to generate, which > Mark's proposal would allow for. Example: > > public data class Foo { > private final int x; > private final int y; > private final String foo; > > public Foo (this.x) {} > > public Foo (this.foo, this.y) {} > } > > > (I eliminated the types from the automagical constructors, as they > can be inferred by the compiler.) From jl0235 at yahoo.com Wed Mar 25 10:39:36 2009 From: jl0235 at yahoo.com (james lowden) Date: Wed, 25 Mar 2009 10:39:36 -0700 (PDT) Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <68314A56-1F12-48E9-85C0-1F52BE8FB8E4@googlemail.com> Message-ID: <628482.25461.qm@web63704.mail.re1.yahoo.com> Shouldn't it still be possible to infer, as in: public data class Foo { private final int must_be_positive; public Foo (this.must_be_positive) throws SomeException { if (must_be_positive < 0) throw new SomeException ("It wasn't positive"); } } -JL --- On Wed, 3/25/09, Mark Mahieu wrote: > From: Mark Mahieu > Subject: Re: PROPOSAL: Auto-assignment Parameters > To: jl0235 at yahoo.com > Cc: coin-dev at openjdk.java.net > Date: Wednesday, March 25, 2009, 12:33 PM > Hi James, > > I looked into inferring the parameter types, and while it > does work quite well for 'brain-dead' POJO classes, > it was not so great when you actually want to put some real > code in the constructor, for example to throw an exception > if a parameter value is not valid. > > The auto-assignment proposal is very much aimed at helping > programmers with code they actually have to *write* (and > therefore read and maintain), rather than just generate. If > it happens to help with the latter as well, that's > great. > > Mark > > > On 25 Mar 2009, at 13:41, james lowden wrote: > > > > > I'd like to see both. > Auto-getters/setters/equals/etc. would be really, really > nice, but it would also be valuable to have a way of > specifying a variety of different constructors to generate, > which Mark's proposal would allow for. Example: > > > > public data class Foo { > > private final int x; > > private final int y; > > private final String foo; > > > > public Foo (this.x) {} > > > > public Foo (this.foo, this.y) {} > > } > > > > > > (I eliminated the types from the automagical > constructors, as they can be inferred by the compiler.) From markmahieu at googlemail.com Wed Mar 25 10:44:24 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Wed, 25 Mar 2009 17:44:24 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <628482.25461.qm@web63704.mail.re1.yahoo.com> References: <628482.25461.qm@web63704.mail.re1.yahoo.com> Message-ID: <4A079116-8009-437E-93A2-E12CBBE426AB@googlemail.com> Oh sure, perfectly possible. I have an earlier prototype of the proposal which will compile that just fine. When I said it wasn't so great I meant that inferring the type - in this context - hinders anyone trying to understand the code, IMO. Mark On 25 Mar 2009, at 17:39, james lowden wrote: > > Shouldn't it still be possible to infer, as in: > > public data class Foo { > > private final int must_be_positive; > > public Foo (this.must_be_positive) throws SomeException { > if (must_be_positive < 0) > throw new SomeException ("It wasn't positive"); > } > > } > > > -JL > > --- On Wed, 3/25/09, Mark Mahieu wrote: > >> From: Mark Mahieu >> Subject: Re: PROPOSAL: Auto-assignment Parameters >> To: jl0235 at yahoo.com >> Cc: coin-dev at openjdk.java.net >> Date: Wednesday, March 25, 2009, 12:33 PM >> Hi James, >> >> I looked into inferring the parameter types, and while it >> does work quite well for 'brain-dead' POJO classes, >> it was not so great when you actually want to put some real >> code in the constructor, for example to throw an exception >> if a parameter value is not valid. >> >> The auto-assignment proposal is very much aimed at helping >> programmers with code they actually have to *write* (and >> therefore read and maintain), rather than just generate. If >> it happens to help with the latter as well, that's >> great. >> >> Mark >> >> >> On 25 Mar 2009, at 13:41, james lowden wrote: >> >>> >>> I'd like to see both. >> Auto-getters/setters/equals/etc. would be really, really >> nice, but it would also be valuable to have a way of >> specifying a variety of different constructors to generate, >> which Mark's proposal would allow for. Example: >>> >>> public data class Foo { >>> private final int x; >>> private final int y; >>> private final String foo; >>> >>> public Foo (this.x) {} >>> >>> public Foo (this.foo, this.y) {} >>> } >>> >>> >>> (I eliminated the types from the automagical >> constructors, as they can be inferred by the compiler.) > > > From vapor1 at teleport.com Wed Mar 25 11:06:03 2009 From: vapor1 at teleport.com (Derek Foster) Date: Wed, 25 Mar 2009 11:06:03 -0700 Subject: PROPOSAL: Binary Literals Message-ID: Hmm. Second try at sending to the list. Let's see if this works. (In the meantime, I noticed that Bruce Chapman has mentioned something similar in his another proposal, so I think we are in agreement on this. This proposal should not be taken as to compete with his similar proposal: I'd quite like to see type suffixes for bytes, shorts, etc. added to Java, in addition to binary literals.) Anyway... Add binary literals to Java. AUTHOR(S): Derek Foster OVERVIEW In some programming domains, use of binary numbers (typically as bitmasks, bit-shifts, etc.) is very common. However, Java code, due to its C heritage, has traditionally forced programmers to represent numbers in only decimal, octal, or hexadecimal. (In practice, octal is rarely used, and is present mostly for backwards compatibility with C) When the data being dealt with is fundamentally bit-oriented, however, using hexadecimal to represent ranges of bits requires an extra degree of translation for the programmer, and this can often become a source of errors. For instance, if a technical specification lists specific values of interest in binary (for example, in a compression encoding algorithm or in the specifications for a network protocol, or for communicating with a bitmapped hardware device) then a programmer coding to that specification must translate each such value from its binary representation into hexadecimal. Checking to see if this translation has been done correctly is accomplished by back-translating the numbers. In most cases, programmers do these translations in their heads, and HOPEFULLY get them right. however, errors can easily creep in, and re-verifying the results is not straightforward enough to be done frequently. Furthermore, in many cases, the binary representations of numbers makes it much more clear what is actually intended than the hexadecimal one. For instance, this: private static final int BITMASK = 0x1E; does not immediately make it clear that the bitmask being declared comprises a single contiguous range of four bits. In many cases, it would be more natural for the programmer to be able to write the numbers in binary in the source code, eliminating the need for manual translation to hexadecimal entirely. FEATURE SUMMARY: In addition to the existing "1" (decimal), "01" (octal) and "0x1" (hexadecimal) form of specifying numeric literals, a new form "0b1" (binary) would be added. Note that this is the same syntax as has been used as an extension by the GCC C/C++ compilers for many years, and also is used in the Ruby language, as well as in the Python language. MAJOR ADVANTAGE: It is no longer necessary for programmers to translate binary numbers to and from hexadecimal in order to use them in Java programs. MAJOR BENEFIT: Code using bitwise operations is more readable and easier to verify against technical specifications that use binary numbers to specify constants. Routines that are bit-oriented are easier to understand when an artifical translation to hexadecimal is not required in order to fulfill the constraints of the language. MAJOR DISADVANTAGE: Someone might incorrectly think that "0b1" represented the same value as hexadecimal number "0xB1". However, note that this problem has existed for octal/decimal for many years (confusion between "050" and "50") and does not seem to be a major issue. ALTERNATIVES: Users could continue to write the numbers as decimal, octal, or hexadecimal, and would continue to have the problems observed in this document. Another alternative would be for code to translate at runtime from binary strings, such as: int BITMASK = Integer.parseInt("00001110", 2); Besides the obvious extra verbosity, there are several problems with this: * Calling a method such as Integer.parseInt at runtime will typically make it impossible for the compiler to inline the value of this constant, since its value has been taken from a runtime method call. Inlining is important, because code that does bitwise parsing is often very low-level code in tight loops that must execute quickly. (This is particularly the case for mobile applications and other applications that run on severely resource-constrained environments, which is one of the cases where binary numbers would be most valuable, since talking to low-level hardware is one of the primary use cases for this feature.) * Constants such as the above cannot be used as selectors in 'switch' statements. * Any errors in the string to be parsed (for instance, an extra space) will result in runtime exceptions, rather than compile-time errors as would have occurred in normal parsing. If such a value is declared 'static', this will result in some very ugly exceptions at runtime. EXAMPLES: // An 8-bit 'byte' literal. byte aByte = (byte)0b00100001; // A 16-bit 'short' literal. short aShort = (short)0b1010000101000101; // Some 32-bit 'int' literals. int anInt1 = 0b10100001010001011010000101000101; int anInt2 = 0b101; int anInt3 = 0B101; // The B can be upper or lower case as per the x in "0x45". // A 64-bit 'long' literal. Note the "L" suffix, as would also be used // for a long in decimal, hexadecimal, or octal. long aLong = 0b01010000101000101101000010100010110100001010001011010000101000101L; SIMPLE EXAMPLE: class Foo { public static void main(String[] args) { System.out.println("The value 10100001 in decimal is " + 0b10100001); } ADVANCED EXAMPLE: // Binary constants could be used in code that needs to be // easily checkable against a specifications document, such // as this simulator for a hypothetical 8-bit microprocessor: public State decodeInstruction(int instruction, State state) { if ((instruction & 0b11100000) == 0b00000000) { final int register = instruction & 0b00001111; switch (instruction & 0b11110000) { case 0b00000000: return state.nop(); case 0b00010000: return state.copyAccumTo(register); case 0b00100000: return state.addToAccum(register); case 0b00110000: return state.subFromAccum(register); case 0b01000000: return state.multiplyAccumBy(register); case 0b01010000: return state.divideAccumBy(register); case 0b01100000: return state.setAccumFrom(register); case 0b01110000: return state.returnFromCall(); default: throw new IllegalArgumentException(); } } else { final int address = instruction & 0b00011111; switch (instruction & 0b11100000) { case 0b00100000: return state.jumpTo(address); case 0b01000000: return state.jumpIfAccumZeroTo(address); case 0b01000000: return state.jumpIfAccumNonzeroTo(address); case 0b01100000: return state.setAccumFromMemory(address); case 0b10100000: return state.writeAccumToMemory(address); case 0b11000000: return state.callTo(address); default: throw new IllegalArgumentException(); } } } // Binary literals can be used to make a bitmap more readable: public static final short[] HAPPY_FACE = { (short)0b0000011111100000; (short)0b0000100000010000; (short)0b0001000000001000; (short)0b0010000000000100; (short)0b0100000000000010; (short)0b1000011001100001; (short)0b1000011001100001; (short)0b1000000000000001; (short)0b1000000000000001; (short)0b1001000000001001; (short)0b1000100000010001; (short)0b0100011111100010; (short)0b0010000000000100; (short)0b0001000000001000; (short)0b0000100000010000; (short)0b0000011111100000; } // Binary literals can make relationships // among data more apparent than they would // be in hex or octal. // // For instance, what does the following // array contain? In hexadecimal, it's hard to tell: public static final int[] PHASES = { 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 } // In binary, it's obvious that a number is being // rotated left one bit at a time. public static final int[] PHASES = { 0b00110001, 0b01100010, 0b11000100, 0b10001001, 0b00010011, 0b00100110, 0b01001100, 0b10011000, } DETAILS SPECIFICATION: Section 3.10.1 ("Integer Literals") of the JLS3 should be changed to add the following: IntegerLiteral: DecimalIntegerLiteral HexIntegerLiteral OctalIntegerLiteral BinaryIntegerLiteral // Added BinaryIntegerLiteral: BinaryNumeral IntegerTypeSuffix_opt BinaryNumeral: 0 b BinaryDigits 0 B BinaryDigits BinaryDigits: BinaryDigit BinaryDigit BinaryDigits BinaryDigit: one of 0 1 COMPILATION: Binary literals would be compiled to class files in the same fashion as existing decimal, hexadecimal, and octal literals are. No special support or changes to the class file format are needed. TESTING: The feature can be tested in the same way as existing decimal, hexadecimal, and octal literals are: Create a bunch of constants in source code, including the maximum and minimum positive and negative values for integer and long types, and verify them at runtime to have the correct values. LIBRARY SUPPORT: The methods Integer.decode(String) and Long.decode(String) should be modified to parse binary numbers (as specified above) in addition to their existing support for decimal, hexadecimal, and octal numbers. REFLECTIVE APIS: No updates to the reflection APIs are needed. OTHER CHANGES: No other changes are needed. MIGRATION: Individual decimal, hexadecimal, or octal constants in existing code can be updated to binary as a programmer desires. COMPATIBILITY BREAKING CHANGES: This feature would not break any existing programs, since the suggested syntax is currently considerd to be a compile-time error. EXISTING PROGRAMS: Class file format does not change, so existing programs can use class files compiled with the new feature without problems. REFERENCES: The GCC/G++ compiler, which already supports this syntax (as of version 4.3) as an extension to standard C/C++. http://gcc.gnu.org/gcc-4.3/changes.html The Ruby language, which supports binary literals: http://wordaligned.org/articles/binary-literals The Python language added binary literals in version 2.6: http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax EXISTING BUGS: "Language support for literal numbers in binary and other bases" http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 URL FOR PROTOTYPE (optional): None. From lk at teamten.com Wed Mar 25 11:25:29 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Wed, 25 Mar 2009 11:25:29 -0700 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: <999760.7333.qm@web63701.mail.re1.yahoo.com> Message-ID: <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> Reinier, The idea of adding a context-sensitive keyword creeps me out. Also this is doing a lot of magic based on a single keyword. Can you tell, at a glance, what the keyword is doing? How much is generated? What are the (complex) rules for auto-generating a constructor? I would prefer a more explicit approach, driven by annotations. If we feel like boilerplate is annoying to write and bug-prone, then we could have a java.lang.gen package with various annotations for automatically generating code. Something like: @GenerateFullConstructor @GenerateEqualsAndHashCode @GenerateToString(JsonToStringGenerator.class) public class Foo { @GenerateGetter private final int x; @GenerateGetter private final int y; @GenerateGetter private final String foo; } Then it's explicit, each annotation can have parameters to modify its behavior, and people can pick and choose what they need. There's no magic about skipping the generation of toString if you've implemented it. Here's an example of useful parameters for such annotations: many people (myself included) like to prefix fields with something. I use "m" (mFoo), but others use an underscore, and some both (m_foo). You'd want the GenerateGetter annotation to be flexible about that. My code would look like this: @GenerateGetter(prefix = "m") private final String mFoo; Your "data" keyword would preclude this, forcing me to either drop my (company-mandated) coding standard for data classes, or have getters like "getMFoo()". With GenerateEqualsAndHashCode you might want to skip some fields. You might want to skip fields for GenerateToString also (e.g., password fields, or super long strings). Lawrence On Wed, Mar 25, 2009 at 9:59 AM, Reinier Zwitserloot wrote: > There's no reference for auto-POJOs anywhere, but this should allow > you to write up all you need: > > 1. 'data' is a context sensitive keyword that is legal on classes. The > 'data' keyword will add a number of members to the class. > > 2. For each field, a getter is generated, according to the beanspec > (getFoo() or isFoo()). if the field is not final, a setter is > generated, according to beanspec (setFoo()), and the field is > considered a property of the data class, unless it is transient. If > the field is public, the getter (and, if not final, the setter), is > not generated. For all generated getters/setters, if the getter/setter > is already in the class, or already defined (that is; not abstract) in > any supertype, then the getter/setter is not generated. protected and > visible package protected members from supertypes are also included > both for generating setters/getters and for hashCode/equals/toString/ > clone (upcoming). > > 3. hashCode() and equals(): Existence of the hashCode() or equals() > method in any supertype is not relevant (obviously; all objects have > them!) > > 3a. If only one of hashCode() or equals() is present, a warning is > generated and neither hashCode() or equals() is auto-generated. The > warning basically explains that overriding one but not the other is a > bug. > > 3b. If both hashCode() and equals() are present, nothing happens. > > 3c. If neither is present, a hashCode() and equals() method are > generated. These involve all properties (non-transient visible > fields). equals() is defined by: > > ?3c1: First check if the other object is of the exact same class as > ourselves; if not, false. If null, false. > ?3c2: For each primitive property, check via == if they are equal. If > any isn't, false. > ?3c3: For each object property, call its .equals(). If they aren't, > false. > ?3c4: return true. > > for hashCode(), do whatever eclipse does out of the box to auto- > generate hashCode() methods. It basically looks like: > > final int PRIME = 31; > int result = 1; > for ( each field ) result = result*31 + field.hashCode(); > return result; > > Where hashCode() is generated in obvious fashion for all primitives > (xor the upper and lower bits of longs together, convert floats and > doubles to long/intbits and use that, chars/bytes/ints/shorts's > hashCode is their own value, booleans are translated to 11/17. 'null' > becomes 3. > > 4. *IF* all fields are private, and *IF* all fields are final, *AND* > the class does not contain any explicit constructors, *AND* the class > has a no-args super constructor, then a constructor is generated that > includes all fields, in order of definition, which simply assigns them > to the fields. visible properties from supertypes aren't included. > > 5. A toString() method is generated, if not already present in the > type, which produces a string like so: "MyClassName [field1=value, > field2=value]", for all properties. (so, non-visible fields from > supertypes and transient fields are skipped). > > 6 (optional). Each generated member gets a @Generated annotation, > which is a new annotation ( java.lang.annotations.Generated ). These > are @Documented and @Retention.RUNTIME. > > > Is it viable for coin? I'll write it up if so. > > ?--Reinier Zwitserloot > > > > On Mar 25, 2009, at 14:41, james lowden wrote: > >> >> I'd like to see both. ?Auto-getters/setters/equals/etc. would be >> really, really nice, but it would also be valuable to have a way of >> specifying a variety of different constructors to generate, which >> Mark's proposal would allow for. ?Example: >> >> public data class Foo { >> ? ? ?private final int x; >> ? ? ?private final int y; >> ? ? ?private final String foo; >> >> ? ? ?public Foo (this.x) {} >> >> ? ? ?public Foo (this.foo, this.y) {} >> } >> >> >> (I eliminated the types from the automagical constructors, as they >> can be inferred by the compiler.) >> >> This would generate all three getters and setters, equals (), >> hashcode (), a general constructor taking in all 3 fields, and two >> additional constructors, one taking in just int x, and one taking in >> both String foo and int y. >> >> Reinier--is there a copy of your original proposal for auto-POJOs >> somewhere? >> >> -JL- >> >> >>> From: Reinier Zwitserloot >>> Subject: Re: PROPOSAL: Auto-assignment Parameters >>> To: "Mark Mahieu" >>> Cc: coin-dev at openjdk.java.net >>> Date: Tuesday, March 24, 2009, 8:34 PM >>> I like where this is going, but I'd rather see a bigger >>> setup for auto- >>> POJO classes. I proposed this before and in most java >>> circles (outside >>> of coin-dev!), this idea was considered very useful: >>> >>> public data class Foo { >>> ? ? private final int x; >>> ? ? private final int y; >>> ? ? private final String foo; >>> } >>> >>> >>> The above class would auto-generate the getters, a >>> constructor, >>> hashCode, equals, and toString. You can add methods to it >>> if you want, >>> and if you define a method that would usually be >>> auto-generated, it >>> isn't auto-generated. So, if you need to do some extra >>> processing >>> before returning 'foo' via the getter, go right >>> ahead. You can even >>> add this later without breaking your API's >>> compatibility. >>> >>> ?--Reinier Zwitserloot >>> >>> >>> >>> On Mar 25, 2009, at 02:07, Mark Mahieu wrote: >>> >>>> HTML version + prototype available at >>> http://slm888.com/javac >>>> >>>> >>>> >>>> Auto-assignment Parameters v0.1 >>>> >>>> >>>> AUTHOR(S): >>>> >>>> Mark Mahieu >>>> >>>> >>>> OVERVIEW >>>> >>>> FEATURE SUMMARY: Should be suitable as a summary in a >>> language >>>> tutorial. >>>> >>>> An additional form of constructor parameter which >>> provides automatic >>>> assignment of the parameter's value to an instance >>> field. ?These >>>> parameters >>>> are implicitly declared as final to prevent >>> unintentional >>>> assignments to the >>>> wrong variable in the constructor body. >>>> >>>> >>>> MAJOR ADVANTAGE: What makes the proposal a favorable >>> change? >>>> >>>> Reduces the likelihood of some common coding errors >>> relating to >>>> assignment >>>> of fields in a constructor, including those where: >>>> >>>> ? * a field is assigned to itself >>>> ? * the parameter is assigned instead of the field >>>> ? * the assignment to the field is missing entirely >>>> >>>> These and other errors are often caused by typos or >>> code refactoring. >>>> >>>> >>>> MAJOR BENEFIT: Why is the platform better if the >>> proposal is adopted? >>>> >>>> A programmer's intent is more clearly expressed >>> for the extremely >>>> common >>>> case of assigning a constructor parameter directly to >>> an instance >>>> field with >>>> the same name. >>>> >>>> >>>> MAJOR DISADVANTAGE: There is always a cost. >>>> >>>> As with any sugar which enables a more concise way of >>> expressing an >>>> existing >>>> idiom, programmers may be tempted to use it even when >>> the original >>>> form >>>> would be more appropriate. >>>> >>>> >>>> ALTERNATIVES: Can the benefits and advantages be had >>> some way >>>> without a >>>> language change? >>>> >>>> IDEs and tools such as FindBugs are good at warning >>> about the kind >>>> of errors >>>> mentioned above, however since the code in question is >>> usually still >>>> valid >>>> to the compiler, they are limited in what action they >>> can take by >>>> default. >>>> >>>> A language change can combine the ability to avoid >>> these errors >>>> entirely >>>> with a more expressive idiom, resulting in an >>> increased signal to >>>> noise >>>> ratio for readers of that code. >>>> >>>> >>>> >>>> EXAMPLES >>>> >>>> SIMPLE EXAMPLE: Show the simplest possible program >>> utilizing the new >>>> feature. >>>> >>>> ? class C { >>>> ? ? ? int i; >>>> ? ? ? C(int this.i) {} >>>> ? } >>>> >>>> >>>> ADVANCED EXAMPLE: Show advanced usage(s) of the >>> feature. >>>> >>>> >>>> ? class Proposal { >>>> >>>> ? ? ? private final String name; >>>> ? ? ? private final String author; >>>> ? ? ? private boolean suitableForCoin; >>>> ? ? ? private Integer score; >>>> >>>> ? ? ? public Proposal(String this.name, >>>> ? ? ? ? ? ? ? ? ? ? ? String this.author, >>>> ? ? ? ? ? ? ? ? ? ? ? boolean this.suitableForCoin, >>>> ? ? ? ? ? ? ? ? ? ? ? int this.score) { >>>> >>>> ? ? ? ? ? if (name.equals(?Auto-assignment >>> Parameters?)) { >>>> ? ? ? ? ? ? ?suitableForCoin = true; // final so >>> compile-time error >>>> ? ? ? ? ? } >>>> ? ? ? } >>>> >>>> ? ? ? // rest of class ... >>>> ? } >>>> >>>> >>>> >>>> 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. >>>> >>>> The syntactic grammar is modified to include >>> auto-assignment >>>> parameters for >>>> constructors: >>>> >>>> ? ? ? ConstructorDeclaratorRest: >>>> ? ? ? ? ? ? ? ?ConstructorParameters [throws >>> QualifiedIdentifierList] >>>> MethodBody >>>> >>>> ? ? ? ConstructorParameters: >>>> ? ? ? ? ? ? ? ?( [ConstructorParameterDecls] ) >>>> >>>> ? ? ? ConstructorParameterDecls: >>>> ? ? ? ? ? ? ? ?[final] [Annotations] Type >>>> ConstructorParameterDeclsRest >>>> >>>> ? ? ? ConstructorParameterDeclsRest: >>>> ? ? ? ? ? ? ? ?ConstructorParameterId [ , >>> ConstructorParameterDecls] >>>> ? ? ? ? ? ? ? ?... ConstructorParameterId >>>> >>>> ? ? ? ConstructorParameterId: >>>> ? ? ? ? ? ? ? ?VariableDeclaratorId >>>> ? ? ? ? ? ? ? ?this . VariableDeclaratorId >>>> ? ? ? ? ? ? ? ?super . VariableDeclaratorId >>>> >>>> An auto-assignment parameter is a formal parameter >>> (JLSv3 ?8.4.1) >>>> which >>>> specifies an instance field instead of an identifier. >>> Its value is >>>> automatically assigned to the specified field. ?It may >>> only be used >>>> in a >>>> constructor. >>>> >>>> The automatic assignment takes place after any >>> explicit or implicit >>>> invocation of another constructor, and before any >>> statements in the >>>> body of >>>> the constructor. ?A constructor which declares n >>> auto-assignment >>>> parameters >>>> will perform n such automatic assignments, in the >>> order that the >>>> parameters >>>> are declared. >>>> >>>> The parameter has the same name (JLSv3 ?6.2) as the >>> field to which >>>> it is >>>> assigned; replacing each auto-assignment parameter >>> with a normal >>>> formal >>>> parameter with the same name would yield a constructor >>> with an >>>> identical >>>> signature. ?As with a normal parameter, the >>> parameter's name is >>>> entered into >>>> the scope of the constructor body (JLSv3 ?6.3), and >>> therefore >>>> shadows the >>>> field (JLSv3 ?6.3.1) within that scope. >>>> >>>> It is a compile-time error if the field is not >>> accessible from the >>>> constructor in which the parameter appears. >>>> >>>> It is a compile-time error if the declared type of the >>> parameter is >>>> not >>>> assignment compatible (JLSv3 ?5.2) with the field to >>> which it is >>>> automatically assigned. >>>> >>>> If an unboxing conversion is required by an automatic >>> assignment, any >>>> NullPointerException thrown as a result (JLSv3 >>> ?5.1.8) will contain >>>> the name >>>> of the field on which the conversion failed, which may >>> be retrieved by >>>> calling getMessage() on the exception. >>>> >>>> Auto-assignment parameters are implicitly final, and >>> follow the >>>> standard >>>> rules for final variables (JLSv3 ?4.12.4). >>> Explicitly declaring an >>>> auto-assignment parameter as final has no effect, and >>> does not cause a >>>> compilation error. >>>> >>>> Auto-assignment parameters follow the standard >>> definite assignment >>>> rules for >>>> formal parameters (JLSv3 ?16.3). >>>> >>>> An auto-assignment parameter may be annotated. >>>> >>>> If an auto-assignment parameter is the last parameter >>> in the list, and >>>> refers to a field of array type, it may be a variable >>> arity parameter. >>>> >>>> >>>> >>>> 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! >>>> >>>> Desugaring of the following class: >>>> >>>> ? class Foo { >>>> ? ? ? int value; >>>> ? ? ? Foo(Integer this.value) { >>>> ? ? ? ? ? System.out.println(value); >>>> ? ? ? } >>>> ? } >>>> >>>> would result in (unboxing desugaring omitted): >>>> >>>> ? class Foo { >>>> ? ? ? int value; >>>> ? ? ? Foo(final Integer value) { >>>> ? ? ? ? ? super(); >>>> ? ? ? ? ? if (value == null) >>>> ? ? ? ? ? ? ? throw new >>> NullPointerException("value"); >>>> ? ? ? ? ? this.value = value; >>>> ? ? ? ? ? System.out.println(value); >>>> ? ? ? } >>>> ? } >>>> >>>> No changes to the classfile format are required. >>> Tools which >>>> consume class >>>> files see the constructor signature as though it had >>> been written >>>> using >>>> normal formal parameters. >>>> >>>> >>>> TESTING: How can the feature be tested? >>>> >>>> An initial set of jtreg tests is included in the >>> prototype. >>>> >>>> >>>> LIBRARY SUPPORT: Are any supporting libraries needed >>> for the feature? >>>> >>>> No >>>> >>>> >>>> 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. >>>> >>>> com.sun.source.tree.VariableTree would require an >>> additional method >>>> which >>>> returns the auto-assigned field. >>>> >>>> >>>> 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 >>>> >>>> >>>> MIGRATION: Sketch how a code base could be converted, >>> manually or >>>> automatically, to use the new feature. >>>> >>>> Assignment statements in constructors for which all of >>> the following >>>> are >>>> true can be considered suitable for conversion: >>>> ? ?* the lhs of the assignment is a non-static field >>>> ? ?* the rhs is a parameter with the same name as the >>> field >>>> ? ?* there are no other assignments to the parameter >>> anywhere in the >>>> constructor >>>> ? ?* there are no assignments to, or other uses of >>> the field before >>>> the >>>> assignment statement in question (including invoked >>> constructors) >>>> >>>> Such statements can be converted by: >>>> ? 1) replacing the parameter with an auto-assignment >>> parameter >>>> (prefixing >>>> the existing parameter's identifier with >>> 'this.'), and >>>> ? 2) removing the assignment statement >>>> >>>> >>>> >>>> COMPATIBILITY >>>> >>>> BREAKING CHANGES: Are any previously valid programs >>> now invalid? If >>>> so, list >>>> one. >>>> >>>> No >>>> >>>> >>>> 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 semantics of existing class files and legal source >>> files are >>>> unchanged >>>> by this feature. >>>> >>>> >>>> >>>> REFERENCES >>>> >>>> EXISTING BUGS: Please include a list of any existing >>> Sun bug ids >>>> related to >>>> this proposal. >>>> >>>> >>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 >>>> (uses a 'setter' method rather than a >>> constructor in its example) >>>> >>>> FindBugs bug patterns - >>> http://findbugs.sourceforge.net/bugDescriptions.html >>>> * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) >>>> * Self comparison of field with itself >>> (SA_FIELD_SELF_COMPARISON) >>>> * Nonsensical self computation involving a field >>> (e.g., x & x) >>>> (SA_FIELD_SELF_COMPUTATION) >>>> * Self assignment of local variable >>> (SA_LOCAL_SELF_ASSIGNMENT) >>>> * Nonsensical self computation involving a variable >>> (e.g., x & x) >>>> (SA_LOCAL_SELF_COMPUTATION) >>>> * Uninitialized read of field in constructor >>> (UR_UNINIT_READ) >>>> * Unwritten field (UWF_UNWRITTEN_FIELD) >>>> * Dead store to local variable (DLS_DEAD_LOCAL_STORE) >>>> * Dead store of null to local variable >>> (DLS_DEAD_LOCAL_STORE_OF_NULL) >>>> >>>> >>>> >>>> URL FOR PROTOTYPE (optional): >>>> >>>> http://slm888.com/javac >>>> >>>> >>>> >>>> DESIGN ALTERNATIVES: >>>> >>>> The following variations have been explored and are >>> worth mentioning: >>>> >>>> * Allow auto-assignment parameters on all non-abstract >>> methods. >>>> ? This may be especially useful on the extremely >>> common 'setter' >>>> methods >>>> in 'value object' classes. >>>> >>>> * Remove the requirement for (or even disallow) the >>> type to be >>>> specified on >>>> auto-assignment parameters. >>>> ? Experimentation with this idea suggests that it may >>> work quite >>>> well for >>>> constructors, further emphasising the difference in >>> intent and >>>> semantics >>>> from those of normal parameters. However, it may not >>> work so well in >>>> combination with auto-assignment parameters on all >>> non-abstract >>>> methods, and >>>> requires a change to the order in which javac compiles >>> classes (can >>>> still >>>> pass jtreg tests). >>>> >>>> * Allow an alternative name to be specified. >>>> ? This adds additional complexity to support a >>> fractional >>>> percentage of >>>> cases, which could continue to use the existing coding >>> pattern. >>>> >> >> >> >> > > > From rssh at gradsoft.com.ua Wed Mar 25 11:32:03 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 25 Mar 2009 20:32:03 +0200 (EET) Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> Message-ID: <15ce0461ceee409decc7e4586326be92.squirrel@wmail.gradsoft.ua> > @GenerateFullConstructor > @GenerateEqualsAndHashCode > @GenerateToString(JsonToStringGenerator.class) > public class Foo { > @GenerateGetter > private final int x; > @GenerateGetter > private final int y; > @GenerateGetter > private final String foo; > } > You can't do this without extensions methods or some mechanisms, which would allow you to generate code in file, where annotation is situated. So, this is impossible in Java7 From scolebourne at joda.org Wed Mar 25 11:50:41 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 18:50:41 +0000 Subject: PROPOSAL: Binary Literals In-Reply-To: References: Message-ID: <4b4f45e00903251150p65628a7anf6be543e75875389@mail.gmail.com> See http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive for my take on this from long ago. In particular, I'd suggest allowing a character to separate long binary strings: int anInt1 = 0b10100001_01000101_10100001_01000101; much more readable. Stephen 2009/3/25 Derek Foster : > Hmm. Second try at sending to the list. Let's see if this works. (In the > meantime, I noticed that Bruce Chapman has mentioned something similar in his > another proposal, so I think we are in agreement on this. This proposal > should not be taken as to compete with his similar proposal: I'd quite like > to see type suffixes for bytes, shorts, etc. added to Java, in addition to > binary literals.) Anyway... > > > > > Add binary literals to Java. > > AUTHOR(S): Derek Foster > > OVERVIEW > > In some programming domains, use of binary numbers (typically as bitmasks, > bit-shifts, etc.) is very common. However, Java code, due to its C heritage, > has traditionally forced programmers to represent numbers in only decimal, > octal, or hexadecimal. (In practice, octal is rarely used, and is present > mostly for backwards compatibility with C) > > When the data being dealt with is fundamentally bit-oriented, however, using > hexadecimal to represent ranges of bits requires an extra degree of > translation for the programmer, and this can often become a source of errors. > For instance, if a technical specification lists specific values of interest > in binary (for example, in a compression encoding algorithm or in the > specifications for a network protocol, or for communicating with a bitmapped > hardware device) then a programmer coding to that specification must > translate each such value from its binary representation into hexadecimal. > Checking to see if this translation has been done correctly is accomplished > by back-translating the numbers. In most cases, programmers do these > translations in their heads, and HOPEFULLY get them right. however, errors > can easily creep in, and re-verifying the results is not straightforward > enough to be done frequently. > > Furthermore, in many cases, the binary representations of numbers makes it > much more clear what is actually intended than the hexadecimal one. For > instance, this: > > private static final int BITMASK = 0x1E; > > does not immediately make it clear that the bitmask being declared comprises > a single contiguous range of four bits. > > In many cases, it would be more natural for the programmer to be able to > write the numbers in binary in the source code, eliminating the need for > manual translation to hexadecimal entirely. > > > FEATURE SUMMARY: > > In addition to the existing "1" (decimal), "01" (octal) and "0x1" > (hexadecimal) form of specifying numeric literals, a new form "0b1" (binary) > would be added. > > Note that this is the same syntax as has been used as an extension by the GCC > C/C++ compilers for many years, and also is used in the Ruby language, as > well as in the Python language. > > > MAJOR ADVANTAGE: > > It is no longer necessary for programmers to translate binary numbers to and > from hexadecimal in order to use them in Java programs. > > > MAJOR BENEFIT: > > Code using bitwise operations is more readable and easier to verify against > technical specifications that use binary numbers to specify constants. > > Routines that are bit-oriented are easier to understand when an artifical > translation to hexadecimal is not required in order to fulfill the > constraints of the language. > > MAJOR DISADVANTAGE: > > Someone might incorrectly think that "0b1" represented the same value as > hexadecimal number "0xB1". However, note that this problem has existed for > octal/decimal for many years (confusion between "050" and "50") and does not > seem to be a major issue. > > > ALTERNATIVES: > > Users could continue to write the numbers as decimal, octal, or hexadecimal, > and would continue to have the problems observed in this document. > > Another alternative would be for code to translate at runtime from binary > strings, such as: > > ? int BITMASK = Integer.parseInt("00001110", 2); > > Besides the obvious extra verbosity, there are several problems with this: > > * Calling a method such as Integer.parseInt at runtime will typically make it > impossible for the compiler to inline the value of this constant, since its > value has been taken from a runtime method call. Inlining is important, > because code that does bitwise parsing is often very low-level code in tight > loops that must execute quickly. (This is particularly the case for mobile > applications and other applications that run on severely resource-constrained > environments, which is one of the cases where binary numbers would be most > valuable, since talking to low-level hardware is one of the primary use cases > for this feature.) > > * Constants such as the above cannot be used as selectors in 'switch' > statements. > > * Any errors in the string to be parsed (for instance, an extra space) will > result in runtime exceptions, rather than compile-time errors as would have > occurred in normal parsing. If such a value is declared 'static', this will > result in some very ugly exceptions at runtime. > > > EXAMPLES: > > // An 8-bit 'byte' literal. > byte aByte = (byte)0b00100001; > > // A 16-bit 'short' literal. > short aShort = (short)0b1010000101000101; > > // Some 32-bit 'int' literals. > int anInt1 = 0b10100001010001011010000101000101; > int anInt2 = 0b101; > int anInt3 = 0B101; // The B can be upper or lower case as per the x in > "0x45". > > // A 64-bit 'long' literal. Note the "L" suffix, as would also be used > // for a long in decimal, hexadecimal, or octal. > long aLong = > 0b01010000101000101101000010100010110100001010001011010000101000101L; > > SIMPLE EXAMPLE: > > class Foo { > public static void main(String[] args) { > ?System.out.println("The value 10100001 in decimal is " + 0b10100001); > } > > > ADVANCED EXAMPLE: > > // Binary constants could be used in code that needs to be > // easily checkable against a specifications document, such > // as this simulator for a hypothetical 8-bit microprocessor: > > public State decodeInstruction(int instruction, State state) { > ?if ((instruction & 0b11100000) == 0b00000000) { > ? ?final int register = instruction & 0b00001111; > ? ?switch (instruction & 0b11110000) { > ? ? ?case 0b00000000: return state.nop(); > ? ? ?case 0b00010000: return state.copyAccumTo(register); > ? ? ?case 0b00100000: return state.addToAccum(register); > ? ? ?case 0b00110000: return state.subFromAccum(register); > ? ? ?case 0b01000000: return state.multiplyAccumBy(register); > ? ? ?case 0b01010000: return state.divideAccumBy(register); > ? ? ?case 0b01100000: return state.setAccumFrom(register); > ? ? ?case 0b01110000: return state.returnFromCall(); > ? ? ?default: throw new IllegalArgumentException(); > ? ?} > ?} else { > ? ?final int address = instruction & 0b00011111; > ? ?switch (instruction & 0b11100000) { > ? ? ?case 0b00100000: return state.jumpTo(address); > ? ? ?case 0b01000000: return state.jumpIfAccumZeroTo(address); > ? ? ?case 0b01000000: return state.jumpIfAccumNonzeroTo(address); > ? ? ?case 0b01100000: return state.setAccumFromMemory(address); > ? ? ?case 0b10100000: return state.writeAccumToMemory(address); > ? ? ?case 0b11000000: return state.callTo(address); > ? ? ?default: throw new IllegalArgumentException(); > ? ?} > ?} > } > > // Binary literals can be used to make a bitmap more readable: > > public static final short[] HAPPY_FACE = { > ? (short)0b0000011111100000; > ? (short)0b0000100000010000; > ? (short)0b0001000000001000; > ? (short)0b0010000000000100; > ? (short)0b0100000000000010; > ? (short)0b1000011001100001; > ? (short)0b1000011001100001; > ? (short)0b1000000000000001; > ? (short)0b1000000000000001; > ? (short)0b1001000000001001; > ? (short)0b1000100000010001; > ? (short)0b0100011111100010; > ? (short)0b0010000000000100; > ? (short)0b0001000000001000; > ? (short)0b0000100000010000; > ? (short)0b0000011111100000; > } > > // Binary literals can make relationships > // among data more apparent than they would > // be in hex or octal. > // > // For instance, what does the following > // array contain? In hexadecimal, it's hard to tell: > public static final int[] PHASES = { > ? ?0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 > } > > // In binary, it's obvious that a number is being > // rotated left one bit at a time. > public static final int[] PHASES = { > ? ?0b00110001, > ? ?0b01100010, > ? ?0b11000100, > ? ?0b10001001, > ? ?0b00010011, > ? ?0b00100110, > ? ?0b01001100, > ? ?0b10011000, > } > > > DETAILS > > SPECIFICATION: > > Section 3.10.1 ("Integer Literals") of the JLS3 should be changed to add the > following: > > IntegerLiteral: > ? ? ? ?DecimalIntegerLiteral > ? ? ? ?HexIntegerLiteral > ? ? ? ?OctalIntegerLiteral > ? ? ? ?BinaryIntegerLiteral ? ? ? ? // Added > > BinaryIntegerLiteral: > ? ? ? ?BinaryNumeral IntegerTypeSuffix_opt > > BinaryNumeral: > ? ? ? ?0 b BinaryDigits > ? ? ? ?0 B BinaryDigits > > BinaryDigits: > ? ? ? ?BinaryDigit > ? ? ? ?BinaryDigit BinaryDigits > > BinaryDigit: one of > ? ? ? ?0 1 > > COMPILATION: > > Binary literals would be compiled to class files in the same fashion as > existing decimal, hexadecimal, and octal literals are. No special support or > changes to the class file format are needed. > > TESTING: > > The feature can be tested in the same way as existing decimal, hexadecimal, > and octal literals are: Create a bunch of constants in source code, including > the maximum and minimum positive and negative values for integer and long > types, and verify them at runtime to have the correct values. > > > LIBRARY SUPPORT: > > The methods Integer.decode(String) and Long.decode(String) should be modified > to parse binary numbers (as specified above) in addition to their existing > support for decimal, hexadecimal, and octal numbers. > > > REFLECTIVE APIS: > > No updates to the reflection APIs are needed. > > > OTHER CHANGES: > > No other changes are needed. > > > MIGRATION: > > Individual decimal, hexadecimal, or octal constants in existing code can be > updated to binary as a programmer desires. > > > COMPATIBILITY > > > BREAKING CHANGES: > > This feature would not break any existing programs, since the suggested > syntax is currently considerd to be a compile-time error. > > > EXISTING PROGRAMS: > > Class file format does not change, so existing programs can use class files > compiled with the new feature without problems. > > > REFERENCES: > > The GCC/G++ compiler, which already supports this syntax (as of version 4.3) > as an extension to standard C/C++. > http://gcc.gnu.org/gcc-4.3/changes.html > > The Ruby language, which supports binary literals: > http://wordaligned.org/articles/binary-literals > > The Python language added binary literals in version 2.6: > http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax > > EXISTING BUGS: > > "Language support for literal numbers in binary and other bases" > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 > > URL FOR PROTOTYPE (optional): > > None. > > From jl0235 at yahoo.com Wed Mar 25 12:04:53 2009 From: jl0235 at yahoo.com (james lowden) Date: Wed, 25 Mar 2009 12:04:53 -0700 (PDT) Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> Message-ID: <150838.58490.qm@web63706.mail.re1.yahoo.com> I don't like the multiple annotations approach as it removes the convenience of being able to easily get the default magic behaviors via one modifier. There's certainly precedent for this in the language; applying the "synchronized" keyword to a method or block of code gives you a default set of "magic" concurrency behaviors which under the hood are in fact somewhat complex. My only concern with it as stands is that "data" in class declarations is a keyword, and presumably is a valid identifier everywhere else; I'd rather see something that wasn't a valid Java identifier used to denote this behavior. I wouldn't mind seeing "default" used this way (to imply desirable "default" behavior), as in: default public class Foo { private int x; private String blah; } generates all the default getters/setters/equals/hashcode/constructor. -JL- --- On Wed, 3/25/09, Lawrence Kesteloot wrote: > From: Lawrence Kesteloot > Subject: Re: PROPOSAL: Auto-assignment Parameters > To: coin-dev at openjdk.java.net > Date: Wednesday, March 25, 2009, 1:25 PM > Reinier, > > The idea of adding a context-sensitive keyword creeps me > out. Also > this is doing a lot of magic based on a single keyword. Can > you tell, > at a glance, what the keyword is doing? How much is > generated? What > are the (complex) rules for auto-generating a constructor? > > I would prefer a more explicit approach, driven by > annotations. If we > feel like boilerplate is annoying to write and bug-prone, > then we > could have a java.lang.gen package with various annotations > for > automatically generating code. Something like: > > @GenerateFullConstructor > @GenerateEqualsAndHashCode > @GenerateToString(JsonToStringGenerator.class) > public class Foo { > @GenerateGetter > private final int x; > @GenerateGetter > private final int y; > @GenerateGetter > private final String foo; > } > > Then it's explicit, each annotation can have parameters > to modify its > behavior, and people can pick and choose what they need. > There's no > magic about skipping the generation of toString if > you've implemented > it. > > Here's an example of useful parameters for such > annotations: many > people (myself included) like to prefix fields with > something. I use > "m" (mFoo), but others use an underscore, and > some both (m_foo). You'd > want the GenerateGetter annotation to be flexible about > that. My code > would look like this: > > @GenerateGetter(prefix = "m") > private final String mFoo; > > Your "data" keyword would preclude this, forcing > me to either drop my > (company-mandated) coding standard for data classes, or > have getters > like "getMFoo()". > > With GenerateEqualsAndHashCode you might want to skip some > fields. You > might want to skip fields for GenerateToString also (e.g., > password > fields, or super long strings). > > Lawrence > > > On Wed, Mar 25, 2009 at 9:59 AM, Reinier Zwitserloot > wrote: > > There's no reference for auto-POJOs anywhere, but > this should allow > > you to write up all you need: > > > > 1. 'data' is a context sensitive keyword that > is legal on classes. The > > 'data' keyword will add a number of members to > the class. > > > > 2. For each field, a getter is generated, according to > the beanspec > > (getFoo() or isFoo()). if the field is not final, a > setter is > > generated, according to beanspec (setFoo()), and the > field is > > considered a property of the data class, unless it is > transient. If > > the field is public, the getter (and, if not final, > the setter), is > > not generated. For all generated getters/setters, if > the getter/setter > > is already in the class, or already defined (that is; > not abstract) in > > any supertype, then the getter/setter is not > generated. protected and > > visible package protected members from supertypes are > also included > > both for generating setters/getters and for > hashCode/equals/toString/ > > clone (upcoming). > > > > 3. hashCode() and equals(): Existence of the > hashCode() or equals() > > method in any supertype is not relevant (obviously; > all objects have > > them!) > > > > 3a. If only one of hashCode() or equals() is present, > a warning is > > generated and neither hashCode() or equals() is > auto-generated. The > > warning basically explains that overriding one but not > the other is a > > bug. > > > > 3b. If both hashCode() and equals() are present, > nothing happens. > > > > 3c. If neither is present, a hashCode() and equals() > method are > > generated. These involve all properties (non-transient > visible > > fields). equals() is defined by: > > > > ?3c1: First check if the other object is of the exact > same class as > > ourselves; if not, false. If null, false. > > ?3c2: For each primitive property, check via == if > they are equal. If > > any isn't, false. > > ?3c3: For each object property, call its .equals(). > If they aren't, > > false. > > ?3c4: return true. > > > > for hashCode(), do whatever eclipse does out of the > box to auto- > > generate hashCode() methods. It basically looks like: > > > > final int PRIME = 31; > > int result = 1; > > for ( each field ) result = result*31 + > field.hashCode(); > > return result; > > > > Where hashCode() is generated in obvious fashion for > all primitives > > (xor the upper and lower bits of longs together, > convert floats and > > doubles to long/intbits and use that, > chars/bytes/ints/shorts's > > hashCode is their own value, booleans are translated > to 11/17. 'null' > > becomes 3. > > > > 4. *IF* all fields are private, and *IF* all fields > are final, *AND* > > the class does not contain any explicit constructors, > *AND* the class > > has a no-args super constructor, then a constructor is > generated that > > includes all fields, in order of definition, which > simply assigns them > > to the fields. visible properties from supertypes > aren't included. > > > > 5. A toString() method is generated, if not already > present in the > > type, which produces a string like so: > "MyClassName [field1=value, > > field2=value]", for all properties. (so, > non-visible fields from > > supertypes and transient fields are skipped). > > > > 6 (optional). Each generated member gets a @Generated > annotation, > > which is a new annotation ( > java.lang.annotations.Generated ). These > > are @Documented and @Retention.RUNTIME. > > > > > > Is it viable for coin? I'll write it up if so. > > > > ?--Reinier Zwitserloot > > > > > > > > On Mar 25, 2009, at 14:41, james lowden wrote: > > > >> > >> I'd like to see both. > ?Auto-getters/setters/equals/etc. would be > >> really, really nice, but it would also be valuable > to have a way of > >> specifying a variety of different constructors to > generate, which > >> Mark's proposal would allow for. ?Example: > >> > >> public data class Foo { > >> ? ? ?private final int x; > >> ? ? ?private final int y; > >> ? ? ?private final String foo; > >> > >> ? ? ?public Foo (this.x) {} > >> > >> ? ? ?public Foo (this.foo, this.y) {} > >> } > >> > >> > >> (I eliminated the types from the automagical > constructors, as they > >> can be inferred by the compiler.) > >> > >> This would generate all three getters and setters, > equals (), > >> hashcode (), a general constructor taking in all 3 > fields, and two > >> additional constructors, one taking in just int x, > and one taking in > >> both String foo and int y. > >> > >> Reinier--is there a copy of your original proposal > for auto-POJOs > >> somewhere? > >> > >> -JL- > >> > >> > >>> From: Reinier Zwitserloot > > >>> Subject: Re: PROPOSAL: Auto-assignment > Parameters > >>> To: "Mark Mahieu" > > >>> Cc: coin-dev at openjdk.java.net > >>> Date: Tuesday, March 24, 2009, 8:34 PM > >>> I like where this is going, but I'd rather > see a bigger > >>> setup for auto- > >>> POJO classes. I proposed this before and in > most java > >>> circles (outside > >>> of coin-dev!), this idea was considered very > useful: > >>> > >>> public data class Foo { > >>> ? ? private final int x; > >>> ? ? private final int y; > >>> ? ? private final String foo; > >>> } > >>> > >>> > >>> The above class would auto-generate the > getters, a > >>> constructor, > >>> hashCode, equals, and toString. You can add > methods to it > >>> if you want, > >>> and if you define a method that would usually > be > >>> auto-generated, it > >>> isn't auto-generated. So, if you need to > do some extra > >>> processing > >>> before returning 'foo' via the getter, > go right > >>> ahead. You can even > >>> add this later without breaking your API's > >>> compatibility. > >>> > >>> ?--Reinier Zwitserloot > >>> > >>> > >>> > >>> On Mar 25, 2009, at 02:07, Mark Mahieu wrote: > >>> > >>>> HTML version + prototype available at > >>> http://slm888.com/javac > >>>> > >>>> > >>>> > >>>> Auto-assignment Parameters v0.1 > >>>> > >>>> > >>>> AUTHOR(S): > >>>> > >>>> Mark Mahieu > >>>> > >>>> > >>>> OVERVIEW > >>>> > >>>> FEATURE SUMMARY: Should be suitable as a > summary in a > >>> language > >>>> tutorial. > >>>> > >>>> An additional form of constructor > parameter which > >>> provides automatic > >>>> assignment of the parameter's value to > an instance > >>> field. ?These > >>>> parameters > >>>> are implicitly declared as final to > prevent > >>> unintentional > >>>> assignments to the > >>>> wrong variable in the constructor body. > >>>> > >>>> > >>>> MAJOR ADVANTAGE: What makes the proposal a > favorable > >>> change? > >>>> > >>>> Reduces the likelihood of some common > coding errors > >>> relating to > >>>> assignment > >>>> of fields in a constructor, including > those where: > >>>> > >>>> ? * a field is assigned to itself > >>>> ? * the parameter is assigned instead of > the field > >>>> ? * the assignment to the field is > missing entirely > >>>> > >>>> These and other errors are often caused by > typos or > >>> code refactoring. > >>>> > >>>> > >>>> MAJOR BENEFIT: Why is the platform better > if the > >>> proposal is adopted? > >>>> > >>>> A programmer's intent is more clearly > expressed > >>> for the extremely > >>>> common > >>>> case of assigning a constructor parameter > directly to > >>> an instance > >>>> field with > >>>> the same name. > >>>> > >>>> > >>>> MAJOR DISADVANTAGE: There is always a > cost. > >>>> > >>>> As with any sugar which enables a more > concise way of > >>> expressing an > >>>> existing > >>>> idiom, programmers may be tempted to use > it even when > >>> the original > >>>> form > >>>> would be more appropriate. > >>>> > >>>> > >>>> ALTERNATIVES: Can the benefits and > advantages be had > >>> some way > >>>> without a > >>>> language change? > >>>> > >>>> IDEs and tools such as FindBugs are good > at warning > >>> about the kind > >>>> of errors > >>>> mentioned above, however since the code in > question is > >>> usually still > >>>> valid > >>>> to the compiler, they are limited in what > action they > >>> can take by > >>>> default. > >>>> > >>>> A language change can combine the ability > to avoid > >>> these errors > >>>> entirely > >>>> with a more expressive idiom, resulting in > an > >>> increased signal to > >>>> noise > >>>> ratio for readers of that code. > >>>> > >>>> > >>>> > >>>> EXAMPLES > >>>> > >>>> SIMPLE EXAMPLE: Show the simplest possible > program > >>> utilizing the new > >>>> feature. > >>>> > >>>> ? class C { > >>>> ? ? ? int i; > >>>> ? ? ? C(int this.i) {} > >>>> ? } > >>>> > >>>> > >>>> ADVANCED EXAMPLE: Show advanced usage(s) > of the > >>> feature. > >>>> > >>>> > >>>> ? class Proposal { > >>>> > >>>> ? ? ? private final String name; > >>>> ? ? ? private final String author; > >>>> ? ? ? private boolean suitableForCoin; > >>>> ? ? ? private Integer score; > >>>> > >>>> ? ? ? public Proposal(String this.name, > >>>> ? ? ? ? ? ? ? ? ? ? ? String > this.author, > >>>> ? ? ? ? ? ? ? ? ? ? ? boolean > this.suitableForCoin, > >>>> ? ? ? ? ? ? ? ? ? ? ? int > this.score) { > >>>> > >>>> ? ? ? ? ? if > (name.equals(?Auto-assignment > >>> Parameters?)) { > >>>> ? ? ? ? ? ? ?suitableForCoin = > true; // final so > >>> compile-time error > >>>> ? ? ? ? ? } > >>>> ? ? ? } > >>>> > >>>> ? ? ? // rest of class ... > >>>> ? } > >>>> > >>>> > >>>> > >>>> 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. > >>>> > >>>> The syntactic grammar is modified to > include > >>> auto-assignment > >>>> parameters for > >>>> constructors: > >>>> > >>>> ? ? ? ConstructorDeclaratorRest: > >>>> ? ? ? ? ? ? ? > ?ConstructorParameters [throws > >>> QualifiedIdentifierList] > >>>> MethodBody > >>>> > >>>> ? ? ? ConstructorParameters: > >>>> ? ? ? ? ? ? ? ?( > [ConstructorParameterDecls] ) > >>>> > >>>> ? ? ? ConstructorParameterDecls: > >>>> ? ? ? ? ? ? ? ?[final] > [Annotations] Type > >>>> ConstructorParameterDeclsRest > >>>> > >>>> ? ? ? ConstructorParameterDeclsRest: > >>>> ? ? ? ? ? ? ? > ?ConstructorParameterId [ , > >>> ConstructorParameterDecls] > >>>> ? ? ? ? ? ? ? ?... > ConstructorParameterId > >>>> > >>>> ? ? ? ConstructorParameterId: > >>>> ? ? ? ? ? ? ? > ?VariableDeclaratorId > >>>> ? ? ? ? ? ? ? ?this . > VariableDeclaratorId > >>>> ? ? ? ? ? ? ? ?super . > VariableDeclaratorId > >>>> > >>>> An auto-assignment parameter is a formal > parameter > >>> (JLSv3 ?8.4.1) > >>>> which > >>>> specifies an instance field instead of an > identifier. > >>> Its value is > >>>> automatically assigned to the specified > field. ?It may > >>> only be used > >>>> in a > >>>> constructor. > >>>> > >>>> The automatic assignment takes place after > any > >>> explicit or implicit > >>>> invocation of another constructor, and > before any > >>> statements in the > >>>> body of > >>>> the constructor. ?A constructor which > declares n > >>> auto-assignment > >>>> parameters > >>>> will perform n such automatic assignments, > in the > >>> order that the > >>>> parameters > >>>> are declared. > >>>> > >>>> The parameter has the same name (JLSv3 > ?6.2) as the > >>> field to which > >>>> it is > >>>> assigned; replacing each auto-assignment > parameter > >>> with a normal > >>>> formal > >>>> parameter with the same name would yield a > constructor > >>> with an > >>>> identical > >>>> signature. ?As with a normal parameter, > the > >>> parameter's name is > >>>> entered into > >>>> the scope of the constructor body (JLSv3 > ?6.3), and > >>> therefore > >>>> shadows the > >>>> field (JLSv3 ?6.3.1) within that scope. > >>>> > >>>> It is a compile-time error if the field is > not > >>> accessible from the > >>>> constructor in which the parameter > appears. > >>>> > >>>> It is a compile-time error if the declared > type of the > >>> parameter is > >>>> not > >>>> assignment compatible (JLSv3 ?5.2) with > the field to > >>> which it is > >>>> automatically assigned. > >>>> > >>>> If an unboxing conversion is required by > an automatic > >>> assignment, any > >>>> NullPointerException thrown as a result > (JLSv3 > >>> ?5.1.8) will contain > >>>> the name > >>>> of the field on which the conversion > failed, which may > >>> be retrieved by > >>>> calling getMessage() on the exception. > >>>> > >>>> Auto-assignment parameters are implicitly > final, and > >>> follow the > >>>> standard > >>>> rules for final variables (JLSv3 > ?4.12.4). > >>> Explicitly declaring an > >>>> auto-assignment parameter as final has no > effect, and > >>> does not cause a > >>>> compilation error. > >>>> > >>>> Auto-assignment parameters follow the > standard > >>> definite assignment > >>>> rules for > >>>> formal parameters (JLSv3 ?16.3). > >>>> > >>>> An auto-assignment parameter may be > annotated. > >>>> > >>>> If an auto-assignment parameter is the > last parameter > >>> in the list, and > >>>> refers to a field of array type, it may be > a variable > >>> arity parameter. > >>>> > >>>> > >>>> > >>>> 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! > >>>> > >>>> Desugaring of the following class: > >>>> > >>>> ? class Foo { > >>>> ? ? ? int value; > >>>> ? ? ? Foo(Integer this.value) { > >>>> ? ? ? ? ? System.out.println(value); > >>>> ? ? ? } > >>>> ? } > >>>> > >>>> would result in (unboxing desugaring > omitted): > >>>> > >>>> ? class Foo { > >>>> ? ? ? int value; > >>>> ? ? ? Foo(final Integer value) { > >>>> ? ? ? ? ? super(); > >>>> ? ? ? ? ? if (value == null) > >>>> ? ? ? ? ? ? ? throw new > >>> NullPointerException("value"); > >>>> ? ? ? ? ? this.value = value; > >>>> ? ? ? ? ? System.out.println(value); > >>>> ? ? ? } > >>>> ? } > >>>> > >>>> No changes to the classfile format are > required. > >>> Tools which > >>>> consume class > >>>> files see the constructor signature as > though it had > >>> been written > >>>> using > >>>> normal formal parameters. > >>>> > >>>> > >>>> TESTING: How can the feature be tested? > >>>> > >>>> An initial set of jtreg tests is included > in the > >>> prototype. > >>>> > >>>> > >>>> LIBRARY SUPPORT: Are any supporting > libraries needed > >>> for the feature? > >>>> > >>>> No > >>>> > >>>> > >>>> 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. > >>>> > >>>> com.sun.source.tree.VariableTree would > require an > >>> additional method > >>>> which > >>>> returns the auto-assigned field. > >>>> > >>>> > >>>> 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 > >>>> > >>>> > >>>> MIGRATION: Sketch how a code base could be > converted, > >>> manually or > >>>> automatically, to use the new feature. > >>>> > >>>> Assignment statements in constructors for > which all of > >>> the following > >>>> are > >>>> true can be considered suitable for > conversion: > >>>> ? ?* the lhs of the assignment is a > non-static field > >>>> ? ?* the rhs is a parameter with the > same name as the > >>> field > >>>> ? ?* there are no other assignments to > the parameter > >>> anywhere in the > >>>> constructor > >>>> ? ?* there are no assignments to, or > other uses of > >>> the field before > >>>> the > >>>> assignment statement in question > (including invoked > >>> constructors) > >>>> > >>>> Such statements can be converted by: > >>>> ? 1) replacing the parameter with an > auto-assignment > >>> parameter > >>>> (prefixing > >>>> the existing parameter's identifier > with > >>> 'this.'), and > >>>> ? 2) removing the assignment statement > >>>> > >>>> > >>>> > >>>> COMPATIBILITY > >>>> > >>>> BREAKING CHANGES: Are any previously valid > programs > >>> now invalid? If > >>>> so, list > >>>> one. > >>>> > >>>> No > >>>> > >>>> > >>>> 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 semantics of existing class files and > legal source > >>> files are > >>>> unchanged > >>>> by this feature. > >>>> > >>>> > >>>> > >>>> REFERENCES > >>>> > >>>> EXISTING BUGS: Please include a list of > any existing > >>> Sun bug ids > >>>> related to > >>>> this proposal. > >>>> > >>>> > >>> > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 > >>>> (uses a 'setter' method rather > than a > >>> constructor in its example) > >>>> > >>>> FindBugs bug patterns - > >>> > http://findbugs.sourceforge.net/bugDescriptions.html > >>>> * Self assignment of field > (SA_FIELD_SELF_ASSIGNMENT) > >>>> * Self comparison of field with itself > >>> (SA_FIELD_SELF_COMPARISON) > >>>> * Nonsensical self computation involving a > field > >>> (e.g., x & x) > >>>> (SA_FIELD_SELF_COMPUTATION) > >>>> * Self assignment of local variable > >>> (SA_LOCAL_SELF_ASSIGNMENT) > >>>> * Nonsensical self computation involving a > variable > >>> (e.g., x & x) > >>>> (SA_LOCAL_SELF_COMPUTATION) > >>>> * Uninitialized read of field in > constructor > >>> (UR_UNINIT_READ) > >>>> * Unwritten field (UWF_UNWRITTEN_FIELD) > >>>> * Dead store to local variable > (DLS_DEAD_LOCAL_STORE) > >>>> * Dead store of null to local variable > >>> (DLS_DEAD_LOCAL_STORE_OF_NULL) > >>>> > >>>> > >>>> > >>>> URL FOR PROTOTYPE (optional): > >>>> > >>>> http://slm888.com/javac > >>>> > >>>> > >>>> > >>>> DESIGN ALTERNATIVES: > >>>> > >>>> The following variations have been > explored and are > >>> worth mentioning: > >>>> > >>>> * Allow auto-assignment parameters on all > non-abstract > >>> methods. > >>>> ? This may be especially useful on the > extremely > >>> common 'setter' > >>>> methods > >>>> in 'value object' classes. > >>>> > >>>> * Remove the requirement for (or even > disallow) the > >>> type to be > >>>> specified on > >>>> auto-assignment parameters. > >>>> ? Experimentation with this idea suggests > that it may > >>> work quite > >>>> well for > >>>> constructors, further emphasising the > difference in > >>> intent and > >>>> semantics > >>>> from those of normal parameters. However, > it may not > >>> work so well in > >>>> combination with auto-assignment > parameters on all > >>> non-abstract > >>>> methods, and > >>>> requires a change to the order in which > javac compiles > >>> classes (can > >>>> still > >>>> pass jtreg tests). > >>>> > >>>> * Allow an alternative name to be > specified. > >>>> ? This adds additional complexity to > support a > >>> fractional > >>>> percentage of > >>>> cases, which could continue to use the > existing coding > >>> pattern. > >>>> > >> > >> > >> > >> > > > > > > From jl0235 at yahoo.com Wed Mar 25 12:07:22 2009 From: jl0235 at yahoo.com (james lowden) Date: Wed, 25 Mar 2009 12:07:22 -0700 (PDT) Subject: PROPOSAL: Binary Literals In-Reply-To: <4b4f45e00903251150p65628a7anf6be543e75875389@mail.gmail.com> Message-ID: <781136.63917.qm@web63705.mail.re1.yahoo.com> Actually, that's a good idea in general for long numeric constants. 9_000_000_000_000_000L is easier to parse than 9000000000000000L. --- On Wed, 3/25/09, Stephen Colebourne wrote: > From: Stephen Colebourne > Subject: Re: PROPOSAL: Binary Literals > To: coin-dev at openjdk.java.net > Date: Wednesday, March 25, 2009, 1:50 PM > See > http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive > for my take on this from long ago. > > In particular, I'd suggest allowing a character to > separate long binary strings: > > int anInt1 = 0b10100001_01000101_10100001_01000101; > > much more readable. > > Stephen > > 2009/3/25 Derek Foster : > > Hmm. Second try at sending to the list. Let's see > if this works. (In the > > meantime, I noticed that Bruce Chapman has mentioned > something similar in his > > another proposal, so I think we are in agreement on > this. This proposal > > should not be taken as to compete with his similar > proposal: I'd quite like > > to see type suffixes for bytes, shorts, etc. added to > Java, in addition to > > binary literals.) Anyway... > > > > > > > > > > Add binary literals to Java. > > > > AUTHOR(S): Derek Foster > > > > OVERVIEW > > > > In some programming domains, use of binary numbers > (typically as bitmasks, > > bit-shifts, etc.) is very common. However, Java code, > due to its C heritage, > > has traditionally forced programmers to represent > numbers in only decimal, > > octal, or hexadecimal. (In practice, octal is rarely > used, and is present > > mostly for backwards compatibility with C) > > > > When the data being dealt with is fundamentally > bit-oriented, however, using > > hexadecimal to represent ranges of bits requires an > extra degree of > > translation for the programmer, and this can often > become a source of errors. > > For instance, if a technical specification lists > specific values of interest > > in binary (for example, in a compression encoding > algorithm or in the > > specifications for a network protocol, or for > communicating with a bitmapped > > hardware device) then a programmer coding to that > specification must > > translate each such value from its binary > representation into hexadecimal. > > Checking to see if this translation has been done > correctly is accomplished > > by back-translating the numbers. In most cases, > programmers do these > > translations in their heads, and HOPEFULLY get them > right. however, errors > > can easily creep in, and re-verifying the results is > not straightforward > > enough to be done frequently. > > > > Furthermore, in many cases, the binary representations > of numbers makes it > > much more clear what is actually intended than the > hexadecimal one. For > > instance, this: > > > > private static final int BITMASK = 0x1E; > > > > does not immediately make it clear that the bitmask > being declared comprises > > a single contiguous range of four bits. > > > > In many cases, it would be more natural for the > programmer to be able to > > write the numbers in binary in the source code, > eliminating the need for > > manual translation to hexadecimal entirely. > > > > > > FEATURE SUMMARY: > > > > In addition to the existing "1" (decimal), > "01" (octal) and "0x1" > > (hexadecimal) form of specifying numeric literals, a > new form "0b1" (binary) > > would be added. > > > > Note that this is the same syntax as has been used as > an extension by the GCC > > C/C++ compilers for many years, and also is used in > the Ruby language, as > > well as in the Python language. > > > > > > MAJOR ADVANTAGE: > > > > It is no longer necessary for programmers to translate > binary numbers to and > > from hexadecimal in order to use them in Java > programs. > > > > > > MAJOR BENEFIT: > > > > Code using bitwise operations is more readable and > easier to verify against > > technical specifications that use binary numbers to > specify constants. > > > > Routines that are bit-oriented are easier to > understand when an artifical > > translation to hexadecimal is not required in order to > fulfill the > > constraints of the language. > > > > MAJOR DISADVANTAGE: > > > > Someone might incorrectly think that "0b1" > represented the same value as > > hexadecimal number "0xB1". However, note > that this problem has existed for > > octal/decimal for many years (confusion between > "050" and "50") and does not > > seem to be a major issue. > > > > > > ALTERNATIVES: > > > > Users could continue to write the numbers as decimal, > octal, or hexadecimal, > > and would continue to have the problems observed in > this document. > > > > Another alternative would be for code to translate at > runtime from binary > > strings, such as: > > > > ? int BITMASK = > Integer.parseInt("00001110", 2); > > > > Besides the obvious extra verbosity, there are several > problems with this: > > > > * Calling a method such as Integer.parseInt at runtime > will typically make it > > impossible for the compiler to inline the value of > this constant, since its > > value has been taken from a runtime method call. > Inlining is important, > > because code that does bitwise parsing is often very > low-level code in tight > > loops that must execute quickly. (This is particularly > the case for mobile > > applications and other applications that run on > severely resource-constrained > > environments, which is one of the cases where binary > numbers would be most > > valuable, since talking to low-level hardware is one > of the primary use cases > > for this feature.) > > > > * Constants such as the above cannot be used as > selectors in 'switch' > > statements. > > > > * Any errors in the string to be parsed (for instance, > an extra space) will > > result in runtime exceptions, rather than compile-time > errors as would have > > occurred in normal parsing. If such a value is > declared 'static', this will > > result in some very ugly exceptions at runtime. > > > > > > EXAMPLES: > > > > // An 8-bit 'byte' literal. > > byte aByte = (byte)0b00100001; > > > > // A 16-bit 'short' literal. > > short aShort = (short)0b1010000101000101; > > > > // Some 32-bit 'int' literals. > > int anInt1 = 0b10100001010001011010000101000101; > > int anInt2 = 0b101; > > int anInt3 = 0B101; // The B can be upper or lower > case as per the x in > > "0x45". > > > > // A 64-bit 'long' literal. Note the > "L" suffix, as would also be used > > // for a long in decimal, hexadecimal, or octal. > > long aLong = > > > 0b01010000101000101101000010100010110100001010001011010000101000101L; > > > > SIMPLE EXAMPLE: > > > > class Foo { > > public static void main(String[] args) { > > ?System.out.println("The value 10100001 in > decimal is " + 0b10100001); > > } > > > > > > ADVANCED EXAMPLE: > > > > // Binary constants could be used in code that needs > to be > > // easily checkable against a specifications document, > such > > // as this simulator for a hypothetical 8-bit > microprocessor: > > > > public State decodeInstruction(int instruction, State > state) { > > ?if ((instruction & 0b11100000) == 0b00000000) { > > ? ?final int register = instruction & > 0b00001111; > > ? ?switch (instruction & 0b11110000) { > > ? ? ?case 0b00000000: return state.nop(); > > ? ? ?case 0b00010000: return > state.copyAccumTo(register); > > ? ? ?case 0b00100000: return > state.addToAccum(register); > > ? ? ?case 0b00110000: return > state.subFromAccum(register); > > ? ? ?case 0b01000000: return > state.multiplyAccumBy(register); > > ? ? ?case 0b01010000: return > state.divideAccumBy(register); > > ? ? ?case 0b01100000: return > state.setAccumFrom(register); > > ? ? ?case 0b01110000: return > state.returnFromCall(); > > ? ? ?default: throw new IllegalArgumentException(); > > ? ?} > > ?} else { > > ? ?final int address = instruction & 0b00011111; > > ? ?switch (instruction & 0b11100000) { > > ? ? ?case 0b00100000: return state.jumpTo(address); > > ? ? ?case 0b01000000: return > state.jumpIfAccumZeroTo(address); > > ? ? ?case 0b01000000: return > state.jumpIfAccumNonzeroTo(address); > > ? ? ?case 0b01100000: return > state.setAccumFromMemory(address); > > ? ? ?case 0b10100000: return > state.writeAccumToMemory(address); > > ? ? ?case 0b11000000: return state.callTo(address); > > ? ? ?default: throw new IllegalArgumentException(); > > ? ?} > > ?} > > } > > > > // Binary literals can be used to make a bitmap more > readable: > > > > public static final short[] HAPPY_FACE = { > > ? (short)0b0000011111100000; > > ? (short)0b0000100000010000; > > ? (short)0b0001000000001000; > > ? (short)0b0010000000000100; > > ? (short)0b0100000000000010; > > ? (short)0b1000011001100001; > > ? (short)0b1000011001100001; > > ? (short)0b1000000000000001; > > ? (short)0b1000000000000001; > > ? (short)0b1001000000001001; > > ? (short)0b1000100000010001; > > ? (short)0b0100011111100010; > > ? (short)0b0010000000000100; > > ? (short)0b0001000000001000; > > ? (short)0b0000100000010000; > > ? (short)0b0000011111100000; > > } > > > > // Binary literals can make relationships > > // among data more apparent than they would > > // be in hex or octal. > > // > > // For instance, what does the following > > // array contain? In hexadecimal, it's hard to > tell: > > public static final int[] PHASES = { > > ? ?0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 > > } > > > > // In binary, it's obvious that a number is being > > // rotated left one bit at a time. > > public static final int[] PHASES = { > > ? ?0b00110001, > > ? ?0b01100010, > > ? ?0b11000100, > > ? ?0b10001001, > > ? ?0b00010011, > > ? ?0b00100110, > > ? ?0b01001100, > > ? ?0b10011000, > > } > > > > > > DETAILS > > > > SPECIFICATION: > > > > Section 3.10.1 ("Integer Literals") of the > JLS3 should be changed to add the > > following: > > > > IntegerLiteral: > > ? ? ? ?DecimalIntegerLiteral > > ? ? ? ?HexIntegerLiteral > > ? ? ? ?OctalIntegerLiteral > > ? ? ? ?BinaryIntegerLiteral ? ? ? ? // Added > > > > BinaryIntegerLiteral: > > ? ? ? ?BinaryNumeral IntegerTypeSuffix_opt > > > > BinaryNumeral: > > ? ? ? ?0 b BinaryDigits > > ? ? ? ?0 B BinaryDigits > > > > BinaryDigits: > > ? ? ? ?BinaryDigit > > ? ? ? ?BinaryDigit BinaryDigits > > > > BinaryDigit: one of > > ? ? ? ?0 1 > > > > COMPILATION: > > > > Binary literals would be compiled to class files in > the same fashion as > > existing decimal, hexadecimal, and octal literals are. > No special support or > > changes to the class file format are needed. > > > > TESTING: > > > > The feature can be tested in the same way as existing > decimal, hexadecimal, > > and octal literals are: Create a bunch of constants in > source code, including > > the maximum and minimum positive and negative values > for integer and long > > types, and verify them at runtime to have the correct > values. > > > > > > LIBRARY SUPPORT: > > > > The methods Integer.decode(String) and > Long.decode(String) should be modified > > to parse binary numbers (as specified above) in > addition to their existing > > support for decimal, hexadecimal, and octal numbers. > > > > > > REFLECTIVE APIS: > > > > No updates to the reflection APIs are needed. > > > > > > OTHER CHANGES: > > > > No other changes are needed. > > > > > > MIGRATION: > > > > Individual decimal, hexadecimal, or octal constants in > existing code can be > > updated to binary as a programmer desires. > > > > > > COMPATIBILITY > > > > > > BREAKING CHANGES: > > > > This feature would not break any existing programs, > since the suggested > > syntax is currently considerd to be a compile-time > error. > > > > > > EXISTING PROGRAMS: > > > > Class file format does not change, so existing > programs can use class files > > compiled with the new feature without problems. > > > > > > REFERENCES: > > > > The GCC/G++ compiler, which already supports this > syntax (as of version 4.3) > > as an extension to standard C/C++. > > http://gcc.gnu.org/gcc-4.3/changes.html > > > > The Ruby language, which supports binary literals: > > http://wordaligned.org/articles/binary-literals > > > > The Python language added binary literals in version > 2.6: > > > http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax > > > > EXISTING BUGS: > > > > "Language support for literal numbers in binary > and other bases" > > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 > > > > URL FOR PROTOTYPE (optional): > > > > None. > > > > From vapor1 at teleport.com Wed Mar 25 12:35:19 2009 From: vapor1 at teleport.com (Gaseous Fumes) Date: Wed, 25 Mar 2009 12:35:19 -0700 (GMT-07:00) Subject: PROPOSAL: Binary Literals Message-ID: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> A couple of quick notes: 1) Ruby already has this. (The underscores in numbers, that is) 2) I considered adding this to the proposal as I was writing it, but decided it was an orthogonal issue and deserved its own proposal, since it has nothing per se to do with binary literals. (As James mentions, it would make sense for all numbers, not just binary ones.) 3) I encourage someone else to write it up as a proposal. If I get done with the other proposals I intend to submit, and still have time, I might do it myself, but if you want to ensure that the proposal gets proposed, I suggest you don't wait for me. One caveat: Consider the impact on Integer.parseInt, Long.decode(), etc. (I suggest the decode methods get changed to accept underscores, but the parseInt ones don't.) 4) An observation to Joe Darcy and the other Sun engineers involved in reviewing proposals: The expected "about five" limit on proposals really encourages people to lump a bunch of semi-related things into one proposal rather than making each their own proposal, even when the latter would be a more logical way of getting individual orthogonal ideas reviewed separately. I think this is a problem. For instance, the "null safe operators" proposal (all or nothing) vs. splitting each of them out as individual proposals. There have been a number of proposals put forth where I thought "I agree with half of this proposal and wish the other half wasn't in the same proposal." I hope that the "about" in "about five" is flexible enough to allow a bunch of very minor proposals to expand that limit well past five if they seem good ideas and easy to implement with few repercussions. Five seems like a pretty low number to me, given that it's been MANY years since it was even possible for users to suggest changes to Java (basically, since JDK 5 was in the planning stages, as JDK 6 was announced to be a "no language changes" release), and there has been much evolution in other programming languages during that time. I think that good ideas should make it into Java (and bad ideas shouldn't) subject to the necessary manpower in review and implementation, regardless of the number of proposals used to submit them. Otherwise, Java risks getting left in the dust as other languages become much easier to use, much faster. Derek -----Original Message----- >From: james lowden >Sent: Mar 25, 2009 12:07 PM >To: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Binary Literals > > >Actually, that's a good idea in general for long numeric constants. 9_000_000_000_000_000L is easier to parse than 9000000000000000L. > > >--- On Wed, 3/25/09, Stephen Colebourne wrote: > >> From: Stephen Colebourne >> Subject: Re: PROPOSAL: Binary Literals >> To: coin-dev at openjdk.java.net >> Date: Wednesday, March 25, 2009, 1:50 PM >> See >> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >> for my take on this from long ago. >> >> In particular, I'd suggest allowing a character to >> separate long binary strings: >> >> int anInt1 = 0b10100001_01000101_10100001_01000101; >> >> much more readable. >> >> Stephen >> >> 2009/3/25 Derek Foster : >> > Hmm. Second try at sending to the list. Let's see >> if this works. (In the >> > meantime, I noticed that Bruce Chapman has mentioned >> something similar in his >> > another proposal, so I think we are in agreement on >> this. This proposal >> > should not be taken as to compete with his similar >> proposal: I'd quite like >> > to see type suffixes for bytes, shorts, etc. added to >> Java, in addition to >> > binary literals.) Anyway... >> > >> > >> > >> > >> > Add binary literals to Java. >> > >> > AUTHOR(S): Derek Foster >> > >> > OVERVIEW >> > >> > In some programming domains, use of binary numbers >> (typically as bitmasks, >> > bit-shifts, etc.) is very common. However, Java code, >> due to its C heritage, >> > has traditionally forced programmers to represent >> numbers in only decimal, >> > octal, or hexadecimal. (In practice, octal is rarely >> used, and is present >> > mostly for backwards compatibility with C) >> > >> > When the data being dealt with is fundamentally >> bit-oriented, however, using >> > hexadecimal to represent ranges of bits requires an >> extra degree of >> > translation for the programmer, and this can often >> become a source of errors. >> > For instance, if a technical specification lists >> specific values of interest >> > in binary (for example, in a compression encoding >> algorithm or in the >> > specifications for a network protocol, or for >> communicating with a bitmapped >> > hardware device) then a programmer coding to that >> specification must >> > translate each such value from its binary >> representation into hexadecimal. >> > Checking to see if this translation has been done >> correctly is accomplished >> > by back-translating the numbers. In most cases, >> programmers do these >> > translations in their heads, and HOPEFULLY get them >> right. however, errors >> > can easily creep in, and re-verifying the results is >> not straightforward >> > enough to be done frequently. >> > >> > Furthermore, in many cases, the binary representations >> of numbers makes it >> > much more clear what is actually intended than the >> hexadecimal one. For >> > instance, this: >> > >> > private static final int BITMASK = 0x1E; >> > >> > does not immediately make it clear that the bitmask >> being declared comprises >> > a single contiguous range of four bits. >> > >> > In many cases, it would be more natural for the >> programmer to be able to >> > write the numbers in binary in the source code, >> eliminating the need for >> > manual translation to hexadecimal entirely. >> > >> > >> > FEATURE SUMMARY: >> > >> > In addition to the existing "1" (decimal), >> "01" (octal) and "0x1" >> > (hexadecimal) form of specifying numeric literals, a >> new form "0b1" (binary) >> > would be added. >> > >> > Note that this is the same syntax as has been used as >> an extension by the GCC >> > C/C++ compilers for many years, and also is used in >> the Ruby language, as >> > well as in the Python language. >> > >> > >> > MAJOR ADVANTAGE: >> > >> > It is no longer necessary for programmers to translate >> binary numbers to and >> > from hexadecimal in order to use them in Java >> programs. >> > >> > >> > MAJOR BENEFIT: >> > >> > Code using bitwise operations is more readable and >> easier to verify against >> > technical specifications that use binary numbers to >> specify constants. >> > >> > Routines that are bit-oriented are easier to >> understand when an artifical >> > translation to hexadecimal is not required in order to >> fulfill the >> > constraints of the language. >> > >> > MAJOR DISADVANTAGE: >> > >> > Someone might incorrectly think that "0b1" >> represented the same value as >> > hexadecimal number "0xB1". However, note >> that this problem has existed for >> > octal/decimal for many years (confusion between >> "050" and "50") and does not >> > seem to be a major issue. >> > >> > >> > ALTERNATIVES: >> > >> > Users could continue to write the numbers as decimal, >> octal, or hexadecimal, >> > and would continue to have the problems observed in >> this document. >> > >> > Another alternative would be for code to translate at >> runtime from binary >> > strings, such as: >> > >> > ? int BITMASK = >> Integer.parseInt("00001110", 2); >> > >> > Besides the obvious extra verbosity, there are several >> problems with this: >> > >> > * Calling a method such as Integer.parseInt at runtime >> will typically make it >> > impossible for the compiler to inline the value of >> this constant, since its >> > value has been taken from a runtime method call. >> Inlining is important, >> > because code that does bitwise parsing is often very >> low-level code in tight >> > loops that must execute quickly. (This is particularly >> the case for mobile >> > applications and other applications that run on >> severely resource-constrained >> > environments, which is one of the cases where binary >> numbers would be most >> > valuable, since talking to low-level hardware is one >> of the primary use cases >> > for this feature.) >> > >> > * Constants such as the above cannot be used as >> selectors in 'switch' >> > statements. >> > >> > * Any errors in the string to be parsed (for instance, >> an extra space) will >> > result in runtime exceptions, rather than compile-time >> errors as would have >> > occurred in normal parsing. If such a value is >> declared 'static', this will >> > result in some very ugly exceptions at runtime. >> > >> > >> > EXAMPLES: >> > >> > // An 8-bit 'byte' literal. >> > byte aByte = (byte)0b00100001; >> > >> > // A 16-bit 'short' literal. >> > short aShort = (short)0b1010000101000101; >> > >> > // Some 32-bit 'int' literals. >> > int anInt1 = 0b10100001010001011010000101000101; >> > int anInt2 = 0b101; >> > int anInt3 = 0B101; // The B can be upper or lower >> case as per the x in >> > "0x45". >> > >> > // A 64-bit 'long' literal. Note the >> "L" suffix, as would also be used >> > // for a long in decimal, hexadecimal, or octal. >> > long aLong = >> > >> 0b01010000101000101101000010100010110100001010001011010000101000101L; >> > >> > SIMPLE EXAMPLE: >> > >> > class Foo { >> > public static void main(String[] args) { >> > ?System.out.println("The value 10100001 in >> decimal is " + 0b10100001); >> > } >> > >> > >> > ADVANCED EXAMPLE: >> > >> > // Binary constants could be used in code that needs >> to be >> > // easily checkable against a specifications document, >> such >> > // as this simulator for a hypothetical 8-bit >> microprocessor: >> > >> > public State decodeInstruction(int instruction, State >> state) { >> > ?if ((instruction & 0b11100000) == 0b00000000) { >> > ? ?final int register = instruction & >> 0b00001111; >> > ? ?switch (instruction & 0b11110000) { >> > ? ? ?case 0b00000000: return state.nop(); >> > ? ? ?case 0b00010000: return >> state.copyAccumTo(register); >> > ? ? ?case 0b00100000: return >> state.addToAccum(register); >> > ? ? ?case 0b00110000: return >> state.subFromAccum(register); >> > ? ? ?case 0b01000000: return >> state.multiplyAccumBy(register); >> > ? ? ?case 0b01010000: return >> state.divideAccumBy(register); >> > ? ? ?case 0b01100000: return >> state.setAccumFrom(register); >> > ? ? ?case 0b01110000: return >> state.returnFromCall(); >> > ? ? ?default: throw new IllegalArgumentException(); >> > ? ?} >> > ?} else { >> > ? ?final int address = instruction & 0b00011111; >> > ? ?switch (instruction & 0b11100000) { >> > ? ? ?case 0b00100000: return state.jumpTo(address); >> > ? ? ?case 0b01000000: return >> state.jumpIfAccumZeroTo(address); >> > ? ? ?case 0b01000000: return >> state.jumpIfAccumNonzeroTo(address); >> > ? ? ?case 0b01100000: return >> state.setAccumFromMemory(address); >> > ? ? ?case 0b10100000: return >> state.writeAccumToMemory(address); >> > ? ? ?case 0b11000000: return state.callTo(address); >> > ? ? ?default: throw new IllegalArgumentException(); >> > ? ?} >> > ?} >> > } >> > >> > // Binary literals can be used to make a bitmap more >> readable: >> > >> > public static final short[] HAPPY_FACE = { >> > ? (short)0b0000011111100000; >> > ? (short)0b0000100000010000; >> > ? (short)0b0001000000001000; >> > ? (short)0b0010000000000100; >> > ? (short)0b0100000000000010; >> > ? (short)0b1000011001100001; >> > ? (short)0b1000011001100001; >> > ? (short)0b1000000000000001; >> > ? (short)0b1000000000000001; >> > ? (short)0b1001000000001001; >> > ? (short)0b1000100000010001; >> > ? (short)0b0100011111100010; >> > ? (short)0b0010000000000100; >> > ? (short)0b0001000000001000; >> > ? (short)0b0000100000010000; >> > ? (short)0b0000011111100000; >> > } >> > >> > // Binary literals can make relationships >> > // among data more apparent than they would >> > // be in hex or octal. >> > // >> > // For instance, what does the following >> > // array contain? In hexadecimal, it's hard to >> tell: >> > public static final int[] PHASES = { >> > ? ?0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >> > } >> > >> > // In binary, it's obvious that a number is being >> > // rotated left one bit at a time. >> > public static final int[] PHASES = { >> > ? ?0b00110001, >> > ? ?0b01100010, >> > ? ?0b11000100, >> > ? ?0b10001001, >> > ? ?0b00010011, >> > ? ?0b00100110, >> > ? ?0b01001100, >> > ? ?0b10011000, >> > } >> > >> > >> > DETAILS >> > >> > SPECIFICATION: >> > >> > Section 3.10.1 ("Integer Literals") of the >> JLS3 should be changed to add the >> > following: >> > >> > IntegerLiteral: >> > ? ? ? ?DecimalIntegerLiteral >> > ? ? ? ?HexIntegerLiteral >> > ? ? ? ?OctalIntegerLiteral >> > ? ? ? ?BinaryIntegerLiteral ? ? ? ? // Added >> > >> > BinaryIntegerLiteral: >> > ? ? ? ?BinaryNumeral IntegerTypeSuffix_opt >> > >> > BinaryNumeral: >> > ? ? ? ?0 b BinaryDigits >> > ? ? ? ?0 B BinaryDigits >> > >> > BinaryDigits: >> > ? ? ? ?BinaryDigit >> > ? ? ? ?BinaryDigit BinaryDigits >> > >> > BinaryDigit: one of >> > ? ? ? ?0 1 >> > >> > COMPILATION: >> > >> > Binary literals would be compiled to class files in >> the same fashion as >> > existing decimal, hexadecimal, and octal literals are. >> No special support or >> > changes to the class file format are needed. >> > >> > TESTING: >> > >> > The feature can be tested in the same way as existing >> decimal, hexadecimal, >> > and octal literals are: Create a bunch of constants in >> source code, including >> > the maximum and minimum positive and negative values >> for integer and long >> > types, and verify them at runtime to have the correct >> values. >> > >> > >> > LIBRARY SUPPORT: >> > >> > The methods Integer.decode(String) and >> Long.decode(String) should be modified >> > to parse binary numbers (as specified above) in >> addition to their existing >> > support for decimal, hexadecimal, and octal numbers. >> > >> > >> > REFLECTIVE APIS: >> > >> > No updates to the reflection APIs are needed. >> > >> > >> > OTHER CHANGES: >> > >> > No other changes are needed. >> > >> > >> > MIGRATION: >> > >> > Individual decimal, hexadecimal, or octal constants in >> existing code can be >> > updated to binary as a programmer desires. >> > >> > >> > COMPATIBILITY >> > >> > >> > BREAKING CHANGES: >> > >> > This feature would not break any existing programs, >> since the suggested >> > syntax is currently considerd to be a compile-time >> error. >> > >> > >> > EXISTING PROGRAMS: >> > >> > Class file format does not change, so existing >> programs can use class files >> > compiled with the new feature without problems. >> > >> > >> > REFERENCES: >> > >> > The GCC/G++ compiler, which already supports this >> syntax (as of version 4.3) >> > as an extension to standard C/C++. >> > http://gcc.gnu.org/gcc-4.3/changes.html >> > >> > The Ruby language, which supports binary literals: >> > http://wordaligned.org/articles/binary-literals >> > >> > The Python language added binary literals in version >> 2.6: >> > >> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >> > >> > EXISTING BUGS: >> > >> > "Language support for literal numbers in binary >> and other bases" >> > >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >> > >> > URL FOR PROTOTYPE (optional): >> > >> > None. >> > >> > > > > > From mbien at fh-landshut.de Wed Mar 25 12:47:37 2009 From: mbien at fh-landshut.de (Michael Bien) Date: Wed, 25 Mar 2009 20:47:37 +0100 Subject: PROPOSAL: Auto-assignment Parameters (resend) In-Reply-To: References: Message-ID: <49CA8A59.4040702@fh-landshut.de> Hello everyone, what about property change listener methods? I mean call "data" "bean" and you would have poor man's properties I suggested in a comment of the small property support proposal: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000629.html having a easy to use property change event mechanism would bring java and javafx a step further together. But i would prefer to move the data keyword to the field declaration rather than to the class declaration. public class Foo { private data final int x; private data final int y; private final String noData } I know this hits a lot for resistance but Annotations would have IMO a huge advantage, consider this example. public class Foo { @Get private data final int x; @Get private data final int y; @Get @Set private String foo } Why Annotations? They are not intended to alter code behaviour.. right? The main reason is that java.next could easily introduce popper properties (with e.g a property keyword) without conflicts. The Annotations could stay where they are and wouldn't break anything. regards, michael Reinier Zwitserloot wrote: > I like where this is going, but I'd rather see a bigger setup for auto- > POJO classes. I proposed this before and in most java circles (outside > of coin-dev!), this idea was considered very useful: > > public data class Foo { > private final int x; > private final int y; > private final String foo; > } > > > The above class would auto-generate the getters, a constructor, > hashCode, equals, and toString. You can add methods to it if you want, > and if you define a method that would usually be auto-generated, it > isn't auto-generated. So, if you need to do some extra processing > before returning 'foo' via the getter, go right ahead. You can even > add this later without breaking your API's compatibility. > > --Reinier Zwitserloot > > > > On Mar 25, 2009, at 02:07, Mark Mahieu wrote: > > >> HTML version + prototype available at http://slm888.com/javac >> >> >> >> Auto-assignment Parameters v0.1 >> >> >> AUTHOR(S): >> >> Mark Mahieu >> >> >> OVERVIEW >> >> FEATURE SUMMARY: Should be suitable as a summary in a language >> tutorial. >> >> An additional form of constructor parameter which provides automatic >> assignment of the parameter's value to an instance field. These >> parameters >> are implicitly declared as final to prevent unintentional >> assignments to the >> wrong variable in the constructor body. >> >> >> MAJOR ADVANTAGE: What makes the proposal a favorable change? >> >> Reduces the likelihood of some common coding errors relating to >> assignment >> of fields in a constructor, including those where: >> >> * a field is assigned to itself >> * the parameter is assigned instead of the field >> * the assignment to the field is missing entirely >> >> These and other errors are often caused by typos or code refactoring. >> >> >> MAJOR BENEFIT: Why is the platform better if the proposal is adopted? >> >> A programmer's intent is more clearly expressed for the extremely >> common >> case of assigning a constructor parameter directly to an instance >> field with >> the same name. >> >> >> MAJOR DISADVANTAGE: There is always a cost. >> >> As with any sugar which enables a more concise way of expressing an >> existing >> idiom, programmers may be tempted to use it even when the original >> form >> would be more appropriate. >> >> >> ALTERNATIVES: Can the benefits and advantages be had some way >> without a >> language change? >> >> IDEs and tools such as FindBugs are good at warning about the kind >> of errors >> mentioned above, however since the code in question is usually still >> valid >> to the compiler, they are limited in what action they can take by >> default. >> >> A language change can combine the ability to avoid these errors >> entirely >> with a more expressive idiom, resulting in an increased signal to >> noise >> ratio for readers of that code. >> >> >> >> EXAMPLES >> >> SIMPLE EXAMPLE: Show the simplest possible program utilizing the new >> feature. >> >> class C { >> int i; >> C(int this.i) {} >> } >> >> >> ADVANCED EXAMPLE: Show advanced usage(s) of the feature. >> >> >> class Proposal { >> >> private final String name; >> private final String author; >> private boolean suitableForCoin; >> private Integer score; >> >> public Proposal(String this.name, >> String this.author, >> boolean this.suitableForCoin, >> int this.score) { >> >> if (name.equals(?Auto-assignment Parameters?)) { >> suitableForCoin = true; // final so compile-time error >> } >> } >> >> // rest of class ... >> } >> >> >> >> 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. >> >> The syntactic grammar is modified to include auto-assignment >> parameters for >> constructors: >> >> ConstructorDeclaratorRest: >> ConstructorParameters [throws QualifiedIdentifierList] >> MethodBody >> >> ConstructorParameters: >> ( [ConstructorParameterDecls] ) >> >> ConstructorParameterDecls: >> [final] [Annotations] Type >> ConstructorParameterDeclsRest >> >> ConstructorParameterDeclsRest: >> ConstructorParameterId [ , ConstructorParameterDecls] >> ... ConstructorParameterId >> >> ConstructorParameterId: >> VariableDeclaratorId >> this . VariableDeclaratorId >> super . VariableDeclaratorId >> >> An auto-assignment parameter is a formal parameter (JLSv3 ?8.4.1) >> which >> specifies an instance field instead of an identifier. Its value is >> automatically assigned to the specified field. It may only be used >> in a >> constructor. >> >> The automatic assignment takes place after any explicit or implicit >> invocation of another constructor, and before any statements in the >> body of >> the constructor. A constructor which declares n auto-assignment >> parameters >> will perform n such automatic assignments, in the order that the >> parameters >> are declared. >> >> The parameter has the same name (JLSv3 ?6.2) as the field to which >> it is >> assigned; replacing each auto-assignment parameter with a normal >> formal >> parameter with the same name would yield a constructor with an >> identical >> signature. As with a normal parameter, the parameter's name is >> entered into >> the scope of the constructor body (JLSv3 ?6.3), and therefore >> shadows the >> field (JLSv3 ?6.3.1) within that scope. >> >> It is a compile-time error if the field is not accessible from the >> constructor in which the parameter appears. >> >> It is a compile-time error if the declared type of the parameter is >> not >> assignment compatible (JLSv3 ?5.2) with the field to which it is >> automatically assigned. >> >> If an unboxing conversion is required by an automatic assignment, any >> NullPointerException thrown as a result (JLSv3 ?5.1.8) will contain >> the name >> of the field on which the conversion failed, which may be retrieved by >> calling getMessage() on the exception. >> >> Auto-assignment parameters are implicitly final, and follow the >> standard >> rules for final variables (JLSv3 ?4.12.4). Explicitly declaring an >> auto-assignment parameter as final has no effect, and does not cause a >> compilation error. >> >> Auto-assignment parameters follow the standard definite assignment >> rules for >> formal parameters (JLSv3 ?16.3). >> >> An auto-assignment parameter may be annotated. >> >> If an auto-assignment parameter is the last parameter in the list, and >> refers to a field of array type, it may be a variable arity parameter. >> >> >> >> 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! >> >> Desugaring of the following class: >> >> class Foo { >> int value; >> Foo(Integer this.value) { >> System.out.println(value); >> } >> } >> >> would result in (unboxing desugaring omitted): >> >> class Foo { >> int value; >> Foo(final Integer value) { >> super(); >> if (value == null) >> throw new NullPointerException("value"); >> this.value = value; >> System.out.println(value); >> } >> } >> >> No changes to the classfile format are required. Tools which >> consume class >> files see the constructor signature as though it had been written >> using >> normal formal parameters. >> >> >> TESTING: How can the feature be tested? >> >> An initial set of jtreg tests is included in the prototype. >> >> >> LIBRARY SUPPORT: Are any supporting libraries needed for the feature? >> >> No >> >> >> 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. >> >> com.sun.source.tree.VariableTree would require an additional method >> which >> returns the auto-assigned field. >> >> >> 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 >> >> >> MIGRATION: Sketch how a code base could be converted, manually or >> automatically, to use the new feature. >> >> Assignment statements in constructors for which all of the following >> are >> true can be considered suitable for conversion: >> * the lhs of the assignment is a non-static field >> * the rhs is a parameter with the same name as the field >> * there are no other assignments to the parameter anywhere in the >> constructor >> * there are no assignments to, or other uses of the field before >> the >> assignment statement in question (including invoked constructors) >> >> Such statements can be converted by: >> 1) replacing the parameter with an auto-assignment parameter >> (prefixing >> the existing parameter's identifier with 'this.'), and >> 2) removing the assignment statement >> >> >> >> COMPATIBILITY >> >> BREAKING CHANGES: Are any previously valid programs now invalid? If >> so, list >> one. >> >> No >> >> >> 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 semantics of existing class files and legal source files are >> unchanged >> by this feature. >> >> >> >> REFERENCES >> >> EXISTING BUGS: Please include a list of any existing Sun bug ids >> related to >> this proposal. >> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 >> (uses a 'setter' method rather than a constructor in its example) >> >> FindBugs bug patterns - http://findbugs.sourceforge.net/bugDescriptions.html >> * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) >> * Self comparison of field with itself (SA_FIELD_SELF_COMPARISON) >> * Nonsensical self computation involving a field (e.g., x & x) >> (SA_FIELD_SELF_COMPUTATION) >> * Self assignment of local variable (SA_LOCAL_SELF_ASSIGNMENT) >> * Nonsensical self computation involving a variable (e.g., x & x) >> (SA_LOCAL_SELF_COMPUTATION) >> * Uninitialized read of field in constructor (UR_UNINIT_READ) >> * Unwritten field (UWF_UNWRITTEN_FIELD) >> * Dead store to local variable (DLS_DEAD_LOCAL_STORE) >> * Dead store of null to local variable (DLS_DEAD_LOCAL_STORE_OF_NULL) >> >> >> >> URL FOR PROTOTYPE (optional): >> >> http://slm888.com/javac >> >> >> >> DESIGN ALTERNATIVES: >> >> The following variations have been explored and are worth mentioning: >> >> * Allow auto-assignment parameters on all non-abstract methods. >> This may be especially useful on the extremely common 'setter' >> methods >> in 'value object' classes. >> >> * Remove the requirement for (or even disallow) the type to be >> specified on >> auto-assignment parameters. >> Experimentation with this idea suggests that it may work quite >> well for >> constructors, further emphasising the difference in intent and >> semantics >> from those of normal parameters. However, it may not work so well in >> combination with auto-assignment parameters on all non-abstract >> methods, and >> requires a change to the order in which javac compiles classes (can >> still >> pass jtreg tests). >> >> * Allow an alternative name to be specified. >> This adds additional complexity to support a fractional >> percentage of >> cases, which could continue to use the existing coding pattern. >> >> > > > > > From reinier at zwitserloot.com Wed Mar 25 13:07:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 21:07:07 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Message-ID: Of all low impact coin submissions, this just isn't very compelling. Real Programmers can count in hexadecimal ever since they were A years old, after all. --Reinier Zwitserloot On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: > A couple of quick notes: > > 1) Ruby already has this. (The underscores in numbers, that is) > > 2) I considered adding this to the proposal as I was writing it, but > decided it was an orthogonal issue and deserved its own proposal, > since it has nothing per se to do with binary literals. (As James > mentions, it would make sense for all numbers, not just binary ones.) > > 3) I encourage someone else to write it up as a proposal. If I get > done with the other proposals I intend to submit, and still have > time, I might do it myself, but if you want to ensure that the > proposal gets proposed, I suggest you don't wait for me. One caveat: > Consider the impact on Integer.parseInt, Long.decode(), etc. (I > suggest the decode methods get changed to accept underscores, but > the parseInt ones don't.) > > 4) An observation to Joe Darcy and the other Sun engineers involved > in reviewing proposals: The expected "about five" limit on proposals > really encourages people to lump a bunch of semi-related things into > one proposal rather than making each their own proposal, even when > the latter would be a more logical way of getting individual > orthogonal ideas reviewed separately. I think this is a problem. > > For instance, the "null safe operators" proposal (all or nothing) > vs. splitting each of them out as individual proposals. There have > been a number of proposals put forth where I thought "I agree with > half of this proposal and wish the other half wasn't in the same > proposal." > > I hope that the "about" in "about five" is flexible enough to allow > a bunch of very minor proposals to expand that limit well past five > if they seem good ideas and easy to implement with few > repercussions. Five seems like a pretty low number to me, given that > it's been MANY years since it was even possible for users to suggest > changes to Java (basically, since JDK 5 was in the planning stages, > as JDK 6 was announced to be a "no language changes" release), and > there has been much evolution in other programming languages during > that time. I think that good ideas should make it into Java (and bad > ideas shouldn't) subject to the necessary manpower in review and > implementation, regardless of the number of proposals used to submit > them. Otherwise, Java risks getting left in the dust as other > languages become much easier to use, much faster. > > Derek > > -----Original Message----- >> From: james lowden >> Sent: Mar 25, 2009 12:07 PM >> To: coin-dev at openjdk.java.net >> Subject: Re: PROPOSAL: Binary Literals >> >> >> Actually, that's a good idea in general for long numeric >> constants. 9_000_000_000_000_000L is easier to parse than >> 9000000000000000L. >> >> >> --- On Wed, 3/25/09, Stephen Colebourne wrote: >> >>> From: Stephen Colebourne >>> Subject: Re: PROPOSAL: Binary Literals >>> To: coin-dev at openjdk.java.net >>> Date: Wednesday, March 25, 2009, 1:50 PM >>> See >>> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >>> for my take on this from long ago. >>> >>> In particular, I'd suggest allowing a character to >>> separate long binary strings: >>> >>> int anInt1 = 0b10100001_01000101_10100001_01000101; >>> >>> much more readable. >>> >>> Stephen >>> >>> 2009/3/25 Derek Foster : >>>> Hmm. Second try at sending to the list. Let's see >>> if this works. (In the >>>> meantime, I noticed that Bruce Chapman has mentioned >>> something similar in his >>>> another proposal, so I think we are in agreement on >>> this. This proposal >>>> should not be taken as to compete with his similar >>> proposal: I'd quite like >>>> to see type suffixes for bytes, shorts, etc. added to >>> Java, in addition to >>>> binary literals.) Anyway... >>>> >>>> >>>> >>>> >>>> Add binary literals to Java. >>>> >>>> AUTHOR(S): Derek Foster >>>> >>>> OVERVIEW >>>> >>>> In some programming domains, use of binary numbers >>> (typically as bitmasks, >>>> bit-shifts, etc.) is very common. However, Java code, >>> due to its C heritage, >>>> has traditionally forced programmers to represent >>> numbers in only decimal, >>>> octal, or hexadecimal. (In practice, octal is rarely >>> used, and is present >>>> mostly for backwards compatibility with C) >>>> >>>> When the data being dealt with is fundamentally >>> bit-oriented, however, using >>>> hexadecimal to represent ranges of bits requires an >>> extra degree of >>>> translation for the programmer, and this can often >>> become a source of errors. >>>> For instance, if a technical specification lists >>> specific values of interest >>>> in binary (for example, in a compression encoding >>> algorithm or in the >>>> specifications for a network protocol, or for >>> communicating with a bitmapped >>>> hardware device) then a programmer coding to that >>> specification must >>>> translate each such value from its binary >>> representation into hexadecimal. >>>> Checking to see if this translation has been done >>> correctly is accomplished >>>> by back-translating the numbers. In most cases, >>> programmers do these >>>> translations in their heads, and HOPEFULLY get them >>> right. however, errors >>>> can easily creep in, and re-verifying the results is >>> not straightforward >>>> enough to be done frequently. >>>> >>>> Furthermore, in many cases, the binary representations >>> of numbers makes it >>>> much more clear what is actually intended than the >>> hexadecimal one. For >>>> instance, this: >>>> >>>> private static final int BITMASK = 0x1E; >>>> >>>> does not immediately make it clear that the bitmask >>> being declared comprises >>>> a single contiguous range of four bits. >>>> >>>> In many cases, it would be more natural for the >>> programmer to be able to >>>> write the numbers in binary in the source code, >>> eliminating the need for >>>> manual translation to hexadecimal entirely. >>>> >>>> >>>> FEATURE SUMMARY: >>>> >>>> In addition to the existing "1" (decimal), >>> "01" (octal) and "0x1" >>>> (hexadecimal) form of specifying numeric literals, a >>> new form "0b1" (binary) >>>> would be added. >>>> >>>> Note that this is the same syntax as has been used as >>> an extension by the GCC >>>> C/C++ compilers for many years, and also is used in >>> the Ruby language, as >>>> well as in the Python language. >>>> >>>> >>>> MAJOR ADVANTAGE: >>>> >>>> It is no longer necessary for programmers to translate >>> binary numbers to and >>>> from hexadecimal in order to use them in Java >>> programs. >>>> >>>> >>>> MAJOR BENEFIT: >>>> >>>> Code using bitwise operations is more readable and >>> easier to verify against >>>> technical specifications that use binary numbers to >>> specify constants. >>>> >>>> Routines that are bit-oriented are easier to >>> understand when an artifical >>>> translation to hexadecimal is not required in order to >>> fulfill the >>>> constraints of the language. >>>> >>>> MAJOR DISADVANTAGE: >>>> >>>> Someone might incorrectly think that "0b1" >>> represented the same value as >>>> hexadecimal number "0xB1". However, note >>> that this problem has existed for >>>> octal/decimal for many years (confusion between >>> "050" and "50") and does not >>>> seem to be a major issue. >>>> >>>> >>>> ALTERNATIVES: >>>> >>>> Users could continue to write the numbers as decimal, >>> octal, or hexadecimal, >>>> and would continue to have the problems observed in >>> this document. >>>> >>>> Another alternative would be for code to translate at >>> runtime from binary >>>> strings, such as: >>>> >>>> int BITMASK = >>> Integer.parseInt("00001110", 2); >>>> >>>> Besides the obvious extra verbosity, there are several >>> problems with this: >>>> >>>> * Calling a method such as Integer.parseInt at runtime >>> will typically make it >>>> impossible for the compiler to inline the value of >>> this constant, since its >>>> value has been taken from a runtime method call. >>> Inlining is important, >>>> because code that does bitwise parsing is often very >>> low-level code in tight >>>> loops that must execute quickly. (This is particularly >>> the case for mobile >>>> applications and other applications that run on >>> severely resource-constrained >>>> environments, which is one of the cases where binary >>> numbers would be most >>>> valuable, since talking to low-level hardware is one >>> of the primary use cases >>>> for this feature.) >>>> >>>> * Constants such as the above cannot be used as >>> selectors in 'switch' >>>> statements. >>>> >>>> * Any errors in the string to be parsed (for instance, >>> an extra space) will >>>> result in runtime exceptions, rather than compile-time >>> errors as would have >>>> occurred in normal parsing. If such a value is >>> declared 'static', this will >>>> result in some very ugly exceptions at runtime. >>>> >>>> >>>> EXAMPLES: >>>> >>>> // An 8-bit 'byte' literal. >>>> byte aByte = (byte)0b00100001; >>>> >>>> // A 16-bit 'short' literal. >>>> short aShort = (short)0b1010000101000101; >>>> >>>> // Some 32-bit 'int' literals. >>>> int anInt1 = 0b10100001010001011010000101000101; >>>> int anInt2 = 0b101; >>>> int anInt3 = 0B101; // The B can be upper or lower >>> case as per the x in >>>> "0x45". >>>> >>>> // A 64-bit 'long' literal. Note the >>> "L" suffix, as would also be used >>>> // for a long in decimal, hexadecimal, or octal. >>>> long aLong = >>>> >>> 0b01010000101000101101000010100010110100001010001011010000101000101L >>> ; >>>> >>>> SIMPLE EXAMPLE: >>>> >>>> class Foo { >>>> public static void main(String[] args) { >>>> System.out.println("The value 10100001 in >>> decimal is " + 0b10100001); >>>> } >>>> >>>> >>>> ADVANCED EXAMPLE: >>>> >>>> // Binary constants could be used in code that needs >>> to be >>>> // easily checkable against a specifications document, >>> such >>>> // as this simulator for a hypothetical 8-bit >>> microprocessor: >>>> >>>> public State decodeInstruction(int instruction, State >>> state) { >>>> if ((instruction & 0b11100000) == 0b00000000) { >>>> final int register = instruction & >>> 0b00001111; >>>> switch (instruction & 0b11110000) { >>>> case 0b00000000: return state.nop(); >>>> case 0b00010000: return >>> state.copyAccumTo(register); >>>> case 0b00100000: return >>> state.addToAccum(register); >>>> case 0b00110000: return >>> state.subFromAccum(register); >>>> case 0b01000000: return >>> state.multiplyAccumBy(register); >>>> case 0b01010000: return >>> state.divideAccumBy(register); >>>> case 0b01100000: return >>> state.setAccumFrom(register); >>>> case 0b01110000: return >>> state.returnFromCall(); >>>> default: throw new IllegalArgumentException(); >>>> } >>>> } else { >>>> final int address = instruction & 0b00011111; >>>> switch (instruction & 0b11100000) { >>>> case 0b00100000: return state.jumpTo(address); >>>> case 0b01000000: return >>> state.jumpIfAccumZeroTo(address); >>>> case 0b01000000: return >>> state.jumpIfAccumNonzeroTo(address); >>>> case 0b01100000: return >>> state.setAccumFromMemory(address); >>>> case 0b10100000: return >>> state.writeAccumToMemory(address); >>>> case 0b11000000: return state.callTo(address); >>>> default: throw new IllegalArgumentException(); >>>> } >>>> } >>>> } >>>> >>>> // Binary literals can be used to make a bitmap more >>> readable: >>>> >>>> public static final short[] HAPPY_FACE = { >>>> (short)0b0000011111100000; >>>> (short)0b0000100000010000; >>>> (short)0b0001000000001000; >>>> (short)0b0010000000000100; >>>> (short)0b0100000000000010; >>>> (short)0b1000011001100001; >>>> (short)0b1000011001100001; >>>> (short)0b1000000000000001; >>>> (short)0b1000000000000001; >>>> (short)0b1001000000001001; >>>> (short)0b1000100000010001; >>>> (short)0b0100011111100010; >>>> (short)0b0010000000000100; >>>> (short)0b0001000000001000; >>>> (short)0b0000100000010000; >>>> (short)0b0000011111100000; >>>> } >>>> >>>> // Binary literals can make relationships >>>> // among data more apparent than they would >>>> // be in hex or octal. >>>> // >>>> // For instance, what does the following >>>> // array contain? In hexadecimal, it's hard to >>> tell: >>>> public static final int[] PHASES = { >>>> 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >>>> } >>>> >>>> // In binary, it's obvious that a number is being >>>> // rotated left one bit at a time. >>>> public static final int[] PHASES = { >>>> 0b00110001, >>>> 0b01100010, >>>> 0b11000100, >>>> 0b10001001, >>>> 0b00010011, >>>> 0b00100110, >>>> 0b01001100, >>>> 0b10011000, >>>> } >>>> >>>> >>>> DETAILS >>>> >>>> SPECIFICATION: >>>> >>>> Section 3.10.1 ("Integer Literals") of the >>> JLS3 should be changed to add the >>>> following: >>>> >>>> IntegerLiteral: >>>> DecimalIntegerLiteral >>>> HexIntegerLiteral >>>> OctalIntegerLiteral >>>> BinaryIntegerLiteral // Added >>>> >>>> BinaryIntegerLiteral: >>>> BinaryNumeral IntegerTypeSuffix_opt >>>> >>>> BinaryNumeral: >>>> 0 b BinaryDigits >>>> 0 B BinaryDigits >>>> >>>> BinaryDigits: >>>> BinaryDigit >>>> BinaryDigit BinaryDigits >>>> >>>> BinaryDigit: one of >>>> 0 1 >>>> >>>> COMPILATION: >>>> >>>> Binary literals would be compiled to class files in >>> the same fashion as >>>> existing decimal, hexadecimal, and octal literals are. >>> No special support or >>>> changes to the class file format are needed. >>>> >>>> TESTING: >>>> >>>> The feature can be tested in the same way as existing >>> decimal, hexadecimal, >>>> and octal literals are: Create a bunch of constants in >>> source code, including >>>> the maximum and minimum positive and negative values >>> for integer and long >>>> types, and verify them at runtime to have the correct >>> values. >>>> >>>> >>>> LIBRARY SUPPORT: >>>> >>>> The methods Integer.decode(String) and >>> Long.decode(String) should be modified >>>> to parse binary numbers (as specified above) in >>> addition to their existing >>>> support for decimal, hexadecimal, and octal numbers. >>>> >>>> >>>> REFLECTIVE APIS: >>>> >>>> No updates to the reflection APIs are needed. >>>> >>>> >>>> OTHER CHANGES: >>>> >>>> No other changes are needed. >>>> >>>> >>>> MIGRATION: >>>> >>>> Individual decimal, hexadecimal, or octal constants in >>> existing code can be >>>> updated to binary as a programmer desires. >>>> >>>> >>>> COMPATIBILITY >>>> >>>> >>>> BREAKING CHANGES: >>>> >>>> This feature would not break any existing programs, >>> since the suggested >>>> syntax is currently considerd to be a compile-time >>> error. >>>> >>>> >>>> EXISTING PROGRAMS: >>>> >>>> Class file format does not change, so existing >>> programs can use class files >>>> compiled with the new feature without problems. >>>> >>>> >>>> REFERENCES: >>>> >>>> The GCC/G++ compiler, which already supports this >>> syntax (as of version 4.3) >>>> as an extension to standard C/C++. >>>> http://gcc.gnu.org/gcc-4.3/changes.html >>>> >>>> The Ruby language, which supports binary literals: >>>> http://wordaligned.org/articles/binary-literals >>>> >>>> The Python language added binary literals in version >>> 2.6: >>>> >>> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >>>> >>>> EXISTING BUGS: >>>> >>>> "Language support for literal numbers in binary >>> and other bases" >>>> >>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >>>> >>>> URL FOR PROTOTYPE (optional): >>>> >>>> None. >>>> >>>> >> >> >> >> > > From reinier at zwitserloot.com Wed Mar 25 13:27:36 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 21:27:36 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> Message-ID: <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> Context sensitive keyword creeps you out? That's problematic. 'module' is already going to be one. I'd love an alternative, but the few things I can come up with are all considerably worse: annotation, which is -slightly- more acceptable here than in other places because generating methods and fields is what annotations are supposed to do. However, they usually do so (via APT) in an entirely new source file, not the same one. (ab)using an existing keyword. 'const' and 'default' are the only reasonable ones, and both of those are a stretch, in my book. I don't like context sensitive keywords either, but as I've said before on this list, that decision has been made: They will be part of java7, and nothing on coin-dev is going to change that. You should move away from the idea of 'this keyword does so much magic!' and move towards the idea that this keyword simply declares that the class is to have bean semantics. The amount of magic performed by the compiler (right now, in java6) is enormous already. The amount of magic performed by a C compiler is a few orders of magnitude larger than that. As far as compiler magic goes, a simple desugaring is in fact one of the simplest things it could possibly do. As long as it doesn't cause surprises amongst the java programmer crowd, that cannot reasonably be put forward as a con. Your suggestion to have separate annotations is immediately going to run into the following complaint: Oh, the boilerplate! Why can't we have 1 annotation that does it all! Which brings us right back to my proposal. Not auto-generating something that's already there is indeed a bit of 'magic', but is that really so far-fetched? What else should it do? Generate an error? That's going to get the new vote as most annoying javac error when the varargs thing finally (yay!) gets sorted via Project Coin. There are very legitimate reasons to roll your own methods for a few of the otherwise POJO-esque classes you'd write with this feature. Backwards compatibility with other implementions of hashCode() is one, and doing some processing on variables is another, as is adding property support (with change listeners). It would obviously be acceptable in a small data pojo to forego hungarian notation. If it isn't - well, that won't be the first time coding practices hurt more than they help. The thing with coding practices is: Everyone has their own variant. One must at the very least expect those practices to evolve a little in the face of language changes, or one would be crippled. What you are suggesting with parameterizing each aspect of the method generation is going to become an entirely new programming language, just so you can specify that you want to avoid the password field, etcetera. The point of this proposal is very very specifically: For the default case, we make it easy for you. If you dont like the default case, that's perfectly allright. Roll your own method. Just to drive the point home, here's a customized class versus how you'd write it now. Note how the savings in size are almost ignorable, and it now looks like a different programming language. @GenerateConstructor(order={"bar", "foo"}, access=Access.PACKAGE_PRIVATE) @GenerateEquals(exclude={"baz"}) @GenerateHashCode(prime=97) @GenerateToString(JsonGenerator.class) public class ThisIsMyDataClass { @GenerateGetter @GenerateSetter(access=Access.PROTECTED) private int foo; @GenerateGetter private final String bar; //Oops! Forgot the annotation. Do I get any warning? private int baz; } vs: public data class ThisIsMyDataClass { private int foo; private final String bar; private final int baz; } The point of such a proposal is NOT to ease the making of getters and setters. It's only to do what it says on the tin: Make data classes. --Reinier Zwitserloot On Mar 25, 2009, at 19:25, Lawrence Kesteloot wrote: > Reinier, > > The idea of adding a context-sensitive keyword creeps me out. Also > this is doing a lot of magic based on a single keyword. Can you tell, > at a glance, what the keyword is doing? How much is generated? What > are the (complex) rules for auto-generating a constructor? > > I would prefer a more explicit approach, driven by annotations. If we > feel like boilerplate is annoying to write and bug-prone, then we > could have a java.lang.gen package with various annotations for > automatically generating code. Something like: > > @GenerateFullConstructor > @GenerateEqualsAndHashCode > @GenerateToString(JsonToStringGenerator.class) > public class Foo { > @GenerateGetter > private final int x; > @GenerateGetter > private final int y; > @GenerateGetter > private final String foo; > } > > Then it's explicit, each annotation can have parameters to modify its > behavior, and people can pick and choose what they need. There's no > magic about skipping the generation of toString if you've implemented > it. > > Here's an example of useful parameters for such annotations: many > people (myself included) like to prefix fields with something. I use > "m" (mFoo), but others use an underscore, and some both (m_foo). You'd > want the GenerateGetter annotation to be flexible about that. My code > would look like this: > > @GenerateGetter(prefix = "m") > private final String mFoo; > > Your "data" keyword would preclude this, forcing me to either drop my > (company-mandated) coding standard for data classes, or have getters > like "getMFoo()". > > With GenerateEqualsAndHashCode you might want to skip some fields. You > might want to skip fields for GenerateToString also (e.g., password > fields, or super long strings). > > Lawrence > > > On Wed, Mar 25, 2009 at 9:59 AM, Reinier Zwitserloot > wrote: >> There's no reference for auto-POJOs anywhere, but this should allow >> you to write up all you need: >> >> 1. 'data' is a context sensitive keyword that is legal on classes. >> The >> 'data' keyword will add a number of members to the class. >> >> 2. For each field, a getter is generated, according to the beanspec >> (getFoo() or isFoo()). if the field is not final, a setter is >> generated, according to beanspec (setFoo()), and the field is >> considered a property of the data class, unless it is transient. If >> the field is public, the getter (and, if not final, the setter), is >> not generated. For all generated getters/setters, if the getter/ >> setter >> is already in the class, or already defined (that is; not abstract) >> in >> any supertype, then the getter/setter is not generated. protected and >> visible package protected members from supertypes are also included >> both for generating setters/getters and for hashCode/equals/toString/ >> clone (upcoming). >> >> 3. hashCode() and equals(): Existence of the hashCode() or equals() >> method in any supertype is not relevant (obviously; all objects have >> them!) >> >> 3a. If only one of hashCode() or equals() is present, a warning is >> generated and neither hashCode() or equals() is auto-generated. The >> warning basically explains that overriding one but not the other is a >> bug. >> >> 3b. If both hashCode() and equals() are present, nothing happens. >> >> 3c. If neither is present, a hashCode() and equals() method are >> generated. These involve all properties (non-transient visible >> fields). equals() is defined by: >> >> 3c1: First check if the other object is of the exact same class as >> ourselves; if not, false. If null, false. >> 3c2: For each primitive property, check via == if they are equal. If >> any isn't, false. >> 3c3: For each object property, call its .equals(). If they aren't, >> false. >> 3c4: return true. >> >> for hashCode(), do whatever eclipse does out of the box to auto- >> generate hashCode() methods. It basically looks like: >> >> final int PRIME = 31; >> int result = 1; >> for ( each field ) result = result*31 + field.hashCode(); >> return result; >> >> Where hashCode() is generated in obvious fashion for all primitives >> (xor the upper and lower bits of longs together, convert floats and >> doubles to long/intbits and use that, chars/bytes/ints/shorts's >> hashCode is their own value, booleans are translated to 11/17. 'null' >> becomes 3. >> >> 4. *IF* all fields are private, and *IF* all fields are final, *AND* >> the class does not contain any explicit constructors, *AND* the class >> has a no-args super constructor, then a constructor is generated that >> includes all fields, in order of definition, which simply assigns >> them >> to the fields. visible properties from supertypes aren't included. >> >> 5. A toString() method is generated, if not already present in the >> type, which produces a string like so: "MyClassName [field1=value, >> field2=value]", for all properties. (so, non-visible fields from >> supertypes and transient fields are skipped). >> >> 6 (optional). Each generated member gets a @Generated annotation, >> which is a new annotation ( java.lang.annotations.Generated ). These >> are @Documented and @Retention.RUNTIME. >> >> >> Is it viable for coin? I'll write it up if so. >> >> --Reinier Zwitserloot >> >> >> >> On Mar 25, 2009, at 14:41, james lowden wrote: >> >>> >>> I'd like to see both. Auto-getters/setters/equals/etc. would be >>> really, really nice, but it would also be valuable to have a way of >>> specifying a variety of different constructors to generate, which >>> Mark's proposal would allow for. Example: >>> >>> public data class Foo { >>> private final int x; >>> private final int y; >>> private final String foo; >>> >>> public Foo (this.x) {} >>> >>> public Foo (this.foo, this.y) {} >>> } >>> >>> >>> (I eliminated the types from the automagical constructors, as they >>> can be inferred by the compiler.) >>> >>> This would generate all three getters and setters, equals (), >>> hashcode (), a general constructor taking in all 3 fields, and two >>> additional constructors, one taking in just int x, and one taking in >>> both String foo and int y. >>> >>> Reinier--is there a copy of your original proposal for auto-POJOs >>> somewhere? >>> >>> -JL- >>> >>> >>>> From: Reinier Zwitserloot >>>> Subject: Re: PROPOSAL: Auto-assignment Parameters >>>> To: "Mark Mahieu" >>>> Cc: coin-dev at openjdk.java.net >>>> Date: Tuesday, March 24, 2009, 8:34 PM >>>> I like where this is going, but I'd rather see a bigger >>>> setup for auto- >>>> POJO classes. I proposed this before and in most java >>>> circles (outside >>>> of coin-dev!), this idea was considered very useful: >>>> >>>> public data class Foo { >>>> private final int x; >>>> private final int y; >>>> private final String foo; >>>> } >>>> >>>> >>>> The above class would auto-generate the getters, a >>>> constructor, >>>> hashCode, equals, and toString. You can add methods to it >>>> if you want, >>>> and if you define a method that would usually be >>>> auto-generated, it >>>> isn't auto-generated. So, if you need to do some extra >>>> processing >>>> before returning 'foo' via the getter, go right >>>> ahead. You can even >>>> add this later without breaking your API's >>>> compatibility. >>>> >>>> --Reinier Zwitserloot >>>> >>>> >>>> >>>> On Mar 25, 2009, at 02:07, Mark Mahieu wrote: >>>> >>>>> HTML version + prototype available at >>>> http://slm888.com/javac >>>>> >>>>> >>>>> >>>>> Auto-assignment Parameters v0.1 >>>>> >>>>> >>>>> AUTHOR(S): >>>>> >>>>> Mark Mahieu >>>>> >>>>> >>>>> OVERVIEW >>>>> >>>>> FEATURE SUMMARY: Should be suitable as a summary in a >>>> language >>>>> tutorial. >>>>> >>>>> An additional form of constructor parameter which >>>> provides automatic >>>>> assignment of the parameter's value to an instance >>>> field. These >>>>> parameters >>>>> are implicitly declared as final to prevent >>>> unintentional >>>>> assignments to the >>>>> wrong variable in the constructor body. >>>>> >>>>> >>>>> MAJOR ADVANTAGE: What makes the proposal a favorable >>>> change? >>>>> >>>>> Reduces the likelihood of some common coding errors >>>> relating to >>>>> assignment >>>>> of fields in a constructor, including those where: >>>>> >>>>> * a field is assigned to itself >>>>> * the parameter is assigned instead of the field >>>>> * the assignment to the field is missing entirely >>>>> >>>>> These and other errors are often caused by typos or >>>> code refactoring. >>>>> >>>>> >>>>> MAJOR BENEFIT: Why is the platform better if the >>>> proposal is adopted? >>>>> >>>>> A programmer's intent is more clearly expressed >>>> for the extremely >>>>> common >>>>> case of assigning a constructor parameter directly to >>>> an instance >>>>> field with >>>>> the same name. >>>>> >>>>> >>>>> MAJOR DISADVANTAGE: There is always a cost. >>>>> >>>>> As with any sugar which enables a more concise way of >>>> expressing an >>>>> existing >>>>> idiom, programmers may be tempted to use it even when >>>> the original >>>>> form >>>>> would be more appropriate. >>>>> >>>>> >>>>> ALTERNATIVES: Can the benefits and advantages be had >>>> some way >>>>> without a >>>>> language change? >>>>> >>>>> IDEs and tools such as FindBugs are good at warning >>>> about the kind >>>>> of errors >>>>> mentioned above, however since the code in question is >>>> usually still >>>>> valid >>>>> to the compiler, they are limited in what action they >>>> can take by >>>>> default. >>>>> >>>>> A language change can combine the ability to avoid >>>> these errors >>>>> entirely >>>>> with a more expressive idiom, resulting in an >>>> increased signal to >>>>> noise >>>>> ratio for readers of that code. >>>>> >>>>> >>>>> >>>>> EXAMPLES >>>>> >>>>> SIMPLE EXAMPLE: Show the simplest possible program >>>> utilizing the new >>>>> feature. >>>>> >>>>> class C { >>>>> int i; >>>>> C(int this.i) {} >>>>> } >>>>> >>>>> >>>>> ADVANCED EXAMPLE: Show advanced usage(s) of the >>>> feature. >>>>> >>>>> >>>>> class Proposal { >>>>> >>>>> private final String name; >>>>> private final String author; >>>>> private boolean suitableForCoin; >>>>> private Integer score; >>>>> >>>>> public Proposal(String this.name, >>>>> String this.author, >>>>> boolean this.suitableForCoin, >>>>> int this.score) { >>>>> >>>>> if (name.equals(?Auto-assignment >>>> Parameters?)) { >>>>> suitableForCoin = true; // final so >>>> compile-time error >>>>> } >>>>> } >>>>> >>>>> // rest of class ... >>>>> } >>>>> >>>>> >>>>> >>>>> 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. >>>>> >>>>> The syntactic grammar is modified to include >>>> auto-assignment >>>>> parameters for >>>>> constructors: >>>>> >>>>> ConstructorDeclaratorRest: >>>>> ConstructorParameters [throws >>>> QualifiedIdentifierList] >>>>> MethodBody >>>>> >>>>> ConstructorParameters: >>>>> ( [ConstructorParameterDecls] ) >>>>> >>>>> ConstructorParameterDecls: >>>>> [final] [Annotations] Type >>>>> ConstructorParameterDeclsRest >>>>> >>>>> ConstructorParameterDeclsRest: >>>>> ConstructorParameterId [ , >>>> ConstructorParameterDecls] >>>>> ... ConstructorParameterId >>>>> >>>>> ConstructorParameterId: >>>>> VariableDeclaratorId >>>>> this . VariableDeclaratorId >>>>> super . VariableDeclaratorId >>>>> >>>>> An auto-assignment parameter is a formal parameter >>>> (JLSv3 ?8.4.1) >>>>> which >>>>> specifies an instance field instead of an identifier. >>>> Its value is >>>>> automatically assigned to the specified field. It may >>>> only be used >>>>> in a >>>>> constructor. >>>>> >>>>> The automatic assignment takes place after any >>>> explicit or implicit >>>>> invocation of another constructor, and before any >>>> statements in the >>>>> body of >>>>> the constructor. A constructor which declares n >>>> auto-assignment >>>>> parameters >>>>> will perform n such automatic assignments, in the >>>> order that the >>>>> parameters >>>>> are declared. >>>>> >>>>> The parameter has the same name (JLSv3 ?6.2) as the >>>> field to which >>>>> it is >>>>> assigned; replacing each auto-assignment parameter >>>> with a normal >>>>> formal >>>>> parameter with the same name would yield a constructor >>>> with an >>>>> identical >>>>> signature. As with a normal parameter, the >>>> parameter's name is >>>>> entered into >>>>> the scope of the constructor body (JLSv3 ?6.3), and >>>> therefore >>>>> shadows the >>>>> field (JLSv3 ?6.3.1) within that scope. >>>>> >>>>> It is a compile-time error if the field is not >>>> accessible from the >>>>> constructor in which the parameter appears. >>>>> >>>>> It is a compile-time error if the declared type of the >>>> parameter is >>>>> not >>>>> assignment compatible (JLSv3 ?5.2) with the field to >>>> which it is >>>>> automatically assigned. >>>>> >>>>> If an unboxing conversion is required by an automatic >>>> assignment, any >>>>> NullPointerException thrown as a result (JLSv3 >>>> ?5.1.8) will contain >>>>> the name >>>>> of the field on which the conversion failed, which may >>>> be retrieved by >>>>> calling getMessage() on the exception. >>>>> >>>>> Auto-assignment parameters are implicitly final, and >>>> follow the >>>>> standard >>>>> rules for final variables (JLSv3 ?4.12.4). >>>> Explicitly declaring an >>>>> auto-assignment parameter as final has no effect, and >>>> does not cause a >>>>> compilation error. >>>>> >>>>> Auto-assignment parameters follow the standard >>>> definite assignment >>>>> rules for >>>>> formal parameters (JLSv3 ?16.3). >>>>> >>>>> An auto-assignment parameter may be annotated. >>>>> >>>>> If an auto-assignment parameter is the last parameter >>>> in the list, and >>>>> refers to a field of array type, it may be a variable >>>> arity parameter. >>>>> >>>>> >>>>> >>>>> 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! >>>>> >>>>> Desugaring of the following class: >>>>> >>>>> class Foo { >>>>> int value; >>>>> Foo(Integer this.value) { >>>>> System.out.println(value); >>>>> } >>>>> } >>>>> >>>>> would result in (unboxing desugaring omitted): >>>>> >>>>> class Foo { >>>>> int value; >>>>> Foo(final Integer value) { >>>>> super(); >>>>> if (value == null) >>>>> throw new >>>> NullPointerException("value"); >>>>> this.value = value; >>>>> System.out.println(value); >>>>> } >>>>> } >>>>> >>>>> No changes to the classfile format are required. >>>> Tools which >>>>> consume class >>>>> files see the constructor signature as though it had >>>> been written >>>>> using >>>>> normal formal parameters. >>>>> >>>>> >>>>> TESTING: How can the feature be tested? >>>>> >>>>> An initial set of jtreg tests is included in the >>>> prototype. >>>>> >>>>> >>>>> LIBRARY SUPPORT: Are any supporting libraries needed >>>> for the feature? >>>>> >>>>> No >>>>> >>>>> >>>>> 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. >>>>> >>>>> com.sun.source.tree.VariableTree would require an >>>> additional method >>>>> which >>>>> returns the auto-assigned field. >>>>> >>>>> >>>>> 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 >>>>> >>>>> >>>>> MIGRATION: Sketch how a code base could be converted, >>>> manually or >>>>> automatically, to use the new feature. >>>>> >>>>> Assignment statements in constructors for which all of >>>> the following >>>>> are >>>>> true can be considered suitable for conversion: >>>>> * the lhs of the assignment is a non-static field >>>>> * the rhs is a parameter with the same name as the >>>> field >>>>> * there are no other assignments to the parameter >>>> anywhere in the >>>>> constructor >>>>> * there are no assignments to, or other uses of >>>> the field before >>>>> the >>>>> assignment statement in question (including invoked >>>> constructors) >>>>> >>>>> Such statements can be converted by: >>>>> 1) replacing the parameter with an auto-assignment >>>> parameter >>>>> (prefixing >>>>> the existing parameter's identifier with >>>> 'this.'), and >>>>> 2) removing the assignment statement >>>>> >>>>> >>>>> >>>>> COMPATIBILITY >>>>> >>>>> BREAKING CHANGES: Are any previously valid programs >>>> now invalid? If >>>>> so, list >>>>> one. >>>>> >>>>> No >>>>> >>>>> >>>>> 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 semantics of existing class files and legal source >>>> files are >>>>> unchanged >>>>> by this feature. >>>>> >>>>> >>>>> >>>>> REFERENCES >>>>> >>>>> EXISTING BUGS: Please include a list of any existing >>>> Sun bug ids >>>>> related to >>>>> this proposal. >>>>> >>>>> >>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582394 >>>>> (uses a 'setter' method rather than a >>>> constructor in its example) >>>>> >>>>> FindBugs bug patterns - >>>> http://findbugs.sourceforge.net/bugDescriptions.html >>>>> * Self assignment of field (SA_FIELD_SELF_ASSIGNMENT) >>>>> * Self comparison of field with itself >>>> (SA_FIELD_SELF_COMPARISON) >>>>> * Nonsensical self computation involving a field >>>> (e.g., x & x) >>>>> (SA_FIELD_SELF_COMPUTATION) >>>>> * Self assignment of local variable >>>> (SA_LOCAL_SELF_ASSIGNMENT) >>>>> * Nonsensical self computation involving a variable >>>> (e.g., x & x) >>>>> (SA_LOCAL_SELF_COMPUTATION) >>>>> * Uninitialized read of field in constructor >>>> (UR_UNINIT_READ) >>>>> * Unwritten field (UWF_UNWRITTEN_FIELD) >>>>> * Dead store to local variable (DLS_DEAD_LOCAL_STORE) >>>>> * Dead store of null to local variable >>>> (DLS_DEAD_LOCAL_STORE_OF_NULL) >>>>> >>>>> >>>>> >>>>> URL FOR PROTOTYPE (optional): >>>>> >>>>> http://slm888.com/javac >>>>> >>>>> >>>>> >>>>> DESIGN ALTERNATIVES: >>>>> >>>>> The following variations have been explored and are >>>> worth mentioning: >>>>> >>>>> * Allow auto-assignment parameters on all non-abstract >>>> methods. >>>>> This may be especially useful on the extremely >>>> common 'setter' >>>>> methods >>>>> in 'value object' classes. >>>>> >>>>> * Remove the requirement for (or even disallow) the >>>> type to be >>>>> specified on >>>>> auto-assignment parameters. >>>>> Experimentation with this idea suggests that it may >>>> work quite >>>>> well for >>>>> constructors, further emphasising the difference in >>>> intent and >>>>> semantics >>>>> from those of normal parameters. However, it may not >>>> work so well in >>>>> combination with auto-assignment parameters on all >>>> non-abstract >>>>> methods, and >>>>> requires a change to the order in which javac compiles >>>> classes (can >>>>> still >>>>> pass jtreg tests). >>>>> >>>>> * Allow an alternative name to be specified. >>>>> This adds additional complexity to support a >>>> fractional >>>>> percentage of >>>>> cases, which could continue to use the existing coding >>>> pattern. >>>>> >>> >>> >>> >>> >> >> >> > From mthornton at optrak.co.uk Wed Mar 25 13:53:52 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Wed, 25 Mar 2009 20:53:52 +0000 Subject: Bracket notation for collections Message-ID: <49CA99E0.9020609@optrak.co.uk> I notice that Joe Darcy has this on his todo list. I wonder if it might stretch to something like this: interface Matrix2d { @arrayGet double get(int i, int j); @arraySet void set(int i, int j, double value); } // Matrix2d m; double z = m[1,2]; m[2,4] = 2*z; Would the use of annotations for such a purpose be permitted? Regards, Mark Thornton From brucechapman at paradise.net.nz Wed Mar 25 14:02:31 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Thu, 26 Mar 2009 10:02:31 +1300 (NZDT) Subject: PROPOSAL: Binary Literals In-Reply-To: References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Message-ID: <1238014951.49ca9be74baf5@www.paradise.net.nz> Quoting Reinier Zwitserloot : > Of all low impact coin submissions, this just isn't very compelling. > Real Programmers can count in hexadecimal ever since they were A years > old, after all. > > --Reinier Zwitserloot > With all due respect, if you want to count, use decimals. Hexadecimal and binary are useful ways of representing patterns of bits. When the pattern of bits is some identifier such as a tag in tag, length, value encoded messages hex makes an easily recognisable representation. When the pattern is a bit mask then binary is probably a better representation. If I want to extract the 3rd, 4th and 5th bit (of 1 through 8) from a byte value which of these captures that intent best, or put it another way, which of these code extracts allows you to see most easily that bits 3,4 and 5 are being extracted? (b & 0b00011100) >> 2 (b & 0x1C) >> 2 (b & 28) >> 2 Having just written those examples it is interesting to note in hindsight that in two of the cases above I had to carefully work out the literal value, and check that it was correct. In the other case I just wrote it down and knew it was correct. Bruce > > > On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: > > > A couple of quick notes: > > > > 1) Ruby already has this. (The underscores in numbers, that is) > > > > 2) I considered adding this to the proposal as I was writing it, but > > decided it was an orthogonal issue and deserved its own proposal, > > since it has nothing per se to do with binary literals. (As James > > mentions, it would make sense for all numbers, not just binary ones.) > > > > 3) I encourage someone else to write it up as a proposal. If I get > > done with the other proposals I intend to submit, and still have > > time, I might do it myself, but if you want to ensure that the > > proposal gets proposed, I suggest you don't wait for me. One caveat: > > Consider the impact on Integer.parseInt, Long.decode(), etc. (I > > suggest the decode methods get changed to accept underscores, but > > the parseInt ones don't.) > > > > 4) An observation to Joe Darcy and the other Sun engineers involved > > in reviewing proposals: The expected "about five" limit on proposals > > really encourages people to lump a bunch of semi-related things into > > one proposal rather than making each their own proposal, even when > > the latter would be a more logical way of getting individual > > orthogonal ideas reviewed separately. I think this is a problem. > > > > For instance, the "null safe operators" proposal (all or nothing) > > vs. splitting each of them out as individual proposals. There have > > been a number of proposals put forth where I thought "I agree with > > half of this proposal and wish the other half wasn't in the same > > proposal." > > > > I hope that the "about" in "about five" is flexible enough to allow > > a bunch of very minor proposals to expand that limit well past five > > if they seem good ideas and easy to implement with few > > repercussions. Five seems like a pretty low number to me, given that > > it's been MANY years since it was even possible for users to suggest > > changes to Java (basically, since JDK 5 was in the planning stages, > > as JDK 6 was announced to be a "no language changes" release), and > > there has been much evolution in other programming languages during > > that time. I think that good ideas should make it into Java (and bad > > ideas shouldn't) subject to the necessary manpower in review and > > implementation, regardless of the number of proposals used to submit > > them. Otherwise, Java risks getting left in the dust as other > > languages become much easier to use, much faster. > > > > Derek > > > > -----Original Message----- > >> From: james lowden > >> Sent: Mar 25, 2009 12:07 PM > >> To: coin-dev at openjdk.java.net > >> Subject: Re: PROPOSAL: Binary Literals > >> > >> > >> Actually, that's a good idea in general for long numeric > >> constants. 9_000_000_000_000_000L is easier to parse than > >> 9000000000000000L. > >> > >> > >> --- On Wed, 3/25/09, Stephen Colebourne > wrote: > >> > >>> From: Stephen Colebourne > >>> Subject: Re: PROPOSAL: Binary Literals > >>> To: coin-dev at openjdk.java.net > >>> Date: Wednesday, March 25, 2009, 1:50 PM > >>> See > >>> > http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive > >>> for my take on this from long ago. > >>> > >>> In particular, I'd suggest allowing a character to > >>> separate long binary strings: > >>> > >>> int anInt1 = 0b10100001_01000101_10100001_01000101; > >>> > >>> much more readable. > >>> > >>> Stephen > >>> > >>> 2009/3/25 Derek Foster : > >>>> Hmm. Second try at sending to the list. Let's see > >>> if this works. (In the > >>>> meantime, I noticed that Bruce Chapman has mentioned > >>> something similar in his > >>>> another proposal, so I think we are in agreement on > >>> this. This proposal > >>>> should not be taken as to compete with his similar > >>> proposal: I'd quite like > >>>> to see type suffixes for bytes, shorts, etc. added to > >>> Java, in addition to > >>>> binary literals.) Anyway... > >>>> > >>>> > >>>> > >>>> > >>>> Add binary literals to Java. > >>>> > >>>> AUTHOR(S): Derek Foster > >>>> > >>>> OVERVIEW > >>>> > >>>> In some programming domains, use of binary numbers > >>> (typically as bitmasks, > >>>> bit-shifts, etc.) is very common. However, Java code, > >>> due to its C heritage, > >>>> has traditionally forced programmers to represent > >>> numbers in only decimal, > >>>> octal, or hexadecimal. (In practice, octal is rarely > >>> used, and is present > >>>> mostly for backwards compatibility with C) > >>>> > >>>> When the data being dealt with is fundamentally > >>> bit-oriented, however, using > >>>> hexadecimal to represent ranges of bits requires an > >>> extra degree of > >>>> translation for the programmer, and this can often > >>> become a source of errors. > >>>> For instance, if a technical specification lists > >>> specific values of interest > >>>> in binary (for example, in a compression encoding > >>> algorithm or in the > >>>> specifications for a network protocol, or for > >>> communicating with a bitmapped > >>>> hardware device) then a programmer coding to that > >>> specification must > >>>> translate each such value from its binary > >>> representation into hexadecimal. > >>>> Checking to see if this translation has been done > >>> correctly is accomplished > >>>> by back-translating the numbers. In most cases, > >>> programmers do these > >>>> translations in their heads, and HOPEFULLY get them > >>> right. however, errors > >>>> can easily creep in, and re-verifying the results is > >>> not straightforward > >>>> enough to be done frequently. > >>>> > >>>> Furthermore, in many cases, the binary representations > >>> of numbers makes it > >>>> much more clear what is actually intended than the > >>> hexadecimal one. For > >>>> instance, this: > >>>> > >>>> private static final int BITMASK = 0x1E; > >>>> > >>>> does not immediately make it clear that the bitmask > >>> being declared comprises > >>>> a single contiguous range of four bits. > >>>> > >>>> In many cases, it would be more natural for the > >>> programmer to be able to > >>>> write the numbers in binary in the source code, > >>> eliminating the need for > >>>> manual translation to hexadecimal entirely. > >>>> > >>>> > >>>> FEATURE SUMMARY: > >>>> > >>>> In addition to the existing "1" (decimal), > >>> "01" (octal) and "0x1" > >>>> (hexadecimal) form of specifying numeric literals, a > >>> new form "0b1" (binary) > >>>> would be added. > >>>> > >>>> Note that this is the same syntax as has been used as > >>> an extension by the GCC > >>>> C/C++ compilers for many years, and also is used in > >>> the Ruby language, as > >>>> well as in the Python language. > >>>> > >>>> > >>>> MAJOR ADVANTAGE: > >>>> > >>>> It is no longer necessary for programmers to translate > >>> binary numbers to and > >>>> from hexadecimal in order to use them in Java > >>> programs. > >>>> > >>>> > >>>> MAJOR BENEFIT: > >>>> > >>>> Code using bitwise operations is more readable and > >>> easier to verify against > >>>> technical specifications that use binary numbers to > >>> specify constants. > >>>> > >>>> Routines that are bit-oriented are easier to > >>> understand when an artifical > >>>> translation to hexadecimal is not required in order to > >>> fulfill the > >>>> constraints of the language. > >>>> > >>>> MAJOR DISADVANTAGE: > >>>> > >>>> Someone might incorrectly think that "0b1" > >>> represented the same value as > >>>> hexadecimal number "0xB1". However, note > >>> that this problem has existed for > >>>> octal/decimal for many years (confusion between > >>> "050" and "50") and does not > >>>> seem to be a major issue. > >>>> > >>>> > >>>> ALTERNATIVES: > >>>> > >>>> Users could continue to write the numbers as decimal, > >>> octal, or hexadecimal, > >>>> and would continue to have the problems observed in > >>> this document. > >>>> > >>>> Another alternative would be for code to translate at > >>> runtime from binary > >>>> strings, such as: > >>>> > >>>> int BITMASK = > >>> Integer.parseInt("00001110", 2); > >>>> > >>>> Besides the obvious extra verbosity, there are several > >>> problems with this: > >>>> > >>>> * Calling a method such as Integer.parseInt at runtime > >>> will typically make it > >>>> impossible for the compiler to inline the value of > >>> this constant, since its > >>>> value has been taken from a runtime method call. > >>> Inlining is important, > >>>> because code that does bitwise parsing is often very > >>> low-level code in tight > >>>> loops that must execute quickly. (This is particularly > >>> the case for mobile > >>>> applications and other applications that run on > >>> severely resource-constrained > >>>> environments, which is one of the cases where binary > >>> numbers would be most > >>>> valuable, since talking to low-level hardware is one > >>> of the primary use cases > >>>> for this feature.) > >>>> > >>>> * Constants such as the above cannot be used as > >>> selectors in 'switch' > >>>> statements. > >>>> > >>>> * Any errors in the string to be parsed (for instance, > >>> an extra space) will > >>>> result in runtime exceptions, rather than compile-time > >>> errors as would have > >>>> occurred in normal parsing. If such a value is > >>> declared 'static', this will > >>>> result in some very ugly exceptions at runtime. > >>>> > >>>> > >>>> EXAMPLES: > >>>> > >>>> // An 8-bit 'byte' literal. > >>>> byte aByte = (byte)0b00100001; > >>>> > >>>> // A 16-bit 'short' literal. > >>>> short aShort = (short)0b1010000101000101; > >>>> > >>>> // Some 32-bit 'int' literals. > >>>> int anInt1 = 0b10100001010001011010000101000101; > >>>> int anInt2 = 0b101; > >>>> int anInt3 = 0B101; // The B can be upper or lower > >>> case as per the x in > >>>> "0x45". > >>>> > >>>> // A 64-bit 'long' literal. Note the > >>> "L" suffix, as would also be used > >>>> // for a long in decimal, hexadecimal, or octal. > >>>> long aLong = > >>>> > >>> 0b01010000101000101101000010100010110100001010001011010000101000101L > > >>> ; > >>>> > >>>> SIMPLE EXAMPLE: > >>>> > >>>> class Foo { > >>>> public static void main(String[] args) { > >>>> System.out.println("The value 10100001 in > >>> decimal is " + 0b10100001); > >>>> } > >>>> > >>>> > >>>> ADVANCED EXAMPLE: > >>>> > >>>> // Binary constants could be used in code that needs > >>> to be > >>>> // easily checkable against a specifications document, > >>> such > >>>> // as this simulator for a hypothetical 8-bit > >>> microprocessor: > >>>> > >>>> public State decodeInstruction(int instruction, State > >>> state) { > >>>> if ((instruction & 0b11100000) == 0b00000000) { > >>>> final int register = instruction & > >>> 0b00001111; > >>>> switch (instruction & 0b11110000) { > >>>> case 0b00000000: return state.nop(); > >>>> case 0b00010000: return > >>> state.copyAccumTo(register); > >>>> case 0b00100000: return > >>> state.addToAccum(register); > >>>> case 0b00110000: return > >>> state.subFromAccum(register); > >>>> case 0b01000000: return > >>> state.multiplyAccumBy(register); > >>>> case 0b01010000: return > >>> state.divideAccumBy(register); > >>>> case 0b01100000: return > >>> state.setAccumFrom(register); > >>>> case 0b01110000: return > >>> state.returnFromCall(); > >>>> default: throw new IllegalArgumentException(); > >>>> } > >>>> } else { > >>>> final int address = instruction & 0b00011111; > >>>> switch (instruction & 0b11100000) { > >>>> case 0b00100000: return state.jumpTo(address); > >>>> case 0b01000000: return > >>> state.jumpIfAccumZeroTo(address); > >>>> case 0b01000000: return > >>> state.jumpIfAccumNonzeroTo(address); > >>>> case 0b01100000: return > >>> state.setAccumFromMemory(address); > >>>> case 0b10100000: return > >>> state.writeAccumToMemory(address); > >>>> case 0b11000000: return state.callTo(address); > >>>> default: throw new IllegalArgumentException(); > >>>> } > >>>> } > >>>> } > >>>> > >>>> // Binary literals can be used to make a bitmap more > >>> readable: > >>>> > >>>> public static final short[] HAPPY_FACE = { > >>>> (short)0b0000011111100000; > >>>> (short)0b0000100000010000; > >>>> (short)0b0001000000001000; > >>>> (short)0b0010000000000100; > >>>> (short)0b0100000000000010; > >>>> (short)0b1000011001100001; > >>>> (short)0b1000011001100001; > >>>> (short)0b1000000000000001; > >>>> (short)0b1000000000000001; > >>>> (short)0b1001000000001001; > >>>> (short)0b1000100000010001; > >>>> (short)0b0100011111100010; > >>>> (short)0b0010000000000100; > >>>> (short)0b0001000000001000; > >>>> (short)0b0000100000010000; > >>>> (short)0b0000011111100000; > >>>> } > >>>> > >>>> // Binary literals can make relationships > >>>> // among data more apparent than they would > >>>> // be in hex or octal. > >>>> // > >>>> // For instance, what does the following > >>>> // array contain? In hexadecimal, it's hard to > >>> tell: > >>>> public static final int[] PHASES = { > >>>> 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 > >>>> } > >>>> > >>>> // In binary, it's obvious that a number is being > >>>> // rotated left one bit at a time. > >>>> public static final int[] PHASES = { > >>>> 0b00110001, > >>>> 0b01100010, > >>>> 0b11000100, > >>>> 0b10001001, > >>>> 0b00010011, > >>>> 0b00100110, > >>>> 0b01001100, > >>>> 0b10011000, > >>>> } > >>>> > >>>> > >>>> DETAILS > >>>> > >>>> SPECIFICATION: > >>>> > >>>> Section 3.10.1 ("Integer Literals") of the > >>> JLS3 should be changed to add the > >>>> following: > >>>> > >>>> IntegerLiteral: > >>>> DecimalIntegerLiteral > >>>> HexIntegerLiteral > >>>> OctalIntegerLiteral > >>>> BinaryIntegerLiteral // Added > >>>> > >>>> BinaryIntegerLiteral: > >>>> BinaryNumeral IntegerTypeSuffix_opt > >>>> > >>>> BinaryNumeral: > >>>> 0 b BinaryDigits > >>>> 0 B BinaryDigits > >>>> > >>>> BinaryDigits: > >>>> BinaryDigit > >>>> BinaryDigit BinaryDigits > >>>> > >>>> BinaryDigit: one of > >>>> 0 1 > >>>> > >>>> COMPILATION: > >>>> > >>>> Binary literals would be compiled to class files in > >>> the same fashion as > >>>> existing decimal, hexadecimal, and octal literals are. > >>> No special support or > >>>> changes to the class file format are needed. > >>>> > >>>> TESTING: > >>>> > >>>> The feature can be tested in the same way as existing > >>> decimal, hexadecimal, > >>>> and octal literals are: Create a bunch of constants in > >>> source code, including > >>>> the maximum and minimum positive and negative values > >>> for integer and long > >>>> types, and verify them at runtime to have the correct > >>> values. > >>>> > >>>> > >>>> LIBRARY SUPPORT: > >>>> > >>>> The methods Integer.decode(String) and > >>> Long.decode(String) should be modified > >>>> to parse binary numbers (as specified above) in > >>> addition to their existing > >>>> support for decimal, hexadecimal, and octal numbers. > >>>> > >>>> > >>>> REFLECTIVE APIS: > >>>> > >>>> No updates to the reflection APIs are needed. > >>>> > >>>> > >>>> OTHER CHANGES: > >>>> > >>>> No other changes are needed. > >>>> > >>>> > >>>> MIGRATION: > >>>> > >>>> Individual decimal, hexadecimal, or octal constants in > >>> existing code can be > >>>> updated to binary as a programmer desires. > >>>> > >>>> > >>>> COMPATIBILITY > >>>> > >>>> > >>>> BREAKING CHANGES: > >>>> > >>>> This feature would not break any existing programs, > >>> since the suggested > >>>> syntax is currently considerd to be a compile-time > >>> error. > >>>> > >>>> > >>>> EXISTING PROGRAMS: > >>>> > >>>> Class file format does not change, so existing > >>> programs can use class files > >>>> compiled with the new feature without problems. > >>>> > >>>> > >>>> REFERENCES: > >>>> > >>>> The GCC/G++ compiler, which already supports this > >>> syntax (as of version 4.3) > >>>> as an extension to standard C/C++. > >>>> http://gcc.gnu.org/gcc-4.3/changes.html > >>>> > >>>> The Ruby language, which supports binary literals: > >>>> http://wordaligned.org/articles/binary-literals > >>>> > >>>> The Python language added binary literals in version > >>> 2.6: > >>>> > >>> > http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax > >>>> > >>>> EXISTING BUGS: > >>>> > >>>> "Language support for literal numbers in binary > >>> and other bases" > >>>> > >>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 > >>>> > >>>> URL FOR PROTOTYPE (optional): > >>>> > >>>> None. > >>>> > >>>> > >> > >> > >> > >> > > > > > > From mthornton at optrak.co.uk Wed Mar 25 14:14:18 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Wed, 25 Mar 2009 21:14:18 +0000 Subject: PROPOSAL: Binary Literals In-Reply-To: <1238014951.49ca9be74baf5@www.paradise.net.nz> References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> <1238014951.49ca9be74baf5@www.paradise.net.nz> Message-ID: <49CA9EAA.5030308@optrak.co.uk> brucechapman at paradise.net.nz wrote: > With all due respect, if you want to count, use decimals. Hexadecimal and binary > are useful ways of representing patterns of bits. When the pattern of bits is > some identifier such as a tag in tag, length, value encoded messages hex makes > an easily recognisable representation. When the pattern is a bit mask then > binary is probably a better representation. > > If I want to extract the 3rd, 4th and 5th bit (of 1 through 8) from a byte value > which of these captures that intent best, or put it another way, which of these > code extracts allows you to see most easily that bits 3,4 and 5 are being extracted? > > (b & 0b00011100) >> 2 > > (b & 0x1C) >> 2 > > (b & 28) >> 2 > > (b >> 2) & 7 is even better in my opinion. OK, so this only applies to contiguous bit fields, but perhaps that is most of the use case. Mark Thornton From reinier at zwitserloot.com Wed Mar 25 14:40:24 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Wed, 25 Mar 2009 22:40:24 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: <1238014951.49ca9be74baf5@www.paradise.net.nz> References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> <1238014951.49ca9be74baf5@www.paradise.net.nz> Message-ID: On Mar 25, 2009, at 22:02, brucechapman at paradise.net.nz wrote: > code extracts allows you to see most easily that bits 3,4 and 5 are > being extracted? > > (b & 0b00011100) >> 2 > > (b & 0x1C) >> 2 > Maybe it's my assembler days, but, seriously: The hexadecimal one. In your example above there's no real difference, they are equally readable to me. But here are some other examples: 0b10000000 vs. 0x80 0b100000000 vs 0x100 0b10000101 vs 0x85 No contest, hex wins hands down, with a big margin the first two margins, and still a winner in the third case, because 5 zeroes already become hard to count at a casual glance. The amount of digits involved in writing out a mask in binary just overwhelms the senses; your average human brain has a hard time processing more than 7 things at once, which means even a simply byte is already too large. Underscores would indeed help some, but what if I want to underscore around a nibble? Is that allowed? But clearly an underscore after 9 digits ought to give me a warning or error, or the underscores are only going to make mistakes permanent. Should they mandatory? If not, trying to decade 0x100 written as a binary literal is still going to be very painful. To summarize: A bitmask might marginally be more readable in rare cases, especially to the casual programmer who doesn't have much experience with bit-level trickery, which is small comfort, because bitmasking comes up very rarely in java code in the first place. In most other situations, binary literals are much worse compared to hex literals. Sign me up for bruce's 0h notation to get around the need to cast-to- byte for 0x80 and up. That would serve all my bitmasking needs. -- Reinier Zwitserloot From develop4lasu at gmail.com Wed Mar 25 14:59:06 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 25 Mar 2009 22:59:06 +0100 Subject: PROPOSAL: Return 'this' Message-ID: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: It allows the method to return reference to 'this' object. MAJOR ADVANTAGE: Simplification of ?return this? statement. 'void' can be easy replaced with 'this'. MAJOR BENEFIT(s): It would prevent NullPointerException, and make some 'builder' like interfaces look really clear and simple. MAJOR DISADVANTAGE: Returned value cannot be changed while inheritance, also other objects cannot be returned. ALTERNATIVES: Self-bounded generics, This type, change returned type for every method on each inheritance. EXAMPLES SIMPLE/ADVANCED EXAMPLE: public class Builder { String text = ""; public this add (char c){text+=c;} public this add (String c){ if (c==null){ text +="null"; return; // this will be returned } text+=c; } public static void test(Builder builder) { builder.add('.').add("test()").add(':'); } } package test; public class ReturnThis { static class A { public this test() { } } static class B extends A { } static Class getReturnedType(Class classs) { try { return classs.getMethod("test").getReturnType(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(getReturnedType(A.class)); // will print: class returnThis.ReturnThis$A System.out.println(getReturnedType((new A()).getClass())); // will print: class returnThis.ReturnThis$A System.out.println(getReturnedType(B.class)); // will print: class returnThis.ReturnThis$B System.out.println(getReturnedType((new B()).getClass())); // will print: class returnThis.ReturnThis$B } } DETAILS SPECIFICATION: JLS 8.4 (modifications) ResultType: Type void this* A method declaration either specifies the type of value that the method returns, uses the keyword void to indicate that the method does not return a value, or uses the keyword this to indicate that the method return the reference to 'this' object. *Keyword this for return cannot occurs if method is static. JLS 14.17 (modifications) ReturnStatement: return Expressionopt ; A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value (?8.4), or in the body of a method that is declared, using the keyword this , to return this reference (?8...),or in the body of a constructor (?8.8). COMPILATION: Method just before exiting from it's scope returns 'this'. Exceptions work same as before. Returned object type is actual object type. TESTING: Normal way. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: None. MIGRATION: None. COMPATIBILITY Backward: full. Forward: Only jars. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 http://java.net/cs/user/view/cs_msg/37432 http://lasu2string.blogspot.com/2009/03/return-this-proposal.html PS. Maybe this Joe consider as 'proposal'. Any questions? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From mthornton at optrak.co.uk Wed Mar 25 15:02:10 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Wed, 25 Mar 2009 22:02:10 +0000 Subject: PROPOSAL: Binary Literals In-Reply-To: References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> <1238014951.49ca9be74baf5@www.paradise.net.nz> Message-ID: <49CAA9E2.3080809@optrak.co.uk> Reinier Zwitserloot wrote: > To summarize: A bitmask might marginally be more readable in rare > cases, especially to the casual programmer who doesn't have much > experience with bit-level trickery, which is small comfort, because > bitmasking comes up very rarely in java code in the first place. In > most other situations, binary literals are much worse compared to hex > literals. > > In many cases bit masks would be more reliably written as expressions. So if we add methods to Integer (and Byte, Long): static int bit(int index); static int bits(int fromIndex, int toIndex); Then we could write Integer.bits(3, 7). Switch statements require constant expressions, so for this to be completely convenient it would be necessary to extend what was allowed in a constant expression to include the standard bit manipulation methods. Mark Thornton From scolebourne at joda.org Wed Mar 25 15:17:09 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 22:17:09 +0000 Subject: PROPOSAL: Binary Literals In-Reply-To: References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Message-ID: <49CAAD65.3070409@joda.org> > A couple of quick notes: > > 1) Ruby already has this. (The underscores in numbers, that is) So, does Fan. Yes, someone should write up underscores in numbers as a separate proposal. It won't be me. > Of all low impact coin submissions, this just isn't very compelling. > Real Programmers can count in hexadecimal ever since they were A years > old, after all. Actually, my experience suggests that lots can't count in hex - we have calculators and the internet we that kind of thing these days. There are definitely use cases for this too, but they occur relatively rarely. For example, I once encoded the 30 year repeating pattern of leap years in the Islamic calendar system as a binary. This was a mess to write: Years to encode: 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 Final int value: 623191204 Binary literal: 0b00010010_10010010_10010010_01010010 It is also beneficial in teaching. But the truth is it will always be low priority (mind you, I'd have placed it higher than hexadecimal floating point literals...) Stephen Reinier Zwitserloot wrote: > Of all low impact coin submissions, this just isn't very compelling. > Real Programmers can count in hexadecimal ever since they were A years > old, after all. > > --Reinier Zwitserloot > > > > On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: > >> A couple of quick notes: >> >> 1) Ruby already has this. (The underscores in numbers, that is) >> >> 2) I considered adding this to the proposal as I was writing it, but >> decided it was an orthogonal issue and deserved its own proposal, >> since it has nothing per se to do with binary literals. (As James >> mentions, it would make sense for all numbers, not just binary ones.) >> >> 3) I encourage someone else to write it up as a proposal. If I get >> done with the other proposals I intend to submit, and still have >> time, I might do it myself, but if you want to ensure that the >> proposal gets proposed, I suggest you don't wait for me. One caveat: >> Consider the impact on Integer.parseInt, Long.decode(), etc. (I >> suggest the decode methods get changed to accept underscores, but >> the parseInt ones don't.) >> >> 4) An observation to Joe Darcy and the other Sun engineers involved >> in reviewing proposals: The expected "about five" limit on proposals >> really encourages people to lump a bunch of semi-related things into >> one proposal rather than making each their own proposal, even when >> the latter would be a more logical way of getting individual >> orthogonal ideas reviewed separately. I think this is a problem. >> >> For instance, the "null safe operators" proposal (all or nothing) >> vs. splitting each of them out as individual proposals. There have >> been a number of proposals put forth where I thought "I agree with >> half of this proposal and wish the other half wasn't in the same >> proposal." >> >> I hope that the "about" in "about five" is flexible enough to allow >> a bunch of very minor proposals to expand that limit well past five >> if they seem good ideas and easy to implement with few >> repercussions. Five seems like a pretty low number to me, given that >> it's been MANY years since it was even possible for users to suggest >> changes to Java (basically, since JDK 5 was in the planning stages, >> as JDK 6 was announced to be a "no language changes" release), and >> there has been much evolution in other programming languages during >> that time. I think that good ideas should make it into Java (and bad >> ideas shouldn't) subject to the necessary manpower in review and >> implementation, regardless of the number of proposals used to submit >> them. Otherwise, Java risks getting left in the dust as other >> languages become much easier to use, much faster. >> >> Derek >> >> -----Original Message----- >>> From: james lowden >>> Sent: Mar 25, 2009 12:07 PM >>> To: coin-dev at openjdk.java.net >>> Subject: Re: PROPOSAL: Binary Literals >>> >>> >>> Actually, that's a good idea in general for long numeric >>> constants. 9_000_000_000_000_000L is easier to parse than >>> 9000000000000000L. >>> >>> >>> --- On Wed, 3/25/09, Stephen Colebourne wrote: >>> >>>> From: Stephen Colebourne >>>> Subject: Re: PROPOSAL: Binary Literals >>>> To: coin-dev at openjdk.java.net >>>> Date: Wednesday, March 25, 2009, 1:50 PM >>>> See >>>> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >>>> for my take on this from long ago. >>>> >>>> In particular, I'd suggest allowing a character to >>>> separate long binary strings: >>>> >>>> int anInt1 = 0b10100001_01000101_10100001_01000101; >>>> >>>> much more readable. >>>> >>>> Stephen >>>> >>>> 2009/3/25 Derek Foster : >>>>> Hmm. Second try at sending to the list. Let's see >>>> if this works. (In the >>>>> meantime, I noticed that Bruce Chapman has mentioned >>>> something similar in his >>>>> another proposal, so I think we are in agreement on >>>> this. This proposal >>>>> should not be taken as to compete with his similar >>>> proposal: I'd quite like >>>>> to see type suffixes for bytes, shorts, etc. added to >>>> Java, in addition to >>>>> binary literals.) Anyway... >>>>> >>>>> >>>>> >>>>> >>>>> Add binary literals to Java. >>>>> >>>>> AUTHOR(S): Derek Foster >>>>> >>>>> OVERVIEW >>>>> >>>>> In some programming domains, use of binary numbers >>>> (typically as bitmasks, >>>>> bit-shifts, etc.) is very common. However, Java code, >>>> due to its C heritage, >>>>> has traditionally forced programmers to represent >>>> numbers in only decimal, >>>>> octal, or hexadecimal. (In practice, octal is rarely >>>> used, and is present >>>>> mostly for backwards compatibility with C) >>>>> >>>>> When the data being dealt with is fundamentally >>>> bit-oriented, however, using >>>>> hexadecimal to represent ranges of bits requires an >>>> extra degree of >>>>> translation for the programmer, and this can often >>>> become a source of errors. >>>>> For instance, if a technical specification lists >>>> specific values of interest >>>>> in binary (for example, in a compression encoding >>>> algorithm or in the >>>>> specifications for a network protocol, or for >>>> communicating with a bitmapped >>>>> hardware device) then a programmer coding to that >>>> specification must >>>>> translate each such value from its binary >>>> representation into hexadecimal. >>>>> Checking to see if this translation has been done >>>> correctly is accomplished >>>>> by back-translating the numbers. In most cases, >>>> programmers do these >>>>> translations in their heads, and HOPEFULLY get them >>>> right. however, errors >>>>> can easily creep in, and re-verifying the results is >>>> not straightforward >>>>> enough to be done frequently. >>>>> >>>>> Furthermore, in many cases, the binary representations >>>> of numbers makes it >>>>> much more clear what is actually intended than the >>>> hexadecimal one. For >>>>> instance, this: >>>>> >>>>> private static final int BITMASK = 0x1E; >>>>> >>>>> does not immediately make it clear that the bitmask >>>> being declared comprises >>>>> a single contiguous range of four bits. >>>>> >>>>> In many cases, it would be more natural for the >>>> programmer to be able to >>>>> write the numbers in binary in the source code, >>>> eliminating the need for >>>>> manual translation to hexadecimal entirely. >>>>> >>>>> >>>>> FEATURE SUMMARY: >>>>> >>>>> In addition to the existing "1" (decimal), >>>> "01" (octal) and "0x1" >>>>> (hexadecimal) form of specifying numeric literals, a >>>> new form "0b1" (binary) >>>>> would be added. >>>>> >>>>> Note that this is the same syntax as has been used as >>>> an extension by the GCC >>>>> C/C++ compilers for many years, and also is used in >>>> the Ruby language, as >>>>> well as in the Python language. >>>>> >>>>> >>>>> MAJOR ADVANTAGE: >>>>> >>>>> It is no longer necessary for programmers to translate >>>> binary numbers to and >>>>> from hexadecimal in order to use them in Java >>>> programs. >>>>> >>>>> MAJOR BENEFIT: >>>>> >>>>> Code using bitwise operations is more readable and >>>> easier to verify against >>>>> technical specifications that use binary numbers to >>>> specify constants. >>>>> Routines that are bit-oriented are easier to >>>> understand when an artifical >>>>> translation to hexadecimal is not required in order to >>>> fulfill the >>>>> constraints of the language. >>>>> >>>>> MAJOR DISADVANTAGE: >>>>> >>>>> Someone might incorrectly think that "0b1" >>>> represented the same value as >>>>> hexadecimal number "0xB1". However, note >>>> that this problem has existed for >>>>> octal/decimal for many years (confusion between >>>> "050" and "50") and does not >>>>> seem to be a major issue. >>>>> >>>>> >>>>> ALTERNATIVES: >>>>> >>>>> Users could continue to write the numbers as decimal, >>>> octal, or hexadecimal, >>>>> and would continue to have the problems observed in >>>> this document. >>>>> Another alternative would be for code to translate at >>>> runtime from binary >>>>> strings, such as: >>>>> >>>>> int BITMASK = >>>> Integer.parseInt("00001110", 2); >>>>> Besides the obvious extra verbosity, there are several >>>> problems with this: >>>>> * Calling a method such as Integer.parseInt at runtime >>>> will typically make it >>>>> impossible for the compiler to inline the value of >>>> this constant, since its >>>>> value has been taken from a runtime method call. >>>> Inlining is important, >>>>> because code that does bitwise parsing is often very >>>> low-level code in tight >>>>> loops that must execute quickly. (This is particularly >>>> the case for mobile >>>>> applications and other applications that run on >>>> severely resource-constrained >>>>> environments, which is one of the cases where binary >>>> numbers would be most >>>>> valuable, since talking to low-level hardware is one >>>> of the primary use cases >>>>> for this feature.) >>>>> >>>>> * Constants such as the above cannot be used as >>>> selectors in 'switch' >>>>> statements. >>>>> >>>>> * Any errors in the string to be parsed (for instance, >>>> an extra space) will >>>>> result in runtime exceptions, rather than compile-time >>>> errors as would have >>>>> occurred in normal parsing. If such a value is >>>> declared 'static', this will >>>>> result in some very ugly exceptions at runtime. >>>>> >>>>> >>>>> EXAMPLES: >>>>> >>>>> // An 8-bit 'byte' literal. >>>>> byte aByte = (byte)0b00100001; >>>>> >>>>> // A 16-bit 'short' literal. >>>>> short aShort = (short)0b1010000101000101; >>>>> >>>>> // Some 32-bit 'int' literals. >>>>> int anInt1 = 0b10100001010001011010000101000101; >>>>> int anInt2 = 0b101; >>>>> int anInt3 = 0B101; // The B can be upper or lower >>>> case as per the x in >>>>> "0x45". >>>>> >>>>> // A 64-bit 'long' literal. Note the >>>> "L" suffix, as would also be used >>>>> // for a long in decimal, hexadecimal, or octal. >>>>> long aLong = >>>>> >>>> 0b01010000101000101101000010100010110100001010001011010000101000101L >>>> ; >>>>> SIMPLE EXAMPLE: >>>>> >>>>> class Foo { >>>>> public static void main(String[] args) { >>>>> System.out.println("The value 10100001 in >>>> decimal is " + 0b10100001); >>>>> } >>>>> >>>>> >>>>> ADVANCED EXAMPLE: >>>>> >>>>> // Binary constants could be used in code that needs >>>> to be >>>>> // easily checkable against a specifications document, >>>> such >>>>> // as this simulator for a hypothetical 8-bit >>>> microprocessor: >>>>> public State decodeInstruction(int instruction, State >>>> state) { >>>>> if ((instruction & 0b11100000) == 0b00000000) { >>>>> final int register = instruction & >>>> 0b00001111; >>>>> switch (instruction & 0b11110000) { >>>>> case 0b00000000: return state.nop(); >>>>> case 0b00010000: return >>>> state.copyAccumTo(register); >>>>> case 0b00100000: return >>>> state.addToAccum(register); >>>>> case 0b00110000: return >>>> state.subFromAccum(register); >>>>> case 0b01000000: return >>>> state.multiplyAccumBy(register); >>>>> case 0b01010000: return >>>> state.divideAccumBy(register); >>>>> case 0b01100000: return >>>> state.setAccumFrom(register); >>>>> case 0b01110000: return >>>> state.returnFromCall(); >>>>> default: throw new IllegalArgumentException(); >>>>> } >>>>> } else { >>>>> final int address = instruction & 0b00011111; >>>>> switch (instruction & 0b11100000) { >>>>> case 0b00100000: return state.jumpTo(address); >>>>> case 0b01000000: return >>>> state.jumpIfAccumZeroTo(address); >>>>> case 0b01000000: return >>>> state.jumpIfAccumNonzeroTo(address); >>>>> case 0b01100000: return >>>> state.setAccumFromMemory(address); >>>>> case 0b10100000: return >>>> state.writeAccumToMemory(address); >>>>> case 0b11000000: return state.callTo(address); >>>>> default: throw new IllegalArgumentException(); >>>>> } >>>>> } >>>>> } >>>>> >>>>> // Binary literals can be used to make a bitmap more >>>> readable: >>>>> public static final short[] HAPPY_FACE = { >>>>> (short)0b0000011111100000; >>>>> (short)0b0000100000010000; >>>>> (short)0b0001000000001000; >>>>> (short)0b0010000000000100; >>>>> (short)0b0100000000000010; >>>>> (short)0b1000011001100001; >>>>> (short)0b1000011001100001; >>>>> (short)0b1000000000000001; >>>>> (short)0b1000000000000001; >>>>> (short)0b1001000000001001; >>>>> (short)0b1000100000010001; >>>>> (short)0b0100011111100010; >>>>> (short)0b0010000000000100; >>>>> (short)0b0001000000001000; >>>>> (short)0b0000100000010000; >>>>> (short)0b0000011111100000; >>>>> } >>>>> >>>>> // Binary literals can make relationships >>>>> // among data more apparent than they would >>>>> // be in hex or octal. >>>>> // >>>>> // For instance, what does the following >>>>> // array contain? In hexadecimal, it's hard to >>>> tell: >>>>> public static final int[] PHASES = { >>>>> 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >>>>> } >>>>> >>>>> // In binary, it's obvious that a number is being >>>>> // rotated left one bit at a time. >>>>> public static final int[] PHASES = { >>>>> 0b00110001, >>>>> 0b01100010, >>>>> 0b11000100, >>>>> 0b10001001, >>>>> 0b00010011, >>>>> 0b00100110, >>>>> 0b01001100, >>>>> 0b10011000, >>>>> } >>>>> >>>>> >>>>> DETAILS >>>>> >>>>> SPECIFICATION: >>>>> >>>>> Section 3.10.1 ("Integer Literals") of the >>>> JLS3 should be changed to add the >>>>> following: >>>>> >>>>> IntegerLiteral: >>>>> DecimalIntegerLiteral >>>>> HexIntegerLiteral >>>>> OctalIntegerLiteral >>>>> BinaryIntegerLiteral // Added >>>>> >>>>> BinaryIntegerLiteral: >>>>> BinaryNumeral IntegerTypeSuffix_opt >>>>> >>>>> BinaryNumeral: >>>>> 0 b BinaryDigits >>>>> 0 B BinaryDigits >>>>> >>>>> BinaryDigits: >>>>> BinaryDigit >>>>> BinaryDigit BinaryDigits >>>>> >>>>> BinaryDigit: one of >>>>> 0 1 >>>>> >>>>> COMPILATION: >>>>> >>>>> Binary literals would be compiled to class files in >>>> the same fashion as >>>>> existing decimal, hexadecimal, and octal literals are. >>>> No special support or >>>>> changes to the class file format are needed. >>>>> >>>>> TESTING: >>>>> >>>>> The feature can be tested in the same way as existing >>>> decimal, hexadecimal, >>>>> and octal literals are: Create a bunch of constants in >>>> source code, including >>>>> the maximum and minimum positive and negative values >>>> for integer and long >>>>> types, and verify them at runtime to have the correct >>>> values. >>>>> >>>>> LIBRARY SUPPORT: >>>>> >>>>> The methods Integer.decode(String) and >>>> Long.decode(String) should be modified >>>>> to parse binary numbers (as specified above) in >>>> addition to their existing >>>>> support for decimal, hexadecimal, and octal numbers. >>>>> >>>>> >>>>> REFLECTIVE APIS: >>>>> >>>>> No updates to the reflection APIs are needed. >>>>> >>>>> >>>>> OTHER CHANGES: >>>>> >>>>> No other changes are needed. >>>>> >>>>> >>>>> MIGRATION: >>>>> >>>>> Individual decimal, hexadecimal, or octal constants in >>>> existing code can be >>>>> updated to binary as a programmer desires. >>>>> >>>>> >>>>> COMPATIBILITY >>>>> >>>>> >>>>> BREAKING CHANGES: >>>>> >>>>> This feature would not break any existing programs, >>>> since the suggested >>>>> syntax is currently considerd to be a compile-time >>>> error. >>>>> >>>>> EXISTING PROGRAMS: >>>>> >>>>> Class file format does not change, so existing >>>> programs can use class files >>>>> compiled with the new feature without problems. >>>>> >>>>> >>>>> REFERENCES: >>>>> >>>>> The GCC/G++ compiler, which already supports this >>>> syntax (as of version 4.3) >>>>> as an extension to standard C/C++. >>>>> http://gcc.gnu.org/gcc-4.3/changes.html >>>>> >>>>> The Ruby language, which supports binary literals: >>>>> http://wordaligned.org/articles/binary-literals >>>>> >>>>> The Python language added binary literals in version >>>> 2.6: >>>> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >>>>> EXISTING BUGS: >>>>> >>>>> "Language support for literal numbers in binary >>>> and other bases" >>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >>>>> URL FOR PROTOTYPE (optional): >>>>> >>>>> None. >>>>> >>>>> >>> >>> >>> >> > > > From scolebourne at joda.org Wed Mar 25 15:33:30 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 22:33:30 +0000 Subject: DISCUSSION: Bean/Data classes In-Reply-To: <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> Message-ID: <49CAB13A.5070605@joda.org> Reinier Zwitserloot wrote: > You should move away from the idea of 'this keyword does so much > magic!' and move towards the idea that this keyword simply declares > that the class is to have bean semantics. I proposed almost exactly this 'data' class two years ago - http://www.jroller.com/scolebourne/entry/a_bean_keyword. public bean Person { // properties property String forename; property String surname; // normal fields and methods private String ordinaryField; public boolean validate() { ... } } This is fundamentally no different to how enum was slotted into the language (note I deliberately omitted the 'class' keyword. The key aspect of this approach is that it allows there to be different grammer rules within 'bean' classes to normal classes, just as there are different rules for 'enum' classes. Now, as for what exactly it generates, that is a much bigger question. Does it just generate getter/setter? What about lists, maps and arrays? How about events? The truth is that is where every property proposal gets bogged down (because server side JavaBeans are just data holders, whereas swing JavaBeans are much more a part of the application). So, will this be in Coin? No. There is way to much to work out. But this could be the best way to get a form of properties into Java. And a group could form to code up a prototype and prove it (Kijaro is available...) Finally, I should say that of all the things Java lacks, I think properties is the biggest - bigger than closures. The sheer amount of wasted effort, lines of code, lack of consistency and sheer focus on the low level detail rather than the high level abstraction is staggering. It is IMO a far bigger hole in writing good Java apps today than closures (or any other language proposal). Stephen From abies at adres.pl Wed Mar 25 15:42:43 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Wed, 25 Mar 2009 23:42:43 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> Message-ID: <49CAB363.4070101@adres.pl> I think that you are putting two separate proposals here: 1) Having 'silent' exit from method and parameterless return equivalent to 'return this' if method return type is non-void 2) Introducing kind of auto-covariant return type, which resolves to given class and accepts only 'this' returns I don't particularly like point 1 - it will save some typing, but has certain kind of magic I would prefer to keep out of java. Point 2 is nice for builders, unfortunately it cannot be used for anything else other than chain calls - for example, clone method could not be written using this functionality (as you could write return new A() in A class and not redefine it in B). I don't understand Compatibility forward: Only jars. I don't see a way to have such code verified in existing versions of java. Regards, Artur Biesiadowski From develop4lasu at gmail.com Wed Mar 25 15:50:07 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 25 Mar 2009 23:50:07 +0100 Subject: DISCUSSION: Bean/Data classes In-Reply-To: <49CAB13A.5070605@joda.org> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> <49CAB13A.5070605@joda.org> Message-ID: <28bca0ff0903251550v304f8123xda2be07fc7d5d490@mail.gmail.com> 2009/3/25 Stephen Colebourne : > Reinier Zwitserloot wrote: >> You should move away from the idea of 'this keyword does so much >> magic!' and move towards the idea that this keyword simply declares >> that the class is to have bean semantics. > > I proposed almost exactly this 'data' class two years ago - > http://www.jroller.com/scolebourne/entry/a_bean_keyword. > > public bean Person { > ? ? // properties > ? ? property String forename; > ? ? property String surname; > > ? ? // normal fields and methods > ? ? private String ordinaryField; > ? ? public boolean validate() { ... } > } > > This is fundamentally no different to how enum was slotted into the > language (note I deliberately omitted the 'class' keyword. > > The key aspect of this approach is that it allows there to be different > grammer rules within 'bean' classes to normal classes, just as there are > different rules for 'enum' classes. > > Now, as for what exactly it generates, that is a much bigger question. > Does it just generate getter/setter? What about lists, maps and arrays? > How about events? The truth is that is where every property proposal > gets bogged down (because server side JavaBeans are just data holders, > whereas swing JavaBeans are much more a part of the application). > > So, will this be in Coin? No. There is way to much to work out. > > But this could be the best way to get a form of properties into Java. > And a group could form to code up a prototype and prove it (Kijaro is > available...) > > Finally, I should say that of all the things Java lacks, I think > properties is the biggest - bigger than closures. The sheer amount of > wasted effort, lines of code, lack of consistency and sheer focus on the > low level detail rather than the high level abstraction is staggering. > It is IMO a far bigger hole in writing good Java apps today than > closures (or any other language proposal). > > Stephen > > I agree that here is to 'much magic'. What would you say about: public bean Person { ? ? // properties ? ? property String forename; ? ? property String surname; ? ? // normal fields and methods ? ? private String ordinaryField; ? ? public boolean validate() { ... } } public delegate.get from forename, surname; public delegate.set from forename, surname; -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Wed Mar 25 15:53:50 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Wed, 25 Mar 2009 23:53:50 +0100 Subject: DISCUSSION: Bean/Data classes In-Reply-To: <49CAB13A.5070605@joda.org> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> <49CAB13A.5070605@joda.org> Message-ID: <28bca0ff0903251553o29a3222el6a062b91f2639b35@mail.gmail.com> 2009/3/25 Stephen Colebourne : > Reinier Zwitserloot wrote: >> You should move away from the idea of 'this keyword does so much >> magic!' and move towards the idea that this keyword simply declares >> that the class is to have bean semantics. > > I proposed almost exactly this 'data' class two years ago - > http://www.jroller.com/scolebourne/entry/a_bean_keyword. > > public bean Person { > ? ? // properties > ? ? property String forename; > ? ? property String surname; > > ? ? // normal fields and methods > ? ? private String ordinaryField; > ? ? public boolean validate() { ... } > } > > This is fundamentally no different to how enum was slotted into the > language (note I deliberately omitted the 'class' keyword. > > The key aspect of this approach is that it allows there to be different > grammer rules within 'bean' classes to normal classes, just as there are > different rules for 'enum' classes. > > Now, as for what exactly it generates, that is a much bigger question. > Does it just generate getter/setter? What about lists, maps and arrays? > How about events? The truth is that is where every property proposal > gets bogged down (because server side JavaBeans are just data holders, > whereas swing JavaBeans are much more a part of the application). > > So, will this be in Coin? No. There is way to much to work out. > > But this could be the best way to get a form of properties into Java. > And a group could form to code up a prototype and prove it (Kijaro is > available...) > > Finally, I should say that of all the things Java lacks, I think > properties is the biggest - bigger than closures. The sheer amount of > wasted effort, lines of code, lack of consistency and sheer focus on the > low level detail rather than the high level abstraction is staggering. > It is IMO a far bigger hole in writing good Java apps today than > closures (or any other language proposal). > > Stephen > > Sorry / to early send! I agree that here is to 'much magic'. What would you say about: public class Person { // properties property String forename; property String surname; private String ordinaryField; private static String some; public delegate(get) from forename, surname; public delegate(set) from forename, surname; private delegate(get,set) from ordinaryField; public static delegate(get) from some; } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From lk at teamten.com Wed Mar 25 15:59:35 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Wed, 25 Mar 2009 15:59:35 -0700 Subject: DISCUSSION: Bean/Data classes In-Reply-To: <49CAB13A.5070605@joda.org> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <997cab100903251125kb5c7f5fn4ade6ba2bcca5229@mail.gmail.com> <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> <49CAB13A.5070605@joda.org> Message-ID: <997cab100903251559s10d3d3f8of527ebcb52854a60@mail.gmail.com> On Wed, Mar 25, 2009 at 3:33 PM, Stephen Colebourne wrote: > Finally, I should say that of all the things Java lacks, I think > properties is the biggest - bigger than closures. I thought that Josh and Neal were in agreement on being against properties. I don't remember the reasoning. Something about encouraging mutable data structures? All the data classes I've made in the last year have been immutable. Maybe we could try a syntax for that? public class Person final { String forename; String surname; } That would make the fields private, generate the getters, constructors, toString/hash/equals (per Reinier), and perhaps "with" methods that return a variant with some field modified. Not sure what to do about fields of mutable types like Date. Maybe it would only generate constructors/getters/"with" methods for fields that are also immutable. The rest you have to write yourself or your clients can't get at the data. It may be too late to go down the functional path with Java. Lawrence From develop4lasu at gmail.com Wed Mar 25 16:03:31 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 00:03:31 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <49CAB363.4070101@adres.pl> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CAB363.4070101@adres.pl> Message-ID: <28bca0ff0903251603h277bc396r1ad21b5ac57b1bc8@mail.gmail.com> 2009/3/25 Artur Biesiadowski : > I think that you are putting two separate proposals here: > > 1) Having 'silent' exit from method and parameterless return equivalent to > 'return this' if method return type is non-void > Yes. but thanks to this proposition is extremely safe and simple (no null-s = NPE/ not other object). > 2) Introducing kind of auto-covariant return type, which resolves to given > class and accepts only 'this' returns > > I don't particularly like point 1 - it will save some typing, but has > certain kind of magic I would prefer to keep out of java. Point 2 is nice > for builders, unfortunately it cannot be used for anything else other than > chain calls - for example, clone method could not be written using this > functionality (as you could write return new A() in A class and not redefine > it in B). This is the price of simplicity. > > I don't understand Compatibility forward: Only jars. I don't see a way to > have such code verified in existing versions of java. > Simple flag would solve the problem, do not forget that this solution is same level with void (already handled). > > Regards, > Artur Biesiadowski > -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Wed Mar 25 16:04:01 2009 From: neal at gafter.com (Neal Gafter) Date: Wed, 25 Mar 2009 16:04:01 -0700 Subject: PROPOSAL: Return 'this' In-Reply-To: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> Message-ID: <15e8b9d20903251604h744da93ar90560ba27753e914@mail.gmail.com> I would expect these methods to be erased to void-returning methods, and the duplication of the receiver to occur on the caller's side in the generated code. So there's no need for any kind of special auto-covariant type or anything. You'd need extra a rule that a method declared to return this can only be overridden by (and can only override) a method similarly declared to return this. You need to say how such methods are recorded in class files (an additional classfile Attribute on the method?). How are they treated by reflection? How do they appear in the javadoc API? How should they appear in javadoc? How do they appear in the program model API for annotation processing? On Wed, Mar 25, 2009 at 2:59 PM, Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? > > > > > OVERVIEW > > FEATURE SUMMARY: > It allows the method to return reference to 'this' object. > > MAJOR ADVANTAGE: > Simplification of "return this" statement. > 'void' can be easy replaced with 'this'. > > MAJOR BENEFIT(s): It would prevent NullPointerException, and make some > 'builder' like interfaces look really clear and simple. > > MAJOR DISADVANTAGE: > Returned value cannot be changed while inheritance, also other objects > cannot be returned. > > ALTERNATIVES: > Self-bounded generics, This type, change returned type for every > method on each inheritance. > > > > > > EXAMPLES > > SIMPLE/ADVANCED EXAMPLE: > public class Builder { > > String text = ""; > > public this add (char c){text+=c;} > > public this add (String c){ > if (c==null){ > text +="null"; > return; // this will be returned > } > text+=c; > } > > public static void test(Builder builder) { > builder.add('.').add("test()").add(':'); > } > > } > > package test; > > public class ReturnThis { > > static class A { public this test() { } } > > static class B extends A { } > > static Class getReturnedType(Class classs) { > try { > return classs.getMethod("test").getReturnType(); > } catch (SecurityException e) { > e.printStackTrace(); > } catch (NoSuchMethodException e) { > e.printStackTrace(); > } > return null; > } > > public static void main(String[] args) { > System.out.println(getReturnedType(A.class)); > // will print: class returnThis.ReturnThis$A > > System.out.println(getReturnedType((new A()).getClass())); > // will print: class returnThis.ReturnThis$A > > System.out.println(getReturnedType(B.class)); > // will print: class returnThis.ReturnThis$B > > System.out.println(getReturnedType((new B()).getClass())); > // will print: class returnThis.ReturnThis$B > } > } > > > > > DETAILS > > SPECIFICATION: > JLS 8.4 (modifications) > > ResultType: > Type > void > this* > > A method declaration either specifies the type of value that the > method returns, uses the keyword void to indicate that the method does > not return a value, or uses the keyword this to indicate that the > method return the reference to 'this' object. > > *Keyword this for return cannot occurs if method is static. > > > JLS 14.17 (modifications) > > ReturnStatement: > return Expressionopt ; > > A return statement with no Expression must be contained in the body of > a method that is declared, using the keyword void, not to return any > value (?8.4), or in the body of a method that is declared, using the > keyword this , to return this reference (?8...),or in the body of a > constructor (?8.8). > > COMPILATION: > Method just before exiting from it's scope returns 'this'. > Exceptions work same as before. > Returned object type is actual object type. > > TESTING: > Normal way. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > None. > > MIGRATION: > None. > > COMPATIBILITY > Backward: full. > Forward: Only jars. > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 > > http://java.net/cs/user/view/cs_msg/37432 > > http://lasu2string.blogspot.com/2009/03/return-this-proposal.html > > PS. > Maybe this Joe consider as 'proposal'. > Any questions? > > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From scolebourne at joda.org Wed Mar 25 16:07:21 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 23:07:21 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: Message-ID: <49CAB929.8050302@joda.org> Mark Mahieu wrote: > class Proposal { > private final String name; > private final String author; > private boolean suitableForCoin; > private Integer score; > public Proposal(String this.name, > String this.author, > boolean this.suitableForCoin, > int this.score) { > if (name.equals(?Auto-assignment Parameters?)) { > suitableForCoin = true; // final so compile-time error > } > } > } Very cool. I like it. > DESIGN ALTERNATIVES: > > The following variations have been explored and are worth mentioning: > > * Allow auto-assignment parameters on all non-abstract methods. > This may be especially useful on the extremely common 'setter' methods > in 'value object' classes. I think its right to leave this out for now, pending more investigation into a bigger properties solution. > * Remove the requirement for (or even disallow) the type to be specified on > auto-assignment parameters. > Experimentation with this idea suggests that it may work quite well for > constructors, further emphasising the difference in intent and semantics > from those of normal parameters. However, it may not work so well in > combination with auto-assignment parameters on all non-abstract methods, and > requires a change to the order in which javac compiles classes (can still > pass jtreg tests). The inference can be added later. It doesn't feel quite right. > * Allow an alternative name to be specified. > This adds additional complexity to support a fractional percentage of > cases, which could continue to use the existing coding pattern. Not worth it. Stephen From scolebourne at joda.org Wed Mar 25 16:10:53 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 23:10:53 +0000 Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions In-Reply-To: <56957.69.239.104.86.1237951010.squirrel@69.239.104.86> References: <56957.69.239.104.86.1237951010.squirrel@69.239.104.86> Message-ID: <49CAB9FD.5030307@joda.org> Alan Snyder wrote: > Unchecked Exceptions as Subclasses of Checked Exceptions > public class TheCheckedException extends Exception {}; > > public class TheUncheckedException extends TheCheckedException implements > UncheckedException {}; I like the idea. I'm not sure if its actually feasible. I suspect that its more complex than it seems. I'm also not sure whether there are that many real use cases. Most of the time you control your exception hierarchy (so you can choose unchecked) or you have to live with a published API (the JDK) and so it can't be changed. Stephen From scolebourne at joda.org Wed Mar 25 16:19:42 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Wed, 25 Mar 2009 23:19:42 +0000 Subject: PROPOSAL: Unsigned Integer Widening Operator In-Reply-To: <49C9F30E.2020008@paradise.net.nz> References: <49C9F30E.2020008@paradise.net.nz> Message-ID: <49CABC0E.5060506@joda.org> Bruce Chapman wrote: > Unsigned Integer Widening Operator > > for(int i = idx; i < idx + length; i++) { > value = (value << 8) | (+)buffer[i]; > } While I think this is neat, I see how an API handles the case reasonably well too. This syntax also removes one option for operator overloading in Java: DateTime dt = ... dt = dt (+) days(3); // which is actually dt.plus(days(3)); } if (a (==) b) { // which is actually a null-safe .equals() comparison } (not that I am pushing for either of these right now, but this syntax does block this potential alternate usage for (+). Stephen From develop4lasu at gmail.com Wed Mar 25 16:24:38 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 00:24:38 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <15e8b9d20903251604h744da93ar90560ba27753e914@mail.gmail.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <15e8b9d20903251604h744da93ar90560ba27753e914@mail.gmail.com> Message-ID: <28bca0ff0903251624l377630aas72e3469637e78ee@mail.gmail.com> W dniu 26 marca 2009 00:04 u?ytkownik Neal Gafter napisa?: > I would expect these methods to be erased to void-returning methods, > and the duplication of the receiver to occur on the caller's side in > the generated code. I know that this is some solution, but proposal in this form can be extended to work with (backward) covariant return types in future: static class A { public this test() { } } static class B extends A { public this A test() { } } >So there's no need for any kind of special > auto-covariant type or anything. ?You'd need extra a rule that a > method declared to return this can only be overridden by (and can only > override) a method similarly declared to return this. ?You need to say > how such methods are recorded in class files (an additional classfile > Attribute on the method?). ?How are they treated by reflection? ?How > do they appear in the javadoc API? ?How should they appear in javadoc? > ?How do they appear in the program model API for annotation > processing? > > Everything would be same as: static class A { public A test() { return this; } } static class B extends A { public B test() { return this; } } But I'm opened to any suggestions. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Wed Mar 25 16:47:31 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 00:47:31 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: <49CAAD65.3070409@joda.org> References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> <49CAAD65.3070409@joda.org> Message-ID: <358A6A10-9BF3-4FFB-91B3-36C6B5D2EA1E@zwitserloot.com> Good points. Another useful method: public class Byte { public static byte withBitsSet(int... positions); public static byte withBitsCleared(int... positions); public static byte of(String bitString); } where setBits starts with 0 and then turns on the bit at each listed position, and clearBits starts with -1 and turns off the bit at each listed position. 0x1C can then be implemented as: Byte.withBitsSet(4, 3, 2); Byte.withBitsCleared(7, 6, 5, 1, 0); Byte.of("00011100"); That WOULD be a useful library addition. Not only are they almost as short as the proposed byte literal, anybody that doesn't have the first clue about bit masking can at least find some javadoc this way and learn. They would be awfully slow compared to a literal, but presumably any literal needs to be calculated only once, so any slowness in the methods should never have a measurable impact. It's a shame the JVM can't memoize, though. --Reinier Zwitserloot On Mar 25, 2009, at 23:17, Stephen Colebourne wrote: >> A couple of quick notes: >> >> 1) Ruby already has this. (The underscores in numbers, that is) > > So, does Fan. Yes, someone should write up underscores in numbers as a > separate proposal. It won't be me. > > >> Of all low impact coin submissions, this just isn't very compelling. >> Real Programmers can count in hexadecimal ever since they were A >> years >> old, after all. > > Actually, my experience suggests that lots can't count in hex - we > have > calculators and the internet we that kind of thing these days. > > There are definitely use cases for this too, but they occur relatively > rarely. For example, I once encoded the 30 year repeating pattern of > leap years in the Islamic calendar system as a binary. This was a mess > to write: > > Years to encode: 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 > > Final int value: 623191204 > > Binary literal: 0b00010010_10010010_10010010_01010010 > > It is also beneficial in teaching. > > But the truth is it will always be low priority (mind you, I'd have > placed it higher than hexadecimal floating point literals...) > > Stephen > > > > > Reinier Zwitserloot wrote: >> Of all low impact coin submissions, this just isn't very compelling. >> Real Programmers can count in hexadecimal ever since they were A >> years >> old, after all. >> >> --Reinier Zwitserloot >> >> >> >> On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: >> >>> A couple of quick notes: >>> >>> 1) Ruby already has this. (The underscores in numbers, that is) >>> >>> 2) I considered adding this to the proposal as I was writing it, but >>> decided it was an orthogonal issue and deserved its own proposal, >>> since it has nothing per se to do with binary literals. (As James >>> mentions, it would make sense for all numbers, not just binary >>> ones.) >>> >>> 3) I encourage someone else to write it up as a proposal. If I get >>> done with the other proposals I intend to submit, and still have >>> time, I might do it myself, but if you want to ensure that the >>> proposal gets proposed, I suggest you don't wait for me. One caveat: >>> Consider the impact on Integer.parseInt, Long.decode(), etc. (I >>> suggest the decode methods get changed to accept underscores, but >>> the parseInt ones don't.) >>> >>> 4) An observation to Joe Darcy and the other Sun engineers involved >>> in reviewing proposals: The expected "about five" limit on proposals >>> really encourages people to lump a bunch of semi-related things into >>> one proposal rather than making each their own proposal, even when >>> the latter would be a more logical way of getting individual >>> orthogonal ideas reviewed separately. I think this is a problem. >>> >>> For instance, the "null safe operators" proposal (all or nothing) >>> vs. splitting each of them out as individual proposals. There have >>> been a number of proposals put forth where I thought "I agree with >>> half of this proposal and wish the other half wasn't in the same >>> proposal." >>> >>> I hope that the "about" in "about five" is flexible enough to allow >>> a bunch of very minor proposals to expand that limit well past five >>> if they seem good ideas and easy to implement with few >>> repercussions. Five seems like a pretty low number to me, given that >>> it's been MANY years since it was even possible for users to suggest >>> changes to Java (basically, since JDK 5 was in the planning stages, >>> as JDK 6 was announced to be a "no language changes" release), and >>> there has been much evolution in other programming languages during >>> that time. I think that good ideas should make it into Java (and bad >>> ideas shouldn't) subject to the necessary manpower in review and >>> implementation, regardless of the number of proposals used to submit >>> them. Otherwise, Java risks getting left in the dust as other >>> languages become much easier to use, much faster. >>> >>> Derek >>> >>> -----Original Message----- >>>> From: james lowden >>>> Sent: Mar 25, 2009 12:07 PM >>>> To: coin-dev at openjdk.java.net >>>> Subject: Re: PROPOSAL: Binary Literals >>>> >>>> >>>> Actually, that's a good idea in general for long numeric >>>> constants. 9_000_000_000_000_000L is easier to parse than >>>> 9000000000000000L. >>>> >>>> >>>> --- On Wed, 3/25/09, Stephen Colebourne >>>> wrote: >>>> >>>>> From: Stephen Colebourne >>>>> Subject: Re: PROPOSAL: Binary Literals >>>>> To: coin-dev at openjdk.java.net >>>>> Date: Wednesday, March 25, 2009, 1:50 PM >>>>> See >>>>> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >>>>> for my take on this from long ago. >>>>> >>>>> In particular, I'd suggest allowing a character to >>>>> separate long binary strings: >>>>> >>>>> int anInt1 = 0b10100001_01000101_10100001_01000101; >>>>> >>>>> much more readable. >>>>> >>>>> Stephen >>>>> >>>>> 2009/3/25 Derek Foster : >>>>>> Hmm. Second try at sending to the list. Let's see >>>>> if this works. (In the >>>>>> meantime, I noticed that Bruce Chapman has mentioned >>>>> something similar in his >>>>>> another proposal, so I think we are in agreement on >>>>> this. This proposal >>>>>> should not be taken as to compete with his similar >>>>> proposal: I'd quite like >>>>>> to see type suffixes for bytes, shorts, etc. added to >>>>> Java, in addition to >>>>>> binary literals.) Anyway... >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> Add binary literals to Java. >>>>>> >>>>>> AUTHOR(S): Derek Foster >>>>>> >>>>>> OVERVIEW >>>>>> >>>>>> In some programming domains, use of binary numbers >>>>> (typically as bitmasks, >>>>>> bit-shifts, etc.) is very common. However, Java code, >>>>> due to its C heritage, >>>>>> has traditionally forced programmers to represent >>>>> numbers in only decimal, >>>>>> octal, or hexadecimal. (In practice, octal is rarely >>>>> used, and is present >>>>>> mostly for backwards compatibility with C) >>>>>> >>>>>> When the data being dealt with is fundamentally >>>>> bit-oriented, however, using >>>>>> hexadecimal to represent ranges of bits requires an >>>>> extra degree of >>>>>> translation for the programmer, and this can often >>>>> become a source of errors. >>>>>> For instance, if a technical specification lists >>>>> specific values of interest >>>>>> in binary (for example, in a compression encoding >>>>> algorithm or in the >>>>>> specifications for a network protocol, or for >>>>> communicating with a bitmapped >>>>>> hardware device) then a programmer coding to that >>>>> specification must >>>>>> translate each such value from its binary >>>>> representation into hexadecimal. >>>>>> Checking to see if this translation has been done >>>>> correctly is accomplished >>>>>> by back-translating the numbers. In most cases, >>>>> programmers do these >>>>>> translations in their heads, and HOPEFULLY get them >>>>> right. however, errors >>>>>> can easily creep in, and re-verifying the results is >>>>> not straightforward >>>>>> enough to be done frequently. >>>>>> >>>>>> Furthermore, in many cases, the binary representations >>>>> of numbers makes it >>>>>> much more clear what is actually intended than the >>>>> hexadecimal one. For >>>>>> instance, this: >>>>>> >>>>>> private static final int BITMASK = 0x1E; >>>>>> >>>>>> does not immediately make it clear that the bitmask >>>>> being declared comprises >>>>>> a single contiguous range of four bits. >>>>>> >>>>>> In many cases, it would be more natural for the >>>>> programmer to be able to >>>>>> write the numbers in binary in the source code, >>>>> eliminating the need for >>>>>> manual translation to hexadecimal entirely. >>>>>> >>>>>> >>>>>> FEATURE SUMMARY: >>>>>> >>>>>> In addition to the existing "1" (decimal), >>>>> "01" (octal) and "0x1" >>>>>> (hexadecimal) form of specifying numeric literals, a >>>>> new form "0b1" (binary) >>>>>> would be added. >>>>>> >>>>>> Note that this is the same syntax as has been used as >>>>> an extension by the GCC >>>>>> C/C++ compilers for many years, and also is used in >>>>> the Ruby language, as >>>>>> well as in the Python language. >>>>>> >>>>>> >>>>>> MAJOR ADVANTAGE: >>>>>> >>>>>> It is no longer necessary for programmers to translate >>>>> binary numbers to and >>>>>> from hexadecimal in order to use them in Java >>>>> programs. >>>>>> >>>>>> MAJOR BENEFIT: >>>>>> >>>>>> Code using bitwise operations is more readable and >>>>> easier to verify against >>>>>> technical specifications that use binary numbers to >>>>> specify constants. >>>>>> Routines that are bit-oriented are easier to >>>>> understand when an artifical >>>>>> translation to hexadecimal is not required in order to >>>>> fulfill the >>>>>> constraints of the language. >>>>>> >>>>>> MAJOR DISADVANTAGE: >>>>>> >>>>>> Someone might incorrectly think that "0b1" >>>>> represented the same value as >>>>>> hexadecimal number "0xB1". However, note >>>>> that this problem has existed for >>>>>> octal/decimal for many years (confusion between >>>>> "050" and "50") and does not >>>>>> seem to be a major issue. >>>>>> >>>>>> >>>>>> ALTERNATIVES: >>>>>> >>>>>> Users could continue to write the numbers as decimal, >>>>> octal, or hexadecimal, >>>>>> and would continue to have the problems observed in >>>>> this document. >>>>>> Another alternative would be for code to translate at >>>>> runtime from binary >>>>>> strings, such as: >>>>>> >>>>>> int BITMASK = >>>>> Integer.parseInt("00001110", 2); >>>>>> Besides the obvious extra verbosity, there are several >>>>> problems with this: >>>>>> * Calling a method such as Integer.parseInt at runtime >>>>> will typically make it >>>>>> impossible for the compiler to inline the value of >>>>> this constant, since its >>>>>> value has been taken from a runtime method call. >>>>> Inlining is important, >>>>>> because code that does bitwise parsing is often very >>>>> low-level code in tight >>>>>> loops that must execute quickly. (This is particularly >>>>> the case for mobile >>>>>> applications and other applications that run on >>>>> severely resource-constrained >>>>>> environments, which is one of the cases where binary >>>>> numbers would be most >>>>>> valuable, since talking to low-level hardware is one >>>>> of the primary use cases >>>>>> for this feature.) >>>>>> >>>>>> * Constants such as the above cannot be used as >>>>> selectors in 'switch' >>>>>> statements. >>>>>> >>>>>> * Any errors in the string to be parsed (for instance, >>>>> an extra space) will >>>>>> result in runtime exceptions, rather than compile-time >>>>> errors as would have >>>>>> occurred in normal parsing. If such a value is >>>>> declared 'static', this will >>>>>> result in some very ugly exceptions at runtime. >>>>>> >>>>>> >>>>>> EXAMPLES: >>>>>> >>>>>> // An 8-bit 'byte' literal. >>>>>> byte aByte = (byte)0b00100001; >>>>>> >>>>>> // A 16-bit 'short' literal. >>>>>> short aShort = (short)0b1010000101000101; >>>>>> >>>>>> // Some 32-bit 'int' literals. >>>>>> int anInt1 = 0b10100001010001011010000101000101; >>>>>> int anInt2 = 0b101; >>>>>> int anInt3 = 0B101; // The B can be upper or lower >>>>> case as per the x in >>>>>> "0x45". >>>>>> >>>>>> // A 64-bit 'long' literal. Note the >>>>> "L" suffix, as would also be used >>>>>> // for a long in decimal, hexadecimal, or octal. >>>>>> long aLong = >>>>>> >>>>> 0b01010000101000101101000010100010110100001010001011010000101000101L >>>>> ; >>>>>> SIMPLE EXAMPLE: >>>>>> >>>>>> class Foo { >>>>>> public static void main(String[] args) { >>>>>> System.out.println("The value 10100001 in >>>>> decimal is " + 0b10100001); >>>>>> } >>>>>> >>>>>> >>>>>> ADVANCED EXAMPLE: >>>>>> >>>>>> // Binary constants could be used in code that needs >>>>> to be >>>>>> // easily checkable against a specifications document, >>>>> such >>>>>> // as this simulator for a hypothetical 8-bit >>>>> microprocessor: >>>>>> public State decodeInstruction(int instruction, State >>>>> state) { >>>>>> if ((instruction & 0b11100000) == 0b00000000) { >>>>>> final int register = instruction & >>>>> 0b00001111; >>>>>> switch (instruction & 0b11110000) { >>>>>> case 0b00000000: return state.nop(); >>>>>> case 0b00010000: return >>>>> state.copyAccumTo(register); >>>>>> case 0b00100000: return >>>>> state.addToAccum(register); >>>>>> case 0b00110000: return >>>>> state.subFromAccum(register); >>>>>> case 0b01000000: return >>>>> state.multiplyAccumBy(register); >>>>>> case 0b01010000: return >>>>> state.divideAccumBy(register); >>>>>> case 0b01100000: return >>>>> state.setAccumFrom(register); >>>>>> case 0b01110000: return >>>>> state.returnFromCall(); >>>>>> default: throw new IllegalArgumentException(); >>>>>> } >>>>>> } else { >>>>>> final int address = instruction & 0b00011111; >>>>>> switch (instruction & 0b11100000) { >>>>>> case 0b00100000: return state.jumpTo(address); >>>>>> case 0b01000000: return >>>>> state.jumpIfAccumZeroTo(address); >>>>>> case 0b01000000: return >>>>> state.jumpIfAccumNonzeroTo(address); >>>>>> case 0b01100000: return >>>>> state.setAccumFromMemory(address); >>>>>> case 0b10100000: return >>>>> state.writeAccumToMemory(address); >>>>>> case 0b11000000: return state.callTo(address); >>>>>> default: throw new IllegalArgumentException(); >>>>>> } >>>>>> } >>>>>> } >>>>>> >>>>>> // Binary literals can be used to make a bitmap more >>>>> readable: >>>>>> public static final short[] HAPPY_FACE = { >>>>>> (short)0b0000011111100000; >>>>>> (short)0b0000100000010000; >>>>>> (short)0b0001000000001000; >>>>>> (short)0b0010000000000100; >>>>>> (short)0b0100000000000010; >>>>>> (short)0b1000011001100001; >>>>>> (short)0b1000011001100001; >>>>>> (short)0b1000000000000001; >>>>>> (short)0b1000000000000001; >>>>>> (short)0b1001000000001001; >>>>>> (short)0b1000100000010001; >>>>>> (short)0b0100011111100010; >>>>>> (short)0b0010000000000100; >>>>>> (short)0b0001000000001000; >>>>>> (short)0b0000100000010000; >>>>>> (short)0b0000011111100000; >>>>>> } >>>>>> >>>>>> // Binary literals can make relationships >>>>>> // among data more apparent than they would >>>>>> // be in hex or octal. >>>>>> // >>>>>> // For instance, what does the following >>>>>> // array contain? In hexadecimal, it's hard to >>>>> tell: >>>>>> public static final int[] PHASES = { >>>>>> 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >>>>>> } >>>>>> >>>>>> // In binary, it's obvious that a number is being >>>>>> // rotated left one bit at a time. >>>>>> public static final int[] PHASES = { >>>>>> 0b00110001, >>>>>> 0b01100010, >>>>>> 0b11000100, >>>>>> 0b10001001, >>>>>> 0b00010011, >>>>>> 0b00100110, >>>>>> 0b01001100, >>>>>> 0b10011000, >>>>>> } >>>>>> >>>>>> >>>>>> DETAILS >>>>>> >>>>>> SPECIFICATION: >>>>>> >>>>>> Section 3.10.1 ("Integer Literals") of the >>>>> JLS3 should be changed to add the >>>>>> following: >>>>>> >>>>>> IntegerLiteral: >>>>>> DecimalIntegerLiteral >>>>>> HexIntegerLiteral >>>>>> OctalIntegerLiteral >>>>>> BinaryIntegerLiteral // Added >>>>>> >>>>>> BinaryIntegerLiteral: >>>>>> BinaryNumeral IntegerTypeSuffix_opt >>>>>> >>>>>> BinaryNumeral: >>>>>> 0 b BinaryDigits >>>>>> 0 B BinaryDigits >>>>>> >>>>>> BinaryDigits: >>>>>> BinaryDigit >>>>>> BinaryDigit BinaryDigits >>>>>> >>>>>> BinaryDigit: one of >>>>>> 0 1 >>>>>> >>>>>> COMPILATION: >>>>>> >>>>>> Binary literals would be compiled to class files in >>>>> the same fashion as >>>>>> existing decimal, hexadecimal, and octal literals are. >>>>> No special support or >>>>>> changes to the class file format are needed. >>>>>> >>>>>> TESTING: >>>>>> >>>>>> The feature can be tested in the same way as existing >>>>> decimal, hexadecimal, >>>>>> and octal literals are: Create a bunch of constants in >>>>> source code, including >>>>>> the maximum and minimum positive and negative values >>>>> for integer and long >>>>>> types, and verify them at runtime to have the correct >>>>> values. >>>>>> >>>>>> LIBRARY SUPPORT: >>>>>> >>>>>> The methods Integer.decode(String) and >>>>> Long.decode(String) should be modified >>>>>> to parse binary numbers (as specified above) in >>>>> addition to their existing >>>>>> support for decimal, hexadecimal, and octal numbers. >>>>>> >>>>>> >>>>>> REFLECTIVE APIS: >>>>>> >>>>>> No updates to the reflection APIs are needed. >>>>>> >>>>>> >>>>>> OTHER CHANGES: >>>>>> >>>>>> No other changes are needed. >>>>>> >>>>>> >>>>>> MIGRATION: >>>>>> >>>>>> Individual decimal, hexadecimal, or octal constants in >>>>> existing code can be >>>>>> updated to binary as a programmer desires. >>>>>> >>>>>> >>>>>> COMPATIBILITY >>>>>> >>>>>> >>>>>> BREAKING CHANGES: >>>>>> >>>>>> This feature would not break any existing programs, >>>>> since the suggested >>>>>> syntax is currently considerd to be a compile-time >>>>> error. >>>>>> >>>>>> EXISTING PROGRAMS: >>>>>> >>>>>> Class file format does not change, so existing >>>>> programs can use class files >>>>>> compiled with the new feature without problems. >>>>>> >>>>>> >>>>>> REFERENCES: >>>>>> >>>>>> The GCC/G++ compiler, which already supports this >>>>> syntax (as of version 4.3) >>>>>> as an extension to standard C/C++. >>>>>> http://gcc.gnu.org/gcc-4.3/changes.html >>>>>> >>>>>> The Ruby language, which supports binary literals: >>>>>> http://wordaligned.org/articles/binary-literals >>>>>> >>>>>> The Python language added binary literals in version >>>>> 2.6: >>>>> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >>>>>> EXISTING BUGS: >>>>>> >>>>>> "Language support for literal numbers in binary >>>>> and other bases" >>>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >>>>>> URL FOR PROTOTYPE (optional): >>>>>> >>>>>> None. >>>>>> >>>>>> >>>> >>>> >>>> >>> >> >> >> > From reinier at zwitserloot.com Wed Mar 25 16:51:43 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 00:51:43 +0100 Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions In-Reply-To: <49CAB9FD.5030307@joda.org> References: <56957.69.239.104.86.1237951010.squirrel@69.239.104.86> <49CAB9FD.5030307@joda.org> Message-ID: Any library that, for whatever reason, needs to know if a given Throwable object is checked or not, currently does this with: (x instanceof Error || x instanceof RuntimeException). There's no .isChecked() method. This proposal would break that, so its not backwards compatible. I think it's a neat idea, but that would auto-disqualify it from coin, I think. --Reinier Zwitserloot On Mar 26, 2009, at 00:10, Stephen Colebourne wrote: > Alan Snyder wrote: >> Unchecked Exceptions as Subclasses of Checked Exceptions >> public class TheCheckedException extends Exception {}; >> >> public class TheUncheckedException extends TheCheckedException >> implements >> UncheckedException {}; > > I like the idea. > > I'm not sure if its actually feasible. I suspect that its more complex > than it seems. > > I'm also not sure whether there are that many real use cases. Most of > the time you control your exception hierarchy (so you can choose > unchecked) or you have to live with a published API (the JDK) and so > it > can't be changed. > > Stephen > From j16sdiz at gmail.com Wed Mar 25 18:08:11 2009 From: j16sdiz at gmail.com (Daniel Cheng) Date: Thu, 26 Mar 2009 09:08:11 +0800 Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: On Wed, Mar 25, 2009 at 8:03 PM, Vilya Harvey wrote: > I would love to see this, but I'd prefer it to be based on special > interfaces rather than annotations. This would adhere to the > principle, mentioned on this list a few times, that annotations > shouldn't modify the results of the compiler. > > For example, if you implement the Addable (say) interface then your > class can be used the '+' operator; or the Subtractable interface for We can't specify the return type if we use an interface. We may want to do something like this: BigInteger + BigInteger = BigInteger BigInteger + BigDecimal = BigDecimal BigDecimal + BigInteger = BigDecimal BigDecimal + BigDecimal = BigDecimal There is no way to implement this using interface. > the '-' operator. I'd imagine you would also want some grouping > interfaces, to reduce the number of interface declarations required > when overloading multiple operators (e.g. interface Artihmetic extends > Addable, Subtractable etc.). > > Whatever form it takes though, it would be great to have this > capability in Java! > > Vil. > > > 2009/3/25 ?: >> Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk >> >> Probably too big, but anyway. >> >> As I remember, alternative proposal (made [] and []= syntax sugar on >> well-known interfaces, as with for-each loop) still not submitted. If >> anybody want submit such proposal, then it is possible to reuse >> JLS-changed for 15.26.1 from there. >> >> > > From vapor1 at teleport.com Wed Mar 25 19:55:35 2009 From: vapor1 at teleport.com (Derek Foster) Date: Wed, 25 Mar 2009 22:55:35 -0400 (EDT) Subject: PROPOSAL: Binary Literals Message-ID: <23073625.1238036135385.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> I am all for the addition of library methods to handle bit/byte/word/whatever munging. I plan to submit proposals for a few myself once the opportunity arises. However, library methods only cover a small subset of the use cases my proposal was intended to address. In my proposal, I specifically discussed the use of a library method and explained why it was not an acceptable substitute. I pointed out the performance impact of library calls, and noted that in the cases where low-level programming is most needed (in severely resource-constrained devices, J2ME, and so forth) that having library calls all over the place just to translate numbers from a readable form poses an unacceptable overhead in terms of performance, code size, and maintainability, not to mention the fact that bugs end up appearing at runtime (if you happen to run the code in _just_ the right way) rather than at compile time. I also pointed out the impossibility of using 'switch' statements with such techniques. With regards to the issue of "real programmers think in hex", by the way, I should point out that I started writing assembly language programs starting in sixth grade, and that that was around thirty years ago. Apparently even though I've been doing both high-level (Java, etc.) and low-level (assembly and occasional hand-coded machine language) programming for most of my life, I'm not a 'real programmer' because I use decimal, hex, binary, and even on some rare occasions, octal in the circumstances where they seem appropriate, rather than sticking religiously to hex regardless of the circumstance. (This is ridiculous, of course: Real Programmers don't really use hex. They program core memory using front-panel switches, in binary. Or possibly using punched cards if they are feeling a need for luxury.) In my experience, *real* "Real Programmers" use the appropriate tool for the job they are doing at the moment. Hex is simply not the appropriate tool for all jobs. It's great to use when it is appropriate (like when data lines up nicely on four-bit boundaries, or when the specification you are working from states its important numbers in hex), but it is extremely inconvenient to use hex the situations where it's not appropriate. Having to translate back and forth between hex and binary all the time when what you really want to do are fundamental binary operations (which are easily and clearly expressed in binary, and easily checkable against the relevant specifications documents which specify them in binary), is a waste of time and a rich source of bugs. Quick: How many bits are set in the number 0x4EC6? If the number were written in binary, you would be able to answer it as fast as you can count to eight. I'll bet you can't do it half that fast when it's expressed in hex. Here's a few more to contemplate: How many contiguous bit ranges exist in the number 0x5FF99C? What are their starting offsets? What will be the result of XORing together 0x4DE6 and 0x3837? Will 0x8567124 and 0x7218DB, ANDed together, be nonzero? What's the index of the fifth-highest set bit in the number 0x4687? All of the above questions are easy and quick to answer in binary, but difficult and error-prone in hex. In fact, the most difficult part of answering them in hex isn't answering the problem -- it's translating the hex to binary so the problem can be solved! When I am doing code review, I don't want "difficult and error prone". I want simple, direct, and mapping as directly to the specification I am implementing as possible. For a recent job, I had to deal with writing a decompiler for a processor which had lots of bitfields that didn't fall on nice even nybble boundaries, but instead often straddled them and had strange widths (3 bits, 9 bits, etc.). Furthermore, there were often multiple noncontiguous ranges of bits that had to be merged into the same field. Using hex numbers for this kind of situation makes the code all but unreadable without close study, and basically required that the size of the code be doubled due to all the extra named hexadecimal constants (for shifting, bit masking, and so forth) plus the comments needed to explain what the heck the code was doing, since its structure no longer directly expressed the problem it was trying to solve as stated in the specification. In most cases, I ended up having to write the binary representations of the numbers as comments alongside the hex translations of them, and then manually check the two against each other, just so I could later also manually check the binary numbers in my comments against the printed specification. Then I wrote and ran unit tests and found that even though I had manually verified the translations, I had still made a mistake. (Not too bad considering that I was translating a couple of hundred numbers in my head). I have recently had the occasion to do programming for microcontrollers in GCC, and was able to use the binary literal support provided by that compiler. It was so easy to use, and made the code so much clearer, that I found myself wondering again why I have to give up this feature when I move to the supposedly more convenient Java language. Why should programmers have to waste their time translating between hex and binary, when this is trivial for a compiler to do, and is considered a common enough need that multiple programming languages already support it? The effort to support this in a Java compiler is tiny, it fits well with the rest of the language and is similar to features in other languages. It won't break any existing code, and it is easy for those who don't want to use it to ignore it. Derek -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 25, 2009 7:47 PM >To: Stephen Colebourne >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Binary Literals > >Good points. Another useful method: > >public class Byte { > public static byte withBitsSet(int... positions); > public static byte withBitsCleared(int... positions); > public static byte of(String bitString); >} > >where setBits starts with 0 and then turns on the bit at each listed >position, and clearBits starts with -1 and turns off the bit at each >listed position. > >0x1C can then be implemented as: > >Byte.withBitsSet(4, 3, 2); >Byte.withBitsCleared(7, 6, 5, 1, 0); >Byte.of("00011100"); > > >That WOULD be a useful library addition. Not only are they almost as >short as the proposed byte literal, anybody that doesn't have the >first clue about bit masking can at least find some javadoc this way >and learn. They would be awfully slow compared to a literal, but >presumably any literal needs to be calculated only once, so any >slowness in the methods should never have a measurable impact. It's a >shame the JVM can't memoize, though. > > > > --Reinier Zwitserloot > > > >On Mar 25, 2009, at 23:17, Stephen Colebourne wrote: > >>> A couple of quick notes: >>> >>> 1) Ruby already has this. (The underscores in numbers, that is) >> >> So, does Fan. Yes, someone should write up underscores in numbers as a >> separate proposal. It won't be me. >> >> >>> Of all low impact coin submissions, this just isn't very compelling. >>> Real Programmers can count in hexadecimal ever since they were A >>> years >>> old, after all. >> >> Actually, my experience suggests that lots can't count in hex - we >> have >> calculators and the internet we that kind of thing these days. >> >> There are definitely use cases for this too, but they occur relatively >> rarely. For example, I once encoded the 30 year repeating pattern of >> leap years in the Islamic calendar system as a binary. This was a mess >> to write: >> >> Years to encode: 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 >> >> Final int value: 623191204 >> >> Binary literal: 0b00010010_10010010_10010010_01010010 >> >> It is also beneficial in teaching. >> >> But the truth is it will always be low priority (mind you, I'd have >> placed it higher than hexadecimal floating point literals...) >> >> Stephen >> >> >> >> >> Reinier Zwitserloot wrote: >>> Of all low impact coin submissions, this just isn't very compelling. >>> Real Programmers can count in hexadecimal ever since they were A >>> years >>> old, after all. >>> >>> --Reinier Zwitserloot >>> >>> >>> >>> On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: >>> >>>> A couple of quick notes: >>>> >>>> 1) Ruby already has this. (The underscores in numbers, that is) >>>> >>>> 2) I considered adding this to the proposal as I was writing it, but >>>> decided it was an orthogonal issue and deserved its own proposal, >>>> since it has nothing per se to do with binary literals. (As James >>>> mentions, it would make sense for all numbers, not just binary >>>> ones.) >>>> >>>> 3) I encourage someone else to write it up as a proposal. If I get >>>> done with the other proposals I intend to submit, and still have >>>> time, I might do it myself, but if you want to ensure that the >>>> proposal gets proposed, I suggest you don't wait for me. One caveat: >>>> Consider the impact on Integer.parseInt, Long.decode(), etc. (I >>>> suggest the decode methods get changed to accept underscores, but >>>> the parseInt ones don't.) >>>> >>>> 4) An observation to Joe Darcy and the other Sun engineers involved >>>> in reviewing proposals: The expected "about five" limit on proposals >>>> really encourages people to lump a bunch of semi-related things into >>>> one proposal rather than making each their own proposal, even when >>>> the latter would be a more logical way of getting individual >>>> orthogonal ideas reviewed separately. I think this is a problem. >>>> >>>> For instance, the "null safe operators" proposal (all or nothing) >>>> vs. splitting each of them out as individual proposals. There have >>>> been a number of proposals put forth where I thought "I agree with >>>> half of this proposal and wish the other half wasn't in the same >>>> proposal." >>>> >>>> I hope that the "about" in "about five" is flexible enough to allow >>>> a bunch of very minor proposals to expand that limit well past five >>>> if they seem good ideas and easy to implement with few >>>> repercussions. Five seems like a pretty low number to me, given that >>>> it's been MANY years since it was even possible for users to suggest >>>> changes to Java (basically, since JDK 5 was in the planning stages, >>>> as JDK 6 was announced to be a "no language changes" release), and >>>> there has been much evolution in other programming languages during >>>> that time. I think that good ideas should make it into Java (and bad >>>> ideas shouldn't) subject to the necessary manpower in review and >>>> implementation, regardless of the number of proposals used to submit >>>> them. Otherwise, Java risks getting left in the dust as other >>>> languages become much easier to use, much faster. >>>> >>>> Derek >>>> >>>> -----Original Message----- >>>>> From: james lowden >>>>> Sent: Mar 25, 2009 12:07 PM >>>>> To: coin-dev at openjdk.java.net >>>>> Subject: Re: PROPOSAL: Binary Literals >>>>> >>>>> >>>>> Actually, that's a good idea in general for long numeric >>>>> constants. 9_000_000_000_000_000L is easier to parse than >>>>> 9000000000000000L. >>>>> >>>>> >>>>> --- On Wed, 3/25/09, Stephen Colebourne >>>>> wrote: >>>>> >>>>>> From: Stephen Colebourne >>>>>> Subject: Re: PROPOSAL: Binary Literals >>>>>> To: coin-dev at openjdk.java.net >>>>>> Date: Wednesday, March 25, 2009, 1:50 PM >>>>>> See >>>>>> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >>>>>> for my take on this from long ago. >>>>>> >>>>>> In particular, I'd suggest allowing a character to >>>>>> separate long binary strings: >>>>>> >>>>>> int anInt1 = 0b10100001_01000101_10100001_01000101; >>>>>> >>>>>> much more readable. >>>>>> >>>>>> Stephen >>>>>> >>>>>> 2009/3/25 Derek Foster : >>>>>>> Hmm. Second try at sending to the list. Let's see >>>>>> if this works. (In the >>>>>>> meantime, I noticed that Bruce Chapman has mentioned >>>>>> something similar in his >>>>>>> another proposal, so I think we are in agreement on >>>>>> this. This proposal >>>>>>> should not be taken as to compete with his similar >>>>>> proposal: I'd quite like >>>>>>> to see type suffixes for bytes, shorts, etc. added to >>>>>> Java, in addition to >>>>>>> binary literals.) Anyway... >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> Add binary literals to Java. >>>>>>> >>>>>>> AUTHOR(S): Derek Foster >>>>>>> >>>>>>> OVERVIEW >>>>>>> >>>>>>> In some programming domains, use of binary numbers >>>>>> (typically as bitmasks, >>>>>>> bit-shifts, etc.) is very common. However, Java code, >>>>>> due to its C heritage, >>>>>>> has traditionally forced programmers to represent >>>>>> numbers in only decimal, >>>>>>> octal, or hexadecimal. (In practice, octal is rarely >>>>>> used, and is present >>>>>>> mostly for backwards compatibility with C) >>>>>>> >>>>>>> When the data being dealt with is fundamentally >>>>>> bit-oriented, however, using >>>>>>> hexadecimal to represent ranges of bits requires an >>>>>> extra degree of >>>>>>> translation for the programmer, and this can often >>>>>> become a source of errors. >>>>>>> For instance, if a technical specification lists >>>>>> specific values of interest >>>>>>> in binary (for example, in a compression encoding >>>>>> algorithm or in the >>>>>>> specifications for a network protocol, or for >>>>>> communicating with a bitmapped >>>>>>> hardware device) then a programmer coding to that >>>>>> specification must >>>>>>> translate each such value from its binary >>>>>> representation into hexadecimal. >>>>>>> Checking to see if this translation has been done >>>>>> correctly is accomplished >>>>>>> by back-translating the numbers. In most cases, >>>>>> programmers do these >>>>>>> translations in their heads, and HOPEFULLY get them >>>>>> right. however, errors >>>>>>> can easily creep in, and re-verifying the results is >>>>>> not straightforward >>>>>>> enough to be done frequently. >>>>>>> >>>>>>> Furthermore, in many cases, the binary representations >>>>>> of numbers makes it >>>>>>> much more clear what is actually intended than the >>>>>> hexadecimal one. For >>>>>>> instance, this: >>>>>>> >>>>>>> private static final int BITMASK = 0x1E; >>>>>>> >>>>>>> does not immediately make it clear that the bitmask >>>>>> being declared comprises >>>>>>> a single contiguous range of four bits. >>>>>>> >>>>>>> In many cases, it would be more natural for the >>>>>> programmer to be able to >>>>>>> write the numbers in binary in the source code, >>>>>> eliminating the need for >>>>>>> manual translation to hexadecimal entirely. >>>>>>> >>>>>>> >>>>>>> FEATURE SUMMARY: >>>>>>> >>>>>>> In addition to the existing "1" (decimal), >>>>>> "01" (octal) and "0x1" >>>>>>> (hexadecimal) form of specifying numeric literals, a >>>>>> new form "0b1" (binary) >>>>>>> would be added. >>>>>>> >>>>>>> Note that this is the same syntax as has been used as >>>>>> an extension by the GCC >>>>>>> C/C++ compilers for many years, and also is used in >>>>>> the Ruby language, as >>>>>>> well as in the Python language. >>>>>>> >>>>>>> >>>>>>> MAJOR ADVANTAGE: >>>>>>> >>>>>>> It is no longer necessary for programmers to translate >>>>>> binary numbers to and >>>>>>> from hexadecimal in order to use them in Java >>>>>> programs. >>>>>>> >>>>>>> MAJOR BENEFIT: >>>>>>> >>>>>>> Code using bitwise operations is more readable and >>>>>> easier to verify against >>>>>>> technical specifications that use binary numbers to >>>>>> specify constants. >>>>>>> Routines that are bit-oriented are easier to >>>>>> understand when an artifical >>>>>>> translation to hexadecimal is not required in order to >>>>>> fulfill the >>>>>>> constraints of the language. >>>>>>> >>>>>>> MAJOR DISADVANTAGE: >>>>>>> >>>>>>> Someone might incorrectly think that "0b1" >>>>>> represented the same value as >>>>>>> hexadecimal number "0xB1". However, note >>>>>> that this problem has existed for >>>>>>> octal/decimal for many years (confusion between >>>>>> "050" and "50") and does not >>>>>>> seem to be a major issue. >>>>>>> >>>>>>> >>>>>>> ALTERNATIVES: >>>>>>> >>>>>>> Users could continue to write the numbers as decimal, >>>>>> octal, or hexadecimal, >>>>>>> and would continue to have the problems observed in >>>>>> this document. >>>>>>> Another alternative would be for code to translate at >>>>>> runtime from binary >>>>>>> strings, such as: >>>>>>> >>>>>>> int BITMASK = >>>>>> Integer.parseInt("00001110", 2); >>>>>>> Besides the obvious extra verbosity, there are several >>>>>> problems with this: >>>>>>> * Calling a method such as Integer.parseInt at runtime >>>>>> will typically make it >>>>>>> impossible for the compiler to inline the value of >>>>>> this constant, since its >>>>>>> value has been taken from a runtime method call. >>>>>> Inlining is important, >>>>>>> because code that does bitwise parsing is often very >>>>>> low-level code in tight >>>>>>> loops that must execute quickly. (This is particularly >>>>>> the case for mobile >>>>>>> applications and other applications that run on >>>>>> severely resource-constrained >>>>>>> environments, which is one of the cases where binary >>>>>> numbers would be most >>>>>>> valuable, since talking to low-level hardware is one >>>>>> of the primary use cases >>>>>>> for this feature.) >>>>>>> >>>>>>> * Constants such as the above cannot be used as >>>>>> selectors in 'switch' >>>>>>> statements. >>>>>>> >>>>>>> * Any errors in the string to be parsed (for instance, >>>>>> an extra space) will >>>>>>> result in runtime exceptions, rather than compile-time >>>>>> errors as would have >>>>>>> occurred in normal parsing. If such a value is >>>>>> declared 'static', this will >>>>>>> result in some very ugly exceptions at runtime. >>>>>>> >>>>>>> >>>>>>> EXAMPLES: >>>>>>> >>>>>>> // An 8-bit 'byte' literal. >>>>>>> byte aByte = (byte)0b00100001; >>>>>>> >>>>>>> // A 16-bit 'short' literal. >>>>>>> short aShort = (short)0b1010000101000101; >>>>>>> >>>>>>> // Some 32-bit 'int' literals. >>>>>>> int anInt1 = 0b10100001010001011010000101000101; >>>>>>> int anInt2 = 0b101; >>>>>>> int anInt3 = 0B101; // The B can be upper or lower >>>>>> case as per the x in >>>>>>> "0x45". >>>>>>> >>>>>>> // A 64-bit 'long' literal. Note the >>>>>> "L" suffix, as would also be used >>>>>>> // for a long in decimal, hexadecimal, or octal. >>>>>>> long aLong = >>>>>>> >>>>>> 0b01010000101000101101000010100010110100001010001011010000101000101L >>>>>> ; >>>>>>> SIMPLE EXAMPLE: >>>>>>> >>>>>>> class Foo { >>>>>>> public static void main(String[] args) { >>>>>>> System.out.println("The value 10100001 in >>>>>> decimal is " + 0b10100001); >>>>>>> } >>>>>>> >>>>>>> >>>>>>> ADVANCED EXAMPLE: >>>>>>> >>>>>>> // Binary constants could be used in code that needs >>>>>> to be >>>>>>> // easily checkable against a specifications document, >>>>>> such >>>>>>> // as this simulator for a hypothetical 8-bit >>>>>> microprocessor: >>>>>>> public State decodeInstruction(int instruction, State >>>>>> state) { >>>>>>> if ((instruction & 0b11100000) == 0b00000000) { >>>>>>> final int register = instruction & >>>>>> 0b00001111; >>>>>>> switch (instruction & 0b11110000) { >>>>>>> case 0b00000000: return state.nop(); >>>>>>> case 0b00010000: return >>>>>> state.copyAccumTo(register); >>>>>>> case 0b00100000: return >>>>>> state.addToAccum(register); >>>>>>> case 0b00110000: return >>>>>> state.subFromAccum(register); >>>>>>> case 0b01000000: return >>>>>> state.multiplyAccumBy(register); >>>>>>> case 0b01010000: return >>>>>> state.divideAccumBy(register); >>>>>>> case 0b01100000: return >>>>>> state.setAccumFrom(register); >>>>>>> case 0b01110000: return >>>>>> state.returnFromCall(); >>>>>>> default: throw new IllegalArgumentException(); >>>>>>> } >>>>>>> } else { >>>>>>> final int address = instruction & 0b00011111; >>>>>>> switch (instruction & 0b11100000) { >>>>>>> case 0b00100000: return state.jumpTo(address); >>>>>>> case 0b01000000: return >>>>>> state.jumpIfAccumZeroTo(address); >>>>>>> case 0b01000000: return >>>>>> state.jumpIfAccumNonzeroTo(address); >>>>>>> case 0b01100000: return >>>>>> state.setAccumFromMemory(address); >>>>>>> case 0b10100000: return >>>>>> state.writeAccumToMemory(address); >>>>>>> case 0b11000000: return state.callTo(address); >>>>>>> default: throw new IllegalArgumentException(); >>>>>>> } >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> // Binary literals can be used to make a bitmap more >>>>>> readable: >>>>>>> public static final short[] HAPPY_FACE = { >>>>>>> (short)0b0000011111100000; >>>>>>> (short)0b0000100000010000; >>>>>>> (short)0b0001000000001000; >>>>>>> (short)0b0010000000000100; >>>>>>> (short)0b0100000000000010; >>>>>>> (short)0b1000011001100001; >>>>>>> (short)0b1000011001100001; >>>>>>> (short)0b1000000000000001; >>>>>>> (short)0b1000000000000001; >>>>>>> (short)0b1001000000001001; >>>>>>> (short)0b1000100000010001; >>>>>>> (short)0b0100011111100010; >>>>>>> (short)0b0010000000000100; >>>>>>> (short)0b0001000000001000; >>>>>>> (short)0b0000100000010000; >>>>>>> (short)0b0000011111100000; >>>>>>> } >>>>>>> >>>>>>> // Binary literals can make relationships >>>>>>> // among data more apparent than they would >>>>>>> // be in hex or octal. >>>>>>> // >>>>>>> // For instance, what does the following >>>>>>> // array contain? In hexadecimal, it's hard to >>>>>> tell: >>>>>>> public static final int[] PHASES = { >>>>>>> 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >>>>>>> } >>>>>>> >>>>>>> // In binary, it's obvious that a number is being >>>>>>> // rotated left one bit at a time. >>>>>>> public static final int[] PHASES = { >>>>>>> 0b00110001, >>>>>>> 0b01100010, >>>>>>> 0b11000100, >>>>>>> 0b10001001, >>>>>>> 0b00010011, >>>>>>> 0b00100110, >>>>>>> 0b01001100, >>>>>>> 0b10011000, >>>>>>> } >>>>>>> >>>>>>> >>>>>>> DETAILS >>>>>>> >>>>>>> SPECIFICATION: >>>>>>> >>>>>>> Section 3.10.1 ("Integer Literals") of the >>>>>> JLS3 should be changed to add the >>>>>>> following: >>>>>>> >>>>>>> IntegerLiteral: >>>>>>> DecimalIntegerLiteral >>>>>>> HexIntegerLiteral >>>>>>> OctalIntegerLiteral >>>>>>> BinaryIntegerLiteral // Added >>>>>>> >>>>>>> BinaryIntegerLiteral: >>>>>>> BinaryNumeral IntegerTypeSuffix_opt >>>>>>> >>>>>>> BinaryNumeral: >>>>>>> 0 b BinaryDigits >>>>>>> 0 B BinaryDigits >>>>>>> >>>>>>> BinaryDigits: >>>>>>> BinaryDigit >>>>>>> BinaryDigit BinaryDigits >>>>>>> >>>>>>> BinaryDigit: one of >>>>>>> 0 1 >>>>>>> >>>>>>> COMPILATION: >>>>>>> >>>>>>> Binary literals would be compiled to class files in >>>>>> the same fashion as >>>>>>> existing decimal, hexadecimal, and octal literals are. >>>>>> No special support or >>>>>>> changes to the class file format are needed. >>>>>>> >>>>>>> TESTING: >>>>>>> >>>>>>> The feature can be tested in the same way as existing >>>>>> decimal, hexadecimal, >>>>>>> and octal literals are: Create a bunch of constants in >>>>>> source code, including >>>>>>> the maximum and minimum positive and negative values >>>>>> for integer and long >>>>>>> types, and verify them at runtime to have the correct >>>>>> values. >>>>>>> >>>>>>> LIBRARY SUPPORT: >>>>>>> >>>>>>> The methods Integer.decode(String) and >>>>>> Long.decode(String) should be modified >>>>>>> to parse binary numbers (as specified above) in >>>>>> addition to their existing >>>>>>> support for decimal, hexadecimal, and octal numbers. >>>>>>> >>>>>>> >>>>>>> REFLECTIVE APIS: >>>>>>> >>>>>>> No updates to the reflection APIs are needed. >>>>>>> >>>>>>> >>>>>>> OTHER CHANGES: >>>>>>> >>>>>>> No other changes are needed. >>>>>>> >>>>>>> >>>>>>> MIGRATION: >>>>>>> >>>>>>> Individual decimal, hexadecimal, or octal constants in >>>>>> existing code can be >>>>>>> updated to binary as a programmer desires. >>>>>>> >>>>>>> >>>>>>> COMPATIBILITY >>>>>>> >>>>>>> >>>>>>> BREAKING CHANGES: >>>>>>> >>>>>>> This feature would not break any existing programs, >>>>>> since the suggested >>>>>>> syntax is currently considerd to be a compile-time >>>>>> error. >>>>>>> >>>>>>> EXISTING PROGRAMS: >>>>>>> >>>>>>> Class file format does not change, so existing >>>>>> programs can use class files >>>>>>> compiled with the new feature without problems. >>>>>>> >>>>>>> >>>>>>> REFERENCES: >>>>>>> >>>>>>> The GCC/G++ compiler, which already supports this >>>>>> syntax (as of version 4.3) >>>>>>> as an extension to standard C/C++. >>>>>>> http://gcc.gnu.org/gcc-4.3/changes.html >>>>>>> >>>>>>> The Ruby language, which supports binary literals: >>>>>>> http://wordaligned.org/articles/binary-literals >>>>>>> >>>>>>> The Python language added binary literals in version >>>>>> 2.6: >>>>>> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >>>>>>> EXISTING BUGS: >>>>>>> >>>>>>> "Language support for literal numbers in binary >>>>>> and other bases" >>>>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >>>>>>> URL FOR PROTOTYPE (optional): >>>>>>> >>>>>>> None. >>>>>>> >>>>>>> >>>>> >>>>> >>>>> >>>> >>> >>> >>> >> > > From reinier at zwitserloot.com Wed Mar 25 20:46:38 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 04:46:38 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: <23073625.1238036135385.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> References: <23073625.1238036135385.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Message-ID: <30B057DE-0332-426D-BAAD-9C8F2794F8F9@zwitserloot.com> In regards to j2me: j2me is on its way out, and will not be receiving many updates regardless, because sun can't exactly update the java version on the billions of phones out there. On performance: I don't understand. The result of a library call is a byte primitive, which you can then assign to a private static final byte constant. From there on out, that will be as fast as a code literal. Unless you were planning on using a few million binary literals in your code, there shouldn't be a performance impact; just an annoyance that you have to constantize every literal you use in a time sensitive area instead of using Byte.of("01000100") directly in your method body. The odds that "0b01000100", where you've added a zero too many (or left one out) is going to result in a compile time error seems odd. Why would that cause a compile time error, exactly? Evidently that wasn't clear, but my reference to "real programmers think in hex since they are A years old" was intended as a joke. I apologize if that wasn't obvious. How many bits are set in 0x4EC6? 8. I was able to count that about as quickly as with 0b0100111011000110. Shame we didn't bet on it. Quick: How many nibbles are in 0b0100111011000110? How many bits are set in the upper byte? There are a select few questions that are just easier when written out in binary, even if that results in a massive amount of digits, such as finding contiguous sequences of bits (the packing into nibbles gets in the way for that kind of thing). Which is why I said that Byte.of("01000100") is a good idea. The theory of 'those who don't care can just ignore it' has a fundamental flaw: It leads to readable-only-by-author code. Grab some perl example code and try to ascertain what it's trying to do. I wish you good luck! Optimally speaking, every language feature is at least somewhat familiar to every programmer of that language. Java is a few steps beyond that already (see the Java Puzzlers for proof), but that doesn't mean we should no longer care about that tenet anymore. Such a feature should introduce extremely significant improvements in a niche area, and/or allow you to things that you just can't do now. This clearly isn't the case. Speaking of 'things that you just can't do now', for bit wrangling and performance, I'd love to see a Math.* library that foregoes exact spec precision and trades it for raw speed. Right now java Math.* can't use the gfx pipelines because those don't use quite the same floating point spec that java docs say they should. Just to give an example of a change that I would wholeheartedly support even if it is extremely niche. --Reinier Zwitserloot On Mar 26, 2009, at 03:55, Derek Foster wrote: > I am all for the addition of library methods to handle bit/byte/word/ > whatever munging. I plan to submit proposals for a few myself once > the opportunity arises. > > However, library methods only cover a small subset of the use cases > my proposal was intended to address. In my proposal, I specifically > discussed the use of a library method and explained why it was not > an acceptable substitute. I pointed out the performance impact of > library calls, and noted that in the cases where low-level > programming is most needed (in severely resource-constrained > devices, J2ME, and so forth) that having library calls all over the > place just to translate numbers from a readable form poses an > unacceptable overhead in terms of performance, code size, and > maintainability, not to mention the fact that bugs end up appearing > at runtime (if you happen to run the code in _just_ the right way) > rather than at compile time. I also pointed out the impossibility of > using 'switch' statements with such techniques. > > With regards to the issue of "real programmers think in hex", by the > way, I should point out that I started writing assembly language > programs starting in sixth grade, and that that was around thirty > years ago. Apparently even though I've been doing both high-level > (Java, etc.) and low-level (assembly and occasional hand-coded > machine language) programming for most of my life, I'm not a 'real > programmer' because I use decimal, hex, binary, and even on some > rare occasions, octal in the circumstances where they seem > appropriate, rather than sticking religiously to hex regardless of > the circumstance. (This is ridiculous, of course: Real Programmers > don't really use hex. They program core memory using front-panel > switches, in binary. Or possibly using punched cards if they are > feeling a need for luxury.) > > In my experience, *real* "Real Programmers" use the appropriate tool > for the job they are doing at the moment. Hex is simply not the > appropriate tool for all jobs. It's great to use when it is > appropriate (like when data lines up nicely on four-bit boundaries, > or when the specification you are working from states its important > numbers in hex), but it is extremely inconvenient to use hex the > situations where it's not appropriate. Having to translate back and > forth between hex and binary all the time when what you really want > to do are fundamental binary operations (which are easily and > clearly expressed in binary, and easily checkable against the > relevant specifications documents which specify them in binary), is > a waste of time and a rich source of bugs. > > Quick: How many bits are set in the number 0x4EC6? > > If the number were written in binary, you would be able to answer it > as fast as you can count to eight. I'll bet you can't do it half > that fast when it's expressed in hex. > > Here's a few more to contemplate: > > > How many contiguous bit ranges exist in the number 0x5FF99C? What > are their starting offsets? > > What will be the result of XORing together 0x4DE6 and 0x3837? > > Will 0x8567124 and 0x7218DB, ANDed together, be nonzero? > > What's the index of the fifth-highest set bit in the number 0x4687? > > > All of the above questions are easy and quick to answer in binary, > but difficult and error-prone in hex. In fact, the most difficult > part of answering them in hex isn't answering the problem -- it's > translating the hex to binary so the problem can be solved! When I > am doing code review, I don't want "difficult and error prone". I > want simple, direct, and mapping as directly to the specification I > am implementing as possible. > > For a recent job, I had to deal with writing a decompiler for a > processor which had lots of bitfields that didn't fall on nice even > nybble boundaries, but instead often straddled them and had strange > widths (3 bits, 9 bits, etc.). Furthermore, there were often > multiple noncontiguous ranges of bits that had to be merged into the > same field. Using hex numbers for this kind of situation makes the > code all but unreadable without close study, and basically required > that the size of the code be doubled due to all the extra named > hexadecimal constants (for shifting, bit masking, and so forth) plus > the comments needed to explain what the heck the code was doing, > since its structure no longer directly expressed the problem it was > trying to solve as stated in the specification. In most cases, I > ended up having to write the binary representations of the numbers > as comments alongside the hex translations of them, and then > manually check the two against each other, just so I could later a > lso manually check the binary numbers in my comments against the > printed specification. > > Then I wrote and ran unit tests and found that even though I had > manually verified the translations, I had still made a mistake. (Not > too bad considering that I was translating a couple of hundred > numbers in my head). > > I have recently had the occasion to do programming for > microcontrollers in GCC, and was able to use the binary literal > support provided by that compiler. It was so easy to use, and made > the code so much clearer, that I found myself wondering again why I > have to give up this feature when I move to the supposedly more > convenient Java language. > > Why should programmers have to waste their time translating between > hex and binary, when this is trivial for a compiler to do, and is > considered a common enough need that multiple programming languages > already support it? > > The effort to support this in a Java compiler is tiny, it fits well > with the rest of the language and is similar to features in other > languages. It won't break any existing code, and it is easy for > those who don't want to use it to ignore it. > > Derek > > -----Original Message----- >> From: Reinier Zwitserloot >> Sent: Mar 25, 2009 7:47 PM >> To: Stephen Colebourne >> Cc: coin-dev at openjdk.java.net >> Subject: Re: PROPOSAL: Binary Literals >> >> Good points. Another useful method: >> >> public class Byte { >> public static byte withBitsSet(int... positions); >> public static byte withBitsCleared(int... positions); >> public static byte of(String bitString); >> } >> >> where setBits starts with 0 and then turns on the bit at each listed >> position, and clearBits starts with -1 and turns off the bit at each >> listed position. >> >> 0x1C can then be implemented as: >> >> Byte.withBitsSet(4, 3, 2); >> Byte.withBitsCleared(7, 6, 5, 1, 0); >> Byte.of("00011100"); >> >> >> That WOULD be a useful library addition. Not only are they almost as >> short as the proposed byte literal, anybody that doesn't have the >> first clue about bit masking can at least find some javadoc this way >> and learn. They would be awfully slow compared to a literal, but >> presumably any literal needs to be calculated only once, so any >> slowness in the methods should never have a measurable impact. It's a >> shame the JVM can't memoize, though. >> >> >> >> --Reinier Zwitserloot >> >> >> >> On Mar 25, 2009, at 23:17, Stephen Colebourne wrote: >> >>>> A couple of quick notes: >>>> >>>> 1) Ruby already has this. (The underscores in numbers, that is) >>> >>> So, does Fan. Yes, someone should write up underscores in numbers >>> as a >>> separate proposal. It won't be me. >>> >>> >>>> Of all low impact coin submissions, this just isn't very >>>> compelling. >>>> Real Programmers can count in hexadecimal ever since they were A >>>> years >>>> old, after all. >>> >>> Actually, my experience suggests that lots can't count in hex - we >>> have >>> calculators and the internet we that kind of thing these days. >>> >>> There are definitely use cases for this too, but they occur >>> relatively >>> rarely. For example, I once encoded the 30 year repeating pattern of >>> leap years in the Islamic calendar system as a binary. This was a >>> mess >>> to write: >>> >>> Years to encode: 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 >>> >>> Final int value: 623191204 >>> >>> Binary literal: 0b00010010_10010010_10010010_01010010 >>> >>> It is also beneficial in teaching. >>> >>> But the truth is it will always be low priority (mind you, I'd have >>> placed it higher than hexadecimal floating point literals...) >>> >>> Stephen >>> >>> >>> >>> >>> Reinier Zwitserloot wrote: >>>> Of all low impact coin submissions, this just isn't very >>>> compelling. >>>> Real Programmers can count in hexadecimal ever since they were A >>>> years >>>> old, after all. >>>> >>>> --Reinier Zwitserloot >>>> >>>> >>>> >>>> On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: >>>> >>>>> A couple of quick notes: >>>>> >>>>> 1) Ruby already has this. (The underscores in numbers, that is) >>>>> >>>>> 2) I considered adding this to the proposal as I was writing it, >>>>> but >>>>> decided it was an orthogonal issue and deserved its own proposal, >>>>> since it has nothing per se to do with binary literals. (As James >>>>> mentions, it would make sense for all numbers, not just binary >>>>> ones.) >>>>> >>>>> 3) I encourage someone else to write it up as a proposal. If I get >>>>> done with the other proposals I intend to submit, and still have >>>>> time, I might do it myself, but if you want to ensure that the >>>>> proposal gets proposed, I suggest you don't wait for me. One >>>>> caveat: >>>>> Consider the impact on Integer.parseInt, Long.decode(), etc. (I >>>>> suggest the decode methods get changed to accept underscores, but >>>>> the parseInt ones don't.) >>>>> >>>>> 4) An observation to Joe Darcy and the other Sun engineers >>>>> involved >>>>> in reviewing proposals: The expected "about five" limit on >>>>> proposals >>>>> really encourages people to lump a bunch of semi-related things >>>>> into >>>>> one proposal rather than making each their own proposal, even when >>>>> the latter would be a more logical way of getting individual >>>>> orthogonal ideas reviewed separately. I think this is a problem. >>>>> >>>>> For instance, the "null safe operators" proposal (all or nothing) >>>>> vs. splitting each of them out as individual proposals. There have >>>>> been a number of proposals put forth where I thought "I agree with >>>>> half of this proposal and wish the other half wasn't in the same >>>>> proposal." >>>>> >>>>> I hope that the "about" in "about five" is flexible enough to >>>>> allow >>>>> a bunch of very minor proposals to expand that limit well past >>>>> five >>>>> if they seem good ideas and easy to implement with few >>>>> repercussions. Five seems like a pretty low number to me, given >>>>> that >>>>> it's been MANY years since it was even possible for users to >>>>> suggest >>>>> changes to Java (basically, since JDK 5 was in the planning >>>>> stages, >>>>> as JDK 6 was announced to be a "no language changes" release), and >>>>> there has been much evolution in other programming languages >>>>> during >>>>> that time. I think that good ideas should make it into Java (and >>>>> bad >>>>> ideas shouldn't) subject to the necessary manpower in review and >>>>> implementation, regardless of the number of proposals used to >>>>> submit >>>>> them. Otherwise, Java risks getting left in the dust as other >>>>> languages become much easier to use, much faster. >>>>> >>>>> Derek >>>>> >>>>> -----Original Message----- >>>>>> From: james lowden >>>>>> Sent: Mar 25, 2009 12:07 PM >>>>>> To: coin-dev at openjdk.java.net >>>>>> Subject: Re: PROPOSAL: Binary Literals >>>>>> >>>>>> >>>>>> Actually, that's a good idea in general for long numeric >>>>>> constants. 9_000_000_000_000_000L is easier to parse than >>>>>> 9000000000000000L. >>>>>> >>>>>> >>>>>> --- On Wed, 3/25/09, Stephen Colebourne >>>>>> wrote: >>>>>> >>>>>>> From: Stephen Colebourne >>>>>>> Subject: Re: PROPOSAL: Binary Literals >>>>>>> To: coin-dev at openjdk.java.net >>>>>>> Date: Wednesday, March 25, 2009, 1:50 PM >>>>>>> See >>>>>>> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >>>>>>> for my take on this from long ago. >>>>>>> >>>>>>> In particular, I'd suggest allowing a character to >>>>>>> separate long binary strings: >>>>>>> >>>>>>> int anInt1 = 0b10100001_01000101_10100001_01000101; >>>>>>> >>>>>>> much more readable. >>>>>>> >>>>>>> Stephen >>>>>>> >>>>>>> 2009/3/25 Derek Foster : >>>>>>>> Hmm. Second try at sending to the list. Let's see >>>>>>> if this works. (In the >>>>>>>> meantime, I noticed that Bruce Chapman has mentioned >>>>>>> something similar in his >>>>>>>> another proposal, so I think we are in agreement on >>>>>>> this. This proposal >>>>>>>> should not be taken as to compete with his similar >>>>>>> proposal: I'd quite like >>>>>>>> to see type suffixes for bytes, shorts, etc. added to >>>>>>> Java, in addition to >>>>>>>> binary literals.) Anyway... >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Add binary literals to Java. >>>>>>>> >>>>>>>> AUTHOR(S): Derek Foster >>>>>>>> >>>>>>>> OVERVIEW >>>>>>>> >>>>>>>> In some programming domains, use of binary numbers >>>>>>> (typically as bitmasks, >>>>>>>> bit-shifts, etc.) is very common. However, Java code, >>>>>>> due to its C heritage, >>>>>>>> has traditionally forced programmers to represent >>>>>>> numbers in only decimal, >>>>>>>> octal, or hexadecimal. (In practice, octal is rarely >>>>>>> used, and is present >>>>>>>> mostly for backwards compatibility with C) >>>>>>>> >>>>>>>> When the data being dealt with is fundamentally >>>>>>> bit-oriented, however, using >>>>>>>> hexadecimal to represent ranges of bits requires an >>>>>>> extra degree of >>>>>>>> translation for the programmer, and this can often >>>>>>> become a source of errors. >>>>>>>> For instance, if a technical specification lists >>>>>>> specific values of interest >>>>>>>> in binary (for example, in a compression encoding >>>>>>> algorithm or in the >>>>>>>> specifications for a network protocol, or for >>>>>>> communicating with a bitmapped >>>>>>>> hardware device) then a programmer coding to that >>>>>>> specification must >>>>>>>> translate each such value from its binary >>>>>>> representation into hexadecimal. >>>>>>>> Checking to see if this translation has been done >>>>>>> correctly is accomplished >>>>>>>> by back-translating the numbers. In most cases, >>>>>>> programmers do these >>>>>>>> translations in their heads, and HOPEFULLY get them >>>>>>> right. however, errors >>>>>>>> can easily creep in, and re-verifying the results is >>>>>>> not straightforward >>>>>>>> enough to be done frequently. >>>>>>>> >>>>>>>> Furthermore, in many cases, the binary representations >>>>>>> of numbers makes it >>>>>>>> much more clear what is actually intended than the >>>>>>> hexadecimal one. For >>>>>>>> instance, this: >>>>>>>> >>>>>>>> private static final int BITMASK = 0x1E; >>>>>>>> >>>>>>>> does not immediately make it clear that the bitmask >>>>>>> being declared comprises >>>>>>>> a single contiguous range of four bits. >>>>>>>> >>>>>>>> In many cases, it would be more natural for the >>>>>>> programmer to be able to >>>>>>>> write the numbers in binary in the source code, >>>>>>> eliminating the need for >>>>>>>> manual translation to hexadecimal entirely. >>>>>>>> >>>>>>>> >>>>>>>> FEATURE SUMMARY: >>>>>>>> >>>>>>>> In addition to the existing "1" (decimal), >>>>>>> "01" (octal) and "0x1" >>>>>>>> (hexadecimal) form of specifying numeric literals, a >>>>>>> new form "0b1" (binary) >>>>>>>> would be added. >>>>>>>> >>>>>>>> Note that this is the same syntax as has been used as >>>>>>> an extension by the GCC >>>>>>>> C/C++ compilers for many years, and also is used in >>>>>>> the Ruby language, as >>>>>>>> well as in the Python language. >>>>>>>> >>>>>>>> >>>>>>>> MAJOR ADVANTAGE: >>>>>>>> >>>>>>>> It is no longer necessary for programmers to translate >>>>>>> binary numbers to and >>>>>>>> from hexadecimal in order to use them in Java >>>>>>> programs. >>>>>>>> >>>>>>>> MAJOR BENEFIT: >>>>>>>> >>>>>>>> Code using bitwise operations is more readable and >>>>>>> easier to verify against >>>>>>>> technical specifications that use binary numbers to >>>>>>> specify constants. >>>>>>>> Routines that are bit-oriented are easier to >>>>>>> understand when an artifical >>>>>>>> translation to hexadecimal is not required in order to >>>>>>> fulfill the >>>>>>>> constraints of the language. >>>>>>>> >>>>>>>> MAJOR DISADVANTAGE: >>>>>>>> >>>>>>>> Someone might incorrectly think that "0b1" >>>>>>> represented the same value as >>>>>>>> hexadecimal number "0xB1". However, note >>>>>>> that this problem has existed for >>>>>>>> octal/decimal for many years (confusion between >>>>>>> "050" and "50") and does not >>>>>>>> seem to be a major issue. >>>>>>>> >>>>>>>> >>>>>>>> ALTERNATIVES: >>>>>>>> >>>>>>>> Users could continue to write the numbers as decimal, >>>>>>> octal, or hexadecimal, >>>>>>>> and would continue to have the problems observed in >>>>>>> this document. >>>>>>>> Another alternative would be for code to translate at >>>>>>> runtime from binary >>>>>>>> strings, such as: >>>>>>>> >>>>>>>> int BITMASK = >>>>>>> Integer.parseInt("00001110", 2); >>>>>>>> Besides the obvious extra verbosity, there are several >>>>>>> problems with this: >>>>>>>> * Calling a method such as Integer.parseInt at runtime >>>>>>> will typically make it >>>>>>>> impossible for the compiler to inline the value of >>>>>>> this constant, since its >>>>>>>> value has been taken from a runtime method call. >>>>>>> Inlining is important, >>>>>>>> because code that does bitwise parsing is often very >>>>>>> low-level code in tight >>>>>>>> loops that must execute quickly. (This is particularly >>>>>>> the case for mobile >>>>>>>> applications and other applications that run on >>>>>>> severely resource-constrained >>>>>>>> environments, which is one of the cases where binary >>>>>>> numbers would be most >>>>>>>> valuable, since talking to low-level hardware is one >>>>>>> of the primary use cases >>>>>>>> for this feature.) >>>>>>>> >>>>>>>> * Constants such as the above cannot be used as >>>>>>> selectors in 'switch' >>>>>>>> statements. >>>>>>>> >>>>>>>> * Any errors in the string to be parsed (for instance, >>>>>>> an extra space) will >>>>>>>> result in runtime exceptions, rather than compile-time >>>>>>> errors as would have >>>>>>>> occurred in normal parsing. If such a value is >>>>>>> declared 'static', this will >>>>>>>> result in some very ugly exceptions at runtime. >>>>>>>> >>>>>>>> >>>>>>>> EXAMPLES: >>>>>>>> >>>>>>>> // An 8-bit 'byte' literal. >>>>>>>> byte aByte = (byte)0b00100001; >>>>>>>> >>>>>>>> // A 16-bit 'short' literal. >>>>>>>> short aShort = (short)0b1010000101000101; >>>>>>>> >>>>>>>> // Some 32-bit 'int' literals. >>>>>>>> int anInt1 = 0b10100001010001011010000101000101; >>>>>>>> int anInt2 = 0b101; >>>>>>>> int anInt3 = 0B101; // The B can be upper or lower >>>>>>> case as per the x in >>>>>>>> "0x45". >>>>>>>> >>>>>>>> // A 64-bit 'long' literal. Note the >>>>>>> "L" suffix, as would also be used >>>>>>>> // for a long in decimal, hexadecimal, or octal. >>>>>>>> long aLong = >>>>>>>> >>>>>>> 0b01010000101000101101000010100010110100001010001011010000101000101L >>>>>>> ; >>>>>>>> SIMPLE EXAMPLE: >>>>>>>> >>>>>>>> class Foo { >>>>>>>> public static void main(String[] args) { >>>>>>>> System.out.println("The value 10100001 in >>>>>>> decimal is " + 0b10100001); >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> ADVANCED EXAMPLE: >>>>>>>> >>>>>>>> // Binary constants could be used in code that needs >>>>>>> to be >>>>>>>> // easily checkable against a specifications document, >>>>>>> such >>>>>>>> // as this simulator for a hypothetical 8-bit >>>>>>> microprocessor: >>>>>>>> public State decodeInstruction(int instruction, State >>>>>>> state) { >>>>>>>> if ((instruction & 0b11100000) == 0b00000000) { >>>>>>>> final int register = instruction & >>>>>>> 0b00001111; >>>>>>>> switch (instruction & 0b11110000) { >>>>>>>> case 0b00000000: return state.nop(); >>>>>>>> case 0b00010000: return >>>>>>> state.copyAccumTo(register); >>>>>>>> case 0b00100000: return >>>>>>> state.addToAccum(register); >>>>>>>> case 0b00110000: return >>>>>>> state.subFromAccum(register); >>>>>>>> case 0b01000000: return >>>>>>> state.multiplyAccumBy(register); >>>>>>>> case 0b01010000: return >>>>>>> state.divideAccumBy(register); >>>>>>>> case 0b01100000: return >>>>>>> state.setAccumFrom(register); >>>>>>>> case 0b01110000: return >>>>>>> state.returnFromCall(); >>>>>>>> default: throw new IllegalArgumentException(); >>>>>>>> } >>>>>>>> } else { >>>>>>>> final int address = instruction & 0b00011111; >>>>>>>> switch (instruction & 0b11100000) { >>>>>>>> case 0b00100000: return state.jumpTo(address); >>>>>>>> case 0b01000000: return >>>>>>> state.jumpIfAccumZeroTo(address); >>>>>>>> case 0b01000000: return >>>>>>> state.jumpIfAccumNonzeroTo(address); >>>>>>>> case 0b01100000: return >>>>>>> state.setAccumFromMemory(address); >>>>>>>> case 0b10100000: return >>>>>>> state.writeAccumToMemory(address); >>>>>>>> case 0b11000000: return state.callTo(address); >>>>>>>> default: throw new IllegalArgumentException(); >>>>>>>> } >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> // Binary literals can be used to make a bitmap more >>>>>>> readable: >>>>>>>> public static final short[] HAPPY_FACE = { >>>>>>>> (short)0b0000011111100000; >>>>>>>> (short)0b0000100000010000; >>>>>>>> (short)0b0001000000001000; >>>>>>>> (short)0b0010000000000100; >>>>>>>> (short)0b0100000000000010; >>>>>>>> (short)0b1000011001100001; >>>>>>>> (short)0b1000011001100001; >>>>>>>> (short)0b1000000000000001; >>>>>>>> (short)0b1000000000000001; >>>>>>>> (short)0b1001000000001001; >>>>>>>> (short)0b1000100000010001; >>>>>>>> (short)0b0100011111100010; >>>>>>>> (short)0b0010000000000100; >>>>>>>> (short)0b0001000000001000; >>>>>>>> (short)0b0000100000010000; >>>>>>>> (short)0b0000011111100000; >>>>>>>> } >>>>>>>> >>>>>>>> // Binary literals can make relationships >>>>>>>> // among data more apparent than they would >>>>>>>> // be in hex or octal. >>>>>>>> // >>>>>>>> // For instance, what does the following >>>>>>>> // array contain? In hexadecimal, it's hard to >>>>>>> tell: >>>>>>>> public static final int[] PHASES = { >>>>>>>> 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >>>>>>>> } >>>>>>>> >>>>>>>> // In binary, it's obvious that a number is being >>>>>>>> // rotated left one bit at a time. >>>>>>>> public static final int[] PHASES = { >>>>>>>> 0b00110001, >>>>>>>> 0b01100010, >>>>>>>> 0b11000100, >>>>>>>> 0b10001001, >>>>>>>> 0b00010011, >>>>>>>> 0b00100110, >>>>>>>> 0b01001100, >>>>>>>> 0b10011000, >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> DETAILS >>>>>>>> >>>>>>>> SPECIFICATION: >>>>>>>> >>>>>>>> Section 3.10.1 ("Integer Literals") of the >>>>>>> JLS3 should be changed to add the >>>>>>>> following: >>>>>>>> >>>>>>>> IntegerLiteral: >>>>>>>> DecimalIntegerLiteral >>>>>>>> HexIntegerLiteral >>>>>>>> OctalIntegerLiteral >>>>>>>> BinaryIntegerLiteral // Added >>>>>>>> >>>>>>>> BinaryIntegerLiteral: >>>>>>>> BinaryNumeral IntegerTypeSuffix_opt >>>>>>>> >>>>>>>> BinaryNumeral: >>>>>>>> 0 b BinaryDigits >>>>>>>> 0 B BinaryDigits >>>>>>>> >>>>>>>> BinaryDigits: >>>>>>>> BinaryDigit >>>>>>>> BinaryDigit BinaryDigits >>>>>>>> >>>>>>>> BinaryDigit: one of >>>>>>>> 0 1 >>>>>>>> >>>>>>>> COMPILATION: >>>>>>>> >>>>>>>> Binary literals would be compiled to class files in >>>>>>> the same fashion as >>>>>>>> existing decimal, hexadecimal, and octal literals are. >>>>>>> No special support or >>>>>>>> changes to the class file format are needed. >>>>>>>> >>>>>>>> TESTING: >>>>>>>> >>>>>>>> The feature can be tested in the same way as existing >>>>>>> decimal, hexadecimal, >>>>>>>> and octal literals are: Create a bunch of constants in >>>>>>> source code, including >>>>>>>> the maximum and minimum positive and negative values >>>>>>> for integer and long >>>>>>>> types, and verify them at runtime to have the correct >>>>>>> values. >>>>>>>> >>>>>>>> LIBRARY SUPPORT: >>>>>>>> >>>>>>>> The methods Integer.decode(String) and >>>>>>> Long.decode(String) should be modified >>>>>>>> to parse binary numbers (as specified above) in >>>>>>> addition to their existing >>>>>>>> support for decimal, hexadecimal, and octal numbers. >>>>>>>> >>>>>>>> >>>>>>>> REFLECTIVE APIS: >>>>>>>> >>>>>>>> No updates to the reflection APIs are needed. >>>>>>>> >>>>>>>> >>>>>>>> OTHER CHANGES: >>>>>>>> >>>>>>>> No other changes are needed. >>>>>>>> >>>>>>>> >>>>>>>> MIGRATION: >>>>>>>> >>>>>>>> Individual decimal, hexadecimal, or octal constants in >>>>>>> existing code can be >>>>>>>> updated to binary as a programmer desires. >>>>>>>> >>>>>>>> >>>>>>>> COMPATIBILITY >>>>>>>> >>>>>>>> >>>>>>>> BREAKING CHANGES: >>>>>>>> >>>>>>>> This feature would not break any existing programs, >>>>>>> since the suggested >>>>>>>> syntax is currently considerd to be a compile-time >>>>>>> error. >>>>>>>> >>>>>>>> EXISTING PROGRAMS: >>>>>>>> >>>>>>>> Class file format does not change, so existing >>>>>>> programs can use class files >>>>>>>> compiled with the new feature without problems. >>>>>>>> >>>>>>>> >>>>>>>> REFERENCES: >>>>>>>> >>>>>>>> The GCC/G++ compiler, which already supports this >>>>>>> syntax (as of version 4.3) >>>>>>>> as an extension to standard C/C++. >>>>>>>> http://gcc.gnu.org/gcc-4.3/changes.html >>>>>>>> >>>>>>>> The Ruby language, which supports binary literals: >>>>>>>> http://wordaligned.org/articles/binary-literals >>>>>>>> >>>>>>>> The Python language added binary literals in version >>>>>>> 2.6: >>>>>>> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >>>>>>>> EXISTING BUGS: >>>>>>>> >>>>>>>> "Language support for literal numbers in binary >>>>>>> and other bases" >>>>>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >>>>>>>> URL FOR PROTOTYPE (optional): >>>>>>>> >>>>>>>> None. >>>>>>>> >>>>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>> >>>> >>>> >>> >> >> > > From vapor1 at teleport.com Wed Mar 25 20:49:28 2009 From: vapor1 at teleport.com (Derek Foster) Date: Wed, 25 Mar 2009 23:49:28 -0400 (EDT) Subject: PROPOSAL: Binary Literals Message-ID: <4367307.1238039368144.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> In response to your questions about underscores... At least as they are used in Ruby, the programmer is allowed to put underscores wherever he/she wants to in a number as long as they are not at the front of it. Presumably, an underscore proposal for Java would allow the same flexibility. The underscores are intended to increase readability, rather than to provide automated error-checking. Thus, if you live in a country that puts commas every three digits in decimal numbers for clarity, you can do this: int tenBillion = 10_000_000_000; If you want to put underscores every eight digits, four digits, or three digits in your binary numbers, you can. You can even use them to separate bitfields of varying sizes within the same number: int bitmask1 = 0b000_00_111; int bitmask2 = 0b000_11_000; int bitmask3 = 0b111_00_000; int number = 0b101_01_010; or in hex numbers for that matter: int bitmask1 = 0x00_000_FFF; int bitmask2 = 0x00_FFF_000; int bitmask3 = 0xFF_000_000; int number = 0x13_254_232; Derek -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 25, 2009 5:40 PM >To: brucechapman at paradise.net.nz >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Binary Literals > >On Mar 25, 2009, at 22:02, brucechapman at paradise.net.nz wrote: > >> code extracts allows you to see most easily that bits 3,4 and 5 are >> being extracted? >> >> (b & 0b00011100) >> 2 >> >> (b & 0x1C) >> 2 >> > >Maybe it's my assembler days, but, seriously: > >The hexadecimal one. > >In your example above there's no real difference, they are equally >readable to me. But here are some other examples: > >0b10000000 vs. 0x80 >0b100000000 vs 0x100 >0b10000101 vs 0x85 > >No contest, hex wins hands down, with a big margin the first two >margins, and still a winner in the third case, because 5 zeroes >already become hard to count at a casual glance. The amount of digits >involved in writing out a mask in binary just overwhelms the senses; >your average human brain has a hard time processing more than 7 things >at once, which means even a simply byte is already too large. >Underscores would indeed help some, but what if I want to underscore >around a nibble? Is that allowed? But clearly an underscore after 9 >digits ought to give me a warning or error, or the underscores are >only going to make mistakes permanent. Should they mandatory? If not, >trying to decade 0x100 written as a binary literal is still going to >be very painful. > >To summarize: A bitmask might marginally be more readable in rare >cases, especially to the casual programmer who doesn't have much >experience with bit-level trickery, which is small comfort, because >bitmasking comes up very rarely in java code in the first place. In >most other situations, binary literals are much worse compared to hex >literals. > >Sign me up for bruce's 0h notation to get around the need to cast-to- >byte for 0x80 and up. That would serve all my bitmasking needs. > > -- Reinier Zwitserloot > > From develop4lasu at gmail.com Wed Mar 25 23:22:04 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 07:22:04 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: References: Message-ID: <28bca0ff0903252322h5fb1c648v5dd5a0fdcaf7c792@mail.gmail.com> All these can be done by libraries (to do not mess in language), you just need to make result static if you need for it to work fast. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From matthias at mernst.org Thu Mar 26 00:29:49 2009 From: matthias at mernst.org (Matthias Ernst) Date: Thu, 26 Mar 2009 08:29:49 +0100 Subject: PROPOSAL: Binary Literals In-Reply-To: <358A6A10-9BF3-4FFB-91B3-36C6B5D2EA1E@zwitserloot.com> References: <25919435.1238009719923.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> <49CAAD65.3070409@joda.org> <358A6A10-9BF3-4FFB-91B3-36C6B5D2EA1E@zwitserloot.com> Message-ID: <22ec15240903260029i567c8e7ay7bbad0a2c19edcf2@mail.gmail.com> On Thu, Mar 26, 2009 at 12:47 AM, Reinier Zwitserloot wrote: > Good points. Another useful method: > > public class Byte { > ? ? public static byte withBitsSet(int... positions); > ? ? public static byte withBitsCleared(int... positions); > ? ? public static byte of(String bitString); > } > > where setBits starts with 0 and then turns on the bit at each listed > position, and clearBits starts with -1 and turns off the bit at each > listed position. > > 0x1C can then be implemented as: > > Byte.withBitsSet(4, 3, 2); > Byte.withBitsCleared(7, 6, 5, 1, 0); > Byte.of("00011100"); JDK 7's BitSet will allow this: new BitSet().set(2, 4).toByteArray()[0]; I believe this proposal could be turned into a new BitSet.valueOf(String) method with higher chances of acceptance? > That WOULD be a useful library addition. Not only are they almost as > short as the proposed byte literal, anybody that doesn't have the > first clue about bit masking can at least find some javadoc this way > and learn. They would be awfully slow compared to a literal, but > presumably any literal needs to be calculated only once, so any > slowness in the methods should never have a measurable impact. It's a > shame the JVM can't memoize, though. > > > > ?--Reinier Zwitserloot > > > > On Mar 25, 2009, at 23:17, Stephen Colebourne wrote: > >>> A couple of quick notes: >>> >>> 1) Ruby already has this. (The underscores in numbers, that is) >> >> So, does Fan. Yes, someone should write up underscores in numbers as a >> separate proposal. It won't be me. >> >> >>> Of all low impact coin submissions, this just isn't very compelling. >>> Real Programmers can count in hexadecimal ever since they were A >>> years >>> old, after all. >> >> Actually, my experience suggests that lots can't count in hex - we >> have >> calculators and the internet we that kind of thing these days. >> >> There are definitely use cases for this too, but they occur relatively >> rarely. For example, I once encoded the 30 year repeating pattern of >> leap years in the Islamic calendar system as a binary. This was a mess >> to write: >> >> Years to encode: 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 & 29 >> >> Final int value: 623191204 >> >> Binary literal: 0b00010010_10010010_10010010_01010010 >> >> It is also beneficial in teaching. >> >> But the truth is it will always be low priority (mind you, I'd have >> placed it higher than hexadecimal floating point literals...) >> >> Stephen >> >> >> >> >> Reinier Zwitserloot wrote: >>> Of all low impact coin submissions, this just isn't very compelling. >>> Real Programmers can count in hexadecimal ever since they were A >>> years >>> old, after all. >>> >>> ?--Reinier Zwitserloot >>> >>> >>> >>> On Mar 25, 2009, at 20:35, Gaseous Fumes wrote: >>> >>>> A couple of quick notes: >>>> >>>> 1) Ruby already has this. (The underscores in numbers, that is) >>>> >>>> 2) I considered adding this to the proposal as I was writing it, but >>>> decided it was an orthogonal issue and deserved its own proposal, >>>> since it has nothing per se to do with binary literals. (As James >>>> mentions, it would make sense for all numbers, not just binary >>>> ones.) >>>> >>>> 3) I encourage someone else to write it up as a proposal. If I get >>>> done with the other proposals I intend to submit, and still have >>>> time, I might do it myself, but if you want to ensure that the >>>> proposal gets proposed, I suggest you don't wait for me. One caveat: >>>> Consider the impact on Integer.parseInt, Long.decode(), etc. (I >>>> suggest the decode methods get changed to accept underscores, but >>>> the parseInt ones don't.) >>>> >>>> 4) An observation to Joe Darcy and the other Sun engineers involved >>>> in reviewing proposals: The expected "about five" limit on proposals >>>> really encourages people to lump a bunch of semi-related things into >>>> one proposal rather than making each their own proposal, even when >>>> the latter would be a more logical way of getting individual >>>> orthogonal ideas reviewed separately. I think this is a problem. >>>> >>>> For instance, the "null safe operators" proposal (all or nothing) >>>> vs. splitting each of them out as individual proposals. There have >>>> been a number of proposals put forth where I thought "I agree with >>>> half of this proposal and wish the other half wasn't in the same >>>> proposal." >>>> >>>> I hope that the "about" in "about five" is flexible enough to allow >>>> a bunch of very minor proposals to expand that limit well past five >>>> if they seem good ideas and easy to implement with few >>>> repercussions. Five seems like a pretty low number to me, given that >>>> it's been MANY years since it was even possible for users to suggest >>>> changes to Java (basically, since JDK 5 was in the planning stages, >>>> as JDK 6 was announced to be a "no language changes" release), and >>>> there has been much evolution in other programming languages during >>>> that time. I think that good ideas should make it into Java (and bad >>>> ideas shouldn't) subject to the necessary manpower in review and >>>> implementation, regardless of the number of proposals used to submit >>>> them. Otherwise, Java risks getting left in the dust as other >>>> languages become much easier to use, much faster. >>>> >>>> Derek >>>> >>>> -----Original Message----- >>>>> From: james lowden >>>>> Sent: Mar 25, 2009 12:07 PM >>>>> To: coin-dev at openjdk.java.net >>>>> Subject: Re: PROPOSAL: Binary Literals >>>>> >>>>> >>>>> Actually, that's a good idea in general for long numeric >>>>> constants. ?9_000_000_000_000_000L is easier to parse than >>>>> 9000000000000000L. >>>>> >>>>> >>>>> --- On Wed, 3/25/09, Stephen Colebourne >>>>> wrote: >>>>> >>>>>> From: Stephen Colebourne >>>>>> Subject: Re: PROPOSAL: Binary Literals >>>>>> To: coin-dev at openjdk.java.net >>>>>> Date: Wednesday, March 25, 2009, 1:50 PM >>>>>> See >>>>>> http://www.jroller.com/scolebourne/entry/changing_java_adding_simpler_primitive >>>>>> for my take on this from long ago. >>>>>> >>>>>> In particular, I'd suggest allowing a character to >>>>>> separate long binary strings: >>>>>> >>>>>> int anInt1 = 0b10100001_01000101_10100001_01000101; >>>>>> >>>>>> much more readable. >>>>>> >>>>>> Stephen >>>>>> >>>>>> 2009/3/25 Derek Foster : >>>>>>> Hmm. Second try at sending to the list. Let's see >>>>>> if this works. (In the >>>>>>> meantime, I noticed that Bruce Chapman has mentioned >>>>>> something similar in his >>>>>>> another proposal, so I think we are in agreement on >>>>>> this. This proposal >>>>>>> should not be taken as to compete with his similar >>>>>> proposal: I'd quite like >>>>>>> to see type suffixes for bytes, shorts, etc. added to >>>>>> Java, in addition to >>>>>>> binary literals.) Anyway... >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> Add binary literals to Java. >>>>>>> >>>>>>> AUTHOR(S): Derek Foster >>>>>>> >>>>>>> OVERVIEW >>>>>>> >>>>>>> In some programming domains, use of binary numbers >>>>>> (typically as bitmasks, >>>>>>> bit-shifts, etc.) is very common. However, Java code, >>>>>> due to its C heritage, >>>>>>> has traditionally forced programmers to represent >>>>>> numbers in only decimal, >>>>>>> octal, or hexadecimal. (In practice, octal is rarely >>>>>> used, and is present >>>>>>> mostly for backwards compatibility with C) >>>>>>> >>>>>>> When the data being dealt with is fundamentally >>>>>> bit-oriented, however, using >>>>>>> hexadecimal to represent ranges of bits requires an >>>>>> extra degree of >>>>>>> translation for the programmer, and this can often >>>>>> become a source of errors. >>>>>>> For instance, if a technical specification lists >>>>>> specific values of interest >>>>>>> in binary (for example, in a compression encoding >>>>>> algorithm or in the >>>>>>> specifications for a network protocol, or for >>>>>> communicating with a bitmapped >>>>>>> hardware device) then a programmer coding to that >>>>>> specification must >>>>>>> translate each such value from its binary >>>>>> representation into hexadecimal. >>>>>>> Checking to see if this translation has been done >>>>>> correctly is accomplished >>>>>>> by back-translating the numbers. In most cases, >>>>>> programmers do these >>>>>>> translations in their heads, and HOPEFULLY get them >>>>>> right. however, errors >>>>>>> can easily creep in, and re-verifying the results is >>>>>> not straightforward >>>>>>> enough to be done frequently. >>>>>>> >>>>>>> Furthermore, in many cases, the binary representations >>>>>> of numbers makes it >>>>>>> much more clear what is actually intended than the >>>>>> hexadecimal one. For >>>>>>> instance, this: >>>>>>> >>>>>>> private static final int BITMASK = 0x1E; >>>>>>> >>>>>>> does not immediately make it clear that the bitmask >>>>>> being declared comprises >>>>>>> a single contiguous range of four bits. >>>>>>> >>>>>>> In many cases, it would be more natural for the >>>>>> programmer to be able to >>>>>>> write the numbers in binary in the source code, >>>>>> eliminating the need for >>>>>>> manual translation to hexadecimal entirely. >>>>>>> >>>>>>> >>>>>>> FEATURE SUMMARY: >>>>>>> >>>>>>> In addition to the existing "1" (decimal), >>>>>> "01" (octal) and "0x1" >>>>>>> (hexadecimal) form of specifying numeric literals, a >>>>>> new form "0b1" (binary) >>>>>>> would be added. >>>>>>> >>>>>>> Note that this is the same syntax as has been used as >>>>>> an extension by the GCC >>>>>>> C/C++ compilers for many years, and also is used in >>>>>> the Ruby language, as >>>>>>> well as in the Python language. >>>>>>> >>>>>>> >>>>>>> MAJOR ADVANTAGE: >>>>>>> >>>>>>> It is no longer necessary for programmers to translate >>>>>> binary numbers to and >>>>>>> from hexadecimal in order to use them in Java >>>>>> programs. >>>>>>> >>>>>>> MAJOR BENEFIT: >>>>>>> >>>>>>> Code using bitwise operations is more readable and >>>>>> easier to verify against >>>>>>> technical specifications that use binary numbers to >>>>>> specify constants. >>>>>>> Routines that are bit-oriented are easier to >>>>>> understand when an artifical >>>>>>> translation to hexadecimal is not required in order to >>>>>> fulfill the >>>>>>> constraints of the language. >>>>>>> >>>>>>> MAJOR DISADVANTAGE: >>>>>>> >>>>>>> Someone might incorrectly think that "0b1" >>>>>> represented the same value as >>>>>>> hexadecimal number "0xB1". However, note >>>>>> that this problem has existed for >>>>>>> octal/decimal for many years (confusion between >>>>>> "050" and "50") and does not >>>>>>> seem to be a major issue. >>>>>>> >>>>>>> >>>>>>> ALTERNATIVES: >>>>>>> >>>>>>> Users could continue to write the numbers as decimal, >>>>>> octal, or hexadecimal, >>>>>>> and would continue to have the problems observed in >>>>>> this document. >>>>>>> Another alternative would be for code to translate at >>>>>> runtime from binary >>>>>>> strings, such as: >>>>>>> >>>>>>> ?int BITMASK = >>>>>> Integer.parseInt("00001110", 2); >>>>>>> Besides the obvious extra verbosity, there are several >>>>>> problems with this: >>>>>>> * Calling a method such as Integer.parseInt at runtime >>>>>> will typically make it >>>>>>> impossible for the compiler to inline the value of >>>>>> this constant, since its >>>>>>> value has been taken from a runtime method call. >>>>>> Inlining is important, >>>>>>> because code that does bitwise parsing is often very >>>>>> low-level code in tight >>>>>>> loops that must execute quickly. (This is particularly >>>>>> the case for mobile >>>>>>> applications and other applications that run on >>>>>> severely resource-constrained >>>>>>> environments, which is one of the cases where binary >>>>>> numbers would be most >>>>>>> valuable, since talking to low-level hardware is one >>>>>> of the primary use cases >>>>>>> for this feature.) >>>>>>> >>>>>>> * Constants such as the above cannot be used as >>>>>> selectors in 'switch' >>>>>>> statements. >>>>>>> >>>>>>> * Any errors in the string to be parsed (for instance, >>>>>> an extra space) will >>>>>>> result in runtime exceptions, rather than compile-time >>>>>> errors as would have >>>>>>> occurred in normal parsing. If such a value is >>>>>> declared 'static', this will >>>>>>> result in some very ugly exceptions at runtime. >>>>>>> >>>>>>> >>>>>>> EXAMPLES: >>>>>>> >>>>>>> // An 8-bit 'byte' literal. >>>>>>> byte aByte = (byte)0b00100001; >>>>>>> >>>>>>> // A 16-bit 'short' literal. >>>>>>> short aShort = (short)0b1010000101000101; >>>>>>> >>>>>>> // Some 32-bit 'int' literals. >>>>>>> int anInt1 = 0b10100001010001011010000101000101; >>>>>>> int anInt2 = 0b101; >>>>>>> int anInt3 = 0B101; // The B can be upper or lower >>>>>> case as per the x in >>>>>>> "0x45". >>>>>>> >>>>>>> // A 64-bit 'long' literal. Note the >>>>>> "L" suffix, as would also be used >>>>>>> // for a long in decimal, hexadecimal, or octal. >>>>>>> long aLong = >>>>>>> >>>>>> 0b01010000101000101101000010100010110100001010001011010000101000101L >>>>>> ; >>>>>>> SIMPLE EXAMPLE: >>>>>>> >>>>>>> class Foo { >>>>>>> public static void main(String[] args) { >>>>>>> System.out.println("The value 10100001 in >>>>>> decimal is " + 0b10100001); >>>>>>> } >>>>>>> >>>>>>> >>>>>>> ADVANCED EXAMPLE: >>>>>>> >>>>>>> // Binary constants could be used in code that needs >>>>>> to be >>>>>>> // easily checkable against a specifications document, >>>>>> such >>>>>>> // as this simulator for a hypothetical 8-bit >>>>>> microprocessor: >>>>>>> public State decodeInstruction(int instruction, State >>>>>> state) { >>>>>>> if ((instruction & 0b11100000) == 0b00000000) { >>>>>>> ? final int register = instruction & >>>>>> 0b00001111; >>>>>>> ? switch (instruction & 0b11110000) { >>>>>>> ? ? case 0b00000000: return state.nop(); >>>>>>> ? ? case 0b00010000: return >>>>>> state.copyAccumTo(register); >>>>>>> ? ? case 0b00100000: return >>>>>> state.addToAccum(register); >>>>>>> ? ? case 0b00110000: return >>>>>> state.subFromAccum(register); >>>>>>> ? ? case 0b01000000: return >>>>>> state.multiplyAccumBy(register); >>>>>>> ? ? case 0b01010000: return >>>>>> state.divideAccumBy(register); >>>>>>> ? ? case 0b01100000: return >>>>>> state.setAccumFrom(register); >>>>>>> ? ? case 0b01110000: return >>>>>> state.returnFromCall(); >>>>>>> ? ? default: throw new IllegalArgumentException(); >>>>>>> ? } >>>>>>> } else { >>>>>>> ? final int address = instruction & 0b00011111; >>>>>>> ? switch (instruction & 0b11100000) { >>>>>>> ? ? case 0b00100000: return state.jumpTo(address); >>>>>>> ? ? case 0b01000000: return >>>>>> state.jumpIfAccumZeroTo(address); >>>>>>> ? ? case 0b01000000: return >>>>>> state.jumpIfAccumNonzeroTo(address); >>>>>>> ? ? case 0b01100000: return >>>>>> state.setAccumFromMemory(address); >>>>>>> ? ? case 0b10100000: return >>>>>> state.writeAccumToMemory(address); >>>>>>> ? ? case 0b11000000: return state.callTo(address); >>>>>>> ? ? default: throw new IllegalArgumentException(); >>>>>>> ? } >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> // Binary literals can be used to make a bitmap more >>>>>> readable: >>>>>>> public static final short[] HAPPY_FACE = { >>>>>>> ?(short)0b0000011111100000; >>>>>>> ?(short)0b0000100000010000; >>>>>>> ?(short)0b0001000000001000; >>>>>>> ?(short)0b0010000000000100; >>>>>>> ?(short)0b0100000000000010; >>>>>>> ?(short)0b1000011001100001; >>>>>>> ?(short)0b1000011001100001; >>>>>>> ?(short)0b1000000000000001; >>>>>>> ?(short)0b1000000000000001; >>>>>>> ?(short)0b1001000000001001; >>>>>>> ?(short)0b1000100000010001; >>>>>>> ?(short)0b0100011111100010; >>>>>>> ?(short)0b0010000000000100; >>>>>>> ?(short)0b0001000000001000; >>>>>>> ?(short)0b0000100000010000; >>>>>>> ?(short)0b0000011111100000; >>>>>>> } >>>>>>> >>>>>>> // Binary literals can make relationships >>>>>>> // among data more apparent than they would >>>>>>> // be in hex or octal. >>>>>>> // >>>>>>> // For instance, what does the following >>>>>>> // array contain? In hexadecimal, it's hard to >>>>>> tell: >>>>>>> public static final int[] PHASES = { >>>>>>> ? 0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98 >>>>>>> } >>>>>>> >>>>>>> // In binary, it's obvious that a number is being >>>>>>> // rotated left one bit at a time. >>>>>>> public static final int[] PHASES = { >>>>>>> ? 0b00110001, >>>>>>> ? 0b01100010, >>>>>>> ? 0b11000100, >>>>>>> ? 0b10001001, >>>>>>> ? 0b00010011, >>>>>>> ? 0b00100110, >>>>>>> ? 0b01001100, >>>>>>> ? 0b10011000, >>>>>>> } >>>>>>> >>>>>>> >>>>>>> DETAILS >>>>>>> >>>>>>> SPECIFICATION: >>>>>>> >>>>>>> Section 3.10.1 ("Integer Literals") of the >>>>>> JLS3 should be changed to add the >>>>>>> following: >>>>>>> >>>>>>> IntegerLiteral: >>>>>>> ? ? ? DecimalIntegerLiteral >>>>>>> ? ? ? HexIntegerLiteral >>>>>>> ? ? ? OctalIntegerLiteral >>>>>>> ? ? ? BinaryIntegerLiteral ? ? ? ? // Added >>>>>>> >>>>>>> BinaryIntegerLiteral: >>>>>>> ? ? ? BinaryNumeral IntegerTypeSuffix_opt >>>>>>> >>>>>>> BinaryNumeral: >>>>>>> ? ? ? 0 b BinaryDigits >>>>>>> ? ? ? 0 B BinaryDigits >>>>>>> >>>>>>> BinaryDigits: >>>>>>> ? ? ? BinaryDigit >>>>>>> ? ? ? BinaryDigit BinaryDigits >>>>>>> >>>>>>> BinaryDigit: one of >>>>>>> ? ? ? 0 1 >>>>>>> >>>>>>> COMPILATION: >>>>>>> >>>>>>> Binary literals would be compiled to class files in >>>>>> the same fashion as >>>>>>> existing decimal, hexadecimal, and octal literals are. >>>>>> No special support or >>>>>>> changes to the class file format are needed. >>>>>>> >>>>>>> TESTING: >>>>>>> >>>>>>> The feature can be tested in the same way as existing >>>>>> decimal, hexadecimal, >>>>>>> and octal literals are: Create a bunch of constants in >>>>>> source code, including >>>>>>> the maximum and minimum positive and negative values >>>>>> for integer and long >>>>>>> types, and verify them at runtime to have the correct >>>>>> values. >>>>>>> >>>>>>> LIBRARY SUPPORT: >>>>>>> >>>>>>> The methods Integer.decode(String) and >>>>>> Long.decode(String) should be modified >>>>>>> to parse binary numbers (as specified above) in >>>>>> addition to their existing >>>>>>> support for decimal, hexadecimal, and octal numbers. >>>>>>> >>>>>>> >>>>>>> REFLECTIVE APIS: >>>>>>> >>>>>>> No updates to the reflection APIs are needed. >>>>>>> >>>>>>> >>>>>>> OTHER CHANGES: >>>>>>> >>>>>>> No other changes are needed. >>>>>>> >>>>>>> >>>>>>> MIGRATION: >>>>>>> >>>>>>> Individual decimal, hexadecimal, or octal constants in >>>>>> existing code can be >>>>>>> updated to binary as a programmer desires. >>>>>>> >>>>>>> >>>>>>> COMPATIBILITY >>>>>>> >>>>>>> >>>>>>> BREAKING CHANGES: >>>>>>> >>>>>>> This feature would not break any existing programs, >>>>>> since the suggested >>>>>>> syntax is currently considerd to be a compile-time >>>>>> error. >>>>>>> >>>>>>> EXISTING PROGRAMS: >>>>>>> >>>>>>> Class file format does not change, so existing >>>>>> programs can use class files >>>>>>> compiled with the new feature without problems. >>>>>>> >>>>>>> >>>>>>> REFERENCES: >>>>>>> >>>>>>> The GCC/G++ compiler, which already supports this >>>>>> syntax (as of version 4.3) >>>>>>> as an extension to standard C/C++. >>>>>>> http://gcc.gnu.org/gcc-4.3/changes.html >>>>>>> >>>>>>> The Ruby language, which supports binary literals: >>>>>>> http://wordaligned.org/articles/binary-literals >>>>>>> >>>>>>> The Python language added binary literals in version >>>>>> 2.6: >>>>>> http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax >>>>>>> EXISTING BUGS: >>>>>>> >>>>>>> "Language support for literal numbers in binary >>>>>> and other bases" >>>>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025288 >>>>>>> URL FOR PROTOTYPE (optional): >>>>>>> >>>>>>> None. >>>>>>> >>>>>>> >>>>> >>>>> >>>>> >>>> >>> >>> >>> >> > > > From vapor1 at teleport.com Thu Mar 26 00:42:38 2009 From: vapor1 at teleport.com (Derek Foster) Date: Thu, 26 Mar 2009 03:42:38 -0400 (EDT) Subject: PROPOSAL: Binary Literals Message-ID: <29224563.1238053358970.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Comments inline. -----Original Message----- >From: Reinier Zwitserloot >Sent: Mar 25, 2009 11:46 PM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Binary Literals > >In regards to j2me: j2me is on its way out, and will not be receiving >many updates regardless, because sun can't exactly update the java >version on the billions of phones out there. You seem to be under the impression that j2me is solely for phones. It is actually for "embedded systems" and "mobile devices" of which phones are only an important subset. A device like a Kindle, or a PalmPilot, or an iPod Touch, or even headless devices like the JavaRing or various kinds of network appliances could conceivably use J2ME. Note that phones get replaced every few years on average as people upgrade for better features or change service providers, so the fact that Sun can't update the existing ones is pretty much irrelevant. In any case, I am not currently using J2ME. I just mentioned it because it has similar constraints to the sort of programming I have been dealing with recently: a system which allowed hundreds of tiny Java programs to be compiled to native code to run together on a single massively parallel processor chip with hundreds of cores, each of which has only a tiny amount of memory. Oddly enough, that kind of severely resource-constrained environment is far more similar to writing a J2ME app to run on a cell phone than it is to writing an app to run on a webserver, and a lot of the same techniques and concerns apply. >On performance: I don't understand. The result of a library call is a >byte primitive, which you can then assign to a private static final >byte constant. From there on out, that will be as fast as a code >literal. Unless you were planning on using a few million binary >literals in your code, there shouldn't be a performance impact; just >an annoyance that you have to constantize every literal you use in a >time sensitive area instead of using Byte.of("01000100") directly in >your method body. 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: private static const final int FOO = 0x42; private static const final int BAR = FOO + 3; private static const final int BAZ = 0x46; private int func(int x) { return x * (BAZ - BAR); } as if it had been written like this: int func() { return x; } Note that there is now no need to even allocate space to hold FOO, BAR, and BAZ, since all references to them were removed as part of the constant folding process. However, if I had instead declared the variable FOO as: static const final int FOO = Integer.decode("0x42"); then the compiler cannot determine its value at compile time, and must generate code to actually call the parseInt function at static initialization time and stow its result in the FOO variable, then calculate BAR, and so forth, eventually compiling the 'func' function as written, with an unnecessary and time-consuming multiply operation in it. The situation gets even more complex when constant folding is combined with method inlining, so that entire methods which perform bitwise or other operations may be simplified to omit certain operations in some call sites but not others depending on what arguments are passed and whether or not some of those can be determined to be compile-time-constant expressions. In general, these kinds of optimizations can't be done for expressions involving a call to a library method, because the compiler does not know at compile time what value that method will return when it is executed. I suggest some research into the justifications given for why the hexadecimal notation for floating point numbers was added to the language (despite its ugliness and the limited domain in which it is used), and why libraries were not judged an adequate solution in that case. Basically the same arguments apply here. >The odds that "0b01000100", where you've added a zero too many (or >left one out) is going to result in a compile time error seems odd. >Why would that cause a compile time error, exactly? for the same reason that this: byte x = 900000000000; is a compile-time error. The compiler checks the numeric ranges at compile time, and knows that the value declared won't fit into a byte. It won't detect leading zeroes, of course. >Evidently that wasn't clear, but my reference to "real programmers >think in hex since they are A years old" was intended as a joke. I >apologize if that wasn't obvious. I took it as a joke, although I started to wonder after later postings of yours seemed basically to be arguing from that perspective. For the record, my comments about front panel switches to program core memory were also a joke. (Real Programmers actually program core memory by reaching into it with a magnet.) >How many bits are set in 0x4EC6? 8. I was able to count that about as >quickly as with 0b0100111011000110. Shame we didn't bet on it. Even if you personally can genuinely do it that fast, I very much doubt that most Java programmers can. >Quick: How many nibbles are in 0b0100111011000110? How many bits are >set in the upper byte? This example only illustrates that a program that needed to answer questions like that would probably best written to use hexadecimal notation. My point was not that hexadecimal notation should be removed from the language or deprecated in some way -- just that some problems are better understood in binary, and it would be useful to have binary notation available for use on those problems. >There are a select few questions that are just easier when written out >in binary, even if that results in a massive amount of digits, such as >finding contiguous sequences of bits (the packing into nibbles gets in >the way for that kind of thing). Which is why I said that >Byte.of("01000100") is a good idea. That method basically already exists (Byte.parseByte("01000100", 2)), and I use it in code where appropriate. However, my prior comments about library methods still apply. Besides the issues I mentioned before about disabling the compiler's support for constant folding, note that the compiler also won't issue any warnings or errors at compile time for any of the following: Byte.parseByte("0100100 ", 2); Byte.parseByte("010O100", 2); Byte.parseByte("0101l00", 2); Byte.parseByte("Slartibartfast", 2); Byte.parseByte("010010001001001001010", 2); It will therefore be left up to unit tests (assuming someone has time to write them, and when executed, they cover the particular code path in question) to find problems like these. This is a Bad Thing. Finding problems at compile time is much more reliable than finding them at runtime. >The theory of 'those who don't care can just ignore it' has a >fundamental flaw: It leads to readable-only-by-author code. Grab some >perl example code and try to ascertain what it's trying to do. I wish >you good luck! You appear to be assuming that people will choose to use this new feature primarily in ways that will be abusive and will decrease the readability of code, rather than choosing to use it in the places where it makes code clearer, and using hex, decimal, or octal in the cases where those make code clearer. I don't understand why you hold this belief. Yes, people can choose to be malicious or stupid in their coding, but most programmers won't be. If that argument were truly persuasive, then we should remove (or should never have added) most of the other existing features from Java as well, as well as pretty much everything currently being discussed in Project Coin, on the grounds that a malicious or incompetent programmer could use them to write horrible code. I've seen things done with nothing more than 'if' statements and 'for' loops that would turn your stomach, but I don't consider that a good reason to remove these features from the language. I just consider them a good reason to remove the programmer that wrote such atrocities from my project, or remove myself from the company that hires such incompetent programmers. A bad programmer will write horrible code no matter what language features are available. Lack of language features can't prevent that. However, language features can enable good programmers to write better code, and can even encourage (although not force) average programmers to do so. Most programmers want to be able to code in a way that clearly expresses the intent of their design. Putting barriers in their way to that goal does not appear to me to be a good idea, since if they are not allowed to do things in an easy, straightforward way, they will be forced to choose between a variety of less-than-optimal alternatives. Consider that if the language does not support binary literals, and someone wants to get the effect of using them anyway, that the most likely approach (in my experience, anyway, having looked at a lot of people's code) is to write their own custom binary-to-integer translator, and call it all over the place. (I've seen this done before.) Do you think this makes the code easier to read? I don't. >Optimally speaking, every language feature is at least somewhat >familiar to every programmer of that language. Java is a few steps >beyond that already (see the Java Puzzlers for proof), but that >doesn't mean we should no longer care about that tenet anymore. Such a >feature should introduce extremely significant improvements in a niche >area, and/or allow you to things that you just can't do now. This >clearly isn't the case. I think there is actually quite a bit of disagreement about what exactly the criteria should be for what features are included, and whether the ones you list are the only ones applicable. In any case, I don't see how this feature satisfies your criteria any less than, for instance, enhanced for loops, static import, or boxing. It's trivially easy to use, and explaining it to a new programmer takes all of two seconds ("binary constants look like 0b000101"), in contrast to having to explain, say, the Iterable interface or how "int x = y;" might now trigger a NullPointerException. I spend significant time programming in a niche that you apparently don't (based on your statement that bitmasks are "seldomly used" which has not been my experience at all in the Java programming domains where I have been spending time for the last few years). This feature would be a significant benefit to me. I would not have bothered to write up a proposal for this feature, and spend time researching that proposal as well as I have, if the lack of this feature was not a significant and frequent irritation to me. >Speaking of 'things that you just can't do now', for bit wrangling and >performance, I'd love to see a Math.* library that foregoes exact spec >precision and trades it for raw speed. Right now java Math.* can't use >the gfx pipelines because those don't use quite the same floating >point spec that java docs say they should. Just to give an example of >a change that I would wholeheartedly support even if it is extremely >niche. That's a change that would affect me basically not at all (I almost never even find myself using floating point in Java, at least for on-the-job programming, and in the circumstances where I do use floating point, I am much more concerned with accuracy than speed), but I wouldn't oppose such a change. While it's not my programming niche, it is somebody else's, and we are both consumers of the Java platform and it needs to meet multiple users' needs. Derek > --Reinier Zwitserloot > >On Mar 26, 2009, at 03:55, Derek Foster wrote: > >> I am all for the addition of library methods to handle bit/byte/word/ >> whatever munging. I plan to submit proposals for a few myself once >> the opportunity arises. >> >> However, library methods only cover a small subset of the use cases >> my proposal was intended to address. In my proposal, I specifically >> discussed the use of a library method and explained why it was not >> an acceptable substitute. I pointed out the performance impact of >> library calls, and noted that in the cases where low-level >> programming is most needed (in severely resource-constrained >> devices, J2ME, and so forth) that having library calls all over the >> place just to translate numbers from a readable form poses an >> unacceptable overhead in terms of performance, code size, and >> maintainability, not to mention the fact that bugs end up appearing >> at runtime (if you happen to run the code in _just_ the right way) >> rather than at compile time. I also pointed out the impossibility of >> using 'switch' statements with such techniques. >> >> With regards to the issue of "real programmers think in hex", by the >> way, I should point out that I started writing assembly language >> programs starting in sixth grade, and that that was around thirty >> years ago. Apparently even though I've been doing both high-level >> (Java, etc.) and low-level (assembly and occasional hand-coded >> machine language) programming for most of my life, I'm not a 'real >> programmer' because I use decimal, hex, binary, and even on some >> rare occasions, octal in the circumstances where they seem >> appropriate, rather than sticking religiously to hex regardless of >> the circumstance. (This is ridiculous, of course: Real Programmers >> don't really use hex. They program core memory using front-panel >> switches, in binary. Or possibly using punched cards if they are >> feeling a need for luxury.) >> >> In my experience, *real* "Real Programmers" use the appropriate tool >> for the job they are doing at the moment. Hex is simply not the >> appropriate tool for all jobs. It's great to use when it is >> appropriate (like when data lines up nicely on four-bit boundaries, >> or when the specification you are working from states its important >> numbers in hex), but it is extremely inconvenient to use hex the >> situations where it's not appropriate. Having to translate back and >> forth between hex and binary all the time when what you really want >> to do are fundamental binary operations (which are easily and >> clearly expressed in binary, and easily checkable against the >> relevant specifications documents which specify them in binary), is >> a waste of time and a rich source of bugs. >> >> Quick: How many bits are set in the number 0x4EC6? >> >> If the number were written in binary, you would be able to answer it >> as fast as you can count to eight. I'll bet you can't do it half >> that fast when it's expressed in hex. >> >> Here's a few more to contemplate: >> >> >> How many contiguous bit ranges exist in the number 0x5FF99C? What >> are their starting offsets? >> >> What will be the result of XORing together 0x4DE6 and 0x3837? >> >> Will 0x8567124 and 0x7218DB, ANDed together, be nonzero? >> >> What's the index of the fifth-highest set bit in the number 0x4687? >> >> >> All of the above questions are easy and quick to answer in binary, >> but difficult and error-prone in hex. In fact, the most difficult >> part of answering them in hex isn't answering the problem -- it's >> translating the hex to binary so the problem can be solved! When I >> am doing code review, I don't want "difficult and error prone". I >> want simple, direct, and mapping as directly to the specification I >> am implementing as possible. >> >> For a recent job, I had to deal with writing a decompiler for a >> processor which had lots of bitfields that didn't fall on nice even >> nybble boundaries, but instead often straddled them and had strange >> widths (3 bits, 9 bits, etc.). Furthermore, there were often >> multiple noncontiguous ranges of bits that had to be merged into the >> same field. Using hex numbers for this kind of situation makes the >> code all but unreadable without close study, and basically required >> that the size of the code be doubled due to all the extra named >> hexadecimal constants (for shifting, bit masking, and so forth) plus >> the comments needed to explain what the heck the code was doing, >> since its structure no longer directly expressed the problem it was >> trying to solve as stated in the specification. In most cases, I >> ended up having to write the binary representations of the numbers >> as comments alongside the hex translations of them, and then >> manually check the two against each other, just so I could later a >> lso manually check the binary numbers in my comments against the >> printed specification. >> >> Then I wrote and ran unit tests and found that even though I had >> manually verified the translations, I had still made a mistake. (Not >> too bad considering that I was translating a couple of hundred >> numbers in my head). >> >> I have recently had the occasion to do programming for >> microcontrollers in GCC, and was able to use the binary literal >> support provided by that compiler. It was so easy to use, and made >> the code so much clearer, that I found myself wondering again why I >> have to give up this feature when I move to the supposedly more >> convenient Java language. >> >> Why should programmers have to waste their time translating between >> hex and binary, when this is trivial for a compiler to do, and is >> considered a common enough need that multiple programming languages >> already support it? >> >> The effort to support this in a Java compiler is tiny, it fits well >> with the rest of the language and is similar to features in other >> languages. It won't break any existing code, and it is easy for >> those who don't want to use it to ignore it. >> >> Derek From brucechapman at paradise.net.nz Thu Mar 26 00:53:33 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Thu, 26 Mar 2009 20:53:33 +1300 Subject: PROPOSAL: Compiletime information access In-Reply-To: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> Message-ID: <49CB347D.2030300@paradise.net.nz> I think the implementation of this could be far cleaner if the values you want were represented as static final fields not methods, which would make them compile time constants. This wouldn't work for exec() and getBindings() but those are probably better done using annotation processing. The strategy would then be that the compiler would contain a custom implementation of javax.lang.model.TypeElement representing only this class. When the compile time constants were being resolved during compilation, this customer TypeElement with Custom VariableElements would be called by the compiler to get the constant value, the VariableElement could (with only a little magic) return the appropriate value for the site where the compile time constant was being copied to. The only concern would be that the compile time constants would have non constant values which varied depending on where they were referenced from. I suspect this might be a small compiler change, the question would then be whether the utility of such a mechanism carried enough benefit to counteract the rather strange behaviour of this particular class. It will be interesting to see what other think. Bruce rssh at gradsoft.com.ua wrote: > AUTHOR: Ruslan Shevchenko > > OVERVIEW: > > FEATURE SUMMARY: > > Add API to access compile-time context of current compiled element from > programs and annotation processors. > > MAJOR ADVANTAGE: > > Now compile time properties are unaccessible for programmer. This meaning > that some functionality (such as access to location of file and line) is > accessible only from debug version of program with technique, which is not > officially supported, some (such as access to time of compilation or > to binding context of current program location) is not avaible at all. > > MAJOR DISADVANTAGE > > Inaccurate usage of this feature can cause producing of unmaintable code. > > ALTERNATIVES: > > External preprocessing of java sources. > > EXAMPLES > > SIMPLE EXAMPLE: > > Example 1 > > if (traceCondigion) { > log.trace(Compiletime.getFileName()+":"+ > Compiletime.getLineNumber()); > } > > Example 2 > > if (system.currentTimeMillis() - Compiletime.getTimeMillis() > 86400) { > System.out.println("This file was compiled more than day ago"); > } > > Example 3 > > System.out.println("Superprogram by AAA AC, version:"+ > Compiletime.exec("svnversion")); > > ADVANCED EXAMPLE: > > Example 1 > // assuming that multiline strings are implemented: > > int a=0; > int b=1; > Binding bindings = Compiletime.getInstance().getCurrentBindings(); > ScriptEngine velocity = ScriptEngineManager.get("velocity"); > try { > String fname = Compiletime.getFileName(); > int line = Compiletime.getLineNumber(); > String s = velocity.eval(""" > #if ($a==$b) > Something interesting here may be, > Are you know that value of b is $b ? > #else > no mistics here. > #end > """, > bindings); > } catch (ScriptException ex){ > Sytem.err.println("error in inline velocity in "+fname+", " > "line "+line+1+ex.getLineNumber()); > } > > > Example 2 > > boolean isDemo = (Compiletime.eval(Properties.class, > "getProperty","is.demo")!=null); > > if (!isDemo) { > String key = (String)Compiletime.eval(GenerateUniqueKey.class, > "generate"); > LoadNotDemoClass(); > } > > > DETAILS: > > > > Add to Java Library pseudo-objects java.lang.Compiletime with access to > compile-time properties and next signature: > > public class Compiletime > { > /** > * get filename of compiled call. > * in case of generated source and avaible JSR-45 SMAP file > * return file name of translated-source. > **/ > public static String getFileName(); > > /** > * get line number of compiled call. > * in case of generated source and avaible JSR-45 SMAP file > * return line number in translated-source. > **/ > public static int getLineNumber(); > > /** > * get class name where this call is placed. > * in case of generated source and avaible JSR-45 SMAP file > * return class name in translated-source. > **/ > public static int getClassName(); > > /** > * get method name where this call is placed. > * in case of generated source and avaible JSR-45 SMAP file > * return method name in translated-source. > **/ > public static int getMethodName(); > > > /** > * generate JSR223 bindings for given names in current compilation > *context. > *Names array must be empty or consists from string literals. > **/ > public static Bindings getBindings(String ... names) > > > /** > * get time of compilation in miliseconds. > **/ > public static long getTimeMillis(); > > /** > * Execute os command in compile-time. > *@command - must be a string literal or result of call of Compiletime > * method, otherwise compile-time error is thrown > **/ > public static String exec(String command) > /** > * call java class at compile-time. > *During processing this directive, compiler will > *1. determinate, if class available in user path. > *2. determinate, if exists method with appropriative number and types > * of parameters. > *3. If such method is static - call one, otherwise > * 3.1 if class have default constructor - create instance of object > * (otherwise throw compile-time error) > * 3.2. Call methid with new-created instance. > * 3.3. If method return some result - substitute output to result, > * on exception throw compile-time error. > *@param classLiteral - must be a class literal for object to call. > *@param methodName - must be a string literal with name of method to > call. > *@param parameters - parameters of method to call. Must be a literals, or > * calls of Compiletime methods. > **/ > public static Object eval(Class classLiteral, String methodName, > Object .. params); > > } > > > > COMPILATION: > > During compilation calls to compile time are changed to generation of > appriative constant expressions. > > String x = Compiletime.getFileName(); > changed to > String x = "com/mycompany/package/MyClass.java"; > > int x = Compiletime.getLinNumber(); > changed to > int x = 33; > > String x = getClassName() > changed to > String x = "com.mycompany.package.MyClass"; > > > class X > { > int p1; > String p2; > > ... > public void doSomething(int x, int y) > { > int local = x+y; > Bindings bindings = Compiletime.getBindings(); > evalSomeScript(bindings); > } > > } > > > will translated to > > class X > { > int p1; > String p2; > ... > > public void doSomething(int x, int y) > { > int local = x+y; > SimpleBinding binding=(SimpleBinging uniqueName= new SimpleBinding(); > uniqueName.put("this",this); > uniqueName.put("p1",p1); > uniqueName.put("p2",p2); > uniqueName.put("x",x); > uniqueName.put("y",y); > uniqueName.put("local",local); > uniqueName ); > evalSomeScript(bindings); > } > > > } > > (assuming that Block Expressions for Java will be avaible. If not - it > will be necessory create own implementation of Bindings as part of > library). > > exec will be changed to Sting literal, with result of execution, i. e. > on Unix > String compiledBy = Compiletime.eval("whoami"); > whill be translated to 'rssh' > > At last eval call is translated to > - appropriative literal, if result of eval is primitive type or boxed > primitivew type. > - Call of code to unserialize constant byte array, which as serialized > during compilation > or throw compile-time error is object is not primitive type and not > implements Serializable. > > JLS changes: current scope of JLS is not touched. > > Btw, may be add to JLS chapter with name 'Compilation process' where > describe: > - high level description of transforming source code to JVM classes. > - process of automatic loading of annotation processors and when ones are > used. > - this API. > > > TESTING: > > Special cases are: > * compability with JSR45 > * testing of exec function is > > LIBRARY SUPPORT: > None, or adding two classes (for Bindings implementation with filling in > constructor and Unserializing Object utility) in depends of avaibility > of block expressions for Java > > (May be exists sence add methods for retrieveing source location (i.e. file > name and line number retrieving) to javax.lang.model.element.Element to > support better diagnostics. > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > None > > REFERENCES > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4411102 > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6439965 > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4649007 > > IMPLEMENTATION URL (optional) > > None yet. > > > > > > > From mthornton at optrak.co.uk Thu Mar 26 01:54:26 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 26 Mar 2009 08:54:26 +0000 Subject: PROPOSAL: Binary Literals In-Reply-To: <29224563.1238053358970.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> References: <29224563.1238053358970.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Message-ID: <49CB42C2.6030709@optrak.co.uk> 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. Mark Thornton From vilya.harvey at gmail.com Thu Mar 26 02:00:13 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Thu, 26 Mar 2009 09:00:13 +0000 Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: You're right, I hadn't considered widening conversions. You really want multiple dispatch in order to solve this elegantly, but somehow I don't see that being added to java anytime soon. :-) So I guess that leaves two options (for the interface-based approach): you could throw ClassCastException, forcing the user to do the conversion themselves; or you could do something like this with generics: interface Addable { R add(T val); } class BigInteger implements Addable, Addable { ... } class BigDecimal implements Addable, Addable { ... } I admit that doesn't look too elegant anymore, but I think it addresses the issue. Do you see any other problems there that I've overlooked? Cheers, Vil. Sent from my iPod On 26 Mar 2009, at 01:08, Daniel Cheng wrote: > On Wed, Mar 25, 2009 at 8:03 PM, Vilya Harvey > wrote: >> I would love to see this, but I'd prefer it to be based on special >> interfaces rather than annotations. This would adhere to the >> principle, mentioned on this list a few times, that annotations >> shouldn't modify the results of the compiler. >> >> For example, if you implement the Addable (say) interface then your >> class can be used the '+' operator; or the Subtractable interface for > > We can't specify the return type if we use an interface. > > We may want to do something like this: > > BigInteger + BigInteger = BigInteger > BigInteger + BigDecimal = BigDecimal > BigDecimal + BigInteger = BigDecimal > BigDecimal + BigDecimal = BigDecimal > > There is no way to implement this using interface. > >> the '-' operator. I'd imagine you would also want some grouping >> interfaces, to reduce the number of interface declarations required >> when overloading multiple operators (e.g. interface Artihmetic >> extends >> Addable, Subtractable etc.). >> >> Whatever form it takes though, it would be great to have this >> capability in Java! >> >> Vil. >> >> >> 2009/3/25 : >>> Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk >>> >>> Probably too big, but anyway. >>> >>> As I remember, alternative proposal (made [] and []= syntax sugar on >>> well-known interfaces, as with for-each loop) still not submitted. >>> If >>> anybody want submit such proposal, then it is possible to reuse >>> JLS-changed for 15.26.1 from there. >>> >>> >> >> From rssh at gradsoft.com.ua Thu Mar 26 02:01:40 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 11:01:40 +0200 (EET) Subject: PROPOSAL: Compiletime information access In-Reply-To: <49CB347D.2030300@paradise.net.nz> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <49CB347D.2030300@paradise.net.nz> Message-ID: <770cfac9aff8576d221e054a87f5a6c0.squirrel@wmail.gradsoft.ua> > > I think the implementation of this could be far cleaner if the values > you want were represented as static final fields not methods, which > would make them compile time constants. I. e. Compiletime.__FILE__, Complietime.__LINE__ import static Compiletime.__FILE__; System.out.println("file is %s",__FILE__); as in old good days. ;) // Nice. Very nice. This wouldn't work for exec() > and getBindings() but those are probably better done using annotation > processing. > getBinding() is impossible to simulate with annotation processing, because generation of binding contains code, which must be executed in local context of current scope. Annotation Processor can't touch current scope, only generate new files. in latest version of this submission: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000890.html All non-trivial parts which is possible to simulate with annotation processing moving out. Anyway, this is already rejected: cite from: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000887.html > >> - improving proposal about access to compile-time information about >> local context can have some sence (?) >> > >Given the existing capabilities of annotation processors, I don't think >the proposed API is necessary or desirable. I does not understand, why Joseph Darcy think, that existing capabilities of annotation processing may allows programmer use compile-time information about local context (it's not true for now). So, proposed changes are very funny, but creation of next version of this proposal will be waste of time:( But it is possible to achieve same effects by changing libraries: Generation of such information will be available from annotation processor if we will add location-method information to javax.annotation.Element, than it would be possible to wrote annotation processor which will retrieve location information near in the same way, as you wrote @LongString in rapt, something in style: @Compiletime(action="getSourceLocation()",id="unique"); final SourceLocation sourceLocation = Compiletime.unique; Emulate getBindings() with annotation processing still impossible (add AST rewriting to compiler is funny, but too avanagard for such archaic^H^H^H^H solid production language as Java), but need for it is quite small, so it can be dropped. (and without enhanced strings getBinding() not needed at all; my plan was to use getBinding() as mechanizm for run-time or compile-time implementation of stirng literals in future, but this is another story). So, practical approach will be wait for 'Small library changed' and submit proposal about adding access to source location of annotation element to it. > The strategy would then be that the compiler would contain a custom > implementation of javax.lang.model.TypeElement representing o nly this > class. When the compile time constants were being resolved during > compilation, this customer TypeElement with Custom VariableElements > would be called by the compiler to get the constant value, the > VariableElement could (with only a little magic) return the appropriate > value for the site where the compile time constant was being copied to. > > The only concern would be that the compile time constants would have non > constant values which varied depending on where they were referenced > from. I suspect this might be a small compiler change, the question > would then be whether the utility of such a mechanism carried enough > benefit to counteract the rather strange behaviour of this particular > class. > > It will be interesting to see what other think. > > Bruce > > rssh at gradsoft.com.ua wrote: >> AUTHOR: Ruslan Shevchenko >> >> OVERVIEW: >> >> FEATURE SUMMARY: >> >> Add API to access compile-time context of current compiled element >> from >> programs and annotation processors. >> >> MAJOR ADVANTAGE: >> >> Now compile time properties are unaccessible for programmer. This >> meaning >> that some functionality (such as access to location of file and line) >> is >> accessible only from debug version of program with technique, which is >> not >> officially supported, some (such as access to time of compilation or >> to binding context of current program location) is not avaible at all. >> >> MAJOR DISADVANTAGE >> >> Inaccurate usage of this feature can cause producing of unmaintable >> code. >> >> ALTERNATIVES: >> >> External preprocessing of java sources. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> >> Example 1 >> >> if (traceCondigion) { >> log.trace(Compiletime.getFileName()+":"+ >> Compiletime.getLineNumber()); >> } >> >> Example 2 >> >> if (system.currentTimeMillis() - Compiletime.getTimeMillis() > 86400) >> { >> System.out.println("This file was compiled more than day ago"); >> } >> >> Example 3 >> >> System.out.println("Superprogram by AAA AC, version:"+ >> Compiletime.exec("svnversion")); >> >> ADVANCED EXAMPLE: >> >> Example 1 >> // assuming that multiline strings are implemented: >> >> int a=0; >> int b=1; >> Binding bindings = Compiletime.getInstance().getCurrentBindings(); >> ScriptEngine velocity = ScriptEngineManager.get("velocity"); >> try { >> String fname = Compiletime.getFileName(); >> int line = Compiletime.getLineNumber(); >> String s = velocity.eval(""" >> #if ($a==$b) >> Something interesting here may be, >> Are you know that value of b is $b ? >> #else >> no mistics here. >> #end >> """, >> bindings); >> } catch (ScriptException ex){ >> Sytem.err.println("error in inline velocity in "+fname+", " >> "line "+line+1+ex.getLineNumber()); >> } >> >> >> Example 2 >> >> boolean isDemo = (Compiletime.eval(Properties.class, >> "getProperty","is.demo")!=null); >> >> if (!isDemo) { >> String key = (String)Compiletime.eval(GenerateUniqueKey.class, >> "generate"); >> LoadNotDemoClass(); >> } >> >> >> DETAILS: >> >> >> >> Add to Java Library pseudo-objects java.lang.Compiletime with access to >> compile-time properties and next signature: >> >> public class Compiletime >> { >> /** >> * get filename of compiled call. >> * in case of generated source and avaible JSR-45 SMAP file >> * return file name of translated-source. >> **/ >> public static String getFileName(); >> >> /** >> * get line number of compiled call. >> * in case of generated source and avaible JSR-45 SMAP file >> * return line number in translated-source. >> **/ >> public static int getLineNumber(); >> >> /** >> * get class name where this call is placed. >> * in case of generated source and avaible JSR-45 SMAP file >> * return class name in translated-source. >> **/ >> public static int getClassName(); >> >> /** >> * get method name where this call is placed. >> * in case of generated source and avaible JSR-45 SMAP file >> * return method name in translated-source. >> **/ >> public static int getMethodName(); >> >> >> /** >> * generate JSR223 bindings for given names in current compilation >> *context. >> *Names array must be empty or consists from string literals. >> **/ >> public static Bindings getBindings(String ... names) >> >> >> /** >> * get time of compilation in miliseconds. >> **/ >> public static long getTimeMillis(); >> >> /** >> * Execute os command in compile-time. >> *@command - must be a string literal or result of call of >> Compiletime >> * method, otherwise compile-time error is thrown >> **/ >> public static String exec(String command) >> /** >> * call java class at compile-time. >> *During processing this directive, compiler will >> *1. determinate, if class available in user path. >> *2. determinate, if exists method with appropriative number and >> types >> * of parameters. >> *3. If such method is static - call one, otherwise >> * 3.1 if class have default constructor - create instance of object >> * (otherwise throw compile-time error) >> * 3.2. Call methid with new-created instance. >> * 3.3. If method return some result - substitute output to result, >> * on exception throw compile-time error. >> *@param classLiteral - must be a class literal for object to call. >> *@param methodName - must be a string literal with name of method to >> call. >> *@param parameters - parameters of method to call. Must be a >> literals, or >> * calls of Compiletime methods. >> **/ >> public static Object eval(Class classLiteral, String methodName, >> Object .. params); >> >> } >> >> >> >> COMPILATION: >> >> During compilation calls to compile time are changed to generation of >> appriative constant expressions. >> >> String x = Compiletime.getFileName(); >> changed to >> String x = "com/mycompany/package/MyClass.java"; >> >> int x = Compiletime.getLinNumber(); >> changed to >> int x = 33; >> >> String x = getClassName() >> changed to >> String x = "com.mycompany.package.MyClass"; >> >> >> class X >> { >> int p1; >> String p2; >> >> ... >> public void doSomething(int x, int y) >> { >> int local = x+y; >> Bindings bindings = Compiletime.getBindings(); >> evalSomeScript(bindings); >> } >> >> } >> >> >> will translated to >> >> class X >> { >> int p1; >> String p2; >> ... >> >> public void doSomething(int x, int y) >> { >> int local = x+y; >> SimpleBinding binding=(SimpleBinging uniqueName= new >> SimpleBinding(); >> uniqueName.put("this",this); >> uniqueName.put("p1",p1); >> uniqueName.put("p2",p2); >> uniqueName.put("x",x); >> uniqueName.put("y",y); >> uniqueName.put("local",local); >> uniqueName ); >> evalSomeScript(bindings); >> } >> >> >> } >> >> (assuming that Block Expressions for Java will be avaible. If not - it >> will be necessory create own implementation of Bindings as part of >> library). >> >> exec will be changed to Sting literal, with result of execution, i. e. >> on Unix >> String compiledBy = Compiletime.eval("whoami"); >> whill be translated to 'rssh' >> >> At last eval call is translated to >> - appropriative literal, if result of eval is primitive type or boxed >> primitivew type. >> - Call of code to unserialize constant byte array, which as serialized >> during compilation >> or throw compile-time error is object is not primitive type and not >> implements Serializable. >> >> JLS changes: current scope of JLS is not touched. >> >> Btw, may be add to JLS chapter with name 'Compilation process' where >> describe: >> - high level description of transforming source code to JVM classes. >> - process of automatic loading of annotation processors and when ones >> are >> used. >> - this API. >> >> >> TESTING: >> >> Special cases are: >> * compability with JSR45 >> * testing of exec function is >> >> LIBRARY SUPPORT: >> None, or adding two classes (for Bindings implementation with filling >> in >> constructor and Unserializing Object utility) in depends of avaibility >> of block expressions for Java >> >> (May be exists sence add methods for retrieveing source location (i.e. >> file >> name and line number retrieving) to javax.lang.model.element.Element to >> support better diagnostics. >> >> REFLECTIVE APIS: None >> >> OTHER CHANGES: None >> >> MIGRATION: None >> >> COMPABILITY >> None >> >> REFERENCES >> >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4411102 >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6439965 >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4649007 >> >> IMPLEMENTATION URL (optional) >> >> None yet. >> >> >> >> >> >> >> > > > From rssh at gradsoft.com.ua Thu Mar 26 02:17:41 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 11:17:41 +0200 (EET) Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: > > interface Addable { > R add(T val); > } > > class BigInteger implements > Addable, > Addable > { ... } > > class BigDecimal implements > Addable, > Addable > { ... } > > I admit that doesn't look too elegant anymore, but I think it > addresses the issue. Do you see any other problems there that I've > overlooked? > Yes, this can work. > Cheers, > Vil. > > Sent from my iPod > > On 26 Mar 2009, at 01:08, Daniel Cheng wrote: > >> On Wed, Mar 25, 2009 at 8:03 PM, Vilya Harvey >> wrote: >>> I would love to see this, but I'd prefer it to be based on special >>> interfaces rather than annotations. This would adhere to the >>> principle, mentioned on this list a few times, that annotations >>> shouldn't modify the results of the compiler. >>> >>> For example, if you implement the Addable (say) interface then your >>> class can be used the '+' operator; or the Subtractable interface for >> >> We can't specify the return type if we use an interface. >> >> We may want to do something like this: >> >> BigInteger + BigInteger = BigInteger >> BigInteger + BigDecimal = BigDecimal >> BigDecimal + BigInteger = BigDecimal >> BigDecimal + BigDecimal = BigDecimal >> >> There is no way to implement this using interface. >> >>> the '-' operator. I'd imagine you would also want some grouping >>> interfaces, to reduce the number of interface declarations required >>> when overloading multiple operators (e.g. interface Artihmetic >>> extends >>> Addable, Subtractable etc.). >>> >>> Whatever form it takes though, it would be great to have this >>> capability in Java! >>> >>> Vil. >>> >>> >>> 2009/3/25 : >>>> Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk >>>> >>>> Probably too big, but anyway. >>>> >>>> As I remember, alternative proposal (made [] and []= syntax sugar on >>>> well-known interfaces, as with for-each loop) still not submitted. >>>> If >>>> anybody want submit such proposal, then it is possible to reuse >>>> JLS-changed for 15.26.1 from there. >>>> >>>> >>> >>> > From brucechapman at paradise.net.nz Thu Mar 26 02:15:25 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Thu, 26 Mar 2009 22:15:25 +1300 Subject: PROPOSAL: Unsigned Integer Widening Operator In-Reply-To: <49CA07D3.8090909@peralex.com> References: <49C9F30E.2020008@paradise.net.nz> <49CA07D3.8090909@peralex.com> Message-ID: <49CB47AD.9000900@paradise.net.nz> Noel Grandin wrote: > I would think that a utility class that performed widening operations, > and maybe some other useful stuff would be preferable to extending the > language/ > > Perhaps a BinaryMath class to live alongside java.lang.Math? > > Regards, Noel. > > There is some truth to that. BUT on the other side of the ledger there are two operators that add extra bits to the left of a value. Right shift has two forms, one to sign extend and one to zero extend, whereas widening only has a sign extend form of the operator (which is the unary + operator if you are wondering). Adding a zero extend widening makes the language consistent. Also it is worth considering that the zero extend widening operator is (hopefully) sufficiently succinct, and gives the impression of being sufficiently cheap that the perceived wisdom for effective unsigned byte manipulation might become to always apply the operator to variable and array accesses. This would reduce bugs. I don't think a method call would have that same subconscious effect. You'd tend to only use the method where it was actually needed, and you'd sometimes get that decision wrong. Bruce > Bruce Chapman wrote: > >> Title >> Unsigned Integer Widening Operator >> >> latest html version at http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf&hl >> >> AUTHOR(S): Bruce Chapman >> >> OVERVIEW >> >> >> >> FEATURE SUMMARY: >> Add an unsigned widening operator to convert bytes (in particular), >> shorts, and chars (for completeness) to int while avoiding sign extension. >> >> SNIP From brucechapman at paradise.net.nz Thu Mar 26 02:23:07 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Thu, 26 Mar 2009 22:23:07 +1300 Subject: PROPOSAL: Unsigned Integer Widening Operator In-Reply-To: <021BD3C7-35AE-4E88-8FA0-31737B0DC8CE@zwitserloot.com> References: <49C9F30E.2020008@paradise.net.nz> <49CA07D3.8090909@peralex.com> <021BD3C7-35AE-4E88-8FA0-31737B0DC8CE@zwitserloot.com> Message-ID: <49CB497B.9020404@paradise.net.nz> Comments inline. regards Bruce Reinier Zwitserloot wrote: > Noel, Bruce: > > Perhaps Noel has a point, here. imagine: > > public class ByteUtils { > public int b2i(byte b) { > return b & 0xFF; > } > } > I wouldn't advise this, b2i is the JVM bytecode to convert a byte to an integer with sign extension, so to use it for a method that does zero extension would be a little confusing. :) > import static ByteUtils.b2i; > > results = (result << 8) | b2i(contents[i]); > > vs: > > results = (result << 8) | (+)contents[i]; > > > The second bit is hardly better, and it suffers from cast ambiguity if > you add more fluff to the expression. Once you also add parens to > localize the cast like so: > > results = (result << 8) | ((+)contents[i]); > the (+) only applies to a byte or short, and the only way to have one of those is a variable or array access (with optional prefix or postfix increment or decrement) or explicitly downcasting, so in practice I don't think there would EVER be a situation where you would need (or even want) to wrap the (+) expression in parenthesis. > The static import starts to win, in my book, and that's before > considering the impact of a language change. > > > > did you not read Bruce's introduction to his three proposals? It > provides some useful background information. > > If you've ever worked with bytes in java, you may remember that the > main issue is crippling wordiness. A librar > --Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > > > On Mar 25, 2009, at 11:30, Noel Grandin wrote: > > >> I would think that a utility class that performed widening operations, >> and maybe some other useful stuff would be preferable to extending the >> language/ >> >> Perhaps a BinaryMath class to live alongside java.lang.Math? >> >> Regards, Noel. >> >> Bruce Chapman wrote: >> >>> Title >>> Unsigned Integer Widening Operator >>> >>> latest html version at http://docs.google.com/Doc?id=dcvp3mkv_2k39wt5gf&hl >>> >>> AUTHOR(S): Bruce Chapman >>> >>> OVERVIEW >>> >>> >>> SNIP From j16sdiz at gmail.com Thu Mar 26 02:25:28 2009 From: j16sdiz at gmail.com (Daniel Cheng) Date: Thu, 26 Mar 2009 17:25:28 +0800 Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: On Thu, Mar 26, 2009 at 5:00 PM, Vilya Harvey wrote: > You're right, I hadn't considered widening conversions. You really want > multiple dispatch in order to solve this elegantly, but somehow I don't see > that being added to java anytime soon. :-) So I guess that leaves two > options (for the interface-based approach): you could throw > ClassCastException, forcing the user to do the conversion themselves; or you > could do something like this with generics: > > interface Addable { > ? ?R add(T val); > } > > class BigInteger implements > ? ?Addable, > ? ?Addable > { ... } > > class BigDecimal implements > ? ?Addable, > ? ?Addable > { ... } Interface with generic is the same interface. -- and you can't implement same interface twice. I don't want to talk about generic Type Erasure, it's a PITA. > I admit that doesn't look too elegant anymore, but I think it addresses the > issue. Do you see any other problems there that I've overlooked? > > Cheers, > Vil. > > Sent from my iPod > [...] From rssh at gradsoft.com.ua Thu Mar 26 03:02:52 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 12:02:52 +0200 (EET) Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: <50ee422e73a1eb79959aa98a1d5c1125.squirrel@wmail.gradsoft.ua> >> >> interface Addable { >> R add(T val); >> } >> >> class BigInteger implements >> Addable, >> Addable >> { ... } >> >> class BigDecimal implements >> Addable, >> Addable >> { ... } >> >> I admit that doesn't look too elegant anymore, but I think it >> addresses the issue. Do you see any other problems there that I've >> overlooked? >> > > Yes, this can work. > Ohh, we need relief generics for this. Now see: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ104 >> Cheers, >> Vil. >> >> Sent from my iPod >> >> On 26 Mar 2009, at 01:08, Daniel Cheng wrote: >> >>> On Wed, Mar 25, 2009 at 8:03 PM, Vilya Harvey >>> wrote: >>>> I would love to see this, but I'd prefer it to be based on special >>>> interfaces rather than annotations. This would adhere to the >>>> principle, mentioned on this list a few times, that annotations >>>> shouldn't modify the results of the compiler. >>>> >>>> For example, if you implement the Addable (say) interface then your >>>> class can be used the '+' operator; or the Subtractable interface for >>> >>> We can't specify the return type if we use an interface. >>> >>> We may want to do something like this: >>> >>> BigInteger + BigInteger = BigInteger >>> BigInteger + BigDecimal = BigDecimal >>> BigDecimal + BigInteger = BigDecimal >>> BigDecimal + BigDecimal = BigDecimal >>> >>> There is no way to implement this using interface. >>> >>>> the '-' operator. I'd imagine you would also want some grouping >>>> interfaces, to reduce the number of interface declarations required >>>> when overloading multiple operators (e.g. interface Artihmetic >>>> extends >>>> Addable, Subtractable etc.). >>>> >>>> Whatever form it takes though, it would be great to have this >>>> capability in Java! >>>> >>>> Vil. >>>> >>>> >>>> 2009/3/25 : >>>>> Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk >>>>> >>>>> Probably too big, but anyway. >>>>> >>>>> As I remember, alternative proposal (made [] and []= syntax sugar on >>>>> well-known interfaces, as with for-each loop) still not submitted. >>>>> If >>>>> anybody want submit such proposal, then it is possible to reuse >>>>> JLS-changed for 15.26.1 from there. >>>>> >>>>> >>>> >>>> >> > > > From vilya.harvey at gmail.com Thu Mar 26 04:33:12 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Thu, 26 Mar 2009 11:33:12 +0000 Subject: PRE-PROPOSAL: Simple operator overloading. In-Reply-To: References: <6aef848f0903250503u5f3ea701y9c363ae85c766749@mail.gmail.com> Message-ID: <6aef848f0903260433u73c9e1f6p21266f82c4f834fe@mail.gmail.com> D'oh! Of course you're right. I'm probably flogging a dead horse now, but perhaps widening conversions could be dealt with by implementing the interface in a common superclass? For example in the case of BigDecimal and BigInteger, Number would implement the Addable interface and it's implementation would be responsible for doing any widening and returning the result in the appropriate subclass. On second thoughts, that seems like a poor solution. Anything which requires superclasses to have knowledge of their subclasses is a Bad Thing. You wouldn't be able to add a class of your own which existing numeric types could widen to, for example. Imagine adding a class for complex numbers; to support widening you'd have to make it a subclass of Number and modify the implementation of Number's add method. This leads back to either not having implicit widening for overloaded operators, or using a non-interface-based approach like Ruslan's annotation proposal. Hmm. 2009/3/26 Daniel Cheng : > On Thu, Mar 26, 2009 at 5:00 PM, Vilya Harvey wrote: >> You're right, I hadn't considered widening conversions. You really want >> multiple dispatch in order to solve this elegantly, but somehow I don't see >> that being added to java anytime soon. :-) So I guess that leaves two >> options (for the interface-based approach): you could throw >> ClassCastException, forcing the user to do the conversion themselves; or you >> could do something like this with generics: >> >> interface Addable { >> ? ?R add(T val); >> } >> >> class BigInteger implements >> ? ?Addable, >> ? ?Addable >> { ... } >> >> class BigDecimal implements >> ? ?Addable, >> ? ?Addable >> { ... } > > > Interface with generic is the same interface. > ?-- and you can't implement same interface twice. > > I don't want to talk about generic Type Erasure, it's a PITA. > >> I admit that doesn't look too elegant anymore, but I think it addresses the >> issue. Do you see any other problems there that I've overlooked? >> >> Cheers, >> Vil. >> >> Sent from my iPod >> > [...] > From tim at peierls.net Thu Mar 26 06:38:16 2009 From: tim at peierls.net (Tim Peierls) Date: Thu, 26 Mar 2009 09:38:16 -0400 Subject: PROPOSAL: Binary Literals In-Reply-To: <29224563.1238053358970.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> References: <29224563.1238053358970.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> Message-ID: <63b4e4050903260638s4747e989v38ae04b65b9f68a2@mail.gmail.com> On Thu, Mar 26, 2009 at 3:42 AM, Derek Foster wrote: > From: Reinier Zwitserloot >> >> The result of a library call is a byte primitive, which you can then >> assign to a private static final byte constant. From there on out, that will >> be as fast as a code literal. > > > You are not considering the impact of constant folding on compiler > optimizations. This might have been an issue years ago, but modern JVMs can handle this kind of thing easily. --tim From mthornton at optrak.co.uk Thu Mar 26 06:48:16 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 26 Mar 2009 13:48:16 +0000 Subject: PROPOSAL: Binary Literals In-Reply-To: <63b4e4050903260638s4747e989v38ae04b65b9f68a2@mail.gmail.com> References: <29224563.1238053358970.JavaMail.root@elwamui-lapwing.atl.sa.earthlink.net> <63b4e4050903260638s4747e989v38ae04b65b9f68a2@mail.gmail.com> Message-ID: <49CB87A0.2040201@optrak.co.uk> Tim Peierls wrote: > On Thu, Mar 26, 2009 at 3:42 AM, Derek Foster wrote: > > >> From: Reinier Zwitserloot >> >>> The result of a library call is a byte primitive, which you can then >>> assign to a private static final byte constant. From there on out, that will >>> be as fast as a code literal. >>> >> You are not considering the impact of constant folding on compiler >> optimizations. >> > > > This might have been an issue years ago, but modern JVMs can handle this > kind of thing easily. > > --tim > > It is still an issue for JavaME and "case" labels in switch statements. However the need for binary values in case labels must surely be very rare. I don't find the processor instruction simulation example to be very convincing. Mark Thornton From jimbethancourt at gmail.com Thu Mar 26 07:46:24 2009 From: jimbethancourt at gmail.com (Jim Bethancourt) Date: Thu, 26 Mar 2009 09:46:24 -0500 Subject: Rough Draft Proposal: "Caused by" information provided when NPE is thrown Message-ID: <1bb1728a0903260746ic82bc8dlc1f149fbd6bc339a@mail.gmail.com> Hi everyone, I realize I'm (very) new to the list, and I'm not sure this proposal fits entirely in the scope of the Coin project since it's not exactly a language level change, but I thought it best to err on the side of sharing my idea and propose it before the deadline and seeing it shot down instead of keeping it to myself. :-) This is definitely a draft proposal and I would welcome any help if it is offered, as this is only in the idea phase for me. I'm by no means a language designer, but I've seen NPEs countless numbers of times in production stacktraces and often found it arduous and time consuming to reproduce the NPE and thought it would be helpful to practitioners if such a feature was added. Thanks so much, Jim *AUTHOR(S):* Jim Bethancourt (Houston JUG leader -- www.hjug.org), you??? *OVERVIEW* FEATURE SUMMARY: Provide more information about Null Pointer Exceptions on the stacktrace when thrown through in the "Caused by" clause. This feature could be written using reflection APIs. Should be suitable as a summary in a language tutorial? NO MAJOR ADVANTAGE: More information about what object reference is null would be provided in the stacktrace "Caused by" clause MAJOR BENEFIT: The programs running using it are easier to support and may allow a quicker resolution of issues, and could also allow for easier programmatic recovery from NPEs MAJOR DISADVANTAGE: None foreseen ALTERNATIVES: could use a flag that enables the feature only during development / troubleshooting *EXAMPLES* SIMPLE EXAMPLE: java.lang.NullPointerException at com.code.NPEThrower(NPEThrower.java:10) ... would instead read java.lang.NullPointerException at com.code.NPEThrower(NPEThrower.java:10) ... Caused by: Null return value: Object.getName() at com.code.NPEThrower.java:7 ... or java.lang.NullPointerException at com.code.NPEThrower(NPEThrower.java:10) ... Caused by: Null reference Object.name at com.code.NPEThrower.java:7 ADVANCED EXAMPLE: try{ code throwing NPE } catch (NullPointerException npe){ System.out.println(npe.getCause()); } *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. This change would not affect the grammar, type system, or expression meaning of statements in the Java Programming Language. 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! TESTING: How can the feature be tested? Write code that throws a NullPointerException and see if the field / method that is throwing the Null Pointer Exception shows up in the Stacktrace as described. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? no REFLECTIVE APIS: Do any of the various and sundry reflection APIs need to be updated? I don't imagine so, though reflection could potentially be used to capture the object throwing the NPE OTHER CHANGES: None MIGRATION: Since this would be a change to the format of the stacktrace and a new api method, there would not be any migration required. *COMPATIBILITY* BREAKING CHANGES: None foreseen EXISTING PROGRAMS: How do source and class files of earlier platform versions interact with the feature? Not known. Can any new overloadings occur? No Can any new overriding occur? No *REFERENCES* EXISTING BUGS: None known URL FOR PROTOTYPE (optional): none From Thomas.Hawtin at Sun.COM Thu Mar 26 08:03:53 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Thu, 26 Mar 2009 15:03:53 +0000 Subject: PROPOSAL: Return 'this' In-Reply-To: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> Message-ID: <49CB9959.4070704@sun.com> Marek Kozie? wrote: > MAJOR ADVANTAGE: > Simplification of ?return this? statement. > 'void' can be easy replaced with 'this'. > > MAJOR BENEFIT(s): It would prevent NullPointerException, and make some > 'builder' like interfaces look really clear and simple. My problem with this is that it is an attempt to fix a hack due to a language problem with a language hack. The underlying problem is that Java does not have a concise syntax for builders. The usual hack is for builders to return this and clients to use method chaining. This solution makes the hack easier. A better solution would be direct, explicit support for builders in some form. Also the variant of this proposal that client-side reinterprets returning void to return this, would interfere to some extent with covariantly returning void when overriding a return of Void. Tom Hawtin From develop4lasu at gmail.com Thu Mar 26 08:51:46 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 16:51:46 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <49CB9959.4070704@sun.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> Message-ID: <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> 2009/3/26 Tom Hawtin : > Marek Kozie? wrote: > >> MAJOR ADVANTAGE: >> Simplification of ?return this? statement. >> 'void' can be easy replaced with 'this'. >> >> MAJOR BENEFIT(s): It would prevent NullPointerException, and make some >> 'builder' like interfaces look really clear and simple. > > My problem with this is that it is an attempt to fix a hack due to a > language problem with a language hack. > > The underlying problem is that Java does not have a concise syntax for > builders. The usual hack is for builders to return this and clients to use > method chaining. This solution makes the hack easier. A better solution > would be direct, explicit support for builders in some form. > > Also the variant of this proposal that client-side reinterprets returning > void to return this, would interfere to some extent with covariantly > returning void when overriding a return of Void. > > Tom Hawtin > This is some point. I do not like it just because in need to be served outside, which increase interactions. Notice that this will work totally in unexpected way when: we have a.jar & b.jar while both are compiled and b.jar use a.jar, than some one change (in a.jar ) interface A{ this some(); } to: interface A{ A some(); } because he want to return other object... this would work in pretty unexpected way. BTW. Did you wander if Interfaces / abstract classes should be final (with explicit declared classes/interfaces available for inheritance), like: final interface A allow Ab, Ac{...} this was my idea connected to inheritance security. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From david.goodenough at linkchoose.co.uk Thu Mar 26 09:50:23 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Thu, 26 Mar 2009 16:50:23 +0000 Subject: DISCUSSION: Bean/Data classes In-Reply-To: <49CAB13A.5070605@joda.org> References: <999760.7333.qm@web63701.mail.re1.yahoo.com> <99842AA9-37BA-4B3F-AB97-60811384EE1A@zwitserloot.com> <49CAB13A.5070605@joda.org> Message-ID: <200903261650.24037.david.goodenough@linkchoose.co.uk> On Wednesday 25 March 2009, Stephen Colebourne wrote: > Reinier Zwitserloot wrote: > > You should move away from the idea of 'this keyword does so much > > magic!' and move towards the idea that this keyword simply declares > > that the class is to have bean semantics. > > I proposed almost exactly this 'data' class two years ago - > http://www.jroller.com/scolebourne/entry/a_bean_keyword. > > public bean Person { > // properties > property String forename; > property String surname; > > // normal fields and methods > private String ordinaryField; > public boolean validate() { ... } > } > > This is fundamentally no different to how enum was slotted into the > language (note I deliberately omitted the 'class' keyword. > > The key aspect of this approach is that it allows there to be different > grammer rules within 'bean' classes to normal classes, just as there are > different rules for 'enum' classes. > > Now, as for what exactly it generates, that is a much bigger question. > Does it just generate getter/setter? What about lists, maps and arrays? > How about events? The truth is that is where every property proposal > gets bogged down (because server side JavaBeans are just data holders, > whereas swing JavaBeans are much more a part of the application). > > So, will this be in Coin? No. There is way to much to work out. > > But this could be the best way to get a form of properties into Java. > And a group could form to code up a prototype and prove it (Kijaro is > available...) > > Finally, I should say that of all the things Java lacks, I think > properties is the biggest - bigger than closures. The sheer amount of > wasted effort, lines of code, lack of consistency and sheer focus on the > low level detail rather than the high level abstraction is staggering. > It is IMO a far bigger hole in writing good Java apps today than > closures (or any other language proposal). Well (given my lightweight Property proposal) I have to say that I agree with this last paragraph. Maybe I have expressed the need for it badly but to me it is blindingly obvious that this is needed, and that it is a gaping hole in Java's otherwise excellent compiler/IDE checkability record. It is nice to know that I am not completely alone in thinking this. David > > Stephen From belingueres at gmail.com Thu Mar 26 11:30:45 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Thu, 26 Mar 2009 15:30:45 -0300 Subject: PROPOSAL: Return 'this' In-Reply-To: <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> Message-ID: Wouldn't it be simpler to add a Pascal-like "with" statement? This would solve at least the method chaining issue: with(object) { method1(); metohd2(); ... methodN(); } 2009/3/26, Marek Kozie? : > 2009/3/26 Tom Hawtin : > > Marek Kozie? wrote: > > > >> MAJOR ADVANTAGE: > >> Simplification of "return this" statement. > >> 'void' can be easy replaced with 'this'. > >> > >> MAJOR BENEFIT(s): It would prevent NullPointerException, and make some > >> 'builder' like interfaces look really clear and simple. > > > > My problem with this is that it is an attempt to fix a hack due to a > > language problem with a language hack. > > > > The underlying problem is that Java does not have a concise syntax for > > builders. The usual hack is for builders to return this and clients to use > > method chaining. This solution makes the hack easier. A better solution > > would be direct, explicit support for builders in some form. > > > > Also the variant of this proposal that client-side reinterprets returning > > void to return this, would interfere to some extent with covariantly > > returning void when overriding a return of Void. > > > > Tom Hawtin > > > > This is some point. > I do not like it just because in need to be served outside, which > increase interactions. > Notice that this will work totally in unexpected way when: > > we have a.jar & b.jar > while both are compiled and b.jar use a.jar, than some one change (in a.jar ) > interface A{ this some(); } > to: > interface A{ A some(); } > because he want to return other object... > > this would work in pretty unexpected way. > > BTW. > Did you wander if Interfaces / abstract classes should be final (with > explicit declared classes/interfaces available for inheritance), like: > final interface A allow Ab, Ac{...} > this was my idea connected to inheritance security. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From javalists at cbfiddle.com Thu Mar 26 11:57:54 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Thu, 26 Mar 2009 11:57:54 -0700 (PDT) Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions Message-ID: <61053.69.239.104.86.1238093874.squirrel@69.239.104.86> [This is a revised proposal based on the previous comments. It includes a use case.] Unchecked Exceptions as Subclasses of Checked Exceptions AUTHOR: Alan Snyder OVERVIEW FEATURE SUMMARY: This proposal would allow the definition of an unchecked exception class that extends a checked exception class. MAJOR ADVANTAGE: Unchecked exception classes are useful when an exception must be thrown through an existing interface that does not declare any checked exceptions or an appropriate checked exception. If one can define both an unchecked exception class and a corresponding checked exception class such that the unchecked exception class extends the checked exception class, then the unchecked exception will be caught by a try statement that catches the checked exception. MAJOR BENEFIT: Programs do not have to explictly catch both the unchecked and checked exceptions. Most developers need only be aware of the checked exception. The potential mistake of not catching the unchecked exception is avoided. MAJOR DISADVANTAGE: A new marker interface (or equivalent) must be defined and the definition of unchecked exceptions changed. ALTERNATIVES: The alternative is to always explicitly catch both the unchecked and checked exceptions, which introduces a likely source of programming errors. EXAMPLE: This proposal uses a marker interface as an alternative way (besides subclassing RuntimeException and Error) of indicating that an exception class defines an unchecked exception. The following would define a checked exception and an unchecked exception that extends the checked exception: public class TheCheckedException extends Exception {}; public class TheUncheckedException extends TheCheckedException implements UncheckedException {}; The following is a sketch of a possible use case. Consider a program A that reads and writes data using file I/O, with the presumption that there are good reasons not to read all of the data into memory. The program catches IOException in appropriate places so that it can recover gracefully should an I/O error occur. Now suppose that program A wants to use existing library B to manipulate this data, but library B does not know about files. Instead, assume that B uses some more generic interface to access data, such as List. Note that the List get() method does not define a checked exception for data access failure. Thus, in the bridge code that allows the file data to be accessed via the List interface, program A would have to wrap any IOExceptions in a RuntimeException. Suppose it defines a new class, UncheckedIOException, for this purpose. In current Java, program A would need to augment its exception handlers to handle both IOException and UncheckedIOException. Using this proposal, UncheckedIOException could be an unchecked exception and also subclass from IOException, so that the exception handlers for IOException would catch UncheckedIOException as well. DETAILS SPECIFICATION: The JLS would be changed to add one more way to define an unchecked exception. JLS 11.2 The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes. would become The unchecked exceptions classes are the class RuntimeException and its subclasses, the class Error and its subclasses, and those subclasses of Exception that implement the UncheckedException interface. All other exception classes are checked exception classes. JLS 11.5 The subclasses of Exception other than RuntimeException are all checked exception classes. would become The subclasses of Exception other than RuntimeException are checked exception classes, unless they implement the UncheckedException interface. The marker interface UncheckedException would have to be defined in some java package, with java.lang being the obvious choice. COMPILATION: The compiler would have to be extended to recognize the new category of unchecked exceptions. I'm not aware of other changes. COMPATIBILITY The major compatibility issue arises from the introduction of a new name in the class name space. That could potentially cause a program to fail to compile if it imported a class with the name UncheckedException using a wild card import statement. There could also be programs that examine the class hierarchy at runtime or using a compiler API that would not recognize some exception classes as being unchecked. I imagine these would mostly be language tools, which one would expect to need revision for a new version of Java. From javalists at cbfiddle.com Thu Mar 26 12:08:55 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Thu, 26 Mar 2009 12:08:55 -0700 (PDT) Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime Message-ID: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> Improved Support for Optional Object Behaviors at Runtime AUTHOR: Alan Snyder OVERVIEW FEATURE SUMMARY: This proposal would add a method to class Object to allow runtime access to optional object behaviors. MAJOR ADVANTAGE: As designs evolve and become more complex, it is useful to split out separable chunks of behavior whose support by an object might be optional. In current Java, the universally applicable technique for testing for and making use of optional behavior is the type cast. The type cast is limited by its tight coupling with the type hierarchy; as a result, because Java has single class inheritance, a class can not support an optional behavior defined by another class that is not already in its class hierarchy. In addition, because type casts cannot be simulated by an object, it is not compatible with delegation. For an object implemented by delegation to support optional behaviors using type casts, there would need to be one delegating class for each possible combination of optional behaviors. This proposal defines a method on class Object that can be used in place of type casts to test for and access optional behaviors. This proposal is not constrained by the type hierarchy of the target object, because it permits the optional behavior to be implemented using a different (but related) object. In addition, the determination of the available behaviors can be made dynamically. Specifically, this proposal allows a class implemented using delegation to mimic the set of optional behaviors supported by its delegate, even if the delegate is replaceable. MAJOR BENEFIT: By adding a method to class Object, this feature can be supported by any class, even existing Java platform classes, with no additional changes to their class hierarchies. Because the feature is universally available, the use of type casts for this purpose can be deprecated. This technique can be used to simply interfaces, or avoid making them more complex. MAJOR DISADVANTAGE: Any change to class Object freaks people out. This is the only change I can think of that is so obviously universal that it deserves to be in class Object. ALTERNATIVES: One alternative is to define this method in a new interface. This disadvantage of defining a new interface is that existing classes and interfaces would not support the method without themselves being changed. The other alternative is to add this method to classes and interfaces on an as needed basis. Either alternative forces programmers to use type casts in those cases where this method was not available. Also, new implementations of unchanged classes and interfaces would not be able to support this feature for existing clients of those classes and interfaces. EXAMPLE: Suppose a program wants to test an object "o" at runtime for an optional behavior defined by a class or interface "T". In current Java, the program could write: try { T t = (T) o; ... use t ... } catch (ClassCastException ex) { } Using the proposed feature, the program would write: T t = o.getExtension(T.class); if (t != null) { ... use t ... } The following examples are all hypothetical, but plausible to varying degrees. Note that many of them use instances of existing platform classes. // Test a list to see if it is observable, and get access // to the observable methods. Observable o = list.getExtension(Observable.class); // Test a file to see if supports metadata, and get access // to the metadata methods. FileMetadata fm = file.getExtension(FileMetadata.class); // Test file metadata to see if Mac OS file metadata is // supported. Note that the file might be on another // machine, so this call might succeed even on a non-Mac system. MacOSFileMetadata mfm = fm.getExtension(MacOSFileMetadata.class); // Test a file to see if it supports the new File API. // Note that using this approach the new File API does // not have to be an extension of the old API. java.nio.File nf = file.getExtension(java.nio.File.class); // Test a file to see if it is a directory, and get access to // the directory methods. Directory dir = file.getExtension(Directory.class); // Test a file to see if it is a symlink, and get access to // the symlink methods. Symlink s = file.getExtension(Symlink.class); // Test a file to see if it a directory and whether it provides // read and update access to the directory contents using the // List API (!). List fs = (List) file.getExtension(List.class); DETAILS The default definition in class Object would be: public T getExtension(Class c) { try { return (T) this; } catch (ClassCastException ex) { return null; } } Thus, if not overridden, the method has the same effect as the type cast. Thus it can be used in place of type casts even on instances of existing classes. Once this method is in place, programmers should be discouraged from using type casts for the purpose of testing for optional behavior. SPECIFICATION: JLS 4.3.2 would be changed to define this method. I'm not aware of other changes. MIGRATION: It would be advisable to convert appropriate type casts to invocations of this method in existing code. Once this method is available in class Object, other Java platform classes and APIs can be changed to take advantage of it. COMPATIBILITY BREAKING CHANGES: No matter what name is chosen for this method, some existing program could fail to compile if it defines a method with the same name and signature but (say) a different return type. Methods with class parameters are presumably uncommon. According to JLS 13.4.12, binary compatibility should not be broken because the method is public. EXISTING PROGRAMS: Existing classes automatically support this method to the same extent that they current support type casts for accessing optional behavior. From rssh at gradsoft.com.ua Thu Mar 26 12:12:15 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 21:12:15 +0200 (EET) Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime In-Reply-To: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> References: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> Message-ID: > EXAMPLE: > > Suppose a program wants to test an object "o" at runtime for an optional > behavior defined by a class or interface "T". In current Java, the program > could write: > > try { > T t = (T) o; > ... use t ... > } catch (ClassCastException ex) { > } > > Using the proposed feature, the program would write: > > T t = o.getExtension(T.class); > if (t != null) { > ... use t ... > } > > The following examples are all hypothetical, but plausible to varying > degrees. Note that many of them use instances of existing platform Sorry, I can't understand, how this differ from if (o instanceof T) { T t = (T)o; .... use t ... } ? From javalists at cbfiddle.com Thu Mar 26 12:20:41 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Thu, 26 Mar 2009 12:20:41 -0700 (PDT) Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime Message-ID: <61199.69.239.104.86.1238095241.squirrel@69.239.104.86> Sorry if I was not clear enough. The difference is that getExtension is a method, therefore it can be overridden in a subclass. On Mar 26, 2009, at 12:12 PM, rssh at gradsoft.com.ua wrote: EXAMPLE: Suppose a program wants to test an object "o" at runtime for an optional behavior defined by a class or interface "T". In current Java, the program could write: try { T t = (T) o; ... use t ... } catch (ClassCastException ex) { } Using the proposed feature, the program would write: T t = o.getExtension(T.class); if (t != null) { ... use t ... } The following examples are all hypothetical, but plausible to varying degrees. Note that many of them use instances of existing platform Sorry, I can't understand, how this differ from if (o instanceof T) { T t = (T)o; .... use t ... } ? From mthornton at optrak.co.uk Thu Mar 26 12:25:27 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Thu, 26 Mar 2009 19:25:27 +0000 Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime In-Reply-To: References: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> Message-ID: <49CBD6A7.3030603@optrak.co.uk> rssh at gradsoft.com.ua wrote: >> EXAMPLE: >> >> Suppose a program wants to test an object "o" at runtime for an optional >> behavior defined by a class or interface "T". In current Java, the program >> could write: >> >> try { >> T t = (T) o; >> ... use t ... >> } catch (ClassCastException ex) { >> } >> >> Using the proposed feature, the program would write: >> >> T t = o.getExtension(T.class); >> if (t != null) { >> ... use t ... >> } >> >> The following examples are all hypothetical, but plausible to varying >> degrees. Note that many of them use instances of existing platform >> > > > Sorry, I can't understand, how this differ from > > if (o instanceof T) { > T t = (T)o; > .... use t ... > } > > ? > > > > The getExtension method need not return its own object but could delegate to another object. This functionality is essentially the same as that provided by objects implementing the java.sql.Wrapper interface. Mark Thornton From markmahieu at googlemail.com Thu Mar 26 12:27:39 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 26 Mar 2009 19:27:39 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <49CAB929.8050302@joda.org> References: <49CAB929.8050302@joda.org> Message-ID: 2009/3/25 Stephen Colebourne > > > Very cool. I like it. Thanks! > > DESIGN ALTERNATIVES: > > > > The following variations have been explored and are worth mentioning: > > > > * Allow auto-assignment parameters on all non-abstract methods. > > This may be especially useful on the extremely common 'setter' > methods > > in 'value object' classes. > > I think its right to leave this out for now, pending more investigation > into a bigger properties solution. Perhaps so, although it would be a very simple way to improve the state of affairs for POJOs right now. The additions to the grammar could be a little smaller than those I proposed as well :) > Stephen Mark From belingueres at gmail.com Thu Mar 26 12:38:00 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Thu, 26 Mar 2009 16:38:00 -0300 Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime In-Reply-To: <61199.69.239.104.86.1238095241.squirrel@69.239.104.86> References: <61199.69.239.104.86.1238095241.squirrel@69.239.104.86> Message-ID: I don't get it. You still need an "if" after you call the getExtension method (thus the client code is not more object-oriented than using instanceof). And instanceof works on null references too. 2009/3/26, Alan Snyder : > Sorry if I was not clear enough. The difference is that getExtension is a > method, therefore it can be overridden in a subclass. > > On Mar 26, 2009, at 12:12 PM, rssh at gradsoft.com.ua wrote: > > EXAMPLE: > > Suppose a program wants to test an object "o" at runtime for an optional > behavior defined by a class or interface "T". In current Java, the program > could write: > > try { > T t = (T) o; > ... use t ... > } catch (ClassCastException ex) { > } > > Using the proposed feature, the program would write: > > T t = o.getExtension(T.class); > if (t != null) { > ... use t ... > } > > The following examples are all hypothetical, but plausible to varying > degrees. Note that many of them use instances of existing platform > > > Sorry, I can't understand, how this differ from > > if (o instanceof T) { > T t = (T)o; > .... use t ... > } > > ? > > > > From abies at adres.pl Thu Mar 26 12:59:13 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Thu, 26 Mar 2009 20:59:13 +0100 Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime In-Reply-To: References: <61199.69.239.104.86.1238095241.squirrel@69.239.104.86> Message-ID: <49CBDE91.90504@adres.pl> Gabriel Belingueres wrote: > I don't get it. You still need an "if" after you call the getExtension > method (thus the client code is not more object-oriented than using > instanceof). > > Idea here is that object doesn't have to implement all the interfaces it provides as 'getExtension'. For example, you could imagine some kind of persistence-aware objects, which delegate actual work to specialized classes. Instead of having Person implementing SQLSerializable interface, you would have getExtension class returning some kind of specialized wrapper (probably retrieved from some kind of externally configurable factory), and you would have to implement only one method delegating things further instead of all the methods of SQLSerializable. Of course, it can be also implemented by having a method like getPersistenceWrapper(TypeOfPersistence) on object - but OP propose to have one method to solve all the needs. I don't really see a major benefit here. For it to be really useful, it would have to be somehow dependent on internals of the object (in other case you can just make a application dependent static method accepting object and target interface). At the same time, there would have to be some incentive for the object to not implement the actual interface (not exposing public methods, maybe some performance benefits because of some kind of caching in wrapper object, without polluting the main object with fields required to implement the interface). In highly dynamic systems/environment, with a bit of trickery it could be used to 'inject' interfaces into existing classes/objects. Still, I think that some kind of outside mediator is better for that rather than putting it in object itself. Regards, Artur Biesiadowski From develop4lasu at gmail.com Thu Mar 26 13:05:09 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 21:05:09 +0100 Subject: PROPOSAL: 'final' without explicit type Message-ID: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> AUTOHOR: Laau aka Marek Kozie? FEATURE SUMMARY: MAJOR ADVANTAGE: It allows people to concentrate on logic during operating on heavy generics and to use values which are more intuitive for them than variables. MAJOR BENEFIT(s): It allows to avoid duplicating unnecessarily types of declaration. It increasea concentration on 'what I've got' than on 'what type is that' (we decrease size by one to obtain last element index, not because we can do this = it's int), while for variables we still keep concentrate on: 'what type is that' / 'what I can put there'. Editing existing code to get some value is easier. That method can be itself multi-thread with this, but it's a far future. Using of Generics is easier. MAJOR DISADVANTAGE: Certainly, some people will overuse this solution. It might be a problem if a person does not know how to give proper names for values. ALTERNATIVES: Normal variables. EXAMPLES SIMPLE / ADVANCED EXAMPLE: public Map> readMaping(){ final map = new HashMap>(); for( final row : readLine() ){ String key = row.get(0); row.remove(0); map.put(key, row); } return map; } public Map> readMaping(){ final map; //compile time error map= new HashMap>(); for( final row : readLine() ){ String key = row.get(0); row.remove(0); map.put(key, row); } return map; } public class Final { static final maping = new HashMap>(); } public class Final { static final maping = (Map>)loadMap(); } DETAILS SPECIFICATION: FieldDeclaration FieldDeclaration would be extended to allow omitting Type declaration if field is final and it's directly followed by assignment of new class instance creation(created object type would be used), or of CastExpression (JLS 15.16) (ReferenceType would be used). SPECIFICATION: LocalVariableDeclarationStatement (JLS 14.4) Local Variable Declaration Statements would be extended to allow omitting Type declaration if field is final and listed rules taking place: - VariableInitializer appears. - Variable is not initialized directly with null. - VariableInitializer type is neither primitive nor Object. - If VariableInitializer -Expression type is intersection type (we always ommit Object type in intersection), then: --> If intersected types have common ancestor then this ancestor is used as type. --> If effect of intersected types is one Interface, then this interface is used as type. --> In other way, an error occurs. COMPILATION: Just as today, value type only need to be determined. For first implementation this solution can omit supporting intersections. TESTING: The same as final-s variables. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: None. COMPATIBILITY Only code is no forward compatible. REFERENCES http://bugs.sun.com/view_bug.do?bug_id=4459053 http://bugs.sun.com/view_bug.do?bug_id=4983159 http://lasu2string.blogspot.com/2009/03/final-without-explicit-type-proposal.html PS. Personally I think that consider operator is better, but I'll take time to improve this proposal while it's more Java-like. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Thu Mar 26 13:08:39 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 21:08:39 +0100 Subject: For further consideration... In-Reply-To: References: <49C95DB5.6020202@sun.com> <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> <49C96A42.9050805@sun.com> Message-ID: <28bca0ff0903261308o6b60d7aar78618817f3edd15b@mail.gmail.com> 2009/3/25 Tim Keith : > I would like to suggest at least leaving out ?[] > > The example in the proposal is not very compelling: > ? ?class Group { > ? ? ? ?Person[] members; // null if no members > ? ?} > ? ?class Person { > ? ? ? ?String name; // may be null > ? ?} > ? ?final String aMember = g?.members?[0]?.name ?: "nobody"; > > If members is null you get "nobody" but if members is empty (the logical way > to signify "no members") you get ArrayIndexOutOfBoundsException. > > "array?[...]" is like saying: if array is null treat it like it's an > infinitely > long array of nulls. > > "object?.member" is like saying: if object it null, treat it like every > field > is null and every method returns null. > The array analog to that should be that "array?.length" means > ? ?array == null ? 0 : array.length > > -- Tim > > ArrayIndexOutOfBoundsException is valid because on ArrayList would work it in the same way. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From neal at gafter.com Thu Mar 26 13:15:06 2009 From: neal at gafter.com (Neal Gafter) Date: Thu, 26 Mar 2009 13:15:06 -0700 Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime In-Reply-To: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> References: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> Message-ID: <15e8b9d20903261315m306f7907u18f0b5386cc21ba2@mail.gmail.com> This can be done today by creating a new interface that you implement if you have any extensions... interface Extension { T getExtension(Class c); } and a utility class to get the extension... T t = Extensions.getExtension(o, T.class); if (t != null) { ... use t ... } This is not much boilerplate in the clients compared to your proposal, and it is not a breaking change because it requires no change to Object. If this pattern becomes wildly popular, one might recommend a change in Object. As far as I know it isn't yet popular. By the way, your implementation of getExtension will cause a ClassCastException in clients that don't implement the type passed in (i.e. your catch clause will never be executed). It also attempts to use exceptions for normal control-flow, which would slow things down due to stack traces being captured by the VM. A better implementation would be public T getExtension(Class c) { return c.isInstance(this) ? c.cast(this) : null; } If performance is a concern, this can be made about twice as fast (at the expense of a generics warning) by replacing c.cast(this) by (T)this. Regards, Neal On Thu, Mar 26, 2009 at 12:08 PM, Alan Snyder wrote: > Improved Support for Optional Object Behaviors at Runtime > > > AUTHOR: Alan Snyder > > OVERVIEW > > FEATURE SUMMARY: > > This proposal would add a method to class Object to allow runtime access > to optional object behaviors. > > MAJOR ADVANTAGE: > > As designs evolve and become more complex, it is useful to split out > separable chunks of behavior whose support by an object might be optional. > In current Java, the universally applicable technique for testing for and > making use of optional behavior is the type cast. The type cast is limited > by its tight coupling with the type hierarchy; as a result, because Java > has single class inheritance, a class can not support an optional behavior > defined by another class that is not already in its class hierarchy. In > addition, because type casts cannot be simulated by an object, it is not > compatible with delegation. For an object implemented by delegation to > support optional behaviors using type casts, there would need to be one > delegating class for each possible combination of optional behaviors. > > This proposal defines a method on class Object that can be used in place > of type casts to test for and access optional behaviors. This proposal is > not constrained by the type hierarchy of the target object, because it > permits the optional behavior to be implemented using a different (but > related) object. In addition, the determination of the available behaviors > can be made dynamically. Specifically, this proposal allows a class > implemented using delegation to mimic the set of optional behaviors > supported by its delegate, even if the delegate is replaceable. > > MAJOR BENEFIT: > > By adding a method to class Object, this feature can be supported by any > class, even existing Java platform classes, with no additional changes to > their class hierarchies. Because the feature is universally available, the > use of type casts for this purpose can be deprecated. > > This technique can be used to simply interfaces, or avoid making them more > complex. > > MAJOR DISADVANTAGE: > > Any change to class Object freaks people out. This is the only change I > can think of that is so obviously universal that it deserves to be in > class Object. > > ALTERNATIVES: > > One alternative is to define this method in a new interface. This > disadvantage of defining a new interface is that existing classes and > interfaces would not support the method without themselves being changed. > The other alternative is to add this method to classes and interfaces on > an as needed basis. Either alternative forces programmers to use type > casts in those cases where this method was not available. Also, new > implementations of unchanged classes and interfaces would not be able to > support this feature for existing clients of those classes and interfaces. > > EXAMPLE: > > Suppose a program wants to test an object "o" at runtime for an optional > behavior defined by a class or interface "T". In current Java, the program > could write: > > ? ? ? ?try { > ? ? ? ? ? ? ? ?T t = (T) o; > ? ? ? ? ? ? ? ?... use t ... > ? ? ? ?} catch (ClassCastException ex) { > ? ? ? ?} > > Using the proposed feature, the program would write: > > ? ? ? ?T t = o.getExtension(T.class); > ? ? ? ?if (t != null) { > ? ? ? ? ? ? ? ?... use t ... > ? ? ? ?} > > The following examples are all hypothetical, but plausible to varying > degrees. Note that many of them use instances of existing platform > classes. > > ? ? ? ?// Test a list to see if it is observable, and get access > ? ? ? ?// to the observable methods. > > ? ? ? ?Observable o = list.getExtension(Observable.class); > > ? ? ? ?// Test a file to see if supports metadata, and get access > ? ? ? ?// to the metadata methods. > > ? ? ? ?FileMetadata fm = file.getExtension(FileMetadata.class); > > ? ? ? ?// Test file metadata to see if Mac OS file metadata is > ? ? ? ?// supported. Note that the file might be on another > ? ? ? ?// machine, so this call might succeed even on a non-Mac system. > > ? ? ? ?MacOSFileMetadata mfm = fm.getExtension(MacOSFileMetadata.class); > > ? ? ? ?// Test a file to see if it supports the new File API. > ? ? ? ?// Note that using this approach the new File API does > ? ? ? ?// not have to be an extension of the old API. > > ? ? ? ?java.nio.File nf = file.getExtension(java.nio.File.class); > > ? ? ? ?// Test a file to see if it is a directory, and get access to > ? ? ? ?// the directory methods. > > ? ? ? ?Directory dir = file.getExtension(Directory.class); > > ? ? ? ?// Test a file to see if it is a symlink, and get access to > ? ? ? ?// the symlink methods. > > ? ? ? ?Symlink s = file.getExtension(Symlink.class); > > ? ? ? ?// Test a file to see if it a directory and whether it provides > ? ? ? ?// read and update access to the directory contents using the > ? ? ? ?// List API (!). > > ? ? ? ?List fs = (List) file.getExtension(List.class); > > DETAILS > > The default definition in class Object would be: > > ? ? ? ?public T getExtension(Class c) > ? ? ? ?{ > ? ? ? ? ? ? ? ?try { > ? ? ? ? ? ? ? ? ? ? ? ?return (T) this; > ? ? ? ? ? ? ? ?} catch (ClassCastException ex) { > ? ? ? ? ? ? ? ? ? ? ? ?return null; > ? ? ? ? ? ? ? ?} > ? ? ? ?} > > Thus, if not overridden, the method has the same effect as the type cast. > Thus it can be used in place of type casts even on instances of existing > classes. > > Once this method is in place, programmers should be discouraged from using > type casts for the purpose of testing for optional behavior. > > SPECIFICATION: > > JLS 4.3.2 would be changed to define this method. > > I'm not aware of other changes. > > MIGRATION: > > It would be advisable to convert appropriate type casts to invocations of > this method in existing code. > > Once this method is available in class Object, other Java platform classes > and APIs can be changed to take advantage of it. > > COMPATIBILITY > > BREAKING CHANGES: > > No matter what name is chosen for this method, some existing program could > fail to compile if it defines a method with the same name and signature > but (say) a different return type. Methods with class parameters are > presumably uncommon. > > According to JLS 13.4.12, binary compatibility should not be broken > because the method is public. > > EXISTING PROGRAMS: > > Existing classes automatically support this method to the same extent that > they current support type casts for accessing optional behavior. > > > > From develop4lasu at gmail.com Thu Mar 26 13:16:42 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 21:16:42 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> Message-ID: <28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> W dniu 26 marca 2009 19:30 u?ytkownik Gabriel Belingueres napisa?: > Wouldn't it be simpler to add a Pascal-like "with" statement? This > would solve at least the method chaining issue: > > with(object) { > ?method1(); > ?metohd2(); > ? ... > ?methodN(); > } > Simpler? Yes. Better? No. this would look like method execution from current class. This would be better: with(object) { ?.method1(); ?.metohd2(); ? ... ?.methodN(); } Other problem are lines, this solution use n+2 lines: it's exactly kind of problem that people want to prevent. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From rssh at gradsoft.com.ua Thu Mar 26 13:19:42 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 22:19:42 +0200 (EET) Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: Also see http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000832.html for URL-s with another proposal and implementation of such feature. and http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000836.html For detailed explanation of Neal Gafter. //BTW, I thing submitting this a good thing and will be happy see this in // next Java version. > AUTOHOR: Laau aka Marek Kozie?? > > FEATURE SUMMARY: > > MAJOR ADVANTAGE: > It allows people to concentrate on logic during operating on heavy > generics and to use values which are more intuitive for them than > variables. > > MAJOR BENEFIT(s): > It allows to avoid duplicating unnecessarily types of declaration. > It increasea concentration on 'what I've got' than on 'what type is > that' (we decrease size by one to obtain last element index, not > because we can do this = it's int), while for variables we still keep > concentrate on: 'what type is that' / 'what I can put there'. > Editing existing code to get some value is easier. > That method can be itself multi-thread with this, but it's a far future. > Using of Generics is easier. > > > MAJOR DISADVANTAGE: > Certainly, some people will overuse this solution. > It might be a problem if a person does not know how to give proper > names for values. > > ALTERNATIVES: > Normal variables. > > > EXAMPLES > > SIMPLE / ADVANCED EXAMPLE: > public Map> readMaping(){ > final map = new HashMap>(); > for( final row : readLine() ){ > String key = row.get(0); > row.remove(0); > map.put(key, row); > } > return map; > } > > public Map> readMaping(){ > final map; //compile time error > map= new HashMap>(); > for( final row : readLine() ){ > String key = row.get(0); > row.remove(0); > map.put(key, row); > } > return map; > } > > public class Final { > static final maping = new HashMap>(); > } > > public class Final { > static final maping = (Map>)loadMap(); > } > > DETAILS > > SPECIFICATION: FieldDeclaration > FieldDeclaration would be extended to allow omitting Type > declaration if field is final and it's directly followed by assignment > of new class instance creation(created object type would be used), or > of CastExpression (JLS 15.16) (ReferenceType would be used). > > SPECIFICATION: LocalVariableDeclarationStatement > (JLS 14.4) Local Variable Declaration Statements would be extended > to allow omitting Type declaration if field is final and listed rules > taking place: > - VariableInitializer appears. > - Variable is not initialized directly with null. > - VariableInitializer type is neither primitive nor Object. > - If VariableInitializer -Expression type is intersection type (we > always ommit Object type in intersection), then: > --> If intersected types have common ancestor then this ancestor is > used as type. > --> If effect of intersected types is one Interface, then this > interface is used as type. > --> In other way, an error occurs. > > > COMPILATION: > Just as today, value type only need to be determined. > For first implementation this solution can omit supporting > intersections. > > TESTING: > The same as final-s variables. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > None. > > COMPATIBILITY > Only code is no forward compatible. > > REFERENCES > > http://bugs.sun.com/view_bug.do?bug_id=4459053 > > http://bugs.sun.com/view_bug.do?bug_id=4983159 > > http://lasu2string.blogspot.com/2009/03/final-without-explicit-type-proposal.html > > > > PS. Personally I think that consider operator is better, but I'll take > time to improve this proposal while it's more Java-like. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie?? > > http://lasu2string.blogspot.com/ > > From develop4lasu at gmail.com Thu Mar 26 13:22:37 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 21:22:37 +0100 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: References: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> <28bca0ff0903230256p48b36533n77a148232743d28e@mail.gmail.com> Message-ID: <28bca0ff0903261322g624a1f22t1916b5f93871aed7@mail.gmail.com> 2009/3/24 Howard Lovatt : > I don't get the example. Is class B meant to be Bar? Can you clarify? > > -- Howard. > No, B is B. I wanted show the problem: public B(Bar bar, Foo foo) { super(bar); this.foo = foo; } mean in runtime: this.bar = bar; this.foo = bar.foo; this.foo = foo; public B(Bar bar, Foo foo) { this.foo = foo; super(bar); } mean in runtime: this.foo = foo; this.bar = bar; this.foo = bar.foo; While second constructor look really innocent. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Thu Mar 26 13:24:22 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 21:24:22 +0100 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: <28bca0ff0903261324odbed74fnd582863859f5738c@mail.gmail.com> 2009/3/26 : > > Also see > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000832.html > ?for URL-s with another proposal and implementation of such feature. > and > ?http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000836.html > For detailed explanation of Neal Gafter. > > //BTW, I thing submitting this a good thing and will be happy see this in > // ?next Java version. > > Thanks, I could not find that. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From rssh at gradsoft.com.ua Thu Mar 26 13:43:04 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 22:43:04 +0200 (EET) Subject: ability to invoke a MethodHandle [?] Message-ID: <30cfe51415dc0c847e4d731185b963ba.squirrel@wmail.gradsoft.ua> Good day. In blog of Remi Forax (http://weblogs.java.net/blog/forax/) I read that ability to invoke method handle was planned in project coin. But I does not see such proposal yet. Is it still planned or plans was changed to leave coin only for non-Sun proposals ? From develop4lasu at gmail.com Thu Mar 26 13:50:30 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 21:50:30 +0100 Subject: PROPOSAL: String parameters compile time validation (early beta) Message-ID: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> Strings represent most wide range of objects, while they are omitted with good validation at compile time (ide). As help I want propose, or at start ask for opinion about adding compile time validation to String parameters. poor sample: class Binary{ @RegExp("regExpName","regExp") @RegExp("regExpName1","regExp") void main(...){ String bites = @RegExp("regExpName") "...."; ... } int parseBites(@RegExp("regExpName") String bites){ ... }; } Validation by regexp-s would be only at compile time (efficiency). Target is quite clear, but anyone see any problems? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Thu Mar 26 14:01:07 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 22:01:07 +0100 Subject: For further consideration... In-Reply-To: <28bca0ff0903261308o6b60d7aar78618817f3edd15b@mail.gmail.com> References: <49C95DB5.6020202@sun.com> <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> <49C96A42.9050805@sun.com> <28bca0ff0903261308o6b60d7aar78618817f3edd15b@mail.gmail.com> Message-ID: Just because something goes wrong in one place is no excuse to let it happen in another. --Reinier Zwitserloot Like it? Tip it! http://tipit.to On Mar 26, 2009, at 21:08, Marek Kozie? wrote: > 2009/3/25 Tim Keith : >> I would like to suggest at least leaving out ?[] >> >> The example in the proposal is not very compelling: >> class Group { >> Person[] members; // null if no members >> } >> class Person { >> String name; // may be null >> } >> final String aMember = g?.members?[0]?.name ?: "nobody"; >> >> If members is null you get "nobody" but if members is empty (the >> logical way >> to signify "no members") you get ArrayIndexOutOfBoundsException. >> >> "array?[...]" is like saying: if array is null treat it like it's an >> infinitely >> long array of nulls. >> >> "object?.member" is like saying: if object it null, treat it like >> every >> field >> is null and every method returns null. >> The array analog to that should be that "array?.length" means >> array == null ? 0 : array.length >> >> -- Tim >> >> > > ArrayIndexOutOfBoundsException is valid because on ArrayList would > work it in the same way. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From develop4lasu at gmail.com Thu Mar 26 14:03:08 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 22:03:08 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: Message-ID: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> I see one problem here. class Some{ final String name; public Some(String this.name){} } perform .intern() is impossible now. But I like the proposition 'much'. Simple and clear. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From rssh at gradsoft.com.ua Thu Mar 26 14:04:28 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Thu, 26 Mar 2009 23:04:28 +0200 (EET) Subject: PROPOSAL: String parameters compile time validation (early beta) In-Reply-To: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> References: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> Message-ID: As I remember, this is part of JSR 305 http://jcp.org/en/jsr/detail?id=305 (In addition, this is library change, not a language change.) > Strings represent most wide range of objects, while they are omitted > with good validation at compile time (ide). > As help I want propose, or at start ask for opinion about adding > compile time validation to String parameters. > > poor sample: > > class Binary{ > @RegExp("regExpName","regExp") > @RegExp("regExpName1","regExp") > > void main(...){ > String bites = @RegExp("regExpName") "...."; > ... > } > > int parseBites(@RegExp("regExpName") String bites){ > ... > }; > } > > Validation by regexp-s would be only at compile time (efficiency). > > Target is quite clear, but anyone see any problems? > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie?? > > http://lasu2string.blogspot.com/ > > From reinier at zwitserloot.com Thu Mar 26 14:06:24 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 22:06:24 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> <28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> Message-ID: <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> That argument makes no sense. If you're concerned about lines, try: with (object) { method1(); method2(); method3(); } If your coding style guide says that you must neccessarily newline after braces and semicolons, then you should question why that rule exists, and why it would not exist for the builder pattern. Incidentally, I like a return this proposal more, because I think it's lower impact (no new keyword, we're already familiar with methods that return themselves, a complete proposal would just enshrine this practice into canon), and looks better. Just saying that 'number of lines' is not a valid argument against. --Reinier Zwitserloot On Mar 26, 2009, at 21:16, Marek Kozie? wrote: > W dniu 26 marca 2009 19:30 u?ytkownik Gabriel Belingueres > napisa?: >> Wouldn't it be simpler to add a Pascal-like "with" statement? This >> would solve at least the method chaining issue: >> >> with(object) { >> method1(); >> metohd2(); >> ... >> methodN(); >> } >> > > Simpler? > Yes. > > Better? > No. this would look like method execution from current class. > This would be better: > with(object) { > .method1(); > .metohd2(); > ... > .methodN(); > } > > Other problem are lines, this solution use n+2 lines: it's exactly > kind of problem that people want to prevent. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From develop4lasu at gmail.com Thu Mar 26 14:10:11 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 22:10:11 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> Message-ID: <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> I just wander loudly: class Some{ private String name; public Some setName (String name){ this.name = name; return this; }; public String getName(){ return this.name; }; } to: class Some{ private String name; public this setName (String this.name){}; public this.name getName(){}; } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Thu Mar 26 14:13:00 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 22:13:00 +0100 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: As Neal Gafter explained, lub (intersection type generator) will already find a common supertype if 1 of the intersection types is a supertype of all others. The notion of making the type 'the interface', if the intersection type contains exactly 1 interface, is a very bad idea. There is no precedent for this, and there are plenty of situations where this will go wrong. For example: final list = foo ? new LinkedList() : new ArrayList(); the type of 'list' is what, exactly? Serializable? Cloneable? List? They're all valid, so that wouldn't work. If the feature says it will attempt to find a proper interface, people will wonder why that does not work. or, how about: final number = foo ? 5 : 10L; This will result in 'number's type being Serializable, which is completely wrong, because that's the only common interface. People would expect that to become 'Number', but it won't be, because Numer is a class and not an interface. finally, what's the wisdom in not allowing this for primitives? What's so bad about: final counter = 0; --Reinier Zwitserloot On Mar 26, 2009, at 21:05, Marek Kozie? wrote: > AUTOHOR: Laau aka Marek Kozie? > > FEATURE SUMMARY: > > MAJOR ADVANTAGE: > It allows people to concentrate on logic during operating on heavy > generics and to use values which are more intuitive for them than > variables. > > MAJOR BENEFIT(s): > It allows to avoid duplicating unnecessarily types of declaration. > It increasea concentration on 'what I've got' than on 'what type is > that' (we decrease size by one to obtain last element index, not > because we can do this = it's int), while for variables we still keep > concentrate on: 'what type is that' / 'what I can put there'. > Editing existing code to get some value is easier. > That method can be itself multi-thread with this, but it's a far > future. > Using of Generics is easier. > > > MAJOR DISADVANTAGE: > Certainly, some people will overuse this solution. > It might be a problem if a person does not know how to give proper > names for values. > > ALTERNATIVES: > Normal variables. > > > EXAMPLES > > SIMPLE / ADVANCED EXAMPLE: > public Map> readMaping(){ > final map = new HashMap>(); > for( final row : readLine() ){ > String key = row.get(0); > row.remove(0); > map.put(key, row); > } > return map; > } > > public Map> readMaping(){ > final map; //compile time error > map= new HashMap>(); > for( final row : readLine() ){ > String key = row.get(0); > row.remove(0); > map.put(key, row); > } > return map; > } > > public class Final { > static final maping = new HashMap>(); > } > > public class Final { > static final maping = (Map>)loadMap(); > } > > DETAILS > > SPECIFICATION: FieldDeclaration > FieldDeclaration would be extended to allow omitting Type > declaration if field is final and it's directly followed by assignment > of new class instance creation(created object type would be used), or > of CastExpression (JLS 15.16) (ReferenceType would be used). > > SPECIFICATION: LocalVariableDeclarationStatement > (JLS 14.4) Local Variable Declaration Statements would be extended > to allow omitting Type declaration if field is final and listed rules > taking place: > - VariableInitializer appears. > - Variable is not initialized directly with null. > - VariableInitializer type is neither primitive nor Object. > - If VariableInitializer -Expression type is intersection type (we > always ommit Object type in intersection), then: > --> If intersected types have common ancestor then this ancestor is > used as type. > --> If effect of intersected types is one Interface, then this > interface is used as type. > --> In other way, an error occurs. > > > COMPILATION: > Just as today, value type only need to be determined. > For first implementation this solution can omit supporting > intersections. > > TESTING: > The same as final-s variables. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > None. > > COMPATIBILITY > Only code is no forward compatible. > > REFERENCES > > http://bugs.sun.com/view_bug.do?bug_id=4459053 > > http://bugs.sun.com/view_bug.do?bug_id=4983159 > > http://lasu2string.blogspot.com/2009/03/final-without-explicit-type-proposal.html > > > > PS. Personally I think that consider operator is better, but I'll take > time to improve this proposal while it's more Java-like. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From abies at adres.pl Thu Mar 26 14:19:56 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Thu, 26 Mar 2009 22:19:56 +0100 Subject: PROPOSAL: String parameters compile time validation (early beta) In-Reply-To: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> References: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> Message-ID: <49CBF17C.1050708@adres.pl> Marek Kozie? wrote: > Validation by regexp-s would be only at compile time (efficiency). > > Target is quite clear, but anyone see any problems? > As somebody else said, it might be a part of the JSR 305. But just to give you example complications: can (a{1-3}) be passed to (a+) ? (a|b) passed to (b|a) ? [0-9][a-z] passed to [:digit:][:letter:] ? It might be a nice project for somebody's thesis to work on equivalence/superset/subset relationships between regexp (especially fun if you take backreferences into account), but I would not put it into java type system... And no, validation only on compile time doesn't make any sense. You would need some kind of cast operator on regexp, which would cast free-form string into regexp-bound string (and throw exception otherwise) - similar to way Class.cast works. Regards, Artur Biesiadowski From markmahieu at googlemail.com Thu Mar 26 14:21:37 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Thu, 26 Mar 2009 21:21:37 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> Message-ID: 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 develop4lasu at gmail.com Thu Mar 26 14:20:12 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 22:20:12 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> <28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> Message-ID: <28bca0ff0903261420t736ab47i7527625e2d9a0545@mail.gmail.com> 2009/3/26 Reinier Zwitserloot : > That argument makes no sense. If you're concerned about lines, try: > > with (object) { method1(); method2(); method3(); } > > > If your coding style guide says that you must neccessarily newline after > braces and semicolons, then you should question why that rule exists, and > why it would not exist for the builder pattern. > > Incidentally, I like a return this proposal more, because I think it's lower > impact (no new keyword, we're already familiar with methods that return > themselves, a complete proposal would just enshrine this practice into > canon), and looks better. Just saying that 'number of lines' is not a valid > argument against. > > ?--Reinier Zwitserloot > > You total right, I just doubt if most peoples will use it in line, but I wasn't clear enough. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Thu Mar 26 14:38:56 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 22:38:56 +0100 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: <28bca0ff0903261438x796a52c5pc0d0375dc5c7fffb@mail.gmail.com> 2009/3/26 Reinier Zwitserloot : > As Neal Gafter explained, lub (intersection type generator) will already > find a common supertype if 1 of the intersection types is a supertype of all > others. The notion of making the type 'the interface', if the intersection > type contains exactly 1 interface, is a very bad idea. There is no precedent > for this, and there are plenty of situations where this will go wrong. For > example: > > final list = foo ? new LinkedList() : new ArrayList(); > > the type of 'list' is what, exactly? Serializable? Cloneable? List? They're > all valid, so that wouldn't work. If the feature says it will attempt to > find a proper interface, people will wonder why that does not work. > > or, how about: > > final number = foo ? 5 : 10L; > "neither primitive" > This will result in 'number's type being Serializable, which is completely > wrong, because that's the only common interface. People would expect that to > become 'Number', but it won't be, because Numer is a class and not an > interface. > > > finally, what's the wisdom in not allowing this for primitives? What's so > bad about: > > final counter = 0; > > > ?--Reinier Zwitserloot > > INTERSECTION: It's no problem for me to forbid intersection here, or limit it to situation when result type is 100% clear (at least for start): final s = ( foo ? some : null ); final s = ( foo ? some : other ); // when one is ancestor of the second one. PRIMITIVES: I want this to be clear and make peoples think automatically: final + no type => Object while primitives have not much common with Objects I'm against mixing them here. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From belingueres at gmail.com Thu Mar 26 14:41:13 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Thu, 26 Mar 2009 18:41:13 -0300 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: VariableInitializer type is neither primitive nor Object. Why? Also, there are times when it might be OK to assign null to a variable as long as the compile time type can be uniquely identified: final a = (booleanCondition) ? null : new SomeClass(); In this case the you can assume that the type of variable a will be SomeClass. What about autoboxing? final a = (booleanCondition) ? 1 : new Integer(2); it is int or Integer? (currently the ? operand resolve it to an int) Also see my notes on the interaction between final variables and overloading: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000859.html IMO, when using the ? operator it should not try to find an intersection type for the compile time type of the final variable, but it should be the exact type on both the 2nd and 3rd operand, otherwise it should raise a compiler error. If you want another type for the variable, then specify it as usual. 2009/3/26 Marek Kozie? : > AUTOHOR: Laau aka Marek Kozie? > > FEATURE SUMMARY: > > MAJOR ADVANTAGE: > It allows people to concentrate on logic during operating on heavy > generics and to use values which are more intuitive for them than > variables. > > MAJOR BENEFIT(s): > It allows to avoid duplicating unnecessarily types of declaration. > It increasea concentration on 'what I've got' than on 'what type is > that' (we decrease size by one to obtain last element index, not > because we can do this = it's int), while for variables we still keep > concentrate on: 'what type is that' / 'what I can put there'. > Editing existing code to get some value is easier. > That method can be itself multi-thread with this, but it's a far future. > Using of Generics is easier. > > > MAJOR DISADVANTAGE: > Certainly, some people will overuse this solution. > It might be a problem if a person does not know how to give proper > names for values. > > ALTERNATIVES: > Normal variables. > > > EXAMPLES > > SIMPLE / ADVANCED EXAMPLE: > ?public Map> readMaping(){ > ? ?final map = new HashMap>(); > ? ?for( final row : readLine() ){ > ? ? ? String key = row.get(0); > ? ? ? row.remove(0); > ? ? ? map.put(key, row); > ? ?} > ? ?return map; > ?} > > ?public Map> readMaping(){ > ? ?final map; //compile time error > ? ?map= new HashMap>(); > ? ?for( final row : readLine() ){ > ? ? ? String key = row.get(0); > ? ? ? row.remove(0); > ? ? ? map.put(key, row); > ? ?} > ? ?return map; > ?} > > public class Final { > ?static final maping = new HashMap>(); > } > > public class Final { > ?static final maping = (Map>)loadMap(); > } > > DETAILS > > SPECIFICATION: FieldDeclaration > ?FieldDeclaration would be extended to allow omitting Type > declaration if field is final and it's directly followed by assignment > of new class instance creation(created object type would be used), or > of CastExpression (JLS 15.16) (ReferenceType would be used). > > SPECIFICATION: LocalVariableDeclarationStatement > ?(JLS 14.4) Local Variable Declaration Statements would be extended > to allow omitting Type declaration if field is final and listed rules > taking place: > - VariableInitializer appears. > - Variable is not initialized directly with null. > - VariableInitializer type is neither primitive nor Object. > - If VariableInitializer -Expression type is intersection type (we > always ommit Object type in intersection), then: > ?--> If intersected types have common ancestor then this ancestor is > used as type. > ?--> If effect of intersected types is one Interface, then this > interface is used as type. > ?--> In other way, an error occurs. > > > COMPILATION: > ?Just as today, value type only need to be determined. > ?For first implementation this solution can omit supporting intersections. > > TESTING: > The same as final-s variables. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > None. > > COMPATIBILITY > Only code is no forward compatible. > > REFERENCES > > http://bugs.sun.com/view_bug.do?bug_id=4459053 > > http://bugs.sun.com/view_bug.do?bug_id=4983159 > > http://lasu2string.blogspot.com/2009/03/final-without-explicit-type-proposal.html > > > > PS. Personally I think that consider operator is better, but I'll take > time to improve this proposal while it's more Java-like. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From develop4lasu at gmail.com Thu Mar 26 14:47:50 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 22:47:50 +0100 Subject: For further consideration... In-Reply-To: References: <49C95DB5.6020202@sun.com> <1631da7d0903241530i772593d7ked8e87ecc9207809@mail.gmail.com> <49C96A42.9050805@sun.com> <28bca0ff0903261308o6b60d7aar78618817f3edd15b@mail.gmail.com> Message-ID: <28bca0ff0903261447g50a6d252yf38ccdd65bde2347@mail.gmail.com> 2009/3/26 Reinier Zwitserloot : > Just because something goes wrong in one place is no excuse to let it happen > in another. > ?--Reinier Zwitserloot > Like it? Tip it! > http://tipit.to > > But I do not like magic work, so if something work in same way in all lists/arrays then this should work in same way in future, or it should be explicit changed. array?[index] : null-safe array??[index] or array?[index?]: null-safe & index safe ? array.?getElementIfExists(index): null-safe & index safe -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From schulz at e-spirit.de Thu Mar 26 14:55:51 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Thu, 26 Mar 2009 22:55:51 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com><49CB9959.4070704@sun.com><28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com><28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> Message-ID: <49CBF9E7.6060802@e-spirit.de> As it happens, I have written about some "with" a while ago, that might have advantages to returning this (and surely pitfalls and disadvantages). The main idea is to have a block on an object that shifts the binding of this to the object itself (as the with being proposed here). There is also an alternative by Howard Lovatt, which is referenced in my post at: http://jroller.com/jadda/entry/support_for_operating_on_a My idea reuses the "do" keyword: object do { method1(); method2(); method3(); }; It also proposes the block to result in the object itself: String str = new StringBuilder() do { append(person.getName()); if (person.isMarried()) { append("(married)"); } }.toString(); Instead of blocks, one could think of using expressions as proposed by Neal Gafter in an earlier post. Though, I think this might be too big for Coin. Stefan Reinier Zwitserloot schrieb: > That argument makes no sense. If you're concerned about lines, try: > > with (object) { method1(); method2(); method3(); } > > > If your coding style guide says that you must neccessarily newline > after braces and semicolons, then you should question why that rule > exists, and why it would not exist for the builder pattern. > > Incidentally, I like a return this proposal more, because I think it's > lower impact (no new keyword, we're already familiar with methods that > return themselves, a complete proposal would just enshrine this > practice into canon), and looks better. Just saying that 'number of > lines' is not a valid argument against. > > --Reinier Zwitserloot > > > From develop4lasu at gmail.com Thu Mar 26 15:19:01 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Thu, 26 Mar 2009 23:19:01 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <49CBF9E7.6060802@e-spirit.de> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> <28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> <49CBF9E7.6060802@e-spirit.de> Message-ID: <28bca0ff0903261519w5bd9a006uc9c1eaef92812762@mail.gmail.com> 2009/3/26 Stefan Schulz : > As it happens, I have written about some "with" a while ago, that might > have advantages to returning this (and surely pitfalls and > disadvantages). The main idea is to have a block on an object that > shifts the binding of this to the object itself (as the with being > proposed here). There is also an alternative by Howard Lovatt, which is > referenced in my post at: > http://jroller.com/jadda/entry/support_for_operating_on_a > > My idea reuses the "do" keyword: > > object do { > ? method1(); > ? method2(); > ? method3(); > }; > > It also proposes the block to result in the object itself: > > String str = new StringBuilder() do { > ? append(person.getName()); > ? if (person.isMarried()) { > ? ? append("(married)"); > ? } > }.toString(); > > Instead of blocks, one could think of using expressions as proposed by > Neal Gafter in an earlier post. > Though, I think this might be too big for Coin. > > Stefan > > class Some{ void method2(Object..) void test(Other other){ other do { method1(); method2(method2()); // unclear method2(Object..); method3(); }; } } class Some{ void method2(Object..) void test(Other other){ other do { .method1(); .method2(method2()); // clear .method2(Object..); .method3(); }; } } We should focus to not create to many interactions, or make people to wander about 'what's this code do?' Will that be clear for someone who see method2 in same screen? Is increasing kinds of blocks good way? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Thomas.Hawtin at Sun.COM Thu Mar 26 15:29:31 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Thu, 26 Mar 2009 22:29:31 +0000 Subject: PROPOSAL: Return 'this' In-Reply-To: <49CBF9E7.6060802@e-spirit.de> References: <28bca0ff0903251459h212121f5peadf2e1ca32468ab@mail.gmail.com> <49CB9959.4070704@sun.com> <28bca0ff0903260851l7a9b496fy265b348c7285b6bf@mail.gmail.com> <28bca0ff0903261316l686bc29fo8bc56531a3d2ea9e@mail.gmail.com> <98F9FA4F-3363-4D12-BA89-8F058A2B5651@zwitserloot.com> <49CBF9E7.6060802@e-spirit.de> Message-ID: <49CC01CB.9050109@sun.com> Stefan Schulz wrote: > String str = new StringBuilder() do { > append(person.getName()); > if (person.isMarried()) { > append("(married)"); > } > }.toString(); I think what disturbs me about these sort of 'with' extensions, is method resolution. How do we decide which object and method 'append' applies to. That area of the language is already broken by complexity. I suspect that a reasonably complete solution in this area would not fit the definition of small, and would be the subject of much conflicting opinion. :( Tom Hawtin From schulz at e-spirit.de Thu Mar 26 15:40:07 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Thu, 26 Mar 2009 23:40:07 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <49CC01CB.9050109@sun.com> References: <49CC01CB.9050109@sun.com> Message-ID: <49CC0447.1080905@e-spirit.de> Tom Hawtin schrieb: > I think what disturbs me about these sort of 'with' extensions, is > method resolution. How do we decide which object and method 'append' > applies to. That area of the language is already broken by complexity. As I wrote, it has some pitfalls. In my blog I noted down the order of resolution, which is the way one would expect it to be in Java, analog to using inner classes. This is a variant using an instance initialization block (legal Java code): String string = new StringBuilder() {{ append(person.getName()); if (person.isMarried()) { append("(married)"); } }}.toString(); > I suspect that a reasonably complete solution in this area would not fit > the definition of small, and would be the subject of much conflicting > opinion. :( As I, too, stated ;) Stefan From reinier at zwitserloot.com Thu Mar 26 15:55:40 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Thu, 26 Mar 2009 23:55:40 +0100 Subject: PROPOSAL: String parameters compile time validation (early beta) In-Reply-To: <49CBF17C.1050708@adres.pl> References: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> <49CBF17C.1050708@adres.pl> Message-ID: <142223BF-521F-4308-8FD8-DC754A4B5D04@zwitserloot.com> I don't think the idea was to make a hierarchical tree of regexp types. There's just 1 regexp type: Pattern. The one we already have. The idea is simply to have a literal syntax for regexps, where the compiler will actually put the binary representation of a compiled pattern in the .class source. As I mentioned, this has very significant speed savings, because compiling a regexp is more expensive than applying one, especially for complex regexps that are performance sensitive. I don't understand your argument about casting. Right now, you get compile-time checking on e.g. the bounds of an integer, but if you cast, you get that check at runtime (or, actually, the bits are just cut off, but you get the point). The regexp literal notation would literally have the type 'Pattern'. You can try to cast a string to this, but that would obviously fail, and the compiler will in fact error when you try, because String is not a subtype of Pattern. If you want to turn a string into a pattern, you'd use Pattern.compile. So: Pattern x = /a*a+a*a+/; Pattern y = Pattern.compile("a*a+a*a+"); simple enough. --Reinier Zwitserloot On Mar 26, 2009, at 22:19, Artur Biesiadowski wrote: > Marek Kozie? wrote: >> Validation by regexp-s would be only at compile time (efficiency). >> >> Target is quite clear, but anyone see any problems? >> > > As somebody else said, it might be a part of the JSR 305. But just to > give you example complications: > > can (a{1-3}) be passed to (a+) ? (a|b) passed to (b|a) ? [0-9][a-z] > passed to [:digit:][:letter:] ? > > It might be a nice project for somebody's thesis to work on > equivalence/superset/subset relationships between regexp (especially > fun > if you take backreferences into account), but I would not put it into > java type system... > > And no, validation only on compile time doesn't make any sense. You > would need some kind of cast operator on regexp, which would cast > free-form string into regexp-bound string (and throw exception > otherwise) - similar to way Class.cast works. > > Regards, > Artur Biesiadowski > From schulz at e-spirit.de Thu Mar 26 15:55:50 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Thu, 26 Mar 2009 23:55:50 +0100 Subject: PROPOSAL: Return 'this' In-Reply-To: <49CC0447.1080905@e-spirit.de> References: <49CC01CB.9050109@sun.com> <49CC0447.1080905@e-spirit.de> Message-ID: <49CC07F6.1000305@e-spirit.de> Stefan Schulz schrieb: > to using inner classes. This is a variant using an instance > initialization block (legal Java code): Well, to correct myself: not quite legal, as StringBuilder is final (at least the java.lang one). And actually this is one of the restrictions to this approach: can only operate on anonymous class instanciation, i.e., no final classes, no other objects. Stefan From develop4lasu at gmail.com Thu Mar 26 16:07:41 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 27 Mar 2009 00:07:41 +0100 Subject: PROPOSAL: String parameters compile time validation (early beta) In-Reply-To: References: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> Message-ID: <28bca0ff0903261607v5aebd454w366f659b2641135e@mail.gmail.com> @Artur I didn't consider inheritance at all. But simple setting: match in all subclasses context / match only in current class context, this would solve 90% of yours problem. class Binary{ @RegExp("regExpName","regExp") int parseBites(@InheritingRegExp("regExpName") String bites){ ... }; } class Binary2 extends Binary{ @RegExp("regExpName","regExp") int parseBites(@RegExp("regExpName") String bites){ ... }; } So in Binary2 context 2 regexp checking ( Binary2 and Binary ) would be performed. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Thu Mar 26 16:35:11 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Fri, 27 Mar 2009 12:35:11 +1300 (NZDT) Subject: PROPOSAL: Language Escape Operator Message-ID: <1238110511.49cc112f28285@www.paradise.net.nz> Title Language Escape Operator latest html version at http://docs.google.com/Doc?docid=dcvp3mkv_9gdg3jfhg AUTHOR(S): Bruce Chapman OVERVIEW FEATURE SUMMARY: There is great potential for syntactic sugars to be implemented in tools rather than the Java language. One requirement of such a mechanism is that the sugared form is NOT valid java source code (otherwise the meaning is ambiguous - is a piece of code intended as is, or intended to be desugared). In order to future proof such mechanisms it is also desirable that such a syntactic sugar form will never become a valid java form due to some unanticipated future language change. A simple way to ensure this is to reserve a character as a language escape, effectively it indicates that source code is at that point escaping from the java language. Such a character should be a printable ascii character to enable it to be typed and read, and it should have no existing defined meaning in the java language within the contexts in which it is to be used. Inside commments, String literals and character literals all printable ascii characters have meaning and therefore there is no way we can escape from these. This is not thought to be an overly burdensome restriction. The candidate characters for the escape operator are therefore # (hash), \ (backslash) and ` (back quote). Neither # or ` have any currently defined meaning in the Java language specification. \ does have defined meanings but only as a unicode escape and inside String and character literals and so is also suitable. The intention of this proposal is to reserve one of these three characters for a range of uses that are outside the language. Although the syntactic sugar example is mentioned above it is but one example. A crystal ball would be advantageous here - alas we are limited to our ability to dream. Several proposals and ideas are circulating which suggest uses for each of these few remaining characters which are becoming a precious resource for language developers due to their scarcity. It is the author's belief that use of any one of these characters as a language escape operator offers far more long term value than use for a single new syntactic form. Let us reserve one of the three characters as a language escape and let all other language proposals squabble over the remaining two. For the rest of this proposal it is assumed the back-quote character is the language escape operator. Either of the three characteres could be used equally from a technical point of view however aesthetic considerations would probably place # as least desirable. MAJOR ADVANTAGE: Shuts the gate before the horse has bolted. Once all these characters are assigned meaning by the language, then there is no single character that can be used as a language escape. MAJOR DISADVANTAGE: Prevents the back-quote (GRAVE-ACCENT) character from being used in other language features. ALTERNATIVES: Alternative characters have been discussed above. Another alternative is to do nothing and let language tools develop further (using any of the three available characters) in order to get a slightly better idea of where this might be heading before committing to a language change. The risk with this approach is that all three characters might get defined uses by other language changes before one can be reserved as a language escape. At that point it would be too late and would restrict language tools. EXAMPLES SIMPLE EXAMPLE: `Property String name; is not valid Java source code, and can be automatically desugared by an IDE. See references section. ADVANCED EXAMPLE: N/A DETAILS SPECIFICATION: Add new section 3.13 after 3.12 operators. 3.12 Language Escape The Ascii back quote ` character (unicode GRAVE ACCENT) is reserved for use by tools that process mixed language content to indicate to their parsers while parsing java source code, the start of something that is not Java source code. It is the responsibility of such tools to pass only java source to the java compiler. It is a compile time error for a ` character to appear in other than a comment, a String literal or a Character literal. COMPILATION: Generate the error if the ` character is encountered in other than a comment, String or Character literal. While the protoype does this, a more specific error message might be useful. TESTING: Test for the compiler error. LIBRARY SUPPORT: No library support required. REFLECTIVE APIS: N/A OTHER CHANGES: N/A MIGRATION: N/A COMPATIBILITY BREAKING CHANGES: N/A EXISTING PROGRAMS: N/A REFERENCES http://docs.google.com/Doc?docid=dcvp3mkv_8sn3ccbkk describes a working proof of concept tool which uses ` as a language escape. EXISTING BUGS: ? URL FOR PROTOTYPE (optional): JDK6's javac is the protoype implementation for this language change. http://java.sun.com/javase/downloads From markmahieu at googlemail.com Thu Mar 26 17:07:40 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 27 Mar 2009 00:07:40 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> Message-ID: 2009/3/26 Marek Kozie? > > class Some{ > > private String name; > > public this setName (String this.name){}; > > public this.name getName(){}; > > } > Leaving to one side the idea of returning 'this' from setName, yes auto-assignment parameters could easily be made to work on all non-abstract instance methods. As you suggest, this could be extended even further to return values, but one of the questions that raises is whether it's acceptable to omit the type, as you've done in your example (imagine what it would look like in a much bigger class with many more methods). Mark From develop4lasu at gmail.com Thu Mar 26 17:22:06 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 27 Mar 2009 01:22:06 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> Message-ID: <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> W dniu 27 marca 2009 01:07 u?ytkownik Mark Mahieu napisa?: > > > 2009/3/26 Marek Kozie? >> >> class Some{ >> >> ? ? private String name; >> >> ? ? public this setName (String this.name){}; >> >> ? ? public this.name getName(){}; >> >> } > > Leaving to one side the idea of returning 'this' from setName, yes > auto-assignment parameters could easily be made to work on all non-abstract > instance methods. > As you suggest, this could be extended even further to return values, but > one of the questions that raises is whether it's acceptable to omit the > type, as you've done in your example (imagine what it would look like in a > much bigger class with many more methods). > Mark > This is the reason why i suggested allowing blocks in classes: class Some{ { // block for name ? ? private String name; ? ? public this setName (String this.name){}; ? ? public this.name getName(){}; } } problem disappears when code is near, but there is no solution that can replace good style. We can also consider: { ? ? private String name; ? ? public this setName (String this.name){}; ? ? public this.name String getName(){}; } While we have quite similar idea, they work really great with each other. I just still wander if that should go so far. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From howard.lovatt at iee.org Thu Mar 26 17:28:14 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Fri, 27 Mar 2009 11:28:14 +1100 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <28bca0ff0903261322g624a1f22t1916b5f93871aed7@mail.gmail.com> References: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> <28bca0ff0903230256p48b36533n77a148232743d28e@mail.gmail.com> <28bca0ff0903261322g624a1f22t1916b5f93871aed7@mail.gmail.com> Message-ID: <3dd3f56a0903261728x58ba5653rbc673d91df3adee4@mail.gmail.com> Hi, I am not understanding your example, what is Bar if its not B - where is its definition. Also my suggestion isn't saying that the super constructor can't access the super class fields or that after calling super you can't access super fields, just that before calling super you can't access super fields (only this.field_name). Also note that you can't call an instance method, at all, before super, not even this.method_name( ... ). Howard. 2009/3/27 Marek Kozie? : > 2009/3/24 Howard Lovatt : >> I don't get the example. Is class B meant to be Bar? Can you clarify? >> >> -- Howard. >> > > No, B is B. > I wanted show the problem: > public B(Bar bar, Foo foo) { > ? ? ? ?super(bar); > ? ? ? ?this.foo = foo; > ? ? } > mean in runtime: > ? ? ? ?this.bar = bar; > ? ? ? ?this.foo = bar.foo; > ? ? ? ?this.foo = foo; > > > public B(Bar bar, Foo foo) { > ? ? ? ?this.foo = foo; > ? ? ? ?super(bar); > ? ? } > mean in runtime: > ? ? ? ?this.foo = foo; > ? ? ? ?this.bar = bar; > ? ? ? ?this.foo = bar.foo; > > While second constructor look really innocent. > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > -- -- Howard. From reinier at zwitserloot.com Thu Mar 26 17:39:08 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 27 Mar 2009 01:39:08 +0100 Subject: PROPOSAL: Language Escape Operator In-Reply-To: <1238110511.49cc112f28285@www.paradise.net.nz> References: <1238110511.49cc112f28285@www.paradise.net.nz> Message-ID: <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> Isn't it easier to do this with a keyword? Right at the top of your java file (after all, a non-java language would work at least on CompileUnits, if not entire Modules/Packages/ directories), put something like: language groovy; some sort of guarantee by java, in the vein of your proposal, that java will never make: language (anything-but-"java", literally); legal. That's not to say that "language java;" at the top WOULD be legal, just that "language foo;" at the top would NEVER be legal. --Reinier Zwitserloot On Mar 27, 2009, at 00:35, brucechapman at paradise.net.nz wrote: > Title Language Escape Operator > > latest html version at http://docs.google.com/Doc?docid=dcvp3mkv_9gdg3jfhg > > AUTHOR(S): Bruce Chapman > > OVERVIEW > > > FEATURE SUMMARY: > > There is great potential for syntactic sugars to be implemented in > tools rather > than the Java language. One requirement of such a mechanism is that > the sugared > form is NOT valid java source code (otherwise the meaning is > ambiguous - is a > piece of code intended as is, or intended to be desugared). In order > to future > proof such mechanisms it is also desirable that such a syntactic > sugar form will > never become a valid java form due to some unanticipated future > language change. > > > A simple way to ensure this is to reserve a character as a language > escape, > effectively it indicates that source code is at that point escaping > from the > java language. > > > Such a character should be a printable ascii character to enable it > to be typed > and read, and it should have no existing defined meaning in the java > language > within the contexts in which it is to be used. > > > Inside commments, String literals and character literals all > printable ascii > characters have meaning and therefore there is no way we can escape > from these. > This is not thought to be an overly burdensome restriction. > > > The candidate characters for the escape operator are therefore # > (hash), \ > (backslash) and ` (back quote). Neither # or ` have any currently > defined > meaning in the Java language specification. \ does have defined > meanings but > only as a unicode escape and inside String and character literals > and so is also > suitable. > > > The intention of this proposal is to reserve one of these three > characters for a > range of uses that are outside the language. Although the syntactic > sugar > example is mentioned above it is but one example. A crystal ball > would be > advantageous here - alas we are limited to our ability to dream. > > > Several proposals and ideas are circulating which suggest uses for > each of these > few remaining characters which are becoming a precious resource for > language > developers due to their scarcity. It is the author's belief that use > of any one > of these characters as a language escape operator offers far more > long term > value than use for a single new syntactic form. Let us reserve one > of the three > characters as a language escape and let all other language proposals > squabble > over the remaining two. > > > For the rest of this proposal it is assumed the back-quote character > is the > language escape operator. Either of the three characteres could be > used equally > from a technical point of view however aesthetic considerations > would probably > place # as least desirable. > > > MAJOR ADVANTAGE: > Shuts the gate before the horse has bolted. Once all these > characters are > assigned meaning by the language, then there is no single character > that can be > used as a language escape. > > > MAJOR DISADVANTAGE: > > Prevents the back-quote (GRAVE-ACCENT) character from being used in > other > language features. > > ALTERNATIVES: > > Alternative characters have been discussed above. Another > alternative is to do > nothing and let language tools develop further (using any of the > three available > characters) in order to get a slightly better idea of where this > might be > heading before committing to a language change. The risk with this > approach is > that all three characters might get defined uses by other language > changes > before one can be reserved as a language escape. At that point it > would be too > late and would restrict language tools. > > EXAMPLES > SIMPLE EXAMPLE: > `Property String name; > > is not valid Java source code, and can be automatically desugared by > an IDE. See > references section. > > > ADVANCED EXAMPLE: > > > N/A > > > > DETAILS > SPECIFICATION: > > > Add new section 3.13 after 3.12 operators. > > > 3.12 Language Escape > > The Ascii back quote ` character (unicode GRAVE ACCENT) is reserved > for use by > tools that process mixed language content to indicate to their > parsers while > parsing java source code, the start of something that is not Java > source code. > It is the responsibility of such tools to pass only java source to > the java > compiler. > > > It is a compile time error for a ` character to appear in other than > a comment, > a String literal or a Character literal. > > COMPILATION: > Generate the error if the ` character is encountered in other than a > comment, > String or Character literal. > > While the protoype does this, a more specific error message might be > useful. > > TESTING: > > Test for the compiler error. > > LIBRARY SUPPORT: > > No library support required. > > REFLECTIVE APIS: > > N/A > > OTHER CHANGES: > > N/A > > MIGRATION: > > N/A > > COMPATIBILITY > BREAKING CHANGES: > > N/A > > EXISTING PROGRAMS: > > N/A > > REFERENCES > > > http://docs.google.com/Doc?docid=dcvp3mkv_8sn3ccbkk describes a > working proof of > concept tool which uses ` as a language escape. > > > EXISTING BUGS: > > ? > > URL FOR PROTOTYPE (optional): > > > JDK6's javac is the protoype implementation for this language change. > > http://java.sun.com/javase/downloads > > From brucechapman at paradise.net.nz Thu Mar 26 20:13:33 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Fri, 27 Mar 2009 16:13:33 +1300 (NZDT) Subject: PROPOSAL: Language Escape Operator In-Reply-To: <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> Message-ID: <1238123613.49cc445d0d940@www.paradise.net.nz> Quoting Reinier Zwitserloot : > Isn't it easier to do this with a keyword? > > Right at the top of your java file (after all, a non-java language > would work at least on CompileUnits, if not entire Modules/Packages/ > directories), put something like: > > language groovy; > > some sort of guarantee by java, in the vein of your proposal, that > java will never make: > > language (anything-but-"java", literally); > > legal. That's not to say that "language java;" at the top WOULD be > legal, just that "language foo;" at the top would NEVER be legal. > > --Reinier Zwitserloot > I think you misunderstood the intent( or I have misunderstood you - either way - my fault). It is NOT about mixed language applications at the file level (file extensions do a fine job of that), but about having mixed content within a single source file, down to the granularity of statement and expression level and possibly even finer. The point is that a tool can interpret the language escape operator and do something different with the content. By the time it get to the compiler the language escape operator should have disappeared because the java compiler doesn't handle mixed language files. That's why I describe the behaviour as raising a compiler error. Many of the other coin proposals define themselves purely as a syntax and desugaring of that to more verbose java code. Such desugarings can done as a view element within an IDE (and code folded back to the sugared form in the view - the model is still bulk standard Java). This proposal offers a low impact indicator to the IDE that what follows is something that is not Java, so please treat it specially (for example by recognizing the syntax and desugaring). That is one use of a language escape. Another slant: JSP embeds java code within XML so that various parts of a web page can be coded with an appropriate syntax. That doesn't need a java language escape character because the java is inside the XML and XML itself and the JSP schema defines which bits are java. But if you invert that model and want to put something that isn't Java inside something that is primarily Java, then the escape operator is the mechanism that the code author and tool can use to indicate and detect the start of the non java stuff. For further background check out my bog http://weblogs.java.net/blog/brucechapman/archive/2009/03/meta_coinage_ro_1.html and the slides from my JUG presentation http://weblogs.java.net/blog/brucechapman/archive/JUG%20Aug%202008%20Mark%20II%20Pecha%20Kucha.ppt And if you have Netbeans, try out the proof of concept module (reference at end of proposal) for using a language escape operator to do properties. I really must do one of those sexy screencast thingies showing that plugin in use so that people don't need to install it in order to experience it. Geertjan can you help? Apologies if I am not doing a good job of getting this concept across. Bruce From reinier at zwitserloot.com Thu Mar 26 20:35:25 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 27 Mar 2009 04:35:25 +0100 Subject: PROPOSAL: Language Escape Operator In-Reply-To: <1238123613.49cc445d0d940@www.paradise.net.nz> References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> Message-ID: The problem then is: When does the special magic end? If there is no end, then this is no different from a 'language' indicator at the top. I am very much in favour of editing a vanilla java AST that involves lots of sugaring, but I don't think such an operator is neccessary or even useful for it; all those backticks would become mighty ugly fast. Also, because you're doing AST editing, those backticks aren't anywhere on disk, so they become a keystroke to indicate: The next few things I'm going to type are definitely intended as non-java sugar that you should java-ize for me. Two things come to mind: 1) That's what cmd/ctrl/alt is for. Typing a backtick on most keyboard is very difficult; I'd rewire a cmd+something to generate it instead, easier on the fingers. 2) *any* IDE that is going to do this correctly also needs to know all about java. Therefore, if an IDE can only handle up to java6 (+AST- based sugaring), and you want to type something java7, which so happens to also be legal sugaring, then - that's only a minor pain. You can't use java7 in this IDE, it doesn't know the syntax. It's unfortunate that this AST sugar now needs to find another syntax, but isn't that part of the point of AST sugaring? Ease of switching around? I really doubt any kind of AST sugaring system is going to make 'start with a backtick' a prerequisite. --Reinier Zwitserloot On Mar 27, 2009, at 04:13, brucechapman at paradise.net.nz wrote: > Quoting Reinier Zwitserloot : > >> Isn't it easier to do this with a keyword? >> >> Right at the top of your java file (after all, a non-java language >> would work at least on CompileUnits, if not entire Modules/Packages/ >> directories), put something like: >> >> language groovy; >> >> some sort of guarantee by java, in the vein of your proposal, that >> java will never make: >> >> language (anything-but-"java", literally); >> >> legal. That's not to say that "language java;" at the top WOULD be >> legal, just that "language foo;" at the top would NEVER be legal. >> >> --Reinier Zwitserloot >> > > I think you misunderstood the intent( or I have misunderstood you - > either way - > my fault). > > It is NOT about mixed language applications at the file level (file > extensions > do a fine job of that), but about having mixed content within a > single source > file, down to the granularity of statement and expression level and > possibly > even finer. > > The point is that a tool can interpret the language escape operator > and do > something different with the content. By the time it get to the > compiler the > language escape operator should have disappeared because the java > compiler > doesn't handle mixed language files. That's why I describe the > behaviour as > raising a compiler error. > > Many of the other coin proposals define themselves purely as a > syntax and > desugaring of that to more verbose java code. Such desugarings can > done as a > view element within an IDE (and code folded back to the sugared form > in the view > - the model is still bulk standard Java). This proposal offers a low > impact > indicator to the IDE that what follows is something that is not > Java, so please > treat it specially (for example by recognizing the syntax and > desugaring). That > is one use of a language escape. > > Another slant: > > JSP embeds java code within XML so that various parts of a web page > can be coded > with an appropriate syntax. That doesn't need a java language escape > character > because the java is inside the XML and XML itself and the JSP schema > defines > which bits are java. But if you invert that model and want to put > something that > isn't Java inside something that is primarily Java, then the escape > operator is > the mechanism that the code author and tool can use to indicate and > detect the > start of the non java stuff. > > > For further background check out my bog > http://weblogs.java.net/blog/brucechapman/archive/2009/03/meta_coinage_ro_1.html > > and the slides from my JUG presentation > http://weblogs.java.net/blog/brucechapman/archive/JUG%20Aug%202008%20Mark%20II%20Pecha%20Kucha.ppt > > And if you have Netbeans, try out the proof of concept module > (reference at end > of proposal) for using a language escape operator to do properties. > I really > must do one of those sexy screencast thingies showing that plugin in > use so that > people don't need to install it in order to experience it. Geertjan > can you help? > > Apologies if I am not doing a good job of getting this concept across. > > Bruce > > From lk at teamten.com Thu Mar 26 21:14:33 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Thu, 26 Mar 2009 21:14:33 -0700 Subject: PROPOSAL: Language Escape Operator In-Reply-To: References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> Message-ID: <997cab100903262114u1b98aa2eo2ced890ae2cf7fab@mail.gmail.com> I think Bruce's coin isn't trying to define the desugaring, it's trying to make sure that backtick (or whatever) is reserved and never used by the Java language itself. That would allow it to be used by IDEs and preprocessors for desugaring, macros, etc. It's similar to # in C, reserved for the preprocessor. Have you looked at metalua? (http://metalua.luaforge.net/quicktour.html) It's an attempt to define a meta language to define new constructs at compile time. It's similar to Lisp macros, but allows extensions to the syntax. A metajava system built into the compiler would take a lot of pressure off the base language. All these proposed language features could just be done as metajava extensions. Lawrence On Thu, Mar 26, 2009 at 8:35 PM, Reinier Zwitserloot wrote: > The problem then is: When does the special magic end? > > If there is no end, then this is no different from a 'language' > indicator at the top. > > I am very much in favour of editing a vanilla java AST that involves > lots of sugaring, but I don't think such an operator is neccessary or > even useful for it; all those backticks would become mighty ugly fast. > Also, because you're doing AST editing, those backticks aren't > anywhere on disk, so they become a keystroke to indicate: The next few > things I'm going to type are definitely intended as non-java sugar > that you should java-ize for me. > > Two things come to mind: > > 1) That's what cmd/ctrl/alt is for. Typing a backtick on most keyboard > is very difficult; I'd rewire a cmd+something to generate it instead, > easier on the fingers. > > 2) *any* IDE that is going to do this correctly also needs to know all > about java. Therefore, if an IDE can only handle up to java6 (+AST- > based sugaring), and you want to type something java7, which so > happens to also be legal sugaring, then - that's only a minor pain. > You can't use java7 in this IDE, it doesn't know the syntax. It's > unfortunate that this AST sugar now needs to find another syntax, but > isn't that part of the point of AST sugaring? Ease of switching > around? I really doubt any kind of AST sugaring system is going to > make 'start with a backtick' a prerequisite. > > > ?--Reinier Zwitserloot > > > > On Mar 27, 2009, at 04:13, brucechapman at paradise.net.nz wrote: > >> Quoting Reinier Zwitserloot : >> >>> Isn't it easier to do this with a keyword? >>> >>> Right at the top of your java file (after all, a non-java language >>> would work at least on CompileUnits, if not entire Modules/Packages/ >>> directories), put something like: >>> >>> language groovy; >>> >>> some sort of guarantee by java, in the vein of your proposal, that >>> java will never make: >>> >>> language (anything-but-"java", literally); >>> >>> legal. That's not to say that "language java;" at the top WOULD be >>> legal, just that "language foo;" at the top would NEVER be legal. >>> >>> --Reinier Zwitserloot >>> >> >> I think you misunderstood the intent( or I have misunderstood you - >> either way - >> my fault). >> >> It is NOT about mixed language applications at the file level (file >> extensions >> do a fine job of that), but about having mixed content within a >> single source >> file, down to the granularity of statement and expression level and >> possibly >> even finer. >> >> The point is that a tool can interpret the language escape operator >> and do >> something different with the content. By the time it get to the >> compiler the >> language escape operator should have disappeared because the java >> compiler >> doesn't handle mixed language files. That's why I describe the >> behaviour as >> raising a compiler error. >> >> Many of the other coin proposals define themselves purely as a >> syntax and >> desugaring of that to more verbose java code. Such desugarings can >> done as a >> view element within an IDE (and code folded back to the sugared form >> in the view >> - the model is still bulk standard Java). This proposal offers a low >> impact >> indicator to the IDE that what follows is something that is not >> Java, so please >> treat it specially (for example by recognizing the syntax and >> desugaring). ?That >> is one use of a language escape. >> >> Another slant: >> >> JSP embeds java code within XML so that various parts of a web page >> can be coded >> with an appropriate syntax. That doesn't need a java language escape >> character >> because the java is inside the XML and XML itself and the JSP schema >> defines >> which bits are java. But if you invert that model and want to put >> something that >> isn't Java inside something that is primarily Java, then the escape >> operator is >> the mechanism that the code author and tool can use to indicate and >> detect the >> start of the non java stuff. >> >> >> For further background check out my bog >> http://weblogs.java.net/blog/brucechapman/archive/2009/03/meta_coinage_ro_1.html >> >> and the slides from my JUG presentation >> http://weblogs.java.net/blog/brucechapman/archive/JUG%20Aug%202008%20Mark%20II%20Pecha%20Kucha.ppt >> >> And if you have Netbeans, try out the proof of concept module >> (reference at end >> of proposal) for using a language escape operator to do properties. >> I really >> must do one of those sexy screencast thingies showing that plugin in >> use so that >> people don't need to install it in order to experience it. Geertjan >> can you help? >> >> Apologies if I am not doing a good job of getting this concept across. >> >> Bruce >> >> > > > From develop4lasu at gmail.com Thu Mar 26 23:03:50 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 27 Mar 2009 07:03:50 +0100 Subject: Loosen Constructor super()/this() call restrictions In-Reply-To: <3dd3f56a0903261728x58ba5653rbc673d91df3adee4@mail.gmail.com> References: <3dd3f56a0903230213x47ebfeb8j8261712c1a9bf6e5@mail.gmail.com> <28bca0ff0903230256p48b36533n77a148232743d28e@mail.gmail.com> <28bca0ff0903261322g624a1f22t1916b5f93871aed7@mail.gmail.com> <3dd3f56a0903261728x58ba5653rbc673d91df3adee4@mail.gmail.com> Message-ID: <28bca0ff0903262303o641a8f7bt97fe10107d5c1f64@mail.gmail.com> class Foo {} class Bar {public Foo foo}; -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From rssh at gradsoft.com.ua Thu Mar 26 23:36:18 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Fri, 27 Mar 2009 08:36:18 +0200 (EET) Subject: PROPOSAL: Language Escape Operator In-Reply-To: <1238110511.49cc112f28285@www.paradise.net.nz> References: <1238110511.49cc112f28285@www.paradise.net.nz> Message-ID: 1. But feature without 'semantic' of use is quite useless. I. e. until processing of 'escaped part' in java program is not standardized, I will be able redistribute and show such code only with knowledge about extra tools and how they are applied. I.e. to be practical, at least process of defining and applying such extra tools must be described somewhere. (something like call of annotation processing interface from compiler) 2. Yet one linked 'bug' in JLS: Behaviour of java compiler is not defined at all. (Annotation processing is described in man page, not in JLS itself, so, strictly it's not part of Java language) //(Hmm, submit issue about this ?) > Title Language Escape Operator > > latest html version at http://docs.google.com/Doc?docid=dcvp3mkv_9gdg3jfhg > > AUTHOR(S): Bruce Chapman > > OVERVIEW > > > FEATURE SUMMARY: > > There is great potential for syntactic sugars to be implemented in tools > rather > than the Java language. One requirement of such a mechanism is that the > sugared > form is NOT valid java source code (otherwise the meaning is ambiguous - > is a > piece of code intended as is, or intended to be desugared). In order to > future > proof such mechanisms it is also desirable that such a syntactic sugar > form will > never become a valid java form due to some unanticipated future language > change. > > > A simple way to ensure this is to reserve a character as a language > escape, > effectively it indicates that source code is at that point escaping from > the > java language. > > > Such a character should be a printable ascii character to enable it to be > typed > and read, and it should have no existing defined meaning in the java > language > within the contexts in which it is to be used. > > > Inside commments, String literals and character literals all printable > ascii > characters have meaning and therefore there is no way we can escape from > these. > This is not thought to be an overly burdensome restriction. > > > The candidate characters for the escape operator are therefore # (hash), \ > (backslash) and ` (back quote). Neither # or ` have any currently defined > meaning in the Java language specification. \ does have defined meanings > but > only as a unicode escape and inside String and character literals and so > is also > suitable. > > > The intention of this proposal is to reserve one of these three characters > for a > range of uses that are outside the language. Although the syntactic sugar > example is mentioned above it is but one example. A crystal ball would be > advantageous here - alas we are limited to our ability to dream. > > > Several proposals and ideas are circulating which suggest uses for each of > these > few remaining characters which are becoming a precious resource for > language > developers due to their scarcity. It is the author's belief that use of > any one > of these characters as a language escape operator offers far more long > term > value than use for a single new syntactic form. Let us reserve one of the > three > characters as a language escape and let all other language proposals > squabble > over the remaining two. > > > For the rest of this proposal it is assumed the back-quote character is > the > language escape operator. Either of the three characteres could be used > equally > from a technical point of view however aesthetic considerations would > probably > place # as least desirable. > > > MAJOR ADVANTAGE: > Shuts the gate before the horse has bolted. Once all these characters are > assigned meaning by the language, then there is no single character that > can be > used as a language escape. > > > MAJOR DISADVANTAGE: > > Prevents the back-quote (GRAVE-ACCENT) character from being used in other > language features. > > ALTERNATIVES: > > Alternative characters have been discussed above. Another alternative is > to do > nothing and let language tools develop further (using any of the three > available > characters) in order to get a slightly better idea of where this might be > heading before committing to a language change. The risk with this > approach is > that all three characters might get defined uses by other language changes > before one can be reserved as a language escape. At that point it would be > too > late and would restrict language tools. > > EXAMPLES > SIMPLE EXAMPLE: > `Property String name; > > is not valid Java source code, and can be automatically desugared by an > IDE. See > references section. > > > ADVANCED EXAMPLE: > > > N/A > > > > DETAILS > SPECIFICATION: > > > Add new section 3.13 after 3.12 operators. > > > 3.12 Language Escape > > The Ascii back quote ` character (unicode GRAVE ACCENT) is reserved for > use by > tools that process mixed language content to indicate to their parsers > while > parsing java source code, the start of something that is not Java source > code. > It is the responsibility of such tools to pass only java source to the > java > compiler. > > > It is a compile time error for a ` character to appear in other than a > comment, > a String literal or a Character literal. > > COMPILATION: > Generate the error if the ` character is encountered in other than a > comment, > String or Character literal. > > While the protoype does this, a more specific error message might be > useful. > > TESTING: > > Test for the compiler error. > > LIBRARY SUPPORT: > > No library support required. > > REFLECTIVE APIS: > > N/A > > OTHER CHANGES: > > N/A > > MIGRATION: > > N/A > > COMPATIBILITY > BREAKING CHANGES: > > N/A > > EXISTING PROGRAMS: > > N/A > > REFERENCES > > > http://docs.google.com/Doc?docid=dcvp3mkv_8sn3ccbkk describes a working > proof of > concept tool which uses ` as a language escape. > > > EXISTING BUGS: > > ? > > URL FOR PROTOTYPE (optional): > > > JDK6's javac is the protoype implementation for this language change. > > http://java.sun.com/javase/downloads > > > From abies at adres.pl Fri Mar 27 00:00:12 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Fri, 27 Mar 2009 08:00:12 +0100 Subject: PROPOSAL: String parameters compile time validation (early beta) In-Reply-To: <142223BF-521F-4308-8FD8-DC754A4B5D04@zwitserloot.com> References: <28bca0ff0903261350w1b12327cne9938ab7502a210d@mail.gmail.com> <49CBF17C.1050708@adres.pl> <142223BF-521F-4308-8FD8-DC754A4B5D04@zwitserloot.com> Message-ID: <49CC797C.3030905@adres.pl> Reinier Zwitserloot wrote: > > The idea is simply to have a literal syntax for regexps, where the > compiler will actually put the binary representation of a compiled > pattern in the .class source. As I mentioned, this has very > significant speed savings, because compiling a regexp is more > expensive than applying one, especially for complex regexps that are > performance sensitive. > > I don't understand your argument about casting. Right now, you get > compile-time checking on e.g. the bounds of an integer, but if you > cast, you get that check at runtime (or, actually, the bits are just > cut off, but you get the point). > > The regexp literal notation would literally have the type 'Pattern'. > You can try to cast a string to this, but that would obviously fail, > and the compiler will in fact error when you try, because String is > not a subtype of Pattern. If you want to turn a string into a pattern, > you'd use Pattern.compile. So: > > Pattern x = /a*a+a*a+/; > Pattern y = Pattern.compile("a*a+a*a+"); I think that we are talking about different things. As far as I understood OP, he wants to have kind of typedef String which accepts only certain values. It is not about compile-time Patterns, which are just a side requirement. Main topic is to have something like @Regexp("JustDigits","[0-9]+"); void setPhoneNumber(@Regexp("JustDigits") String phoneNumber) Now, you can call it from the code like obj.setPhoneNumber("12345") and compile would do a static check if 12345 is fitting "[0-9]+" regexp, but you probably would also like to do String number = someField.getText(); obj.setPhoneNumber(number); which is not safe. We would need to have something like String number = someField.getText(); @Regexp("JustDigits") String reallyNumber = @Regexp("JustDigits").check(number); obj.setPhoneNumber(reallyNumber); Actually, when I think about static code checks like in the first case, I don't think it could be pulled out if this crosses class boundary - you could recompile receiver class, changing the regexp contents and the safety would fail (unless regexp would be included into method signature by contents). Regards, Artur Biesiadowski From brucechapman at paradise.net.nz Fri Mar 27 00:25:07 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Fri, 27 Mar 2009 20:25:07 +1300 Subject: PROPOSAL: Language Escape Operator In-Reply-To: References: <1238110511.49cc112f28285@www.paradise.net.nz> Message-ID: <49CC7F53.4040905@paradise.net.nz> rssh at gradsoft.com.ua wrote: > 1. But feature without 'semantic' of use is quite useless. I. e. until > processing of 'escaped part' in java program is not standardized, I will > be able redistribute and show such code only with knowledge about extra > tools and how they are applied. > "Code" which uses the escaped part is not Java code. It is a mix of java code and something else. It has no meaning as a purely java program - thus it would at least be immoral to use ".java" file extension. It has meaning only in the context of some external tool, or externally defined mechanism. In some ways it makes no more sense to describe the semantics of the escaped part than it does to describe the semantics of a String literal's content. In the particular proof of concept I have used as an example, the escape part is only visible when looking at the IDE, it is a complex series of linked folds. To distribute this in a form where the escape operator was visible you would need something like a screen shot image - in which case it would be obvious that you were not looking at complete code. The source file in that case would not contain the escape operator, just pure java code, and distributing it would be no different from when the tool was not being used. > I.e. to be practical, at least process of defining and applying such > extra tools must be described somewhere. (something like call of > annotation processing interface from compiler) > The "semantics of use" with respect to the java language and compiler are defined in the proposal. It is quite simply a compiler error. How tools choose to use this is beyond the scope of the java language specification, but for an example see the referenced proof of concept. I very deliberately have absolutely no intention of dictating how such a feature should be used by tools outside of the language. I merely wish to reserve the opportunity for them to do something - anything if it is of value. > 2. Yet one linked 'bug' in JLS: Behaviour of java compiler is not defined > at all. (Annotation processing is described in man page, not in JLS > itself, so, strictly it's not part of Java language) > True, it is not part of the language but it is a part of the java platform because it is described in javax.annotation.processing package and the platform documentation for the javac compiler says that it is an annotation processor. If you are having trouble understanding - please see my previous post (approx 4 hours earlier) for links to some more background material. I am aware that I am "going meta" somewhat here and it might be difficult to understand. Believe me I have struggled to find ways to explain it. If I need to struggle harder, please ask and I'll do my best. Bruce - SNIP - From rssh at gradsoft.com.ua Fri Mar 27 00:39:45 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Fri, 27 Mar 2009 09:39:45 +0200 (EET) Subject: PROPOSAL: Language Escape Operator In-Reply-To: <49CC7F53.4040905@paradise.net.nz> References: <1238110511.49cc112f28285@www.paradise.net.nz> <49CC7F53.4040905@paradise.net.nz> Message-ID: <37afba92f376e97cf6b3631d26d952e2.squirrel@wmail.gradsoft.ua> Thanks, now understand, i. e. this can be summarized as: The seance of proposal is reserve character to prevent break of external processing tools caused by changing of Java syntax during language evolution. > > If you are having trouble understanding - please see my previous post > (approx 4 hours earlier) for links to some more background material. I > am aware that I am "going meta" somewhat here and it might be difficult > to understand. Believe me I have struggled to find ways to explain it. > If I need to struggle harder, please ask and I'll do my best. > > > Bruce > > - SNIP - > From brucechapman at paradise.net.nz Fri Mar 27 01:11:02 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Fri, 27 Mar 2009 21:11:02 +1300 Subject: PROPOSAL: Language Escape Operator In-Reply-To: References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> Message-ID: <49CC8A16.9050807@paradise.net.nz> Reinier Zwitserloot wrote: > The problem then is: When does the special magic end? Yes I wrestled with that issue, but in the end I decided it was not up to java to specify where the magic ends, and the java restarts. It is up to whatever starts to specify that. If you were to attempt to specify the end, you must be certain that the end was not actually valid content for any possible use of the escape operator. I believe that to be impossible, unless the java tools are to interpret the content and pass it to the other tool. That is a restriction on how the tools work together which I do not want to make - and doesn't fit the example use case. The Java compiler has pretty good heuristics for determining where to attempt a restart of parsing once a error is detected. At this stage I would not want to specify any more than that. > > If there is no end, then this is no different from a 'language' > indicator at the top. There is a difference if it doesn't start at the top. If it always starts at the top (by which I presume you mean the beginning of the source file - but you seem to be labouring this point so maybe I am misunderstanding you) then its not java source code. > > I am very much in favour of editing a vanilla java AST that involves > lots of sugaring, but I don't think such an operator is neccessary or > even useful for it; all those backticks would become mighty ugly fast. > Also, because you're doing AST editing, those backticks aren't > anywhere on disk, so they become a keystroke to indicate: The next few > things I'm going to type are definitely intended as non-java sugar > that you should java-ize for me. > > Two things come to mind: > > 1) That's what cmd/ctrl/alt is for. Typing a backtick on most keyboard > is very difficult; I'd rewire a cmd+something to generate it instead, > easier on the fingers. On my standard US ascii keyboard its just a single keypress, no shift, no ctrl, just ` For the example use the intention is make make it feel almost as good as if the syntax sugar was in the language. yes you could use a magic key combination in this particular case, but that would skip your brain out of the "laying down code" mode, and into the editing and driving the IDE mode, that context switch takes quite a lot of effort. Writing experts suggest that if you are writing, just write, if you are editing, just edit, to swap back and forth frequently, even pressing backspace to fix a typo is really really inefficient. For other possible uses of the language escape I cannot comment but I suspect some at least will work with files that are a mix of content. > > 2) *any* IDE that is going to do this correctly also needs to know all > about java. Therefore, if an IDE can only handle up to java6 > (+AST-based sugaring), and you want to type something java7, which so > happens to also be legal sugaring, then - that's only a minor pain. > You can't use java7 in this IDE, it doesn't know the syntax. It's > unfortunate that this AST sugar now needs to find another syntax, but > isn't that part of the point of AST sugaring? Ease of switching > around? I really doubt any kind of AST sugaring system is going to > make 'start with a backtick' a prerequisite. I presume you are talking about the specific sugaring example and not the use of language escape operator in general. The way I envisage the sugaring working is that the tool will load a regular java source file and for any code constructs that happen to match the desugared form of a particular loaded syntactic sugar, and if that sugar was defined in such a way as to always collapse to the sugared form when a file is loaded, then (and only then) would it be shown in sugared form. If someone else opened the file without the sugar definition loaded, they'd just see the long form. IF they edited that so that it no longer matched the sugar definition, and the original user reloaded the file, it wouldn't be shown in sugared form because it wouldn't match. The sugared form is JUST A VIEW, an EDITABLE VIEW, but still JUST A VIEW. There is no prerequisite for any tool to use the backtick. By making it a compiler error, we reserve the opportunity for tools to use that if that is deemed the best strategy for the particular tool. There is nothing prescriptive about this other than the compiler error which is already the case, I just want to make sure it remains the case in the future. Bruce > > > --Reinier Zwitserloot > > > > On Mar 27, 2009, at 04:13, brucechapman at paradise.net.nz wrote: > >> Quoting Reinier Zwitserloot : >> >>> Isn't it easier to do this with a keyword? >>> >>> Right at the top of your java file (after all, a non-java language >>> would work at least on CompileUnits, if not entire Modules/Packages/ >>> directories), put something like: - SNIP - From schulz at e-Spirit.de Fri Mar 27 01:40:30 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Fri, 27 Mar 2009 09:40:30 +0100 Subject: PROPOSAL: Language Escape Operator In-Reply-To: <49CC8A16.9050807@paradise.net.nz> References: <1238110511.49cc112f28285@www.paradise.net.nz><5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com><1238123613.49cc445d0d940@www.paradise.net.nz> <49CC8A16.9050807@paradise.net.nz> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC10887C2A@osiris2.e-spirit.de> > On my standard US ascii keyboard its just a single keypress, > no shift, > no ctrl, just ` On my standard German keyboard, it requires a shift-` plus space, as the back-tick-key is a dead key. The same holds (at least) for Austrian and French keyboards (different combination). > The sugared form is JUST A VIEW, an EDITABLE VIEW, but still JUST A VIEW. If it's a view, solely handled by some IDE, neither visible in persistence nor common editors, I don't understand the use for adding it to the language as reserved character. As a developer, I don't even want to see that the code I just wrote is an IDE only sugaring (maybe I want to by some color or marker outside the source). And as the sugar would (or should) be recognizable by the IDE, what is the back-tick for? Gilad Bracha wrote a blog post* on a related idea for "skinning" a programming language (in his case Newspeak). If one has an intelligent IDE (that does more than simple folding), allowing skins could be a nice thing, but wouldn't require any language support itself. Stefan *) http://gbracha.blogspot.com/2008/09/skinning-newspeak.html From reinier at zwitserloot.com Fri Mar 27 04:11:33 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Fri, 27 Mar 2009 12:11:33 +0100 Subject: PROPOSAL: Language Escape Operator In-Reply-To: References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> Message-ID: <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> The backtick, on a standard US 101, needs to be typed by awkwardly bending your left pinky, traditionally the least flexible typing finger. At least, for 10-fingers on the home row kind of typer. As Stefan pointed out, on international keyboards its akin to using the umlaut (without any characters under it) as a symbol. However, that's not really my issue with this proposal, this is: Who ever types or sees that backtick? 1. The source file - but, no. It doesn't even end in .java, there is no way that source could possibly be mistaken for java code. 2. The programmer - but, no. I would never use a new language (even if its folding sugar on vanilla java) if it requires me to type a gazillion backticks. I wouldn't do it even if it were a nice, easily typed symbol like, say, semi-colon. Turning my code into perl cartoon swearing surely cannot be the point. Even if I never see them (because the folder folds them away!), I don't want to hit a special 'I want sugar' modifier key, that breaks the flow just as much as a cmd-key combo. Also, You hit shift routinely as you are 'just typing', so what's the problem with hitting CMD+X or whatever key such a folding IDE comes up with? 3. The parser - but, no. A code-folding view on the AST would never be in a position to parse such a thing. other problem: Many non-java languages already need the backtick, such as scala, which uses it to mean: The contents of the backticks are an identifier, even if it looks like a keyword. This allows you to call Thread.yield() in scala like so : Thread.`yield`(), because 'yield' in scala is a keyword, and therefore Thread.yield() would not invoke the method (it is instead a syntax error). Java has only 2 common keyboard symbols left, the backtick and the hash, and taking one of them is a big deal. I am not convinced its worth it, mostly because of the above problems. The only benefit I can see is that, IF the code-folding AST view editor does use the backtick as some kind of escaping key, that any future java expansions do not all of a sudden make previous syntax sugar legal actual java. But this really doesn't sound very good either, because: 1. The backtick really really needs to be in the source, so that if I copy and paste, it sticks around. A view on the AST could dynamically add it to the text buffer when you copy and paste, but this is introducing rather a lot of voodoo. There's also no way for different AST node view tools t 2. Odds are that a very useful and often used desugaring in a popular AST view editor (which we don't have yet, but hopefully someone will take the time to write one someday), will end up in java itself. Except it can't, by definition: That backtick is in the way. 3. If, other than the backtick, the syntax is the same, or at least so similar that a key-by-key parsing is going to have issues, as a real java syntax, than the AST view desugaring syntax *needs to go away*. That point I made before but you haven't answered it yet: One of the points of ast views is that you can just change everything without breaking backwards compatibility. The only compatibility you're breaking is training your programmers to use a different syntax - which they have to do anyway, because they're learning to use a new java version which shipped with at least 1 non-trivial language change (after all, something that used to be illegal in java but legal as an AST view syntax, is now legal java!) - I consider the penalty for not having a language escape operator very low as is, in other words. Take that last point, and combine it with the notion that I thoroughly do not look forward to hitting ` all the time, and you see why I don't like this proposal. This is what I would type in an AST view language: private property int foo; and this is what it should write to disk @TypedDifferently(original="private property int foo;") private int foo; @GeneratedBy("#foo") public Constructor(int foo) { this.foo = foo; } @GeneratedBy("#foo") public int getFoo() { return foo; } @GeneratedBy("#foo") public void setFoo(int foo) { this.foo = foo;} @GeneratedBy("#foo") public void addFooListener(..... (you get the point) but if I load this file, -with or without annotations in it-, I want to see: private property int foo; -though- I'll accept that it might give me: property private int foo; If the @OriginallyTyped annotation is no longer there. I don't want to type backticks. I don't want to see backticks. A proposal to make *THIS* work well would be great. I actually tried to write up the specs for an AST node editing language, and it's very very difficult. One of the issues you run into is that you can not save layout at all - you need to save the code to a java file, in a different structure, so it becomes almost impossible to preserve the whitespace, or things like order between keywords, or ordering between methods, when you read it back in. I thought of magic comments that keep the original syntax around, but that makes the java code ugly and not very accessible for people who are not using your particular AST desugaring engine. Something standardized there that links code to the originally typed stuff (as a comment or string literal) would allow vanilla java IDEs to not render that comment at all (their own little AST node view :P) and to notice that a user is editing a generated block, and e.g. show a little warning, or alternatively offer a view of the originally typed code, which a vanilla java editor may not understand, though likely the raw english text in the source would carry some meaning of intent, probably moreso than the generated code. Such a proposal wouldn't neccessarily fit in the JLS, it's just a standardized format that is also legal vanilla java (by using magic comments, probably), which all IDEs agree on as something they'll eventually detect. If you want special syntax for this, that would be fine too, but its okay if its verbose. You could introduce a keyword such as 'ast-node-view', which is so rare that I really doubt anyone's going to run into an issue with that no longer being a legal identifier. There's so much you can do - the backtick seems like one of the worst choices. --Reinier Zwitserloot On Mar 27, 2009, at 04:35, Reinier Zwitserloot wrote: > The problem then is: When does the special magic end? > > If there is no end, then this is no different from a 'language' > indicator at the top. > > I am very much in favour of editing a vanilla java AST that involves > lots of sugaring, but I don't think such an operator is neccessary > or even useful for it; all those backticks would become mighty ugly > fast. Also, because you're doing AST editing, those backticks aren't > anywhere on disk, so they become a keystroke to indicate: The next > few things I'm going to type are definitely intended as non-java > sugar that you should java-ize for me. > > Two things come to mind: > > 1) That's what cmd/ctrl/alt is for. Typing a backtick on most > keyboard is very difficult; I'd rewire a cmd+something to generate > it instead, easier on the fingers. > > 2) *any* IDE that is going to do this correctly also needs to know > all about java. Therefore, if an IDE can only handle up to java6 > (+AST-based sugaring), and you want to type something java7, which > so happens to also be legal sugaring, then - that's only a minor > pain. You can't use java7 in this IDE, it doesn't know the syntax. > It's unfortunate that this AST sugar now needs to find another > syntax, but isn't that part of the point of AST sugaring? Ease of > switching around? I really doubt any kind of AST sugaring system is > going to make 'start with a backtick' a prerequisite. > > > --Reinier Zwitserloot > > > > On Mar 27, 2009, at 04:13, brucechapman at paradise.net.nz wrote: > >> Quoting Reinier Zwitserloot : >> >>> Isn't it easier to do this with a keyword? >>> >>> Right at the top of your java file (after all, a non-java language >>> would work at least on CompileUnits, if not entire Modules/Packages/ >>> directories), put something like: >>> >>> language groovy; >>> >>> some sort of guarantee by java, in the vein of your proposal, that >>> java will never make: >>> >>> language (anything-but-"java", literally); >>> >>> legal. That's not to say that "language java;" at the top WOULD be >>> legal, just that "language foo;" at the top would NEVER be legal. >>> >>> --Reinier Zwitserloot >>> >> >> I think you misunderstood the intent( or I have misunderstood you - >> either way - >> my fault). >> >> It is NOT about mixed language applications at the file level (file >> extensions >> do a fine job of that), but about having mixed content within a >> single source >> file, down to the granularity of statement and expression level and >> possibly >> even finer. >> >> The point is that a tool can interpret the language escape operator >> and do >> something different with the content. By the time it get to the >> compiler the >> language escape operator should have disappeared because the java >> compiler >> doesn't handle mixed language files. That's why I describe the >> behaviour as >> raising a compiler error. >> >> Many of the other coin proposals define themselves purely as a >> syntax and >> desugaring of that to more verbose java code. Such desugarings can >> done as a >> view element within an IDE (and code folded back to the sugared >> form in the view >> - the model is still bulk standard Java). This proposal offers a >> low impact >> indicator to the IDE that what follows is something that is not >> Java, so please >> treat it specially (for example by recognizing the syntax and >> desugaring). That >> is one use of a language escape. >> >> Another slant: >> >> JSP embeds java code within XML so that various parts of a web page >> can be coded >> with an appropriate syntax. That doesn't need a java language >> escape character >> because the java is inside the XML and XML itself and the JSP >> schema defines >> which bits are java. But if you invert that model and want to put >> something that >> isn't Java inside something that is primarily Java, then the escape >> operator is >> the mechanism that the code author and tool can use to indicate and >> detect the >> start of the non java stuff. >> >> >> For further background check out my bog >> http://weblogs.java.net/blog/brucechapman/archive/2009/03/meta_coinage_ro_1.html >> >> and the slides from my JUG presentation >> http://weblogs.java.net/blog/brucechapman/archive/JUG%20Aug%202008%20Mark%20II%20Pecha%20Kucha.ppt >> >> And if you have Netbeans, try out the proof of concept module >> (reference at end >> of proposal) for using a language escape operator to do properties. >> I really >> must do one of those sexy screencast thingies showing that plugin >> in use so that >> people don't need to install it in order to experience it. Geertjan >> can you help? >> >> Apologies if I am not doing a good job of getting this concept >> across. >> >> Bruce >> >> > From rssh at gradsoft.com.ua Fri Mar 27 06:37:33 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Fri, 27 Mar 2009 15:37:33 +0200 (EET) Subject: PROPOSAL: Language Escape Operator In-Reply-To: <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> Message-ID: <8cbe5da1c1dc7b41ea333df4bb11cf0a.squirrel@wmail.gradsoft.ua> > Inside commments, String literals and character literals all printable ascii > characters have meaning and therefore there is no way we can escape from these. > This is not thought to be an overly burdensome restriction. Hmm, this means, that new forms of string literals or comments must not be added to java language in future, becouse ` in multiline string literal or new form of multiline comment will enable you tool. This requirement (does not add new multiline constructions) is something, that I can't agree, //especially for multiline string literals, which will be added in some form to Java if language will used, otherwise near nobody will use java for new projects in corporate sector related to sql, because live without ones is extremely ugly, after seeing same code on any other language with multiline string support, Why tools must use one escape symbol, not 2, starting from \' Than ... oh, in principle this will break raw strings (or made one 'not-raw' ) So, those requirements to evolution of Java language is not so tiny, as expected. From develop4lasu at gmail.com Fri Mar 27 07:02:34 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 27 Mar 2009 15:02:34 +0100 Subject: PROPOSAL: 'forget' keyword (beta) Message-ID: <28bca0ff0903270702r52d610a5j792e1912781722d6@mail.gmail.com> I do not know if there is point to describe this proposal in details, because it require to introduce new keyword which may be impossible for project Coin scope.? AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: 'forget' keyword allows to erase variable from current context, or it means that field should not be used. MAJOR ADVANTAGE: This change makes language be more WYSIWYG. MAJOR BENEFIT(s): - It makes people be able to erase 'variable' from current context, while now it's: -> impossible for final variables (only by comments), -> impossible for arguments (for not final Object we can assign null), -> impossible for fields. -> local fields need more or 'less' artificial blocks (two lines wasted and one indent level). - Declaring that variable should not be used, or does not contain valid information for this scope (at current time) will be possible. - Code quality does not fall so drastically after we leave it, comparing to '=null', 'only comments' or 'weird blocks'. MAJOR DISADVANTAGE: New keyword == Someone can have declared method/field/variable named 'forget'. ALTERNATIVES: It's already listed. EXAMPLES SIMPLE / ADVANCED EXAMPLE(s): public static void main(final String[] args) { System.out.println(Arrays.toString(args)); forget args; // 'args' cannot be used anymore String[] args; // ignore/warning/error : unclear code ... } public class Forget { private ArrayList criticKeys; public void addKey(String newKey){ forget this.criticKeys; // use synchronized method ONLY ... // validate ... // add } } DETAILS SPECIFICATION: ... COMPILATION: ... TESTING: It's the same as testing effects of exiting from the block for variables. For fields, it's just an access control. LIBRARY SUPPORT: None. REFLECTIVE APIS: None. OTHER CHANGES: None. MIGRATION: - COMPATIBILITY New keyword can be problem. There is not other impact. REFERENCES http://lasu2string.blogspot.com/2009/03/forget-keyword-proposal_27.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From markmahieu at googlemail.com Fri Mar 27 07:10:06 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 27 Mar 2009 14:10:06 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> Message-ID: On 27 Mar 2009, at 00:22, Marek Kozie? wrote: > > We can also consider: > > { > private String name; > > public this setName (String this.name){}; > > public this.name String getName(){}; > } > > While we have quite similar idea, they work really great with each > other. I just still wander if that should go so far. I think you're right to question whether this would be going too far. Looking at the getter method, I don't see a clear gain over the way it would currently be written, ie, public this.name String getName() {} doesn't strike me as a definite improvement on: public String getName() { return name; } So far, the only extension to the proposal which looks like it might be reasonable, is simply to allow it for method parameters in general. I'm not convinced that it would be worthwhile, but for the sake of illustration here's the example again if that option were taken: private String name; public void setName(String this.name) {} public String getName() { return name; } In this variation, the method name, field, and type are each mentioned once for the getter, and once for the setter, with no need to mention extra variables. Improving on that would almost certainly require language support for properties in general, which isn't what this proposal is about (and isn't in scope for Coin). Thanks for sharing your thoughts. Regards, Mark From vilya.harvey at gmail.com Fri Mar 27 08:10:41 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Fri, 27 Mar 2009 15:10:41 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> Message-ID: <6aef848f0903270810r4b98f906k1a47d0b9faf464e4@mail.gmail.com> I think the general idea here is great, but I also think the original proposal tries to be too specific about what gets auto-assigned. The main use cases are constructors, getters and setters; so how about just being able to declare those items as having an automatically created implementation rather than specific parameters to them? You could use the "default" keyword (for example) as a modifier in a similar way to "abstract": methods and constructors declared with it would be prevented from having a body and the compiler would provide it instead (or report an error if it couldn't). The method bodies that the compiler generates could be kept pretty simple. For example, this: class Example { private int attr1; private String attr2; public default Example(int attr1, String attr2); public default int getAttr1(); public default void setAttr1(int val); public default String getAttr2(); public default void setAttr2(String val); } could desugar to this: class Example { private int attr1; private String attr2; public Example(int attr1, String attr2) { super(); this.attr1 = attr1; this.attr2 = attr2; } public int getAttr1() { return this.attr1; } public void setAttr1(int val) { this.attr1 = attr1; } public default String getAttr2() { return this.attr2; } public default void setAttr2(String val) { this.attr2 = val; } } The rules would be something like: * A constructor would call super() then assign each of it's parameters to an attribute with same name. * A getter method would just return the value of the corresponding attribute. * A setter method would assign the parameter value to the corresponding attribute. The compiler would report an error if the default modifier is misused. For example: * Using it on a method whose name doesn't match the rules for a getter or a setter * Using it on a method whose name does match the getter/setter rules, but for which there's no corresponding attribute. * Using it on a constructor where any of the parameter names do not correspond to the name of assignable attribute. I wouldn't suggest extending this to cover getters and setters for indexed or bound properties, at this stage. You could imagine extending this to cover default implementations of equals and hashCode too, but that might also be a step too far. As is, I think it would cover the majority of the use cases while keeping it conceptually simple for users of Java (and hopefully simpler to implement as well). What do the rest of you think? Vil. 2009/3/27 Mark Mahieu : > On 27 Mar 2009, at 00:22, Marek Kozie? wrote: >> >> We can also consider: >> >> ? { >> ? ? ?private String name; >> >> ? ? ?public this setName (String this.name){}; >> >> ? ? ?public this.name String getName(){}; >> ? ?} >> >> While we have quite similar idea, they work really great with each >> other. I just still wander if that should go so far. > > > I think you're right to question whether this would be going too > far. ?Looking at the getter method, I don't see a clear gain over the > way it would currently be written, ie, > > ? ? ? ?public this.name String getName() {} > > doesn't strike me as a definite improvement on: > > ? ? ? ?public String getName() { return name; } > > > So far, the only extension to the proposal which looks like it might > be reasonable, is simply to allow it for method parameters in > general. ?I'm not convinced that it would be worthwhile, but for the > sake of illustration here's the example again if that option were taken: > > ? ? ? ?private String name; > > ? ? ? ?public void setName(String this.name) {} > > ? ? ? ?public String getName() { return name; } > > > In this variation, the method name, field, and type are each > mentioned once for the getter, and once for the setter, with no need > to mention extra variables. ?Improving on that would almost certainly > require language support for properties in general, which isn't what > this proposal is about (and isn't in scope for Coin). > > Thanks for sharing your thoughts. > > Regards, > > Mark > > > From javalists at cbfiddle.com Fri Mar 27 12:11:36 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Fri, 27 Mar 2009 12:11:36 -0700 (PDT) Subject: Improved Support for Optional Object Behaviors at Runtime Message-ID: <53321.69.239.104.86.1238181096.squirrel@69.239.104.86> Perhaps a few more words of explanation would help clarify the proposal. I will write them using a FAQ format. * What is the problem being solved? The goal of the proposal is to better support objects with optional behaviors, meaning that the client must perform some sort of test to see if the the optional behavior is defined and also somehow get access to the optional behavior using an appropriately typed variable (one whose type is the class or interface that specifies the optional behavior). Better means better than the current solution of using a type cast. * The client code that you recommend (to access optional behavior in an object) doesn't look that different than what people would write today. What is the point? Are you saying that an if statement is better than an exception handler? Actually, I do think an if statement is better than an exception handler in this case, but that is incidental. Changing the code that the client writes is necessary to access the new features of this proposal. Using the new style, the client invokes a method. Using the old style, the client uses a primitive operator (type cast). The advantage of invoking a method is that method invocation is extensible, whereas the behavior of the primitive operator is fixed (or limited) to what the Java Language Specification says. When I say that method invocation is extensible, I mean that the code that gets executed is defined by the developer of the class of the target object. * The method definition that you proposed (for class Object) looks just like the old style code in the client. What is the point? It is completely intentional that the code looks the same, because that is how backward compatibility is supported. What this means is that if a client program is changed to invoke the getExtension method instead of using a type cast, the program will behave exactly as it did before, when it is using old objects (that is, objects whose implementations have not been changed to take advantage of this proposal). However, the proposed method definition is just a default method definition. A class can be written that overrides the getExtension method, and it can do things that a type cast cannot do. * What can a custom implementation of the getExtension method do that a type cast cannot? Good question. The main thing that a method can do that a type cast cannot is return a reference to a different object than the original target object. If you haven't thought about this sort of thing before, this idea might sound strange, but it is really not. The new object would almost certainly share data with the original object. Here's an example from current Java: Any collection object can return an iterator that provides the elements of the collection one at a time, and may even allow elements to be removed from the collection. The iterator is a different object than the collection, but they share access to the same underlying data. Such sharing is not only more efficient than making a copy of the data for the iterator, it is essential to allow the iterator to remove elements from the collection. Because the method can return a different object, it can support class parameters that are unrelated to the class of the target object. As a simple, perhaps fanciful example: File f = ...; List l = (List) f; This cast will always fail, because File does not implement the List interface (and probably never will). However, consider this call: File f = ...; List l = f.getExtension(List.class); This call might succeed. It won't succeed on an ordinary File, but I could write a subclass of File for which it would return a List (say, of the files in a directory, if the File represented a directory). * You say this proposal better supports delegation. What is delegation and why is it important? If you have never encountered delegation before, you probably need to do some reading before you will fully appreciate it. In a nutshell, delegation is an alternative to subclassing as a way of customizing object behavior. You write a new object that supports the same methods as the old object, and implement the methods by forwarding them to the old object, but the new class may add new methods, or do other things in the old methods, or alter method parameters or results. This concept is also called wrapping. People who know a lot about delegation know that Java does not support delegation in its full glory, but even a limited form can be useful. The problem with type cast is that it can be very hard to make a wrapper object that simulates the behavior of the original object when a client uses a type cast on the wrapper object. The reason it is hard is that no wrapper class code gets executed when the type cast is done. Instead, the wrapper class must be constructed to simulate the relevant aspects of the class hierarchy of the original object. * OK, so the getExtension method is useful, but why not just define it in a new Interface instead of adding it to class Object? This can certainly be done, and it has. I know of four public APIs that have included a method similar to getExtension in their interfaces, and there are probably many more. The unwrap method in java.sql.Wrapper has already been mentioned as one example. However, defining getExtension in a new interface means that it can be used only on new APIs that contain this method or old APIs that have been modified to contain this method. By adding this method to class Object, any class developer can now or in the future add optional behaviors to their class without changing the class hierarchy or the API. This ability is available to Java platform class developers as well as to application class developers. I have not looked, but it would not surprise me that some JSR expert group is considering adding some new behavior to an existing Java platform class. If they used the getExtension method to provide access to that new behavior, then they would not have to make any change to the existing API, only to the documentation. Because the API is unchanged, any application created subclasses would continue to work and to compile. They would simply return null when asked for the new extension. In effect, this one small API change now can remove the need to make many future API changes. * Extra credit: If the basic problem is that type cast is not extensible, why not make it extensible? Excellent question. Feel free to submit a proposal! From javalists at cbfiddle.com Fri Mar 27 12:25:44 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Fri, 27 Mar 2009 12:25:44 -0700 (PDT) Subject: PROPOSAL: Using Ordinary Syntax for Reflective Method Invocations Message-ID: <53374.69.239.104.86.1238181944.squirrel@69.239.104.86> Using Ordinary Syntax for Reflective Method Invocations AUTHOR: Alan Snyder OVERVIEW FEATURE SUMMARY: This proposal allows ordinary method invocation syntax to be used to issue a reflective method invocation, when enabled by the use of a new marker type for the target object. MAJOR ADVANTAGE: Invoking a method using the reflection API is tedious and verbose, and it does not look anything like the corresponding ordinary method invocation that would be used when the target class or interface is statically known. The proposal allows the ordinary method invocation syntax to be used instead to invoke a method using reflection. MAJOR BENEFIT: This proposal makes invoking methods using reflection much easier to write and also much more readable. When a programmer wants to avoid creating a static dependency on an optional module, one way to do so is to invoke the module using reflection. (Note that the target interface may be packaged with the rest of the module, so even a static reference to the target interface would create a dependency.) This proposal would make such loose couplings much simpler and more natural, and would also make it easier to change from tight coupling to loose coupling, or vice versa. MAJOR DISADVANTAGE: A small language change is required, involving the introduction of a new marker type and an extension of method invocation semantics to cover the new marker type. ALTERNATIVES: The major alternatives are to use an IDE or a (nonstandard) preprocessor to generate the appropriate calls on the reflection API. IDE generated code is easy to write but remains difficult to read. Preprocessors do not interact well with tools, especially debuggers. EXAMPLE: Here is a simple invocation of a method on an object whose type is not statically known. The type Unknown is the new marker type that signals the use of reflection to invoke methods on the object so declared. Unknown o = ...; // obtain object without referencing its class try { String s = (String) o.getName("Foo", 3); } catch (InvocationTargetException ex) { ... method threw an exception } catch (Exception ex) { ... could not find method, invoke method, or wrong result type } A more complex example might need to use a type cast to provide a type for a null argument: String s = (String) o.getName((String) null, 3); Another complex example would handle the various individual exceptions that can be raised: try { String s = (String) o.getName("Foo", 3); } catch (NoSuchMethodException ex) { ... } catch (SecurityException ex) { ... } catch (IllegalAccessException ex) { ... } catch (ExceptionInInitializerError ex) { ... } catch (InvocationTargetException ex) { ... } catch (ClassCastException ex) { ... } DETAILS The proposal requires the introduction of a new marker type, which I am calling Unknown. It could be new interface, perhaps in java.reflect. My thought is that extending this interface probably should not be allowed, as it would seem pointless. The Unknown type is used by the programmer to indicate a desire to perform reflective invocations on an object whose type is not statically known. It is thus different than Object (despite having the same set of declared methods), where no such intent is implied. Thus, there is no relaxation of static type checking in programs that do not explicitly use this new feature. When the compiler encounters a method invocation where the static type of the target object expression is Unknown, it replaces the static invocation with the equivalent reflection code, something like this: { Class c = o.getClass(); Class c1 = String.class; Class c2 = Integer.class; Method m = c.getMethod("getName", c1, c2); Object arg1 = "Foo"; Object arg2 = 3; String s = (String) m.invoke(o, arg1, arg2); } The Class objects used in the method lookup are determined based on the expression types of the invocation argument expressions, not the runtime types of the argument objects. (The latter would fail to handle null arguments, for example.) As in the above example, the null literal could not be used without a type cast. I do not claim to have full command of the type system vocabulary, but it seems to me that the process is roughly equivalent to creating a class literal based on the result of type erasure. SPECIFICATION: JLS 15.12.1 would need to be changed to recognize this new case. Specifically, this clause: If the form is Primary.NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier. Let T be the type of the Primary expression; then the class or interface to be searched is T if T is a class or interface type, or the upper bound of T if T is a type variable. would be extended as follows: If the form is Primary.NonWildTypeArgumentsopt Identifier, then the name of the method is the Identifier. Let T be the type of the Primary expression; then the class or interface to be searched is T if T is a class or interface type, or the upper bound of T if T is a type variable. However, if T is the interface Unknown, no search of that interface is performed. Instead, the method is determined at runtime by examining the class of the target object. Since the JLS does not define reflection, it is not clear to me whether the exact details would be specified in the JLS. COMPILATION: The compiler would have to implement this new case. I don't believe there are any new concepts involved. Debuggers should be changed to make the invocation look like an ordinary invocation. COMPATIBILITY The major compatibility issue arises from the introduction of a new name in the class name space. That could potentially cause a program to fail to compile if it imported a class with the name Unknown using a wild card import statement. From lk at teamten.com Fri Mar 27 12:36:26 2009 From: lk at teamten.com (Lawrence Kesteloot) Date: Fri, 27 Mar 2009 12:36:26 -0700 Subject: PROPOSAL: Using Ordinary Syntax for Reflective Method Invocations In-Reply-To: <53374.69.239.104.86.1238181944.squirrel@69.239.104.86> References: <53374.69.239.104.86.1238181944.squirrel@69.239.104.86> Message-ID: <997cab100903271236n15ece63ds8e0ec13652feba41@mail.gmail.com> Could you get rid of the Unknown marker type and use a different syntax for method invocation? > String s = o->getName("Foo", 3); It would be allowed on any object. There would be no need to cast the return value, it would be cast implicitly by the generated code and throw an exception if it didn't match. Lawrence On Fri, Mar 27, 2009 at 12:25 PM, Alan Snyder wrote: > Using Ordinary Syntax for Reflective Method Invocations > > > AUTHOR: Alan Snyder > > OVERVIEW > > FEATURE SUMMARY: > > This proposal allows ordinary method invocation syntax to be used to issue > a reflective method invocation, when enabled by the use of a new marker > type for the target object. > > MAJOR ADVANTAGE: > > Invoking a method using the reflection API is tedious and verbose, and it > does not look anything like the corresponding ordinary method invocation > that would be used when the target class or interface is statically known. > The proposal allows the ordinary method invocation syntax to be used > instead to invoke a method using reflection. > > MAJOR BENEFIT: > > This proposal makes invoking methods using reflection much easier to write > and also much more readable. > > When a programmer wants to avoid creating a static dependency on an > optional module, one way to do so is to invoke the module using > reflection. (Note that the target interface may be packaged with the rest > of the module, so even a static reference to the target interface would > create a dependency.) This proposal would make such loose couplings much > simpler and more natural, and would also make it easier to change from > tight coupling to loose coupling, or vice versa. > > MAJOR DISADVANTAGE: > > A small language change is required, involving the introduction of a new > marker type and an extension of method invocation semantics to cover the > new marker type. > > ALTERNATIVES: > > The major alternatives are to use an IDE or a (nonstandard) preprocessor > to generate the appropriate calls on the reflection API. IDE generated > code is easy to write but remains difficult to read. Preprocessors do not > interact well with tools, especially debuggers. > > EXAMPLE: > > Here is a simple invocation of a method on an object whose type is not > statically known. The type Unknown is the new marker type that signals the > use of reflection to invoke methods on the object so declared. > > ? ?Unknown o = ...; ?// obtain object without referencing its class > ? ?try { > ? ? ?String s = (String) o.getName("Foo", 3); > ? ?} catch (InvocationTargetException ex) { > ? ? ?... method threw an exception > ? ?} catch (Exception ex) { > ? ? ?... could not find method, invoke method, or wrong result type > ? ?} > > A more complex example might need to use a type cast to provide a type for > a null argument: > > ? ?String s = (String) o.getName((String) null, 3); > > Another complex example would handle the various individual exceptions > that can be raised: > > ? ?try { > ? ? ?String s = (String) o.getName("Foo", 3); > ? ?} catch (NoSuchMethodException ex) { > ? ? ?... > ? ?} catch (SecurityException ex) { > ? ? ?... > ? ?} catch (IllegalAccessException ex) { > ? ? ?... > ? ?} catch (ExceptionInInitializerError ex) { > ? ? ?... > ? ?} catch (InvocationTargetException ex) { > ? ? ?... > ? ?} catch (ClassCastException ex) { > ? ? ?... > ? ?} > > DETAILS > > The proposal requires the introduction of a new marker type, which I am > calling Unknown. It could be new interface, perhaps in java.reflect. My > thought is that extending this interface probably should not be allowed, > as it would seem pointless. > > The Unknown type is used by the programmer to indicate a desire to perform > reflective invocations on an object whose type is not statically known. It > is thus different than Object (despite having the same set of declared > methods), where no such intent is implied. Thus, there is no relaxation of > static type checking in programs that do not explicitly use this new > feature. > > When the compiler encounters a method invocation where the static type of > the target object expression is Unknown, it replaces the static invocation > with the equivalent reflection code, something like this: > > ? ?{ > ? ? ?Class c = o.getClass(); > ? ? ?Class c1 = String.class; > ? ? ?Class c2 = Integer.class; > ? ? ?Method m = c.getMethod("getName", c1, c2); > ? ? ?Object arg1 = "Foo"; > ? ? ?Object arg2 = 3; > ? ? ?String s = (String) m.invoke(o, arg1, arg2); > ? ?} > > The Class objects used in the method lookup are determined based on the > expression types of the invocation argument expressions, not the runtime > types of the argument objects. (The latter would fail to handle null > arguments, for example.) As in the above example, the null literal could > not be used without a type cast. I do not claim to have full command of > the type system vocabulary, but it seems to me that the process is roughly > equivalent to creating a class literal based on the result of type > erasure. > > SPECIFICATION: > > JLS 15.12.1 would need to be changed to recognize this new case. > Specifically, this clause: > > ? ?If the form is Primary.NonWildTypeArgumentsopt Identifier, then the > name of the method is the Identifier. Let T be the type of the Primary > expression; then the class or interface to be searched is T if T is a > class or interface type, or the upper bound of T if T is a type > variable. > > would be extended as follows: > > ? ?If the form is Primary.NonWildTypeArgumentsopt Identifier, then the > name of the method is the Identifier. Let T be the type of the Primary > expression; then the class or interface to be searched is T if T is a > class or interface type, or the upper bound of T if T is a type > variable. However, if T is the interface Unknown, no search of that > interface is performed. Instead, the method is determined at runtime > by examining the class of the target object. > > Since the JLS does not define reflection, it is not clear to me whether > the exact details would be specified in the JLS. > > COMPILATION: > > The compiler would have to implement this new case. I don't believe there > are any new concepts involved. Debuggers should be changed to make the > invocation look like an ordinary invocation. > > COMPATIBILITY > > The major compatibility issue arises from the introduction of a new name > in the class name space. That could potentially cause a program to fail to > compile if it imported a class with the name Unknown using a wild card > import statement. > > > > From develop4lasu at gmail.com Fri Mar 27 14:44:53 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 27 Mar 2009 22:44:53 +0100 Subject: PROPOSAL: 'forget' keyword (beta) In-Reply-To: References: <28bca0ff0903270702r52d610a5j792e1912781722d6@mail.gmail.com> Message-ID: <28bca0ff0903271444x2f269c54wca4b462e0813af5e@mail.gmail.com> W dniu 27 marca 2009 17:38 u?ytkownik Daniel Cheng napisa?: > On Fri, Mar 27, 2009 at 10:02 PM, Marek Kozie? wrote: >> ? I do not know if there is point to describe this proposal in >> details, because it require to introduce new keyword which may be >> impossible for project Coin scope.? > > You are encourage going against the ?CERT Secure Programming Practice: > ?https://www.securecoding.cert.org/confluence/display/java/SCP03-J.+Do+not+reuse+names > > Almost all modern programming style manual against reuseing variable name, eg: > ?http://www.cs.cmu.edu/~pattis/15-1XX/15-200/lectures/style/index.html > > > Reusing names is bad (we have the same opinion here) Let's say explicit that something should not be used what's good Contrary to pretension this solution will decrease a number of resused variables "names". Notice that for example someone has opened stream, worked on it and closed. Nowdays, it's quite common to reuse variable for second stream, but if someone has used "forget stream" and had warning/error on "reuse" , he will use for 95% new variable. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Fri Mar 27 15:20:01 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Fri, 27 Mar 2009 23:20:01 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> Message-ID: <28bca0ff0903271520o76cd9720t6991ab626f753167@mail.gmail.com> 2009/3/27 Mark Mahieu : > On 27 Mar 2009, at 00:22, Marek Kozie? wrote: > > We can also consider: > ? { > ?? ? private String name; > ?? ? public this setName (String this.name){}; > ?? ? public this.name String getName(){}; > ?? } > While we have quite similar idea, they work really great with each > other. I just still wander if that should go so far. > > I think you're right to question whether this would be going too far. > ?Looking at the getter method, I don't see a clear gain over the way it > would currently be written, ie, > public this.name String getName() {} > doesn't strike me as a definite improvement on: > public String getName() { return name; } > > So far, the only extension to the proposal which looks like it might be > reasonable, is simply to allow it for method parameters in general. ?I'm not > convinced that it would be worthwhile, but for the sake of illustration > here's the example again if that option were taken: > private String name; > public void setName(String this.name) {} > public String getName() { return name; } > > In this variation, the method name, field, and type are each mentioned once > for the getter, and once for the setter, with no need to mention extra > variables. ?Improving on that would almost certainly require language > support for properties in general, which isn't what this proposal is about > (and isn't in scope for Coin). > Thanks for sharing your thoughts. > Regards, > Mark > I was thinking about that and found few conclusions about syntax: [returned field] returnedType methodName (Type assignedField, ...); MAJOR DISADVANTAGE: We have few ways to obtain same target. ADVANTAGE(s): (input) decreased a number of variables. (return) if we have 5 return statement in method's body, we do not have to write "return this.SomeVariable" 5 times, and this is good. We have to notice that value is returned once while we might be forced to write it 5 / 10 / 15 ... times. INTERACTIONS: public this.name String getName(){ if ( name==null ) return; synchronized (some){ //determine name operations return; } // other operations ... }; Let's focus on second return statement. Return need to be executed in synchronized block to prevent unexpected events. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Fri Mar 27 15:45:02 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Sat, 28 Mar 2009 11:45:02 +1300 Subject: PROPOSAL: Language Escape Operator In-Reply-To: <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> Message-ID: <49CD56EE.3000603@paradise.net.nz> Comments inline thanks Bruce Reinier Zwitserloot wrote: > The backtick, on a standard US 101, needs to be typed by awkwardly > bending your left pinky, traditionally the least flexible typing > finger. At least, for 10-fingers on the home row kind of typer. As > Stefan pointed out, on international keyboards its akin to using the > umlaut (without any characters under it) as a symbol. > > > However, that's not really my issue with this proposal, this is: > > Who ever types or sees that backtick? > > 1. The source file - but, no. It doesn't even end in .java, there is > no way that source could possibly be mistaken for java code. > > 2. The programmer - but, no. I would never use a new language (even if > its folding sugar on vanilla java) if it requires me to type a > gazillion backticks. I wouldn't do it even if it were a nice, easily > typed symbol like, say, semi-colon. Turning my code into perl cartoon > swearing surely cannot be the point. Even if I never see them (because > the folder folds them away!), I don't want to hit a special 'I want > sugar' modifier key, that breaks the flow just as much as a cmd-key > combo. Also, You hit shift routinely as you are 'just typing', so > what's the problem with hitting CMD+X or whatever key such a folding > IDE comes up with? > > 3. The parser - but, no. A code-folding view on the AST would never be > in a position to parse such a thing. > > The proposal doesn't say how the language escape operator should be used. If you are talking about the example use case then here is the logic for why I think it is a good idea. 1. Syntactic sugar is good because it increases the signal to noise ratio when humans read or write the code. 2. Syntactic sugar in the language has a few problems - It takes years to get it in there - Only a few very select and very universal ones get in the language - If it is done wrong then you have to live with it (no rollback) - Its existence constrains the way in which new language features are implemented 3. So if you do syntactic sugar as a view in the IDE and say you use a single character language escape operator then - You get almost all the benefits of having it in the language - at the cost of typing one more character - you can choose whether you want each one separately - If you use one, it doesn't affect anyone else looking at the code - you completely avoid all the negatives. 4. Thats a pretty big nett gain in my book If you don't find any use compelling, you are under no obligation to use it. > > other problem: > > Many non-java languages already need the backtick, such as scala, > which uses it to mean: The contents of the backticks are an > identifier, even if it looks like a keyword. This allows you to call > Thread.yield() in scala like so : Thread.`yield`(), because 'yield' in > scala is a keyword, and therefore Thread.yield() would not invoke the > method (it is instead a syntax error). Java has only 2 common keyboard > symbols left, the backtick and the hash, and taking one of them is a > big deal. I am not convinced its worth it, mostly because of the above > problems. > Right, and so when choosing the character we need to allow for how Java will implement that feature of specifying names of API elements generated in other languages that are not valid Java identifiers. That work is underway as far as I know. > > > The only benefit I can see is that, IF the code-folding AST view > editor does use the backtick as some kind of escaping key, that any > future java expansions do not all of a sudden make previous syntax > sugar legal actual java. But this really doesn't sound very good > either, because: > > 1. The backtick really really needs to be in the source, so that if I > copy and paste, it sticks around. For the example use case, I would imagine that copying and pasting would copy and paste the desugared form. IF you pasted it into another source file in the same IDE with the sugar loaded, then it would get folded back into the sugared form. IF you posted into a blog entry, the desugared form would get pasted. I just don't see a problem here. > A view on the AST could dynamically > add it to the text buffer when you copy and paste, but this is > introducing rather a lot of voodoo. There's also no way for different > AST node view tools t > > 2. Odds are that a very useful and often used desugaring in a popular > AST view editor (which we don't have yet, but hopefully someone will > take the time to write one someday), will end up in java itself. > Except it can't, by definition: That backtick is in the way. > You are presupposing how a possible use of this proposal might work. If there was a really popular IDE based syntactic sugar that became so ubiquitous that it made sense to put it in the language, then migration could be considered at that point. However, if it was good enough in a fit for purpose sense that this scenario came about, then one could ask what would actually be gained by putting it in the language. I don't know what would happen, it is at this stage very hypothetical. I do however want to make sure that we at least have the opportunity to get to that point. IF all the easily type characters got used for other things, then we have lost the opportunity. > 3. If, other than the backtick, the syntax is the same, or at least so > similar that a key-by-key parsing is going to have issues, as a real > java syntax, than the AST view desugaring syntax *needs to go away*. > That point I made before but you haven't answered it yet: Sorry I missed that. Could you please restate your question in and I'll have a go at answering it. > One of the > points of ast views is that you can just change everything without > breaking backwards compatibility. The only compatibility you're > breaking is training your programmers to use a different syntax - > which they have to do anyway, because they're learning to use a new > java version which shipped with at least 1 non-trivial language change > (after all, something that used to be illegal in java but legal as an > AST view syntax, is now legal java!) - I consider the penalty for not > having a language escape operator very low as is, in other words. > > Take that last point, and combine it with the notion that I thoroughly > do not look forward to hitting ` all the time, and you see why I don't > like this proposal. > > > This is what I would type in an AST view language: > > private property int foo; > > and this is what it should write to disk > > @TypedDifferently(original="private property int foo;") > private int foo; > > @GeneratedBy("#foo") public Constructor(int foo) { > this.foo = foo; > } > > @GeneratedBy("#foo") public int getFoo() { > return foo; > } > > @GeneratedBy("#foo") public void setFoo(int foo) { this.foo = foo;} > > @GeneratedBy("#foo") public void addFooListener(..... > > (you get the point) > > > but if I load this file, -with or without annotations in it-, I want > to see: > > private property int foo; > > -though- I'll accept that it might give me: > > property private int foo; > > If the @OriginallyTyped annotation is no longer there. > > I don't want to type backticks. I don't want to see backticks. > > > > > > > A proposal to make *THIS* work well would be great. I would really like to work on that too. Yes it is hard and a significant amount of work, but I think we are at a point in history where it has become feasible. It would be a shame if those of us interested in pursuing this later found that we really needed a language escape operator to make it all work from a technical and aesthetic view and while we had been progressing, a couple of esoteric language changes had come along and used up all the viable escape characters. (I think coin has other proposals or comments for using all of them) I just want to "stake the claim" on such a character now before it is too late because I honestly believe this is the most valuable way we could use one of these characters. > I actually tried > to write up the specs for an AST node editing language, and it's very > very difficult. One of the issues you run into is that you can not > save layout at all - you need to save the code to a java file, in a > different structure, so it becomes almost impossible to preserve the > whitespace, or things like order between keywords, or ordering between > methods, when you read it back in. I thought of magic comments that > keep the original syntax around, but that makes the java code ugly and > not very accessible for people who are not using your particular AST > desugaring engine. > > Something standardized there that links code to the originally typed > stuff (as a comment or string literal) would allow vanilla java IDEs > to not render that comment at all (their own little AST node view :P) > and to notice that a user is editing a generated block, and e.g. show > a little warning, or alternatively offer a view of the originally > typed code, which a vanilla java editor may not understand, though > likely the raw english text in the source would carry some meaning of > intent, probably moreso than the generated code. > > > Such a proposal wouldn't neccessarily fit in the JLS, it's just a > standardized format that is also legal vanilla java (by using magic > comments, probably), which all IDEs agree on as something they'll > eventually detect. If you want special syntax for this, that would be > fine too, but its okay if its verbose. You could introduce a keyword > such as 'ast-node-view', which is so rare that I really doubt anyone's > going to run into an issue with that no longer being a legal > identifier. There's so much you can do - the backtick seems like one > of the worst choices. > > I could comment on that, but it is getting way off topic. Maybe we could collaborate with other interested parties to explore this further in a different forum. > --Reinier Zwitserloot > Bruce From markmahieu at googlemail.com Fri Mar 27 16:32:20 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Fri, 27 Mar 2009 23:32:20 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <6aef848f0903270810r4b98f906k1a47d0b9faf464e4@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> <6aef848f0903270810r4b98f906k1a47d0b9faf464e4@mail.gmail.com> Message-ID: <9D8EEB63-FE3F-468B-9CD8-BCFB963A47A4@googlemail.com> On 27 Mar 2009, at 15:10, Vilya Harvey wrote: > I think the general idea here is great, but I also think the original > proposal tries to be too specific about what gets auto-assigned. The > main use cases are constructors, getters and setters; so how about > just being able to declare those items as having an automatically > created implementation rather than specific parameters to them? > > You could use the "default" keyword (for example) as a modifier in a > similar way to "abstract": methods and constructors declared with it > would be prevented from having a body and the compiler would provide > it instead (or report an error if it couldn't). The method bodies that > the compiler generates could be kept pretty simple. For example, this: The use cases are rather different, to my mind - the Auto-assignment Parameters proposal really isn't aimed at generating whole constructor/method implementations, even though it can be used that way; in fact, fitting in well alongside programmer-supplied code (in the constructor body) is a primary design goal, as it's common to want to do much more than just assign the parameters to some fields. Validating the parameters, or initializing other fields would be common examples. Many of the classes I'd want to apply it to simply don't fit in with the bean-style getter/setter conventions anyway. For the use cases you describe though - where a straightforward auto- generation approach *is* what's wanted - your suggestion seems quite nice in many respects. I suspect it falls firmly into the 'properties support' category of language change, which I'd also welcome progress on, personally. I think the two are largely orthogonal though. Mark From develop4lasu at gmail.com Fri Mar 27 17:10:52 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 01:10:52 +0100 Subject: Proposal: Large arrays In-Reply-To: <49C95773.6020902@sun.com> References: <248872.90823.qm@web63703.mail.re1.yahoo.com> <9C2F9883-B8B7-4AC4-83D0-19398395BC0D@zwitserloot.com> <49C95773.6020902@sun.com> Message-ID: <28bca0ff0903271710p544a93e6q4e1dd4031a380958@mail.gmail.com> 2009/3/24 Joe Darcy : > > ... which is generally why I favor letting collection-like types use the > bracket notation to get and set elements. ?That would eliminate the > syntactically advantages of arrays. > > -Joe > In my opinion, supporting access throw indexes will cause that bad style programming will increase. 2009/3/24 Mark Mahieu : > 2009/3/24 Joe Darcy >> >> >> ... which is generally why I favor letting collection-like types use the >> bracket notation to get and set elements. > > > +1 > > >> ?That would eliminate the >> syntactically advantages of arrays. > > > Except, possibly, for 'adding' elements to them, which in many cases just > looks like: > ? ?fooArray[i++] = foo; > > Collections could conceivably go even cuter though: > ? ?fooList += foo; This is not valid sytanx, because this suggest merging operation rather than addin element. fooList[] += foo; or fooList[] = foo; > and > > ? ?fooList -= foo; > Mark > > -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From markmahieu at googlemail.com Fri Mar 27 17:11:34 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 28 Mar 2009 00:11:34 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <28bca0ff0903271520o76cd9720t6991ab626f753167@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> <28bca0ff0903271520o76cd9720t6991ab626f753167@mail.gmail.com> Message-ID: That's a good example, but to me it's a nice illustration of why that approach doesn't work very well for return values, especially when there's additional logic in the method body. 'return;' already has very clear semantics in Java, and this would add too much confusion, and complexity, for there to be a net gain. Mark 2009/3/27 Marek Kozie? > 2009/3/27 Mark Mahieu : > > On 27 Mar 2009, at 00:22, Marek Kozie? wrote: > > > > We can also consider: > > { > > private String name; > > public this setName (String this.name){}; > > public this.name String getName(){}; > > } > > While we have quite similar idea, they work really great with each > > other. I just still wander if that should go so far. > > > > I think you're right to question whether this would be going too far. > > Looking at the getter method, I don't see a clear gain over the way it > > would currently be written, ie, > > public this.name String getName() {} > > doesn't strike me as a definite improvement on: > > public String getName() { return name; } > > > > So far, the only extension to the proposal which looks like it might be > > reasonable, is simply to allow it for method parameters in general. I'm > not > > convinced that it would be worthwhile, but for the sake of illustration > > here's the example again if that option were taken: > > private String name; > > public void setName(String this.name) {} > > public String getName() { return name; } > > > > In this variation, the method name, field, and type are each mentioned > once > > for the getter, and once for the setter, with no need to mention extra > > variables. Improving on that would almost certainly require language > > support for properties in general, which isn't what this proposal is > about > > (and isn't in scope for Coin). > > Thanks for sharing your thoughts. > > Regards, > > Mark > > > > I was thinking about that and found few conclusions about syntax: > [returned field] returnedType methodName (Type assignedField, ...); > > > MAJOR DISADVANTAGE: > We have few ways to obtain same target. > > > ADVANTAGE(s): > (input) decreased a number of variables. > (return) if we have 5 return statement in method's body, we do not > have to write "return this.SomeVariable" 5 times, and this is good. We > have to notice that value is returned once while we might be forced to > write it 5 / 10 / 15 ... times. > > > INTERACTIONS: > public this.name String getName(){ > if ( name==null ) return; > synchronized (some){ > //determine name operations > return; > } > // other operations ... > }; > > Let's focus on second return statement. > Return need to be executed in synchronized block to prevent unexpected > events. > > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From develop4lasu at gmail.com Fri Mar 27 17:41:32 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 01:41:32 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> <28bca0ff0903271520o76cd9720t6991ab626f753167@mail.gmail.com> Message-ID: <28bca0ff0903271741x37a811d3q5a6c86b2a7568da0@mail.gmail.com> W dniu 28 marca 2009 01:11 u?ytkownik Mark Mahieu napisa?: > That's a good example, but to me it's a nice illustration of?why that > approach doesn't work very well for return values, especially when there's > additional logic in the method body. > 'return;' already has very clear semantics in Java, and this would add too > much confusion, and complexity, for there to be a net gain. > Mark > > But this can be even bigger problem with input parameters, while they are not able to be placed in synchronization block in given syntax (except synchronization over method). While with output parameter this can be quite easy handled. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Fri Mar 27 20:24:02 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 04:24:02 +0100 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: <28bca0ff0903272024u2c8569efp6aa776a1bb3c0921@mail.gmail.com> W dniu 26 marca 2009 22:41 u?ytkownik Gabriel Belingueres napisa?: > VariableInitializer type is neither primitive nor Object. Why? > primitive: are 'special' and they should not be mixed with objects to much. Object: this is more complicated situation. Notice that: final some = null; have no sense at all, it's just new name for something common. Similar situation overlap with Objects, so while we do not know that type we have, then omitting 'this' type have no sense as well, because we loose information 'this object type is unknown'. > Also, there are times when it might be OK to assign null to a variable > as long as the compile time type can be uniquely identified: > > final a = (booleanCondition) ? null : new SomeClass(); > > In this case the you can assume that the type of variable a will be SomeClass. > > What about autoboxing? > > final a = (booleanCondition) ? 1 : new Integer(2); > Forbid (at least in first version). > it is int or Integer? (currently the ? operand resolve it to an int) > > Also see my notes on the interaction between final variables and overloading: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000859.html > > IMO, when using the ? operator it should not try to find an > intersection type for the compile time type of the final variable, but > it should be the exact type on both the 2nd and 3rd operand, otherwise > it should raise a compiler error. If you want another type for the > variable, then specify it as usual. > > I agree, except @see previous mail. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Fri Mar 27 20:38:49 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 04:38:49 +0100 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: References: Message-ID: <28bca0ff0903272038p1f28e05bt60a26491776a2a3@mail.gmail.com> 2009/3/24 Alexandre MAKARENKO : > Naked dot > > AUTHOR(S): MAKARENKO Alexandre > OVERVIEW > FEATURE SUMMARY: Accessing object fields through unqualified "." > > MAJOR ADVANTAGE: Obsoletes attribute naming conventions. > > MAJOR BENEFIT: ?Makes Java programs visually more readable and eventually > less error-prone (see ?Strict mode? in details). > > To avoid name collisions and make source codes more maintainable > developers either hold with a convention for attribute names or prefix > members by ?this.? when refer to. Any naming convention, since not a part > of the language, offers only a weak distinction between local variable and > object field. Moreover it introduces extra characters and makes the source > code not very natural. Using ?this.? is absolutely safe but makes the > source code too much heavy. > Assessing object fields through unqualified ?.? may be an elegant > trade-off between readability and strictness. > > MAJOR DISADVANTAGE: ?May look assemblish. > > ALTERNATIVES: > Use "this.aField" or m_aField, or _aField, or any other naming convention > to distinguish between local variables and object fields. > > EXAMPLES > public class Point > { > ? ?public Point( double x, double y ) > ? ?{ > ? ? ? ?.x = x; // compiles like this.x = x; > ? ? ? ?.y = y; // compiles like this.y = y; > ? ?} > ? ?private double x, y; > } > > DETAILS > SPECIFICATION: > During the name lookup process a package-less ?.? will be considered as > ?this.?. So that > ?.fieldName? will be equivalent to ?this.fieldName?. > > COMPILATION: The compiler detects unqualified dots and (if not a start of > floating point value) inserts an imaginary ?this?. > > TESTING: ?Not relevant > > LIBRARY SUPPORT: Not relevant. > > REFLECTIVE APIS: ?Not relevant > > OTHER CHANGES: Not relevant > > MIGRATION: > Weak mode (default). Attribute name look-up is carried out as it is > mentioned in the current language specification. For example > public class Point > { > ? ?... > ? ?public move( double dx, double dy ) > ? ?{ > ? ? ? ?.x += dx; // resolves .x to this.x > ? ? ? ? y += dy; // resolves ?y to this.y > ? ?} > ? ?private double x, y; > } > Strict mode ?(optional). For enterprises who would like to enforce > in-house coding styles, there may be a kind of -XStrictMemberAccess > compiler option. In this case the unqualified attribute references will > fail to compile. For example > > public class Point > { > ? ?... > ? ?public move( double dx, double dy ) > ? ?{ > ? ? ? ?.x += dx; // only local and static variables may > ? ? ? ? ? ? ? ? ?// be referred to without ?.? > ? ? ? ? y += dy; // compile time error: unknown y > ? ?} > ? ?private double x, y; > } > COMPATIBILITY > Ascending source level compatibility (in Weak mode) with existing Java > programs. > Absolute binary compatibility with all existing Java software. > Disassemblers may produce both ?this.? and ?.? (since they are > equivalent). > REFERENCES > None > > ************************************************************************* > This message and any attachments (the "message") are confidential, intended solely for the addressee(s), and may contain legally privileged information. > Any unauthorised use or dissemination is prohibited. E-mails are susceptible to alteration. > Neither SOCIETE GENERALE nor any of its subsidiaries or affiliates shall be liable for the message if altered, changed or > falsified. > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?************ > Ce message et toutes les pieces jointes (ci-apres le "message") sont confidentiels et susceptibles de contenir des informations couvertes > par le secret professionnel. > Ce message est etabli a l'intention exclusive de ses destinataires. Toute utilisation ou diffusion non autorisee est interdite. > Tout message electronique est susceptible d'alteration. > La SOCIETE GENERALE et ses filiales declinent toute responsabilite au titre de ce message s'il a ete altere, deforme ou falsifie. > ************************************************************************* > > MAJOR DISADVANTAGE(s): 1. Semicolon removed by mistake or forgotten will be real problem here and can create really deep bugs. 2. Joe have right. Both are serious and can end with ravishing code analyzing. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Fri Mar 27 21:29:09 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 05:29:09 +0100 Subject: I need your opinion... In-Reply-To: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> Message-ID: <28bca0ff0903272129o25bc16bajd774ccd67334d899@mail.gmail.com> 5.while-each (same as for-each but ONLY for Iterator-s) void f( Iterator> sheet , boolean containsTitle) if ( ! iterator.hasNext() ) return; ArrayList title = ( containsTitle ? iterator.next() : null ); while (ArrayList row : iterator){ ... } ... } while-each & final: void f( Iterator> sheet , boolean containsTitle) if ( ! iterator.hasNext() ) return; final title = ( containsTitle ? iterator.next() : null ); while (final row : iterator){ ... } ... } Normal 1: void f(List> sheet, boolean containsTitle) if ( sheet.size==0 ) return; ArrayList title = ( containsTitle ? sheet.get(0) : null ); boolean ignore = containsTitle; for(ArrayList row : sheet) if (ignore){ ignore = false; continue; } ... } ... } Normal 2: void f(List> sheet, boolean containsTitle) if ( sheet.size==0 ) return; ArrayList title = ( containsTitle ? sheet.get(0) : null ); for(int i =1 ; i< sheet.size(); i++) ArrayList row = sheet.get(i); ... } ... } 6. Automatic read-write synchronization through lock-s (this need deep analyze) Muli-thread applications are future for sure, this is one of the ways to handle that... static class Collection{ ReadWriteLock lock =...; synchronized.read(lock) T get(int i){ ... } synchronized.write(lock) boolean add(T newElement){ ... } int addAll(Iterator iterator){ synchronized.write (lock) { .... } } } 7. final interfaces and abstract classes. make interface final would cause that only specified inheritance would be possible final interface A allow B,C{} interface B extends A{} interface D extends A{} // compile time error interface E extends B{} // OK, B allow for that final class C implements A{} // ok 8. extends WaekReference-s with query allowing re-use objects -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From fyaoxy at gmail.com Fri Mar 27 21:42:48 2009 From: fyaoxy at gmail.com (=?GB2312?B?z/LRxQ==?=) Date: Sat, 28 Mar 2009 12:42:48 +0800 Subject: I need your opinion... In-Reply-To: <28bca0ff0903272129o25bc16bajd774ccd67334d899@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <28bca0ff0903272129o25bc16bajd774ccd67334d899@mail.gmail.com> Message-ID: <91dd9a4f0903272142w469bcbd4xd47dff3907fc8742@mail.gmail.com> Hi, newcomer to Coin:) 2009/3/28 Marek Kozie? : > 7. final interfaces and abstract classes. > make interface final would cause that only specified inheritance would > be possible > > > final interface A allow B,C{} > > interface B extends A{} > > interface D extends A{} // compile time error > > interface E extends B{} // OK, B allow for that > > final class C implements A{} // ok > > In my view "final" semantics, "final class, final interface", seems belong to API level, which in scope of the upper protocol. But you talk at language level, yes? > 8. extends WaekReference-s with query allowing re-use objects > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > -- ?? ?? From reinier at zwitserloot.com Sat Mar 28 00:10:03 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Sat, 28 Mar 2009 08:10:03 +0100 Subject: PROPOSAL: Language Escape Operator In-Reply-To: <49CD56EE.3000603@paradise.net.nz> References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> <49CD56EE.3000603@paradise.net.nz> Message-ID: <44C4C8CE-83C2-48C9-9AB7-8FD54BE6AD37@zwitserloot.com> Can you give me a use-case that used a back-tick? I found the property keyword one to be very un-compelling (in fact, I would use it as proof that we don't need it, and that even if it was available, it wouldn't even be used. If I was designing an AST view language, I wouldn't do that, and if I had to pick one, I'd count the need to type a backtick as a major con). I think we're misunderstanding each other on some topics because of a lack of examples. I understand the point of this operator is for there to be NO actual use-cases yet, but nevertheless, gazing into the future should give some possible examples, no matter how esoteric. NB: Loved your slides on the topic. I have comments because I care :P --Reinier Zwitserloot On Mar 27, 2009, at 23:45, Bruce Chapman wrote: > Comments inline > > thanks > > Bruce > > Reinier Zwitserloot wrote: >> The backtick, on a standard US 101, needs to be typed by awkwardly >> bending your left pinky, traditionally the least flexible typing >> finger. At least, for 10-fingers on the home row kind of typer. As >> Stefan pointed out, on international keyboards its akin to using the >> umlaut (without any characters under it) as a symbol. >> >> >> However, that's not really my issue with this proposal, this is: >> >> Who ever types or sees that backtick? >> >> 1. The source file - but, no. It doesn't even end in .java, there is >> no way that source could possibly be mistaken for java code. >> >> 2. The programmer - but, no. I would never use a new language (even >> if >> its folding sugar on vanilla java) if it requires me to type a >> gazillion backticks. I wouldn't do it even if it were a nice, easily >> typed symbol like, say, semi-colon. Turning my code into perl cartoon >> swearing surely cannot be the point. Even if I never see them >> (because >> the folder folds them away!), I don't want to hit a special 'I want >> sugar' modifier key, that breaks the flow just as much as a cmd-key >> combo. Also, You hit shift routinely as you are 'just typing', so >> what's the problem with hitting CMD+X or whatever key such a folding >> IDE comes up with? >> >> 3. The parser - but, no. A code-folding view on the AST would never >> be >> in a position to parse such a thing. >> >> > The proposal doesn't say how the language escape operator should be > used. If you are talking about the example use case then here is the > logic for why I think it is a good idea. > > 1. Syntactic sugar is good because it increases the signal to noise > ratio when humans read or write the code. > > 2. Syntactic sugar in the language has a few problems > - It takes years to get it in there > - Only a few very select and very universal ones get in the > language > - If it is done wrong then you have to live with it (no rollback) > - Its existence constrains the way in which new language features > are implemented > > 3. So if you do syntactic sugar as a view in the IDE and say you use a > single character language escape operator then > - You get almost all the benefits of having it in the language - at > the cost of typing one more character > - you can choose whether you want each one separately > - If you use one, it doesn't affect anyone else looking at the code > - you completely avoid all the negatives. > > 4. Thats a pretty big nett gain in my book > > If you don't find any use compelling, you are under no obligation to > use it. >> >> other problem: >> >> Many non-java languages already need the backtick, such as scala, >> which uses it to mean: The contents of the backticks are an >> identifier, even if it looks like a keyword. This allows you to call >> Thread.yield() in scala like so : Thread.`yield`(), because 'yield' >> in >> scala is a keyword, and therefore Thread.yield() would not invoke the >> method (it is instead a syntax error). Java has only 2 common >> keyboard >> symbols left, the backtick and the hash, and taking one of them is a >> big deal. I am not convinced its worth it, mostly because of the >> above >> problems. >> > Right, and so when choosing the character we need to allow for how > Java > will implement that feature of specifying names of API elements > generated in other languages that are not valid Java identifiers. That > work is underway as far as I know. >> >> >> The only benefit I can see is that, IF the code-folding AST view >> editor does use the backtick as some kind of escaping key, that any >> future java expansions do not all of a sudden make previous syntax >> sugar legal actual java. But this really doesn't sound very good >> either, because: >> >> 1. The backtick really really needs to be in the source, so that if I >> copy and paste, it sticks around. > For the example use case, I would imagine that copying and pasting > would > copy and paste the desugared form. IF you pasted it into another > source > file in the same IDE with the sugar loaded, then it would get folded > back into the sugared form. IF you posted into a blog entry, the > desugared form would get pasted. I just don't see a problem here. >> A view on the AST could dynamically >> add it to the text buffer when you copy and paste, but this is >> introducing rather a lot of voodoo. There's also no way for different >> AST node view tools t >> >> 2. Odds are that a very useful and often used desugaring in a popular >> AST view editor (which we don't have yet, but hopefully someone will >> take the time to write one someday), will end up in java itself. >> Except it can't, by definition: That backtick is in the way. >> > You are presupposing how a possible use of this proposal might work. > If > there was a really popular IDE based syntactic sugar that became so > ubiquitous that it made sense to put it in the language, then > migration > could be considered at that point. However, if it was good enough in a > fit for purpose sense that this scenario came about, then one could > ask > what would actually be gained by putting it in the language. I don't > know what would happen, it is at this stage very hypothetical. I do > however want to make sure that we at least have the opportunity to get > to that point. IF all the easily type characters got used for other > things, then we have lost the opportunity. >> 3. If, other than the backtick, the syntax is the same, or at least >> so >> similar that a key-by-key parsing is going to have issues, as a real >> java syntax, than the AST view desugaring syntax *needs to go away*. >> That point I made before but you haven't answered it yet: > Sorry I missed that. Could you please restate your question in and > I'll > have a go at answering it. > >> One of the >> points of ast views is that you can just change everything without >> breaking backwards compatibility. The only compatibility you're >> breaking is training your programmers to use a different syntax - >> which they have to do anyway, because they're learning to use a new >> java version which shipped with at least 1 non-trivial language >> change >> (after all, something that used to be illegal in java but legal as an >> AST view syntax, is now legal java!) - I consider the penalty for not >> having a language escape operator very low as is, in other words. >> >> Take that last point, and combine it with the notion that I >> thoroughly >> do not look forward to hitting ` all the time, and you see why I >> don't >> like this proposal. >> >> >> This is what I would type in an AST view language: >> >> private property int foo; >> >> and this is what it should write to disk >> >> @TypedDifferently(original="private property int foo;") >> private int foo; >> >> @GeneratedBy("#foo") public Constructor(int foo) { >> this.foo = foo; >> } >> >> @GeneratedBy("#foo") public int getFoo() { >> return foo; >> } >> >> @GeneratedBy("#foo") public void setFoo(int foo) { this.foo = foo;} >> >> @GeneratedBy("#foo") public void addFooListener(..... >> >> (you get the point) >> >> >> but if I load this file, -with or without annotations in it-, I want >> to see: >> >> private property int foo; >> >> -though- I'll accept that it might give me: >> >> property private int foo; >> >> If the @OriginallyTyped annotation is no longer there. >> >> I don't want to type backticks. I don't want to see backticks. >> >> >> >> >> >> >> A proposal to make *THIS* work well would be great. > I would really like to work on that too. Yes it is hard and a > significant amount of work, but I think we are at a point in history > where it has become feasible. > > It would be a shame if those of us interested in pursuing this later > found that we really needed a language escape operator to make it all > work from a technical and aesthetic view and while we had been > progressing, a couple of esoteric language changes had come along and > used up all the viable escape characters. (I think coin has other > proposals or comments for using all of them) I just want to "stake the > claim" on such a character now before it is too late because I > honestly > believe this is the most valuable way we could use one of these > characters. >> I actually tried >> to write up the specs for an AST node editing language, and it's very >> very difficult. One of the issues you run into is that you can not >> save layout at all - you need to save the code to a java file, in a >> different structure, so it becomes almost impossible to preserve the >> whitespace, or things like order between keywords, or ordering >> between >> methods, when you read it back in. I thought of magic comments that >> keep the original syntax around, but that makes the java code ugly >> and >> not very accessible for people who are not using your particular AST >> desugaring engine. >> >> Something standardized there that links code to the originally typed >> stuff (as a comment or string literal) would allow vanilla java IDEs >> to not render that comment at all (their own little AST node view :P) >> and to notice that a user is editing a generated block, and e.g. show >> a little warning, or alternatively offer a view of the originally >> typed code, which a vanilla java editor may not understand, though >> likely the raw english text in the source would carry some meaning of >> intent, probably moreso than the generated code. >> >> >> Such a proposal wouldn't neccessarily fit in the JLS, it's just a >> standardized format that is also legal vanilla java (by using magic >> comments, probably), which all IDEs agree on as something they'll >> eventually detect. If you want special syntax for this, that would be >> fine too, but its okay if its verbose. You could introduce a keyword >> such as 'ast-node-view', which is so rare that I really doubt >> anyone's >> going to run into an issue with that no longer being a legal >> identifier. There's so much you can do - the backtick seems like one >> of the worst choices. >> >> > I could comment on that, but it is getting way off topic. Maybe we > could > collaborate with other interested parties to explore this further in a > different forum. >> --Reinier Zwitserloot >> > Bruce > From brucechapman at paradise.net.nz Sat Mar 28 01:24:58 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Sat, 28 Mar 2009 21:24:58 +1300 Subject: PROPOSAL: Language Escape Operator In-Reply-To: <44C4C8CE-83C2-48C9-9AB7-8FD54BE6AD37@zwitserloot.com> References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> <49CD56EE.3000603@paradise.net.nz> <44C4C8CE-83C2-48C9-9AB7-8FD54BE6AD37@zwitserloot.com> Message-ID: <49CDDEDA.1070000@paradise.net.nz> Reinier Zwitserloot wrote: > Can you give me a use-case that used a back-tick? I found the property > keyword one to be very un-compelling (in fact, I would use it as proof > that we don't need it, and that even if it was available, it wouldn't > even be used. If I was designing an AST view language, I wouldn't do > that, and if I had to pick one, I'd count the need to type a backtick > as a major con). I think we're misunderstanding each other on some > topics because of a lack of examples. I understand the point of this > operator is for there to be NO actual use-cases yet, but nevertheless, > gazing into the future should give some possible examples, no matter > how esoteric. OK, so Property would be fairly easy to parse in the absence of an escape operator. I have used the property plugin on a real project and typing the backtick wasn't a major negative. So some more examples - straight off the top of my head what about operator overloading say BigDecimal a,b,c; b = a \+ c; <=> b = a.add(c); or String switches where the first syntax error wrt JLS occurs way after the start of the statement. (I am assuming in the absence of a language escape you'd use a parsing error for the standard java language to trigger a reparse with various loaded sugars.) Or here's a favourite PITA for me. There is no simple obvious way to pass a generic type as an annotation value. What you can do is have the annotation value be a Class[], then just parse the supplied classes assuming no raw types, recursive read as many type parameters as you need. @interface SomeReasonForAType { Class[] value(); } so when you wanted to specify Map> it would be encoded as {Map.class,String.class, List.class, String.class} now what if we got an IDE hosted syntactic sugar for that with the following mapping \Map> <=> {Map.class,String.class, List.class, String.class} maybe only when used as an annotation value. Stefan Schulz has explained the back tick problem to me (I only use a US-101 keyboard so back tick is no big deal) and I think that is a good enough reason to maybe use one of the other available characters. Don't get hung up on the individual character, it is easily changed at this point. Would you prefer \? . I'd be happy to change it to \, there are some semantic advantages to \. > > NB: Loved your slides on the topic. I have comments because I care :P Glad about that. I was a wondering how much they made sense in the absence of the narrative, its pretty hard to know when you've done it yourself with the aim of Illustrating a talk. Have you made comment somewhere regarding the slides? or are you referring to these comments on coin-dev? thanks Bruce > > --Reinier Zwitserloot > > > > On Mar 27, 2009, at 23:45, Bruce Chapman wrote: > >> Comments inline >> >> thanks >> >> Bruce >> >> Reinier Zwitserloot wrote: >>> The backtick, on a standard US 101, needs to be typed by awkwardly >>> bending your left pinky, traditionally the least flexible typing >>> finger. At least, for 10-fingers on the home row kind of typer. As >>> Stefan pointed out, on international keyboards its akin to using the >>> umlaut (without any characters under it) as a symbol. >>> >>> >>> However, that's not really my issue with this proposal, this is: >>> >>> Who ever types or sees that backtick? >>> >>> 1. The source file - but, no. It doesn't even end in .java, there is >>> no way that source could possibly be mistaken for java code. >>> >>> 2. The programmer - but, no. I would never use a new language (even if >>> its folding sugar on vanilla java) if it requires me to type a >>> gazillion backticks. I wouldn't do it even if it were a nice, easily >>> typed symbol like, say, semi-colon. Turning my code into perl cartoon >>> swearing surely cannot be the point. Even if I never see them (because >>> the folder folds them away!), I don't want to hit a special 'I want >>> sugar' modifier key, that breaks the flow just as much as a cmd-key >>> combo. Also, You hit shift routinely as you are 'just typing', so >>> what's the problem with hitting CMD+X or whatever key such a folding >>> IDE comes up with? >>> >>> 3. The parser - but, no. A code-folding view on the AST would never be >>> in a position to parse such a thing. >>> >>> >> The proposal doesn't say how the language escape operator should be >> used. If you are talking about the example use case then here is the >> logic for why I think it is a good idea. >> >> 1. Syntactic sugar is good because it increases the signal to noise >> ratio when humans read or write the code. >> >> 2. Syntactic sugar in the language has a few problems >> - It takes years to get it in there >> - Only a few very select and very universal ones get in the language >> - If it is done wrong then you have to live with it (no rollback) >> - Its existence constrains the way in which new language features >> are implemented >> >> 3. So if you do syntactic sugar as a view in the IDE and say you use a >> single character language escape operator then >> - You get almost all the benefits of having it in the language - at >> the cost of typing one more character >> - you can choose whether you want each one separately >> - If you use one, it doesn't affect anyone else looking at the code >> - you completely avoid all the negatives. >> >> 4. Thats a pretty big nett gain in my book >> >> If you don't find any use compelling, you are under no obligation to >> use it. >>> >>> other problem: >>> >>> Many non-java languages already need the backtick, such as scala, >>> which uses it to mean: The contents of the backticks are an >>> identifier, even if it looks like a keyword. This allows you to call >>> Thread.yield() in scala like so : Thread.`yield`(), because 'yield' in >>> scala is a keyword, and therefore Thread.yield() would not invoke the >>> method (it is instead a syntax error). Java has only 2 common keyboard >>> symbols left, the backtick and the hash, and taking one of them is a >>> big deal. I am not convinced its worth it, mostly because of the above >>> problems. >>> >> Right, and so when choosing the character we need to allow for how Java >> will implement that feature of specifying names of API elements >> generated in other languages that are not valid Java identifiers. That >> work is underway as far as I know. >>> >>> >>> The only benefit I can see is that, IF the code-folding AST view >>> editor does use the backtick as some kind of escaping key, that any >>> future java expansions do not all of a sudden make previous syntax >>> sugar legal actual java. But this really doesn't sound very good >>> either, because: >>> >>> 1. The backtick really really needs to be in the source, so that if I >>> copy and paste, it sticks around. >> For the example use case, I would imagine that copying and pasting would >> copy and paste the desugared form. IF you pasted it into another source >> file in the same IDE with the sugar loaded, then it would get folded >> back into the sugared form. IF you posted into a blog entry, the >> desugared form would get pasted. I just don't see a problem here. >>> A view on the AST could dynamically >>> add it to the text buffer when you copy and paste, but this is >>> introducing rather a lot of voodoo. There's also no way for different >>> AST node view tools t >>> >>> 2. Odds are that a very useful and often used desugaring in a popular >>> AST view editor (which we don't have yet, but hopefully someone will >>> take the time to write one someday), will end up in java itself. >>> Except it can't, by definition: That backtick is in the way. >>> >> You are presupposing how a possible use of this proposal might work. If >> there was a really popular IDE based syntactic sugar that became so >> ubiquitous that it made sense to put it in the language, then migration >> could be considered at that point. However, if it was good enough in a >> fit for purpose sense that this scenario came about, then one could ask >> what would actually be gained by putting it in the language. I don't >> know what would happen, it is at this stage very hypothetical. I do >> however want to make sure that we at least have the opportunity to get >> to that point. IF all the easily type characters got used for other >> things, then we have lost the opportunity. >>> 3. If, other than the backtick, the syntax is the same, or at least so >>> similar that a key-by-key parsing is going to have issues, as a real >>> java syntax, than the AST view desugaring syntax *needs to go away*. >>> That point I made before but you haven't answered it yet: >> Sorry I missed that. Could you please restate your question in and I'll >> have a go at answering it. >> >>> One of the >>> points of ast views is that you can just change everything without >>> breaking backwards compatibility. The only compatibility you're >>> breaking is training your programmers to use a different syntax - >>> which they have to do anyway, because they're learning to use a new >>> java version which shipped with at least 1 non-trivial language change >>> (after all, something that used to be illegal in java but legal as an >>> AST view syntax, is now legal java!) - I consider the penalty for not >>> having a language escape operator very low as is, in other words. >>> >>> Take that last point, and combine it with the notion that I thoroughly >>> do not look forward to hitting ` all the time, and you see why I don't >>> like this proposal. >>> >>> >>> This is what I would type in an AST view language: >>> >>> private property int foo; >>> >>> and this is what it should write to disk >>> >>> @TypedDifferently(original="private property int foo;") >>> private int foo; >>> >>> @GeneratedBy("#foo") public Constructor(int foo) { >>> this.foo = foo; >>> } >>> >>> @GeneratedBy("#foo") public int getFoo() { >>> return foo; >>> } >>> >>> @GeneratedBy("#foo") public void setFoo(int foo) { this.foo = foo;} >>> >>> @GeneratedBy("#foo") public void addFooListener(..... >>> >>> (you get the point) >>> >>> >>> but if I load this file, -with or without annotations in it-, I want >>> to see: >>> >>> private property int foo; >>> >>> -though- I'll accept that it might give me: >>> >>> property private int foo; >>> >>> If the @OriginallyTyped annotation is no longer there. >>> >>> I don't want to type backticks. I don't want to see backticks. >>> >>> >>> >>> >>> >>> >>> A proposal to make *THIS* work well would be great. >> I would really like to work on that too. Yes it is hard and a >> significant amount of work, but I think we are at a point in history >> where it has become feasible. >> >> It would be a shame if those of us interested in pursuing this later >> found that we really needed a language escape operator to make it all >> work from a technical and aesthetic view and while we had been >> progressing, a couple of esoteric language changes had come along and >> used up all the viable escape characters. (I think coin has other >> proposals or comments for using all of them) I just want to "stake the >> claim" on such a character now before it is too late because I honestly >> believe this is the most valuable way we could use one of these >> characters. >>> I actually tried >>> to write up the specs for an AST node editing language, and it's very >>> very difficult. One of the issues you run into is that you can not >>> save layout at all - you need to save the code to a java file, in a >>> different structure, so it becomes almost impossible to preserve the >>> whitespace, or things like order between keywords, or ordering between >>> methods, when you read it back in. I thought of magic comments that >>> keep the original syntax around, but that makes the java code ugly and >>> not very accessible for people who are not using your particular AST >>> desugaring engine. >>> >>> Something standardized there that links code to the originally typed >>> stuff (as a comment or string literal) would allow vanilla java IDEs >>> to not render that comment at all (their own little AST node view :P) >>> and to notice that a user is editing a generated block, and e.g. show >>> a little warning, or alternatively offer a view of the originally >>> typed code, which a vanilla java editor may not understand, though >>> likely the raw english text in the source would carry some meaning of >>> intent, probably moreso than the generated code. >>> >>> >>> Such a proposal wouldn't neccessarily fit in the JLS, it's just a >>> standardized format that is also legal vanilla java (by using magic >>> comments, probably), which all IDEs agree on as something they'll >>> eventually detect. If you want special syntax for this, that would be >>> fine too, but its okay if its verbose. You could introduce a keyword >>> such as 'ast-node-view', which is so rare that I really doubt anyone's >>> going to run into an issue with that no longer being a legal >>> identifier. There's so much you can do - the backtick seems like one >>> of the worst choices. >>> >>> >> I could comment on that, but it is getting way off topic. Maybe we could >> collaborate with other interested parties to explore this further in a >> different forum. >>> --Reinier Zwitserloot >>> >> Bruce >> > From tim.lebedkov at googlemail.com Sat Mar 28 01:35:46 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Sat, 28 Mar 2009 09:35:46 +0100 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. Message-ID: 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 develop4lasu at gmail.com Sat Mar 28 02:00:47 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 10:00:47 +0100 Subject: I need your opinion... In-Reply-To: <91dd9a4f0903272142w469bcbd4xd47dff3907fc8742@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <28bca0ff0903272129o25bc16bajd774ccd67334d899@mail.gmail.com> <91dd9a4f0903272142w469bcbd4xd47dff3907fc8742@mail.gmail.com> Message-ID: <28bca0ff0903280200g54cf959btf8d288710fa91725@mail.gmail.com> 2009/3/28 ?? : > Hi, ?newcomer to Coin:) > > > In my view "final" semantics, "final class, final interface", > seems belong to API level, which in scope of the upper protocol. > But you talk at language level, yes? > > -- > ?? > ?? > > Hi. Notice that complicator need to be extended with such a validation, so it's language change that refers to API. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From fyaoxy at gmail.com Sat Mar 28 02:58:13 2009 From: fyaoxy at gmail.com (=?GB2312?B?z/LRxQ==?=) Date: Sat, 28 Mar 2009 17:58:13 +0800 Subject: I need your opinion... In-Reply-To: <28bca0ff0903280200g54cf959btf8d288710fa91725@mail.gmail.com> References: <28bca0ff0903211252g36fcd4dkaf1c0214f7f93a28@mail.gmail.com> <28bca0ff0903272129o25bc16bajd774ccd67334d899@mail.gmail.com> <91dd9a4f0903272142w469bcbd4xd47dff3907fc8742@mail.gmail.com> <28bca0ff0903280200g54cf959btf8d288710fa91725@mail.gmail.com> Message-ID: <91dd9a4f0903280258u382bc9adt64d47f4bd9142526@mail.gmail.com> 2009/3/28 Marek Kozie? : > 2009/3/28 ?? : >> Hi, newcomer to Coin:) >> >> >> In my view "final" semantics, "final class, final interface", >> seems belong to API level, which in scope of the upper protocol. >> But you talk at language level, yes? >> >> -- >> ?? >> ?? >> >> > > Hi. > Notice that complicator need to be extended with such a validation, so > it's language change that refers to API. Indeed, I mean this kind process would be better if deliver the upper protocol manager, such as super package or osgi-like manager. In above, my API not the language API. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > -- ?? ?? From fyaoxy at gmail.com Sat Mar 28 03:14:56 2009 From: fyaoxy at gmail.com (=?GB2312?B?z/LRxQ==?=) Date: Sat, 28 Mar 2009 18:14:56 +0800 Subject: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: References: Message-ID: <91dd9a4f0903280314o2f0253c9ub08e8f459e6e3ae5@mail.gmail.com> Hi, A variable declaration has 3 kind of style: 1, field: class Case1{ fieldType fieldName;} 2, local: method or si, type varName; 3, statement, for(type var...) then do assignment, switch(case) 1: the "fieldName" field type determinated, so assignment value must acceptable by the field type. so the generic type argument is no need at all. 2: split 2 child case, 2.1assign a given argument, which type determinated, same as 1. 2.2 new local var, Yes, the new instance and generic type argument is just my want. in this case, the type of local variable is no need at all. 3: same as 2.2 So I would hope this: class Test{ List list1 = new ArrayList(); List list2; Test(){ list2 = new ArrayList(); } void test(List list){ list = new ArrayList(); list2 = new ArrayList(); for(s: list) handleString(s); for(i: list2) handleInteger(i); } } What do you think? 2009/3/28 Tim Lebedkov : > 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 scolebourne at joda.org Sat Mar 28 03:40:19 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Sat, 28 Mar 2009 10:40:19 +0000 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49C56020.2070207@joda.org> References: <49C56020.2070207@joda.org> Message-ID: <49CDFE93.9090702@joda.org> Were there any comments on this? Stephen Stephen Colebourne wrote: > Enhanced for each loop iteration control > > (re-sent with correct subject line) > > This proposal extends the for each loop to allow access to meta data > including the index and the remove method. > > (This proposal doesn't really go into enough detail - with JSR-310 my > time here is limited. I'd hope that there is just about enough though....) > > ----------------------------------------------------------------------------------- > Enhanced for each loop iteration control > > AUTHOR(S): > Stephen Colebourne > > *OVERVIEW* > > FEATURE SUMMARY: > Extends the Java 5 for-each loop to allow access to the loop index, > whether this is the first or last iteration, and to remove the current item. > > MAJOR ADVANTAGE: > The for-each loop is almost certainly the most new popular feature from > Java 5. It works because it increases the abstraction level - instead of > having to express the low-level details of how to loop around a list or > array (with an index or iterator), the developer simply states that they > want to loop and the language takes care of the rest. However, all the > benefit is lost as soon as the developer needs to access the index or to > remove an item. > > The original Java 5 for each work took a relatively conservative stance > on a number of issues aiming to tackle the 80% case. However, loops are > such a common form in coding that the remaining 20% that was not tackled > represents a significant body of code. > > The process of converting the loop back from the for each to be index or > iterator based is painful. This is because the old loop style if > significantly lower-level, more verbose and less clear. It is also > painful as most IDEs don't support this kind of 'de-refactoring'. > > MAJOR BENEFIT: > A common coding idiom is expressed at a higher abstraction than at > present. This aids readability and clarity. > > Accessing the index currently requires using an int based loop, or > placing a separate int counter outside the loop (which then remains in > scope after the loop). The proposed solution doesn't result in manual > manipulation of the index. > > Accessing the iterator remove requires using an iterator based loop. > With generics this is remarkably verbose. The proposed solution is > significantly shorter and cleaner. > > MAJOR DISADVANTAGE: > The enhanced for each loop is complicated with additional functionality. > (This is mitigated by being easy and obvious to use) > > More code is generated magically by the compiler. (This is mitigated by > a simple desugaring) > > ALTERNATIVES: > Use the existing language constructs, typically the standard for loop. > > Use BGGA/JCA style closures, with control statements. It should be noted > that these are consistently the most controversial parts of the closure > debate, making the 'let's wait for closures' argument against this > proposal weaker (as any final closures implementation may not include > control statements). > > > *EXAMPLES* > > SIMPLE EXAMPLE: > > StringBuilder buf = new StringBuilder(); > for (String str : list : it) { > if (str == null) { > it.remove(); > } > } > > whereas, today we write: > > StringBuilder buf = new StringBuilder(); > for (Iterator it = list.iterator(); it.hasNext();) { > String str = it.next(); > if (str == null) { > it.remove(); > } > } > > ADVANCED EXAMPLE: > > Example1: > > for (String str : list : it) { > System.out.println("Row " + it.index() + " has the value " + str); > } > > whereas, today we might write: > > int index = 0; > for (String str : list) { > System.out.println("Row " + index + " has the value " + str); > index++; > } > > or > > for (int i = 0; i < list.size(); i++) { > String str = list.get(i); > System.out.println("Row " + index + " has the value " + str); > } > > Example 2: > > StringBuilder buf = new StringBuilder(); > for (String str : list : it) { > if (it.isFirst()) { > buf.append(str); > } else { > buf.append(", ").append(str); > } > } > > StringBuilder buf = new StringBuilder(); > for (String str : list : it) { > if (it.isLast()) { > buf.append(str); > } else { > buf.append(str).append(", "); > } > } > > > *DETAILS* > > SPECIFICATION: > > Lexical: > No new tokens are added. The colon token is reused in the extended > enhanced for each statement. > > Syntax: > > EnhancedForStatement: > for ( VariableModifiersopt Type Identifier : Expression) Statement > for ( VariableModifiersopt Type Identifier : Expression : Ident) > Statement > > Semantics: > > The first enhanced for each statement (the current form) will compile as > it does today. > > The extended enhanced for each statement will operate as follows. > The iterator control variable is a standard variable declared to be > final. It will never be null. The type is dependent on whether the > expression is an array or an Iterable. It will either be > ArrayIterationControl or IterableIterationControl. The type is not > specified as it is redundent information, ie. the type is inferred. It > is scoped for the life of the loop. > > public final class IterableIterationControlIterator { > public IterableIterationControlIterator(Iterable iterable) { > this.control = new IterableIterationControl(iterable.iterator()); > } > public boolean hasNext() { return control.hasNext() } > public T next() { return control.next() } > public IterableIterationControl control() { return control } > } > public final class IterableIterationControl { > public IterableIterationControl(Iterator iteratorToWrap) { > this.it = iteratorToWrap; > } > boolean hasNext() { return it.hasNext() } > T next() { originalIndex++; if (lastWasRemoved) { lastWasRemoved = > false } else { index++ } return it.next() } > public T remove() { removed++; lastWasRemoved = true; return > it.remove() } > public int index() { return index } > public int originalIndex() { return originalIndex } > public boolean isFirst() { return index == 1 } > public boolean isLast() { return it.hasNext() == false } > } > > public final class ArrayIterationControlIterator { > public ArrayIterationControlIterator(T[] array) { > this.control = new ArrayIterationControl(array); > } > public boolean hasNext() { return control.hasNext() } > public T next() { return control.next() } > public ArrayIterationControl control() { return control } > } > public final class ArrayIterationControl { > public ArrayIterationControl(T[] array) { this.array = array; } > boolean hasNext() { return index < array.length; } > T next() { return array[++index]; } > public int index() { return index - 1; } > public boolean isFirst() { return index == 1; } > public boolean isLast() { return index == array.length; } > } > > Exception analysis: > The method remove() on the iteration control variable can throw an > UnsuportedOperationException. However, this is no different from any > other method call. > > Definite assignment: > The new variable iteration control variable is a final variable that is > definitely assigned from creation. > > COMPILATION: > The extended enhanced for each loop is implemented by wrapping the two > control classes around the Iterable or the array. > > The Iterable design is desugared from: > > for (T item : iterable : control) { ... } > > to: > { > IterableIterationControlIterator $it = new > IterableIterationControlIterator(iterable); > IterableIterationControl control = $it.control(); > while ($it.hasNext()) { > T item = $it.next(); > ... > } > } > > The array design is desugared similarly: > > { > ArrayIterationControlIterator $it = new > ArrayIterationControlIterator(iterable); > ArrayIterationControl control = $it.control(); > while ($it.hasNext()) { > T item = $it.next(); > ... > } > } > > There is the option to optimise this if the iteration control variable > is not assigned to any other variable or passed to any other method. > However, that is out of scope for now. > > TESTING: > Testing will be similar to the enhanced for loop. Arrays and Iterables > of various types and sizes will be used. The null expression will also > be tested. > > LIBRARY SUPPORT: > Yes, as detailed above. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > The javac tree API would need to be updated to model the change. > > MIGRATION: > Migration is not required. However, an IDE refactoring could now convert > more int and Iterator based for loops than it does at present. > > > *COMPATIBILITY* > > BREAKING CHANGES: > No breaking changes are known using this conversion scheme. > > EXISTING PROGRAMS: > This conversion is pure syntax sugar, so there are no known interactions > with existing programs. > > > *REFERENCES* > > EXISTING BUGS: > I searched the bug database, but nothing came up (which is surprising). > > URL FOR PROTOTYPE: > None > > DOCUMENTS: > [1] Stephen Colebourne's blog: > http://www.jroller.com/scolebourne/entry/java_7_for_each_loop > [2] Stephen Colebourne's original writeup: > http://docs.google.com/Edit?docID=dfn5297z_15ck7x5ghr > > > *DESIGN ISSUES* > There are numerous alternative ways in which this feature can be added. > These include: > - using the keyword: > for (String str : list) { > for.remove(); // problem is nested for loops > } > - using a label as a psuedo-variable: > it: for (String str : list) { > it:remove(); // note colon and not dot > } > - using an additional clause before the for each colon: > for (String str, int index : list) { > // no access to remove, and conflicts for for each for maps > } > > The chosen solution involves simple Java classes, and a simple desugar. > The downside of the chosen solution is performance, as it involves > creating two wrapping objects and routing hasNext() and next() via > additional layers of method calls. A possible extension would be for the > compiler to identify if the iteration control variable is not passed to > another method. If so, then the code could be all be generated inline. > > > > > > From rssh at gradsoft.com.ua Sat Mar 28 03:57:32 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sat, 28 Mar 2009 12:57:32 +0200 (EET) Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49CDFE93.9090702@joda.org> References: <49C56020.2070207@joda.org> <49CDFE93.9090702@joda.org> Message-ID: <66eb521106c5798e732e2fea33018380.squirrel@wmail.gradsoft.ua> > Were there any comments on this? > Stephen > I like one. (remove is often needed) From mthornton at optrak.co.uk Sat Mar 28 04:06:03 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Sat, 28 Mar 2009 11:06:03 +0000 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49CDFE93.9090702@joda.org> References: <49C56020.2070207@joda.org> <49CDFE93.9090702@joda.org> Message-ID: <49CE049B.7040503@optrak.co.uk> Stephen Colebourne wrote: >> There is the option to optimise this if the iteration control variable >> is not assigned to any other variable or passed to any other method. >> However, that is out of scope for now. >> >> This should be left to the JVM and never done at source compile time. Improvements to HotSpot already implemented or planned for JDK 7 will probably achieve the desired effect. Otherwise, not much to say. Mark Thornton From tim at peierls.net Sat Mar 28 04:18:05 2009 From: tim at peierls.net (Tim Peierls) Date: Sat, 28 Mar 2009 07:18:05 -0400 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49CDFE93.9090702@joda.org> References: <49C56020.2070207@joda.org> <49CDFE93.9090702@joda.org> Message-ID: <63b4e4050903280418y1b2b1a9ah567f29ad9492c6ef@mail.gmail.com> Stephen, I have nothing against the proposal, but it really hasn't bothered me to write out the explicit use of an Iterator or an index in the few cases I've needed to. I doubt I would remember to use this facility if it were added. --tim On Sat, Mar 28, 2009 at 6:40 AM, Stephen Colebourne wrote: > Were there any comments on this? > Stephen > > Stephen Colebourne wrote: > > Enhanced for each loop iteration control > > > > (re-sent with correct subject line) > > > > This proposal extends the for each loop to allow access to meta data > > including the index and the remove method. > > > > (This proposal doesn't really go into enough detail - with JSR-310 my > > time here is limited. I'd hope that there is just about enough > though....) > > > > > ----------------------------------------------------------------------------------- > > Enhanced for each loop iteration control > > > > AUTHOR(S): > > Stephen Colebourne > > > > *OVERVIEW* > > > > FEATURE SUMMARY: > > Extends the Java 5 for-each loop to allow access to the loop index, > > whether this is the first or last iteration, and to remove the current > item. > > > > MAJOR ADVANTAGE: > > The for-each loop is almost certainly the most new popular feature from > > Java 5. It works because it increases the abstraction level - instead of > > having to express the low-level details of how to loop around a list or > > array (with an index or iterator), the developer simply states that they > > want to loop and the language takes care of the rest. However, all the > > benefit is lost as soon as the developer needs to access the index or to > > remove an item. > > > > The original Java 5 for each work took a relatively conservative stance > > on a number of issues aiming to tackle the 80% case. However, loops are > > such a common form in coding that the remaining 20% that was not tackled > > represents a significant body of code. > > > > The process of converting the loop back from the for each to be index or > > iterator based is painful. This is because the old loop style if > > significantly lower-level, more verbose and less clear. It is also > > painful as most IDEs don't support this kind of 'de-refactoring'. > > > > MAJOR BENEFIT: > > A common coding idiom is expressed at a higher abstraction than at > > present. This aids readability and clarity. > > > > Accessing the index currently requires using an int based loop, or > > placing a separate int counter outside the loop (which then remains in > > scope after the loop). The proposed solution doesn't result in manual > > manipulation of the index. > > > > Accessing the iterator remove requires using an iterator based loop. > > With generics this is remarkably verbose. The proposed solution is > > significantly shorter and cleaner. > > > > MAJOR DISADVANTAGE: > > The enhanced for each loop is complicated with additional functionality. > > (This is mitigated by being easy and obvious to use) > > > > More code is generated magically by the compiler. (This is mitigated by > > a simple desugaring) > > > > ALTERNATIVES: > > Use the existing language constructs, typically the standard for loop. > > > > Use BGGA/JCA style closures, with control statements. It should be noted > > that these are consistently the most controversial parts of the closure > > debate, making the 'let's wait for closures' argument against this > > proposal weaker (as any final closures implementation may not include > > control statements). > > > > > > *EXAMPLES* > > > > SIMPLE EXAMPLE: > > > > StringBuilder buf = new StringBuilder(); > > for (String str : list : it) { > > if (str == null) { > > it.remove(); > > } > > } > > > > whereas, today we write: > > > > StringBuilder buf = new StringBuilder(); > > for (Iterator it = list.iterator(); it.hasNext();) { > > String str = it.next(); > > if (str == null) { > > it.remove(); > > } > > } > > > > ADVANCED EXAMPLE: > > > > Example1: > > > > for (String str : list : it) { > > System.out.println("Row " + it.index() + " has the value " + str); > > } > > > > whereas, today we might write: > > > > int index = 0; > > for (String str : list) { > > System.out.println("Row " + index + " has the value " + str); > > index++; > > } > > > > or > > > > for (int i = 0; i < list.size(); i++) { > > String str = list.get(i); > > System.out.println("Row " + index + " has the value " + str); > > } > > > > Example 2: > > > > StringBuilder buf = new StringBuilder(); > > for (String str : list : it) { > > if (it.isFirst()) { > > buf.append(str); > > } else { > > buf.append(", ").append(str); > > } > > } > > > > StringBuilder buf = new StringBuilder(); > > for (String str : list : it) { > > if (it.isLast()) { > > buf.append(str); > > } else { > > buf.append(str).append(", "); > > } > > } > > > > > > *DETAILS* > > > > SPECIFICATION: > > > > Lexical: > > No new tokens are added. The colon token is reused in the extended > > enhanced for each statement. > > > > Syntax: > > > > EnhancedForStatement: > > for ( VariableModifiersopt Type Identifier : Expression) Statement > > for ( VariableModifiersopt Type Identifier : Expression : Ident) > > Statement > > > > Semantics: > > > > The first enhanced for each statement (the current form) will compile as > > it does today. > > > > The extended enhanced for each statement will operate as follows. > > The iterator control variable is a standard variable declared to be > > final. It will never be null. The type is dependent on whether the > > expression is an array or an Iterable. It will either be > > ArrayIterationControl or IterableIterationControl. The type is not > > specified as it is redundent information, ie. the type is inferred. It > > is scoped for the life of the loop. > > > > public final class IterableIterationControlIterator { > > public IterableIterationControlIterator(Iterable iterable) { > > this.control = new IterableIterationControl(iterable.iterator()); > > } > > public boolean hasNext() { return control.hasNext() } > > public T next() { return control.next() } > > public IterableIterationControl control() { return control } > > } > > public final class IterableIterationControl { > > public IterableIterationControl(Iterator iteratorToWrap) { > > this.it = iteratorToWrap; > > } > > boolean hasNext() { return it.hasNext() } > > T next() { originalIndex++; if (lastWasRemoved) { lastWasRemoved = > > false } else { index++ } return it.next() } > > public T remove() { removed++; lastWasRemoved = true; return > > it.remove() } > > public int index() { return index } > > public int originalIndex() { return originalIndex } > > public boolean isFirst() { return index == 1 } > > public boolean isLast() { return it.hasNext() == false } > > } > > > > public final class ArrayIterationControlIterator { > > public ArrayIterationControlIterator(T[] array) { > > this.control = new ArrayIterationControl(array); > > } > > public boolean hasNext() { return control.hasNext() } > > public T next() { return control.next() } > > public ArrayIterationControl control() { return control } > > } > > public final class ArrayIterationControl { > > public ArrayIterationControl(T[] array) { this.array = array; } > > boolean hasNext() { return index < array.length; } > > T next() { return array[++index]; } > > public int index() { return index - 1; } > > public boolean isFirst() { return index == 1; } > > public boolean isLast() { return index == array.length; } > > } > > > > Exception analysis: > > The method remove() on the iteration control variable can throw an > > UnsuportedOperationException. However, this is no different from any > > other method call. > > > > Definite assignment: > > The new variable iteration control variable is a final variable that is > > definitely assigned from creation. > > > > COMPILATION: > > The extended enhanced for each loop is implemented by wrapping the two > > control classes around the Iterable or the array. > > > > The Iterable design is desugared from: > > > > for (T item : iterable : control) { ... } > > > > to: > > { > > IterableIterationControlIterator $it = new > > IterableIterationControlIterator(iterable); > > IterableIterationControl control = $it.control(); > > while ($it.hasNext()) { > > T item = $it.next(); > > ... > > } > > } > > > > The array design is desugared similarly: > > > > { > > ArrayIterationControlIterator $it = new > > ArrayIterationControlIterator(iterable); > > ArrayIterationControl control = $it.control(); > > while ($it.hasNext()) { > > T item = $it.next(); > > ... > > } > > } > > > > There is the option to optimise this if the iteration control variable > > is not assigned to any other variable or passed to any other method. > > However, that is out of scope for now. > > > > TESTING: > > Testing will be similar to the enhanced for loop. Arrays and Iterables > > of various types and sizes will be used. The null expression will also > > be tested. > > > > LIBRARY SUPPORT: > > Yes, as detailed above. > > > > REFLECTIVE APIS: > > No. > > > > OTHER CHANGES: > > The javac tree API would need to be updated to model the change. > > > > MIGRATION: > > Migration is not required. However, an IDE refactoring could now convert > > more int and Iterator based for loops than it does at present. > > > > > > *COMPATIBILITY* > > > > BREAKING CHANGES: > > No breaking changes are known using this conversion scheme. > > > > EXISTING PROGRAMS: > > This conversion is pure syntax sugar, so there are no known interactions > > with existing programs. > > > > > > *REFERENCES* > > > > EXISTING BUGS: > > I searched the bug database, but nothing came up (which is surprising). > > > > URL FOR PROTOTYPE: > > None > > > > DOCUMENTS: > > [1] Stephen Colebourne's blog: > > http://www.jroller.com/scolebourne/entry/java_7_for_each_loop > > [2] Stephen Colebourne's original writeup: > > http://docs.google.com/Edit?docID=dfn5297z_15ck7x5ghr > > > > > > *DESIGN ISSUES* > > There are numerous alternative ways in which this feature can be added. > > These include: > > - using the keyword: > > for (String str : list) { > > for.remove(); // problem is nested for loops > > } > > - using a label as a psuedo-variable: > > it: for (String str : list) { > > it:remove(); // note colon and not dot > > } > > - using an additional clause before the for each colon: > > for (String str, int index : list) { > > // no access to remove, and conflicts for for each for maps > > } > > > > The chosen solution involves simple Java classes, and a simple desugar. > > The downside of the chosen solution is performance, as it involves > > creating two wrapping objects and routing hasNext() and next() via > > additional layers of method calls. A possible extension would be for the > > compiler to identify if the iteration control variable is not passed to > > another method. If so, then the code could be all be generated inline. > > > > > > > > > > > > > > From develop4lasu at gmail.com Sat Mar 28 05:02:48 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sat, 28 Mar 2009 13:02:48 +0100 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49C56020.2070207@joda.org> References: <49C56020.2070207@joda.org> Message-ID: <28bca0ff0903280502t3b350e20l7b481d8d81169ddc@mail.gmail.com> As Isaid, in my opinion while-each is better, because complexity is much lower: void test(ExtendedIterator iterator){ while( final some : iterator ){ iterator.index(); iterator.remove(); and other... } } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From markmahieu at googlemail.com Sat Mar 28 05:11:31 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sat, 28 Mar 2009 12:11:31 +0000 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <28bca0ff0903271741x37a811d3q5a6c86b2a7568da0@mail.gmail.com> References: <28bca0ff0903261403y6c8e3988r2c187a062e507ba8@mail.gmail.com> <28bca0ff0903261410t76d91705xcfdc08ef4ff93a77@mail.gmail.com> <28bca0ff0903261722xb2c26f6qc5ee4f2ff251a0bc@mail.gmail.com> <28bca0ff0903271520o76cd9720t6991ab626f753167@mail.gmail.com> <28bca0ff0903271741x37a811d3q5a6c86b2a7568da0@mail.gmail.com> Message-ID: 2009/3/28 Marek Kozie? > W dniu 28 marca 2009 01:11 u?ytkownik Mark Mahieu > napisa?: > > That's a good example, but to me it's a nice illustration of why that > > approach doesn't work very well for return values, especially when > there's > > additional logic in the method body. > > 'return;' already has very clear semantics in Java, and this would add > too > > much confusion, and complexity, for there to be a net gain. > > Mark > > > > > > But this can be even bigger problem with input parameters, while they > are not able to be placed in synchronization block in given syntax > (except synchronization over method). > > While with output parameter this can be quite easy handled. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > In either case, if you need to do something more sophisticated than straightforward assignment (or, arguably, return), it would be better make that explicit in the method body so that it's obvious to anyone reading the code. Regards, Mark From fw at deneb.enyo.de Sat Mar 28 10:31:48 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 28 Mar 2009 18:31:48 +0100 Subject: Rough Draft Proposal: "Caused by" information provided when NPE is thrown In-Reply-To: <1bb1728a0903260746ic82bc8dlc1f149fbd6bc339a@mail.gmail.com> (Jim Bethancourt's message of "Thu, 26 Mar 2009 09:46:24 -0500") References: <1bb1728a0903260746ic82bc8dlc1f149fbd6bc339a@mail.gmail.com> Message-ID: <87ljqph7uj.fsf@mid.deneb.enyo.de> * Jim Bethancourt: > java.lang.NullPointerException > > at com.code.NPEThrower(NPEThrower.java:10) > > ... > > Caused by: Null return value: Object.getName() > > at com.code.NPEThrower.java:7 > > ... I think that this is equivalent to providing useful exception tracebacks in lazily evaluated languages: The null value is a promise, and forcing it causes an exception which should be attributed to the code which made the promise. If the promise gets passed around quite a bit, it's very difficult to provide useful information, performance considerations aside. To my knowledge, this is an open research problem. From javalists at cbfiddle.com Sat Mar 28 12:50:02 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Sat, 28 Mar 2009 12:50:02 -0700 (PDT) Subject: A Non-Proposal related to Properties Message-ID: <63005.69.239.104.86.1238269802.squirrel@69.239.104.86> A Non-Proposal related to Properties This is not a proposal, but it seems related to Properties, so knowing that there are people on this list who are knowledgeable and care about Properties, I was hoping to get some useful feedback and suggestions. (I'll apologize in advance if this is old news...) As background, I have for a long time been a strong believer in static type checking and using methods for public access to data. Therefore, many years ago, when Java and JavaBeans decided to represent each property or attribute as a get/set method pair, I believed they made a good decision. However, after spending a year or two applying this approach to large sets of configuration parameters and winding up with huge interfaces and way too many wrapper classes, I have changed my mind. It's not that I think that all get and set methods are bad, but I now believe that dynamic access to properties is the right way to go in many cases (especially when there are large numbers of properties and/or an extensible set of properties, where extension can happen by subclassing or by introducing new versions of the class). By dynamic access, I mean one get method (or a small number) and one set method (or a small number) that each take a parameter identifying the property to get or set. The only problem is the loss of static type checking. If my code accesses a specific property (the property identifier is known at compile time), I want the compiler to type check my code, and I don't want to have to use a type cast. Fortunately, there are clever people out there who have figured out a way to do this using the current Java generics. The basic idea is to define a class whose instances contain the basic property identifier (a String, say) along with a class object indicating the type of values that are acceptable for that property. Something like this: public class PropertyName { private String name; private Class type; public PropertyName(String name, Class type) { this.name = name; this.type = type; } public String getName() { return name; } public Class getType() { return type; } } So, for example, if I want to define an integer valued property named "width", I would write: PropertyName WIDTH = new PropertyName("width", Integer.class); Not ideal with that pesky class literal, but the best we can do for now. Now, using the magic of type inference, one can define a get method that is statically type checked: public T get(PropertyName p); Here is an example use: Integer n = o.get(WIDTH); where o is defined to support the above get method. No type cast is required in my program (although one happens under the covers). This gets me what I want: a simple interface for getting and setting properties by name, and static type checking when I access properties in a non-dynamic way. This idea is obviously not appropriate for COIN because it is too simple... no language changes required! My questions: This idea can be realized with a small set of classes and interfaces. How would one go about getting them into the JDK? Is someone already doing this? What other support would be useful? One issue is how a class documents the properties that it understands, so that clients of the class will know what properties can usefully be set and how they will be interpreted. We could just rely on ad hoc commentary, but would it be useful to have annotations and/or javadoc constructs that can make this information available in a better way? From vapor1 at teleport.com Sat Mar 28 13:06:18 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sat, 28 Mar 2009 16:06:18 -0400 (EDT) Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax Message-ID: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Simplified StringBuffer/StringBuilder syntax. AUTHOR: Derek Foster OVERVIEW The Java language is designed to use immutable strings. Strings are intended to be constructed via one of two builder classes: StringBuffer (older, and slower due to synchronization) and StringBuilder (newer, and faster). Using these classes can make constructing Strings out of multiple pieces considerably more efficient than repeatedly concatenating strings together. These classes are often used by the Java compiler to concatenate strings behind the scenes, so that an expression like this: String foo = "abcd" + 42 + "efgh"; might be compiled as: String foo = new StringBuilder("abcd").append(42).append("efgh"); (Note: For clarity in this overview, I am ignoring the impact of constant folding by the compiler. Constant folding will be discussed more later.) Unfortunately, the syntax for constructing strings using these builder classes differs significantly from that of constructing strings using string concatenation. This has proved to be a barrier for their use. For instance, programmers can easily write and understand the following: void getString(List baz) { String foo = "abcd" + "efgh"; if (whatever) { foo += "ghij" + 42 + "klmn"; } for (String bar : baz) { foo += bar + "\n"; } return foo; } This syntax is clear and readable. It's also quite inefficient, since it has to create a StringBuilder for each concatenation operation, only to throw it away later. This results in multiple unnecessary memory allocations. For instance, the 'foreach' loop will exhibit memory allocation performance proportional to O(N^2), since it has to allocate a new String containing the prior contents each time the body of the loop is executed. Regardless, the programmers who wrote such code may legitimately wonder why on earth someone would want to use a StringBuilder to do the same thing, when the syntax is so much more verbose and awkward: String getString(List baz) { StringBuilder foo = new StringBuilder("abcd"); foo.append("efgh"); if (whatever) { foo.append("ghij"); foo.append(42); foo.append("klmn"); } for (String bar : baz) { foo.append(bar); foo.append("\n"); } return foo; } Note that now, the important parts of the code (the strings being appended) are swallowed up in the syntax required to invoke the "append" method repeatedly. This impairs readability significantly. However, it is much more efficient. The memory allocation performance in the loop is now likely O(log(N)) instead of O(N^2), since the StringBuilder can simply double its allocated memory size each time the existing threshold is exceeded, and most append operations simply use more of memory that has already been allocated. Even using the chaining syntax allowed by the append method doesn't make things much better: String getString() { StringBuilder foo = new StringBuilder("abcd").append("efgh"); if (whatever) { foo.append("ghij").append(42).append("klmn"); } for (String foo : bar) { foo.append(bar).append("\n"); } return foo; } This code has the same problem as the previous example in that the syntax necessary to call "append" multiple times dwarfs the values actually being appended. This makes it easy to miss bugs when reading the code. Also, long chains of method calls like these are seldom handled well by automatic formatting utilities such as are found in Eclipse and other development tools. As a result, many readability-minded programmers have simply decided that StringBuffer and StringBuilder are not worth the trouble to use in the vast majority of cases, due to their uglier syntax. These programmers have decided that directly concatenating strings to other strings is worth it for the simplicity of syntax even though it results in considerably less efficient code (with lots of extra memory allocation and more work for the garbage collector) than using StringBuffer or StringBuilder. Still other more efficiency-minded programmers have written large string-processing methods with large numbers of calls to "append" (often, each on a separate line) which results in code that is quite efficient, but three or four times as long as it would otherwise need to be if it were written to use string concatenation. Even simple algorithms can become huge when written in this style. Yet other programmers try to mix the approaches, like this: foo.append("ghij"+42+"klmn"); This is in between the other examples given above, both in readability and efficiency, since it is typically expanded by a compiler to something like: foo.append(new StringBuilder("ghij").append(42).append("klmn")); rather than foo.append("ghij").append(42).append("klmn"); which would be more optimal. This proposal attempts to introduce new syntax to remove the currently existing tradeoff between readability and efficency when performing string concatenation. FEATURE SUMMARY: This proposal suggests that StringBuilder and StringBuffer should allow syntax similar to that which is used to append and assign strings to each other. In particular, the Java language should be modified to allow the "+=" operator to be used between a StringBuffer or StringBuilder and a string-valued expression on its right-hand side, and the "=" operator to be used between a StringBuffer or StringBuilder and a string-valued expression on its right-hand side. The following forms of expressions would then become legal: StringBuilder foo = "abc"; foo += "abc"; foo = "abc"; Furthermore, the following special cases would be recognized, and optimized further by the compiler: StringBuilder foo = "abc" + 42 + "def"; foo += "abc" + 42 + "def"; foo = "abc" + 42 + "def"; Using desugarings as described below, these would be expanded by the compiler into code that is as efficient as writing expressions using the existing StringBuilder/StringBuffer APIs. MAJOR ADVANTAGE: The syntax for creating strings using the efficient StringBuffer and StringBuilder classes will become simpler and clearer, with less clutter, which will give people fewer reasons to avoid their use. MAJOR BENEFIT: Elimination of the existing tradeoff between efficiency and readability will mean that programmers will have either more readable programs or more efficient programs, depending on which of these alternatives they were used to choosing. MAJOR DISADVANTAGE: Compiler vendors would have to implement the new feature. This feature has been designed to be relatively easy to implement, but it will still take some effort. Some programmers might be confused by the fact that these formerly illegal expressions were now legal and had defined semantics. ALTERNATIVES: The standard workarounds to this problem are shown above. Each has drawbacks, in either efficiency or readability. As another alternative, it would be possible for a compiler to do more extensive analysis of String expressions, considering the entire body of a function, and invisibly substituting a StringBuilder for the String up until the point it was needed for assignment to another String, passed to a String-valued function parameter, or returned. With such a change, it might be unnecessary for programmers to ever explicitly use StringBuilder or StringBuffer in their code. This type of sophisticated analysis and optimization is in principle possible, but would be quite a challenge for a compiler vendor to implement. Also, efficiency-minded Java programmers would have to be "untrained" from the widespread advice that using StringBuilders directly is the way to achieve efficient code. SIMPLE EXAMPLE: The following method written using current syntax: String getFoo() { StringBuilder foo = new StringBuilder("abc"); foo.append("def"); return foo.toString(); } could be reduced to the following with the new syntax: String getFoo() { StringBuilder foo = "abc"; foo += "def"; return foo.toString(); } ADVANCED EXAMPLE: Assuming the existence of the following class: class Person { public String name; public int age; public int weight; } The following method: class People { private List people = ...; public String toString() { StringBuilder result = new StringBuilder("{"); for (Person person : people) { result.append("{name=").append(person.name); result.append(",age=").append(person.age); result.append(",weight=").append(person.weight).append("}"); } result.append("}"); return result.toString(); } } could be reduced by the new constructs to: class People { private List people = ...; public String toString() { StringBuilder result = "{"; for (Person person : people) { result += "{name=" + name + ",age=" + age + ",weight=" + weight + "}"; } result += "}"; return result.toString(); } } and would be just as efficient (and would ideally translate to the same compiler-generated code). DETAILS For conciseness, the discussion below refers to java.util.StringBuilder only, but the intent of this proposal is that java.util.StringBuffer be treated in the same manner. SPECIFICATION: Note that in the following that the intent is not to create special type-conversion rules between String and StringBuilder, since that would complicate method overloading and other mechanisms of Java and would dramatically widen the impact of this proposal. As such, this proposal only seeks to add new, very limited use overloads of existing = and += operators, without altering how the String and StringBuilder types are otherwise used within the language. INITIALIZATION: A declaration of the form: StringBuilder SB = S; where S is an expression of type String, shall be considered to have meaning as defined below. (Previously, this was a syntax error) 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 where SB is an LValue 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). Note that SB must be provable by the compiler to denote the same variable in both instances. ASSIGNMENT: An expression of the form: SB = S where SB is an LValue 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.) COMPILATION: The expressions as shown above shall be compiled to normal class files, desugared as follows. In the following discussion, the expression "S" shall refer to an arbitrary String expression. In the following discussion, the expression "A + B + C + ..." refers to a special case of String expressions: namely, a String concatenation expression consisting of an arbitrary number of operands being concatenated together (of which at least one is a String, as per the normal Java rules on the "+" String concatenation operator). Optimizations for this common special case are as shown below. [For the purpose of detecting this special case, constant folding optimizations should first be applied by the compiler. Also, redundant parentheses enclosing string concatenation subexpressions should be flattened prior to analysis. For instance, "A + B + (C + D)" may be treated the same as "A + B + C + D" if "C + D" is also a String concatenation expression.] Within the context of the preceding definitions, then: Declarations of the "INITIALIZATION" form specified above: StringBuilder SB = S; StringBuilder SB = A + B + C + ...; shall be desugared to: StringBuilder SB = new StringBuilder(S); StringBuilder SB = new StringBuilder(A).append(B).append(C)....; expressions of the "CONCATENATION" form specified above: SB += S SB += A + B + C + ... shall be desugared to: SB.append(S) SB.append(A).append(B).append(C).... Expressions of the "SELF-CONCATENATION" form specified above: SB = SB + S SB = SB + A + B + C + ... shall be desugared to: SB.append(S) SB.append(A).append(B).append(C).... Expression of the "ASSIGNMENT" form specified above: B = S B = A + B + C + ... shall be desugared to: B = new StringBuilder(S) B = new StringBuilder(A).append(B).append(C).... TESTING: Expressions and statements of the above types can be constructed and compared with the results of their desugared equivalents. LIBRARY SUPPORT: No changes to supporting libraries are needed. REFLECTIVE APIS: No changes to reflective APIs are needed. OTHER CHANGES: No other changes to the JAVA platform are needed. MIGRATION: See simple and advanced examples above. COMPATIBILITY BREAKING CHANGES: Since the proposed syntax now provokes a syntax error, this change will not break any existing programs. EXISTING PROGRAMS: Since class file format does not need to change as a result of this feature, interaction with existing class files is not affected. REFERENCES EXISTING BUGS: I searched the bug database but was unable to find any enhancement proposals similar to this one. URL FOR PROTOTYPE (optional): None From mthornton at optrak.co.uk Sat Mar 28 13:06:26 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Sat, 28 Mar 2009 20:06:26 +0000 Subject: A Non-Proposal related to Properties In-Reply-To: <63005.69.239.104.86.1238269802.squirrel@69.239.104.86> References: <63005.69.239.104.86.1238269802.squirrel@69.239.104.86> Message-ID: <49CE8342.2000607@optrak.co.uk> Alan Snyder wrote: > A Non-Proposal related to Properties > > This is not a proposal, but it seems related to Properties, so knowing > that there are people on this list who are knowledgeable and care about > Properties, I was hoping to get some useful feedback and suggestions. > (I'll apologize in advance if this is old news...) > > As background, I have for a long time been a strong believer in static > type checking and using methods for public access to data. Therefore, many > years ago, when Java and JavaBeans decided to represent each property or > attribute as a get/set method pair, I believed they made a good decision. > > However, after spending a year or two applying this approach to large sets > of configuration parameters and winding up with huge interfaces and way > too many wrapper classes, I have changed my mind. I know what you mean, but I'm not convinced by your solution. I'm tending to more delegation and use of the wrapper pattern with unwrapping to get at the configuration of delegated behaviour. This avoids those awful omnibus interfaces. Mark Thornton From mthornton at optrak.co.uk Sat Mar 28 13:14:57 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Sat, 28 Mar 2009 20:14:57 +0000 Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax In-Reply-To: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <49CE8541.7050009@optrak.co.uk> 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 vapor1 at teleport.com Sat Mar 28 13:23:43 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sat, 28 Mar 2009 16:23:43 -0400 (EDT) Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax Message-ID: <1862546.1238271823802.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> >From: Mark Thornton >Sent: Mar 28, 2009 4:14 PM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: Simplified StringBuffer/StringBuilder syntax > >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? Good point. Sounds like a good suggestion to me. Thanks! Derek From vapor1 at teleport.com Sat Mar 28 14:31:31 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sat, 28 Mar 2009 17:31:31 -0400 (EDT) Subject: PROPOSAL: Auto-assignment Parameters Message-ID: <1502806.1238275891268.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> 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 belingueres at gmail.com Sat Mar 28 15:09:30 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Sat, 28 Mar 2009 19:09:30 -0300 Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax In-Reply-To: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: I compiled this code: String getString(List baz) { int i = 2; String foo = "abcd" + "efgh"; if (i % 2 == 0) { foo += "ghij" + 42 + "klmn"; } for (String bar : baz) { foo += bar + "\n"; } return foo; } that decompile to this: String getString(List baz) { int i = 2; String foo = "abcdefgh"; if(i % 2 == 0) foo = (new StringBuilder(String.valueOf(foo))).append("ghij42klmn").toString(); for(Iterator iterator = baz.iterator(); iterator.hasNext();) { String bar = (String)iterator.next(); foo = (new StringBuilder(String.valueOf(foo))).append(bar).append("\n").toString(); } return foo; } Maybe other solution can be make the compiler smarter. Here, the String foo is a local variable that is used as an lvalue only, meaning it is always written and NEVER read (a perfect candidate for optimizing it creating only one StringBuilder) I'm astonished to find that the compiler didn't optimize the += assignment tough. 2009/3/28 Derek Foster : > Simplified StringBuffer/StringBuilder syntax. > > AUTHOR: Derek Foster > > > OVERVIEW > > The Java language is designed to use immutable strings. Strings are intended to be constructed via one of two builder classes: StringBuffer (older, and slower due to synchronization) and StringBuilder (newer, and faster). Using these classes can make constructing Strings out of multiple pieces considerably more efficient than repeatedly concatenating strings together. These classes are often used by the Java compiler to concatenate strings behind the scenes, so that an expression like this: > > ? ?String foo = "abcd" + 42 + "efgh"; > > might be compiled as: > > ? ?String foo = new StringBuilder("abcd").append(42).append("efgh"); > > (Note: For clarity in this overview, I am ignoring the impact of constant folding by the compiler. Constant folding will be discussed more later.) > > Unfortunately, the syntax for constructing strings using these builder classes differs significantly from that of constructing strings using string concatenation. This has proved to be a barrier for their use. For instance, programmers can easily write and understand the following: > > ? ?void getString(List baz) { > ? ? ? ?String foo = "abcd" + "efgh"; > ? ? ? ?if (whatever) { > ? ? ? ? ? ?foo += "ghij" + 42 + "klmn"; > ? ? ? ?} > ? ? ? ?for (String bar : baz) { > ? ? ? ? ? ?foo += bar + "\n"; > ? ? ? ?} > ? ? ? ?return foo; > ? ? } > > This syntax is clear and readable. It's also quite inefficient, since it has to create a StringBuilder for each concatenation operation, only to throw it away later. This results in multiple unnecessary memory allocations. For instance, the 'foreach' loop will exhibit memory allocation performance proportional to O(N^2), since it has to allocate a new String containing the prior contents each time the body of the loop is executed. > > Regardless, the programmers who wrote such code may legitimately wonder why on earth someone would want to use a StringBuilder to do the same thing, when the syntax is so much more verbose and awkward: > > ? ?String getString(List baz) { > ? ? ? ?StringBuilder foo = new StringBuilder("abcd"); > ? ? ? ?foo.append("efgh"); > ? ? ? ?if (whatever) { > ? ? ? ? ? ?foo.append("ghij"); > ? ? ? ? ? ?foo.append(42); > ? ? ? ? ? ?foo.append("klmn"); > ? ? ? ?} > ? ? ? ?for (String bar : baz) { > ? ? ? ? ? ?foo.append(bar); > ? ? ? ? ? ?foo.append("\n"); > ? ? ? ?} > ? ? ? ?return foo; > ? ?} > > Note that now, the important parts of the code (the strings being appended) are swallowed up in the syntax required to invoke the "append" method repeatedly. This impairs readability significantly. However, it is much more efficient. The memory allocation performance in the loop is now likely O(log(N)) instead of O(N^2), since the StringBuilder can simply double its allocated memory size each time the existing threshold is exceeded, and most append operations simply use more of memory that has already been allocated. > > Even using the chaining syntax allowed by the append method doesn't make things much better: > > ? ?String getString() { > ? ? ? ?StringBuilder foo = new StringBuilder("abcd").append("efgh"); > ? ? ? ?if (whatever) { > ? ? ? ? ? ?foo.append("ghij").append(42).append("klmn"); > ? ? ? ?} > ? ? ? ?for (String foo : bar) { > ? ? ? ? ? ?foo.append(bar).append("\n"); > ? ? ? ?} > ? ? ? ?return foo; > ? ? } > > This code has the same problem as the previous example in that the syntax necessary to call "append" multiple times dwarfs the values actually being appended. This makes it easy to miss bugs when reading the code. Also, long chains of method calls like these are seldom handled well by automatic formatting utilities such as are found in Eclipse and other development tools. > > As a result, many readability-minded programmers have simply decided that StringBuffer and StringBuilder are not worth the trouble to use in the vast majority of cases, due to their uglier syntax. These programmers have decided that directly concatenating strings to other strings is worth it for the simplicity of syntax even though it results in considerably less efficient code (with lots of extra memory allocation and more work for the garbage collector) than using StringBuffer or StringBuilder. > > Still other more efficiency-minded programmers have written large string-processing methods with large numbers of calls to "append" (often, each on a separate line) which results in code that is quite efficient, but three or four times as long as it would otherwise need to be if it were written to use string concatenation. Even simple algorithms can become huge when written in this style. > > Yet other programmers try to mix the approaches, like this: > > ? ?foo.append("ghij"+42+"klmn"); > > This is in between the other examples given above, both in readability and efficiency, since it is typically expanded by a compiler to something like: > > ? ?foo.append(new StringBuilder("ghij").append(42).append("klmn")); > > rather than > > ? ?foo.append("ghij").append(42).append("klmn"); > > which would be more optimal. > > > This proposal attempts to introduce new syntax to remove the currently existing tradeoff between readability and efficency when performing string concatenation. > > > FEATURE SUMMARY: > > This proposal suggests that StringBuilder and StringBuffer should allow syntax similar to that which is used to append and assign strings to each other. In particular, the Java language should be modified to allow the "+=" operator to be used between a StringBuffer or StringBuilder and a string-valued expression on its right-hand side, and the "=" operator to be used between a StringBuffer or StringBuilder and a string-valued expression on its right-hand side. The following forms of expressions would then become legal: > > ? StringBuilder foo = "abc"; > ? foo += "abc"; > ? foo = "abc"; > > Furthermore, the following special cases would be recognized, and optimized further by the compiler: > > ? StringBuilder foo = "abc" + 42 + "def"; > ? foo += "abc" + 42 + "def"; > ? foo = "abc" + 42 + "def"; > > > Using desugarings as described below, these would be expanded by the compiler into code that is as efficient as writing expressions using the existing StringBuilder/StringBuffer APIs. > > > MAJOR ADVANTAGE: > > The syntax for creating strings using the efficient StringBuffer and StringBuilder classes will become simpler and clearer, with less clutter, which will give people fewer reasons to avoid their use. > > > MAJOR BENEFIT: > > Elimination of the existing tradeoff between efficiency and readability will mean that programmers will have either more readable programs or more efficient programs, depending on which of these alternatives they were used to choosing. > > > MAJOR DISADVANTAGE: > > Compiler vendors would have to implement the new feature. This feature has been designed to be relatively easy to implement, but it will still take some effort. > > Some programmers might be confused by the fact that these formerly illegal expressions were now legal and had defined semantics. > > > ALTERNATIVES: > > The standard workarounds to this problem are shown above. Each has drawbacks, in either efficiency or readability. > > As another alternative, it would be possible for a compiler to do more extensive analysis of String expressions, considering the entire body of a function, and invisibly substituting a StringBuilder for the String up until the point it was needed for assignment to another String, passed to a String-valued function parameter, or returned. With such a change, it might be unnecessary for programmers to ever explicitly use StringBuilder or StringBuffer in their code. This type of sophisticated analysis and optimization is in principle possible, but would be quite a challenge for a compiler vendor to implement. Also, efficiency-minded Java programmers would have to be "untrained" from the widespread advice that using StringBuilders directly is the way to achieve efficient code. > > > SIMPLE EXAMPLE: > > The following method written using current syntax: > > ? ?String getFoo() { > ? ? ? StringBuilder foo = new StringBuilder("abc"); > ? ? ? foo.append("def"); > ? ? ? return foo.toString(); > ? ?} > > could be reduced to the following with the new syntax: > > ? ?String getFoo() { > ? ? ? StringBuilder foo = "abc"; > ? ? ? foo += "def"; > ? ? ? return foo.toString(); > ? ?} > > > ADVANCED EXAMPLE: > > Assuming the existence of the following class: > > ? ?class Person { > ? ? ? ?public String name; > ? ? ? ?public int age; > ? ? ? ?public int weight; > ? ?} > > The following method: > > ? ?class People { > ? ? ? ?private List people = ...; > ? ? ? ?public String toString() { > ? ? ? ? ? ?StringBuilder result = new StringBuilder("{"); > ? ? ? ? ? ?for (Person person : people) { > ? ? ? ? ? ? ? ?result.append("{name=").append(person.name); > ? ? ? ? ? ? ? ?result.append(",age=").append(person.age); > ? ? ? ? ? ? ? ?result.append(",weight=").append(person.weight).append("}"); > ? ? ? ? ? ?} > ? ? ? ? ? ?result.append("}"); > ? ? ? ? ? ?return result.toString(); > ? ? ? ?} > ? ?} > > could be reduced by the new constructs to: > > ? ?class People { > ? ? ? ?private List people = ...; > ? ? ? ?public String toString() { > ? ? ? ? ? ?StringBuilder result = "{"; > ? ? ? ? ? ?for (Person person : people) { > ? ? ? ? ? ? ? ?result += "{name=" + name + ",age=" + age + ",weight=" + weight + "}"; > ? ? ? ? ? ?} > ? ? ? ? ? ?result += "}"; > ? ? ? ? ? ?return result.toString(); > ? ? ? ?} > ? ?} > > and would be just as efficient (and would ideally translate to the same compiler-generated code). > > > DETAILS > > For conciseness, the discussion below refers to java.util.StringBuilder only, but the intent of this proposal is that java.util.StringBuffer be treated in the same manner. > > > SPECIFICATION: > > Note that in the following that the intent is not to create special type-conversion rules between String and StringBuilder, since that would complicate method overloading and other mechanisms of Java and would dramatically widen the impact of this proposal. As such, this proposal only seeks to add new, very limited use overloads of existing = and += operators, without altering how the String and StringBuilder types are otherwise used within the language. > > > INITIALIZATION: A declaration of the form: > > ? ?StringBuilder SB = S; > > where S is an expression of type String, shall be considered to have meaning as defined below. (Previously, this was a syntax error) > > > 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 > > where SB is an LValue 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). Note that SB must be provable by the compiler to denote the same variable in both instances. > > > ASSIGNMENT: An expression of the form: > > ? ?SB = S > > where SB is an LValue 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.) > > > > COMPILATION: > > The expressions as shown above shall be compiled to normal class files, desugared as follows. > > In the following discussion, the expression "S" shall refer to an arbitrary String expression. > > In the following discussion, the expression "A + B + C + ..." refers to a special case of String expressions: namely, a String concatenation expression consisting of an arbitrary number of operands being concatenated together (of which at least one is a String, as per the normal Java rules on the "+" String concatenation operator). Optimizations for this common special case are as shown below. > > [For the purpose of detecting this special case, constant folding optimizations should first be applied by the compiler. Also, redundant parentheses enclosing string concatenation subexpressions should be flattened prior to analysis. For instance, "A + B + (C + D)" may be treated the same as "A + B + C + D" if "C + D" is also a String concatenation expression.] > > Within the context of the preceding definitions, then: > > Declarations of the "INITIALIZATION" form specified above: > > ? ?StringBuilder SB = S; > ? ?StringBuilder SB = A + B + C + ...; > > shall be desugared to: > > ? ?StringBuilder SB = new StringBuilder(S); > ? ?StringBuilder SB = new StringBuilder(A).append(B).append(C)....; > > > expressions of the "CONCATENATION" form specified above: > > ? ?SB += S > ? ?SB += A + B + C + ... > > shall be desugared to: > > ? ?SB.append(S) > ? ?SB.append(A).append(B).append(C).... > > > Expressions of the "SELF-CONCATENATION" form specified above: > > ? ?SB = SB + S > ? ?SB = SB + A + B + C + ... > > shall be desugared to: > > ? ?SB.append(S) > ? ?SB.append(A).append(B).append(C).... > > > Expression of the "ASSIGNMENT" form specified above: > > ? ?B = S > ? ?B = A + B + C + ... > > shall be desugared to: > > ? ?B = new StringBuilder(S) > ? ?B = new StringBuilder(A).append(B).append(C).... > > > > > TESTING: > > Expressions and statements of the above types can be constructed and compared with the results of their desugared equivalents. > > > LIBRARY SUPPORT: > > No changes to supporting libraries are needed. > > > REFLECTIVE APIS: > > No changes to reflective APIs are needed. > > > OTHER CHANGES: > > No other changes to the JAVA platform are needed. > > > MIGRATION: > > See simple and advanced examples above. > > > > COMPATIBILITY > > > BREAKING CHANGES: > > Since the proposed syntax now provokes a syntax error, this change will not break any existing programs. > > > EXISTING PROGRAMS: > > Since class file format does not need to change as a result of this feature, interaction with existing class files is not affected. > > > REFERENCES > > > EXISTING BUGS: > > I searched the bug database but was unable to find any enhancement proposals similar to this one. > > > URL FOR PROTOTYPE (optional): > > None > > > From vapor1 at teleport.com Sat Mar 28 15:17:30 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sat, 28 Mar 2009 18:17:30 -0400 (EDT) Subject: Improved Support for Optional Object Behaviors at Runtime Message-ID: <22550089.1238278650365.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> First of all, I would like to say that I understand the problem you are trying to solve, and I like the general approach of your solution. I have seen the same thing done less well in the Eclipse framework. where it is used all over the place. (Their solution doesn't use generics, and does use a custom interface). I have appended the definition of the relevant interface below, in case you are curious. I like your approach of adding a method to Object. This lends itself to a wide variety of interesting uses even involving existing standard library classes. I have had a number of cases where I have had to "roll my own" interface of this sort where using a standardized one would have been better and more versatile. I am less sure that I care for the practice of returning null rather than throwing a ClassCastException. It is very common for people to neglect to check for null, and for code to therefore suffer NullPointerExceptions at a much later point in the code when someone tries to use an interface that they had assumed would be present. This can be quite difficult to track down. A ClassCastException at the point of call localizes the problem very tightly, and makes debugging easier. Thus, I would rather see something like: boolean hasExtension(); T getExtension(Class extension) throws ClassCastException; so that those who forget to ensure the existence of the extension they are trying to use will have their thread throwing ClassCastException and thus aborting future processing, rather than continuing on as if nothing had happened and eventually getting a NullPointerException when code later (possibly much later) tries to make a call thorugh the interface. Those who want to be sure exceptions won't get thrown can do something like: if (obj.hasExtension(Foo.class)) { Foo obj = obj.getExtension(Foo.class)); // Guaranteed not to throw ClassCastException now } Note that a hasExtension method can also be useful in other contexts: void func(Thing obj) { assert obj.hasExtension(Foo.class); ... do stuff ... } One significant concern: I am not sure that 'getExtension' is an uncommon enough name that it could be added to Object without blowing anybody's existing class library out of the water, although I appreciate that the method signature is unusual enough that this is not as likely as it could be. (There might be some unexpected overloading of it, however.) I would still prefer something much less common that is much less likely to be used already. Derek Here's the interface from Eclipse that I mentioned. A huge number of objects in the Eclipse framework and its plugins extend this, either directly or indirectly. package org.eclipse.core.runtime; /** * An interface for an adaptable object. *

* Adaptable objects can be dynamically extended to provide different * interfaces (or "adapters"). Adapters are created by adapter * factories, which are in turn managed by type by adapter managers. *

* For example, *
 *     IAdaptable a = [some adaptable];
 *     IFoo x = (IFoo)a.getAdapter(IFoo.class);
 *     if (x != null)
 *         [do IFoo things with x]
 * 
*

* This interface can be used without OSGi running. *

* Clients may implement this interface, or obtain a default implementation * of this interface by subclassing PlatformObject. *

* @see IAdapterFactory * @see IAdapterManager * @see PlatformObject */ public interface IAdaptable { /** * Returns an object which is an instance of the given class * associated with this object. Returns null if * no such object can be found. * * @param adapter the adapter class to look up * @return a object castable to the given class, * or null if this object does not * have an adapter for the given class */ public Object getAdapter(Class adapter); } From vapor1 at teleport.com Sat Mar 28 17:43:47 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sat, 28 Mar 2009 20:43:47 -0400 (EDT) Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions Message-ID: <10080769.1238287427700.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Although I appreciate what you are trying to do with this proposal, and I have certainly been inconvenienced by the problem that you are trying to solve, I am also very concerned with unintended consequences of your proposal. Your proposal describes its intended effect, and it certainly seems able to solve that use case, but does not seem to really delve into other impacts of this change in behavior which might be less positive. One of the reasons I typically use checked exceptions in programs is to ensure that all callers of an API must consider and handle the various error conditions that can occur. Thus if I have a method like: void getFoo() throws FooDoesNotExistException; I can be assured that anyone who calls getFoo() will be forced to consider what to do if the Foo object does not exist. They may choose to ignore the error condition, but at least they will have been forced to consider it (by adding a 'catch' clause somewhere in the program for it or one of its supertypes). This is one of the most important reasons to use checked exceptions in the first place: They allow the compiler to do what amounts to essentially a compile-time proof that all checked exceptions will eventually be handled by someone. Your proposal seems to have the potential to break this guarantee, so that someone could have a method like: void getFoo2(); // throws UncheckedSubtypeOfFooDoesNotExistException; then if I call it in my code: Foo getStuff() { return getFoo2(); } I am never forced to add a catch clause for FooDoesNotExistException anywhere. Furthermore, I in many ways CAN'T add a catch clause for the base type in outside code, as your proposal suggests is its goal: Foo getStuff() { try { return getFoo2(); } catch (FooDoesNotExistException e) { // This is a compiler error. Exception is never thrown in try block. // handle exception here } } The only time it would be legal for me to add a catch clause for the base type would be if there was another method also being called in the same try..catch block which DID throw the base exception. It appears to me that if this proposal is implemented, I will now have the potential for both unchecked and checked exceptions to go entirely uncaught and unhandled in my program, thus invalidating the guarantee that I had (before your proposal) that all checked exceptions would be handled somewhere. FYI, the workaround that I typically use in your List/File example is to do something like this, which I think of as the "smuggler exception" pattern: class MyUncheckedIOException extends RuntimeException { MyUncheckedIOException(IOException cause) { super(cause); } IOException getCause() { return (IOException)cause; } } // This can't throw IOException, so we have to use the workaround. File get(int index) { try { return _theFile.list()[index]; } catch (IOException e) { throw new MyUncheckedIOException(e); } } // This knows it is using a List which is backed by Files, so // it can translate back to a checked exception. File doGet(List foo) throws IOException { try { foo.get(); } catch (MyUncheckedIOException e) { throw e.getCause(); } } Although I would like to have a clean way to throw checked exceptions through interfaces that don't support them (Visitor interfaces are the ones that I personally find most inconvenient in this regard), I am very skeptical that fixing this problem is worth losing the guarantee that all checked exceptions and their subtypes will be handled somewhere. Derek -----Original Message----- >From: Alan Snyder >Sent: Mar 26, 2009 2:57 PM >To: coin-dev at openjdk.java.net >Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions > >[This is a revised proposal based on the previous comments. It includes a >use case.] > >Unchecked Exceptions as Subclasses of Checked Exceptions > > >AUTHOR: Alan Snyder > >OVERVIEW > >FEATURE SUMMARY: > >This proposal would allow the definition of an unchecked exception class >that extends a checked exception class. > >MAJOR ADVANTAGE: > >Unchecked exception classes are useful when an exception must be thrown >through an existing interface that does not declare any checked exceptions >or an appropriate checked exception. If one can define both an unchecked >exception class and a corresponding checked exception class such that the >unchecked exception class extends the checked exception class, then the >unchecked exception will be caught by a try statement that catches the >checked exception. > >MAJOR BENEFIT: > >Programs do not have to explictly catch both the unchecked and checked >exceptions. Most developers need only be aware of the checked exception. >The potential mistake of not catching the unchecked exception is avoided. > >MAJOR DISADVANTAGE: > >A new marker interface (or equivalent) must be defined and the definition >of unchecked exceptions changed. > >ALTERNATIVES: > >The alternative is to always explicitly catch both the unchecked and >checked exceptions, which introduces a likely source of programming >errors. > >EXAMPLE: > >This proposal uses a marker interface as an alternative way (besides >subclassing RuntimeException and Error) of indicating that an exception >class defines an unchecked exception. > >The following would define a checked exception and an unchecked exception >that extends the checked exception: > > public class TheCheckedException > extends Exception {}; > > public class TheUncheckedException > extends TheCheckedException > implements UncheckedException {}; > >The following is a sketch of a possible use case. > >Consider a program A that reads and writes data using file I/O, with the >presumption that there are good reasons not to read all of the data into >memory. The program catches IOException in appropriate places so that it >can recover gracefully should an I/O error occur. > >Now suppose that program A wants to use existing library B to manipulate >this data, but library B does not know about files. Instead, assume that B >uses some more generic interface to access data, such as List. Note that >the List get() method does not define a checked exception for data access >failure. Thus, in the bridge code that allows the file data to be accessed >via the List interface, program A would have to wrap any IOExceptions in a >RuntimeException. Suppose it defines a new class, UncheckedIOException, >for this purpose. > >In current Java, program A would need to augment its exception handlers to >handle both IOException and UncheckedIOException. > >Using this proposal, UncheckedIOException could be an unchecked exception >and also subclass from IOException, so that the exception handlers for >IOException would catch UncheckedIOException as well. > >DETAILS > >SPECIFICATION: > >The JLS would be changed to add one more way to define an unchecked >exception. > >JLS 11.2 >The unchecked exceptions classes are the class RuntimeException and its >subclasses, and the class Error and its subclasses. All other exception >classes are checked exception classes. > >would become > >The unchecked exceptions classes are the class RuntimeException and its >subclasses, the class Error and its subclasses, and those subclasses of >Exception that implement the UncheckedException interface. All other >exception classes are checked exception classes. > >JLS 11.5 >The subclasses of Exception other than RuntimeException are all checked >exception classes. > >would become > >The subclasses of Exception other than RuntimeException are checked >exception classes, unless they implement the UncheckedException interface. > >The marker interface UncheckedException would have to be defined in some >java package, with java.lang being the obvious choice. > >COMPILATION: > >The compiler would have to be extended to recognize the new category of >unchecked exceptions. > >I'm not aware of other changes. > >COMPATIBILITY > >The major compatibility issue arises from the introduction of a new name >in the class name space. That could potentially cause a program to fail to >compile if it imported a class with the name UncheckedException using a >wild card import statement. > >There could also be programs that examine the class hierarchy at runtime >or using a compiler API that would not recognize some exception classes as >being unchecked. I imagine these would mostly be language tools, which one >would expect to need revision for a new version of Java. > > > From ericraymond at allocade.com Fri Mar 27 20:59:17 2009 From: ericraymond at allocade.com (Eric Raymond) Date: Fri, 27 Mar 2009 20:59:17 -0700 Subject: PROPOSAL: Named method parameters (works best in conjunction with default values) Message-ID: <49CDA095.5040408@allocade.com> Named parameters work best if they are combined with default values for parameters. With defaults, there is no requirement to supply every parameter defined (which can be a burden as the number of arguments increase). For example with the following example, both param1 and param2 need to be supplied: public void foo(String param1, int param2) .... foo(param1: "123", param2: 4); // OK foo(param1: "123"); // Not OK foo(param2: 4); // Not OK With default values, the caller can simply pick and choose the parameters which are of interest (and ignore the other parameters). public void foo(String param1 = null , int param2 = 0) .... foo(param1: "123", param2: 4); // OK foo(param1: "123"); // OK, param2 is 0 foo(param2: 4); // OK, param1 is null From vapor1 at teleport.com Sat Mar 28 19:42:05 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sat, 28 Mar 2009 22:42:05 -0400 (EDT) Subject: Naked dot - accessing object fields through unqualified "." [C1] Message-ID: <11840193.1238294525158.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> 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 John.Rose at Sun.COM Sat Mar 28 23:53:51 2009 From: John.Rose at Sun.COM (John Rose) Date: Sat, 28 Mar 2009 23:53:51 -0700 Subject: PROPOSAL: language support for JSR 292 Message-ID: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> Hello, colleagues. Here is a proposal which is linked to JSR 292 (invokedynamic). http://wikis.sun.com/display/mlvm/ProjectCoinProposal http://blogs.sun.com/jrose/entry/jsr_292_support_in_javac Here's the teaser (from my blog): In order to work with dynamic types, method handles, and invokedynamic I have made some provisional changes to javac as part of the Da Vinci Machine Project. The mlvm wiki has a full description for Project COIN. It is most desirable, of course, to program invokedynamic call sites as Java expressions, not just ASM code, and that's what those langtools patches are for. The essential features are four: ? The type java.dyn.Dynamic will accept any method call and turn it into an invokedynamic instruction, and the full range of such instructions can be spelled from Java code. ? The type java.dyn.MethodHandle will accept any argument and return types for a call to the method named invoke, which means that Java code can spell the full range of method handle invocations. ? The full range of bytecode names acceptable to the JVM can be spelled from Java code, using an exotic identifier quoting syntax. ? The type java.dyn.Dynamic serves as a bare reference type: Anything implicitly converts to it, and it can be cast to anything, but it is not a subtype of java.lang.Object. Its methods, of course, are those from point #1, so it is handy for forming invokedynamic calls. The rationale is pretty simple: If we put some minimal support into Java for defining and using names in other languages, then Java can be used as a system programming language for implementing them. Otherwise, the system programming language will be assembled bytecode. (I like to visit ASM, but don't want to live there.) Do check out the wiki page; it has the full Project COIN proposal format. Best wishes, -- John Rose (Da Vinci Machine Project) From Joe.Darcy at Sun.COM Sun Mar 29 00:14:27 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Mar 2009 00:14:27 -0700 Subject: PROPOSAL: Compiletime information access In-Reply-To: <770cfac9aff8576d221e054a87f5a6c0.squirrel@wmail.gradsoft.ua> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <49CB347D.2030300@paradise.net.nz> <770cfac9aff8576d221e054a87f5a6c0.squirrel@wmail.gradsoft.ua> Message-ID: <49CF1FD3.40105@sun.com> rssh at gradsoft.com.ua wrote: [snip] >>> - improving proposal about access to compile-time information about >>> local context can have some sence (?) >>> >>> >> Given the existing capabilities of annotation processors, I don't think >> the proposed API is necessary or desirable. >> > > > I does not understand, why Joseph Darcy think, that existing capabilities > of annotation processing may allows programmer use compile-time > information about local context (it's not true for now). > > Joe Darcy thinks standardized annotation processing is an existing feature in the platform to address problems in the space of analyzing programs and generating code. The first-line solution to problems in this space is to approach the problem in a way that can be addressed by the existing annotation processing facilities. Even if a particular worthwhile issue in this class of problem cannot be solving by annotation processing (or a small extension to annotation processing), we will probably choose to not provide a solution to the problem in the platform because the marginal utility of the solution over annotation processing is likely to be too small. -Joe From Joe.Darcy at Sun.COM Sun Mar 29 00:22:24 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Mar 2009 00:22:24 -0700 Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax In-Reply-To: References: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <49CF21B0.7030904@sun.com> Gabriel Belingueres wrote: > I compiled this code: > > String getString(List baz) { > int i = 2; > String foo = "abcd" + "efgh"; > if (i % 2 == 0) { > foo += "ghij" + 42 + "klmn"; > } > for (String bar : baz) { > foo += bar + "\n"; > } > return foo; > } > > that decompile to this: > > String getString(List baz) > { > int i = 2; > String foo = "abcdefgh"; > if(i % 2 == 0) > foo = (new > StringBuilder(String.valueOf(foo))).append("ghij42klmn").toString(); > for(Iterator iterator = baz.iterator(); iterator.hasNext();) > { > String bar = (String)iterator.next(); > foo = (new > StringBuilder(String.valueOf(foo))).append(bar).append("\n").toString(); > } > > return foo; > } > > Maybe other solution can be make the compiler smarter. > Here, the String foo is a local variable that is used as an lvalue > only, meaning it is always written and NEVER read (a perfect candidate > for optimizing it creating only one StringBuilder) > > I'm astonished to find that the compiler didn't optimize the += > assignment tough. > > Generally javac lets HotSpot do the heavy lifting in terms of optimizations. If you want to try to hack on the compiler and make it smarter, all the code you need is at http://hg.openjdk.java.net/jdk7/jdk7/langtools -Joe From Joe.Darcy at Sun.COM Sun Mar 29 00:31:20 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Mar 2009 00:31:20 -0700 Subject: PROPOSAL: 'forget' keyword (beta) In-Reply-To: <28bca0ff0903270702r52d610a5j792e1912781722d6@mail.gmail.com> References: <28bca0ff0903270702r52d610a5j792e1912781722d6@mail.gmail.com> Message-ID: <49CF23C8.4070409@sun.com> Marek Kozie? wrote: > I do not know if there is point to describe this proposal in > details, because it require to introduce new keyword which may be > impossible for project Coin scope.? > > AUTHOR: Lasu aka Marek Kozie? > > OVERVIEW > > FEATURE SUMMARY: > 'forget' keyword allows to erase variable from current context, or it > means that field should not be used. > > [snip] > DETAILS > > SPECIFICATION: > ... > > COMPILATION: > ... > > This proposal is incomplete and does not merit further consideration or comment. -Joe From rssh at gradsoft.com.ua Sun Mar 29 00:34:46 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 29 Mar 2009 10:34:46 +0300 (EEST) Subject: PROPOSAL: Compiletime information access In-Reply-To: <49CF1FD3.40105@sun.com> References: <217fcd1a108e5e340dd97c080b16ef7e.squirrel@wmail.gradsoft.ua> <49CB347D.2030300@paradise.net.nz> <770cfac9aff8576d221e054a87f5a6c0.squirrel@wmail.gradsoft.ua> <49CF1FD3.40105@sun.com> Message-ID: <36632a556bfba4f083669122b494112e.squirrel@wmail.gradsoft.ua> > rssh at gradsoft.com.ua wrote: > [snip] >>>> - improving proposal about access to compile-time information about >>>> local context can have some sence (?) >>>> >>>> >>> Given the existing capabilities of annotation processors, I don't think >>> the proposed API is necessary or desirable. >>> >> >> >> I does not understand, why Joseph Darcy think, that existing >> capabilities >> of annotation processing may allows programmer use compile-time >> information about local context (it's not true for now). >> >> > > Joe Darcy thinks standardized annotation processing is an existing > feature in the platform to address problems in the space of analyzing > programs and generating code. The first-line solution to problems in > this space is to approach the problem in a way that can be addressed by > the existing annotation processing facilities. Even if a particular > worthwhile issue in this class of problem cannot be solving by > annotation processing (or a small extension to annotation processing), > we will probably choose to not provide a solution to the problem in the > platform because the marginal utility of the solution over annotation > processing is likely to be too small. > I. e. right place for such changes is annotations API. (And in general library-level changes is preferable agains language changes with same effects). Thanks for refinement. > -Joe > From neal at gafter.com Sun Mar 29 00:55:42 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Mar 2009 00:55:42 -0700 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> Message-ID: <15e8b9d20903290055p399a724al786f34b8188a62d2@mail.gmail.com> John- Could you please send the proposal to this list? I don't really understand the intended specification with respect to Dynamic. It is one the one hand described as an object type (e.g. section 1.9) but on the other hand it doesn't inherit from Object (section 1.1). You can't have it both ways. I can't tell, for example, whether Dynamic is a valid type in a generic type parameter. If the answer is yes, then it must have Object as a supertype. You might find it useful to review what C# has done in this area with their type "dynamic". In short, it occupies the same location in C#'s type lattice as Object, but it has some additional conversions defined that are not subtype relationships. I don't believe this is a "small change". However, if it is going to happen anyway in JDK 7 to support jsr292, I can see the sense in having it dealt with in the same expert group as four or so other small, local changes. Regards, Neal On Sat, Mar 28, 2009 at 11:53 PM, John Rose wrote: > Hello, colleagues. ?Here is a proposal which is linked to JSR 292 > (invokedynamic). > > http://wikis.sun.com/display/mlvm/ProjectCoinProposal > http://blogs.sun.com/jrose/entry/jsr_292_support_in_javac > > Here's the teaser (from my blog): > > In order to work with dynamic types, method handles, and invokedynamic > I have made some provisional changes to javac as part of the Da Vinci > Machine Project. The mlvm wiki has a full description for Project > COIN. It is most desirable, of course, to program invokedynamic call > sites as Java expressions, not just ASM code, and that's what those > langtools patches are for. > The essential features are four: > > ? ? ? ?? The type java.dyn.Dynamic will accept any method call and turn it > into an invokedynamic instruction, and the full range of such > instructions can be spelled from Java code. > ? ? ? ?? The type java.dyn.MethodHandle will accept any argument and return > types for a call to the method named invoke, which means that Java > code can spell the full range of method handle invocations. > ? ? ? ?? The full range of bytecode names acceptable to the JVM can be > spelled from Java code, using an exotic identifier quoting syntax. > ? ? ? ?? The type java.dyn.Dynamic serves as a bare reference type: Anything > implicitly converts to it, and it can be cast to anything, but it is > not a subtype of java.lang.Object. Its methods, of course, are those > from point #1, so it is handy for forming invokedynamic calls. > The rationale is pretty simple: If we put some minimal support into > Java for defining and using names in other languages, then Java can be > used as a system programming language for implementing them. > Otherwise, the system programming language will be assembled bytecode. > (I like to visit ASM, but don't want to live there.) > > Do check out the wiki page; it has the full Project COIN proposal > format. > > Best wishes, > > -- John Rose (Da Vinci Machine Project) > > From rssh at gradsoft.com.ua Sun Mar 29 01:03:21 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 29 Mar 2009 11:03:21 +0300 (EEST) Subject: PROPOSAL: Language Escape Operator In-Reply-To: References: <1238110511.49cc112f28285@www.paradise.net.nz> <5D30A93B-3434-438B-A178-5B095CADA06F@zwitserloot.com> <1238123613.49cc445d0d940@www.paradise.net.nz> <8D192CF8-71E9-4B29-B000-DAA980B53502@zwitserloot.com> <8cbe5da1c1dc7b41ea333df4bb11cf0a.squirrel@wmail.gradsoft.ua> <49CF0B75.6080804@paradise.net.nz> Message-ID: <0fa161efce84a7ebdbf8e2564a6cfe08.squirrel@wmail.gradsoft.ua> > Coin proposals have >> to be written without reference to other coin proposals. It would seem >> logical that if both multiline strings and language escape operator were >> chosen to be developed further, then the language escape operator spec >> would be modified to include multiline strings as one of the places were >> it wasn't a compiler error. > Yes. I. e. what I mean that changes It is a compile time error for a ` character to appear in other than a comment, a String literal or a Character literal. does not prevent such tools from breaking in future, because comments, string literals in principle can be changed. But again, it's better than nothing, i.e. better to know that maximum changers will be tune escaping for commnents and literals, than think how to change near all after introducing new '`' operator, so can count me to supporters ;) > ... >> justifies a single character. With a double character escape, there >> may be certain uses where the additional character (2 instead of 1) >> tips the use from being viable to ugly. For a thought experiment here >> think operator overloading. > > Hmm, Yes. > Interesting, but closest generator for you idea, which I seen (don;t remember where, but MSVC derived), used extensions in comment. I. e. something like //#(ext) y = x+y //#{{ y=plus(x,y) //#}} From markmahieu at googlemail.com Sun Mar 29 03:18:09 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Sun, 29 Mar 2009 11:18:09 +0100 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <1502806.1238275891268.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <1502806.1238275891268.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <7F3DCD49-2F6F-45B5-ADCE-60EDBABCA741@googlemail.com> On 28 Mar 2009, at 21: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. Hi Derek, That's very encouraging to hear. Thanks! > I use a lot of immutable class objects, and this Your sentence got cut off, but this proposal came about while writing an immutable class, and accidentally initializing a field from the wrong parameter (the joys of copy/paste). > 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: The majority of my colleagues preferred 'this.' as it's meaningful and quite short but still stands out enough to say "I'm not just a normal parameter!". There are other options though, if the wider consensus turned out to be different. I wouldn't favour a dot, personally - it might be a little too easy to miss. Syntax highlighting wouldn't help either, as a red, italic dot still looks much the same as any other dot ;) > 2) I think that allowing the syntax for all method parameters, not > just constructor parameters, would be nice. A number of people have expressed that wish. It's certainly a possibility, and doesn't change very much in terms of the proposal's details - the grammar would change the most (it could be simpler in that case). I imagine it might encourage people to employ the Builder pattern more often (Effective Java 2nd Ed., Item 2), which would be a good thing I think. > 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; } Defining appropriate semantics seems less straightforward for return values than for parameters, if there are also statements in the method body. For example, should early return statements be allowed in the method body? If so, can they only return the declared value? > 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. > I wouldn't expect people to change publicly exposed parameter names to reflect the implementation details of their classes - it should be the other way around, or not at all. I hijacked javac to gather some statistics across of a number of large, currently active code-bases, and prefixes seem to be very much the exception rather than the norm. More common are cases where there's no prefix, but the field and parameter names are different for other reasons. Some of these look like good choices, but quite a number seem to have very good field names, and poor parameter names which would be improved if they did adopt the same name as the corresponding field! Either way, they're all vastly outnumbered (in the source I've analysed so far) by parameters which do have the same name as the field to which they're assigned, as noted in Java Puzzlers (page 181). It would be possible to extend the proposal to allow the field name to be specified along with an (optional) alternative parameter name. I'm just not sure the added complexity would be justified, although such a change could also conceivably happen in a later release if evidence were to stack up in its favour. In one of your other emails to this list, you mentioned that you use a prefix on field names to prevent typographical mistakes. Given that this proposal aims to avoid many of the situations in which those mistakes can be made, would you continue to do so if it were implemented? > 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. That's an interesting idea, though perhaps best suited to a language feature directly supporting properties, if one is implemented. Whether it could fit in here would depend on a number of factors, but it's worth bearing in mind. > 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. When I tried that, I found that it worked reasonably well for simple (ie. very small) classes, but didn't scale well; my ability to comprehend the code decreased as the class increased in size. Also, including the type in the parameter declaration makes it clear that a local variable is being introduced into the scope of the constructor/ method body, just like a normal formal parameter. Finally, omitting the type places restrictions upon the order in which a tool such as javac can choose to process Java source, which is something I'd rather avoid if possible. Thanks for all your comments! Regards, Mark From schulz at e-spirit.de Sun Mar 29 04:17:32 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Sun, 29 Mar 2009 13:17:32 +0200 Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime In-Reply-To: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> References: <61117.69.239.104.86.1238094535.squirrel@69.239.104.86> Message-ID: <49CF58CC.6000400@e-spirit.de> I like this proposal a lot, as it would solve quite some problems with Inheritance and Delegation. Mozilla uses a similar approach (no Java though) where you query a specific interface for an object. In their case, it returns null, but a ClassCastException, as suggested by Derek, would be fine as well. Maybe, I am burned a bit with respect to taking classes as parameters for such methods, though. As we have parameterized classes all over the place, I am quite sure that the need or desire will arise for asking for more specific "extensions" that also fulfill a classes generics (e.g., List). It might be usefull to apply the Super Type Token approach as described by Neal Gafter in his blog. Hence, you would pass in a parameterized TypeReference object instead of a Class instance. This approach would also solve another problem, mentioned by Derek: method clashes with existing classes. By introducing a new class, let's say java.lang.TypeReference, the resulting signature for the methods to query (has) and retrieve (get) an extension will be new to any class, and compete only with those taking Object as parameter, which could never have been invoked with an instance of TypeReference before. Reflecting on this, I am not sure, though, if Coin is the appropriate project for this change, as it is rather a JDK change than a language change. At least, I cannot see any support necessary from the language side. Stefan Alan Snyder schrieb: > Improved Support for Optional Object Behaviors at Runtime > > > AUTHOR: Alan Snyder > > OVERVIEW > > FEATURE SUMMARY: > > This proposal would add a method to class Object to allow runtime access > to optional object behaviors. > > MAJOR ADVANTAGE: > > As designs evolve and become more complex, it is useful to split out > separable chunks of behavior whose support by an object might be optional. > In current Java, the universally applicable technique for testing for and > making use of optional behavior is the type cast. The type cast is limited > by its tight coupling with the type hierarchy; as a result, because Java > has single class inheritance, a class can not support an optional behavior > defined by another class that is not already in its class hierarchy. In > addition, because type casts cannot be simulated by an object, it is not > compatible with delegation. For an object implemented by delegation to > support optional behaviors using type casts, there would need to be one > delegating class for each possible combination of optional behaviors. > > This proposal defines a method on class Object that can be used in place > of type casts to test for and access optional behaviors. This proposal is > not constrained by the type hierarchy of the target object, because it > permits the optional behavior to be implemented using a different (but > related) object. In addition, the determination of the available behaviors > can be made dynamically. Specifically, this proposal allows a class > implemented using delegation to mimic the set of optional behaviors > supported by its delegate, even if the delegate is replaceable. > > MAJOR BENEFIT: > > By adding a method to class Object, this feature can be supported by any > class, even existing Java platform classes, with no additional changes to > their class hierarchies. Because the feature is universally available, the > use of type casts for this purpose can be deprecated. > > This technique can be used to simply interfaces, or avoid making them more > complex. > > MAJOR DISADVANTAGE: > > Any change to class Object freaks people out. This is the only change I > can think of that is so obviously universal that it deserves to be in > class Object. > > ALTERNATIVES: > > One alternative is to define this method in a new interface. This > disadvantage of defining a new interface is that existing classes and > interfaces would not support the method without themselves being changed. > The other alternative is to add this method to classes and interfaces on > an as needed basis. Either alternative forces programmers to use type > casts in those cases where this method was not available. Also, new > implementations of unchanged classes and interfaces would not be able to > support this feature for existing clients of those classes and interfaces. > > EXAMPLE: > > Suppose a program wants to test an object "o" at runtime for an optional > behavior defined by a class or interface "T". In current Java, the program > could write: > > try { > T t = (T) o; > ... use t ... > } catch (ClassCastException ex) { > } > > Using the proposed feature, the program would write: > > T t = o.getExtension(T.class); > if (t != null) { > ... use t ... > } > > The following examples are all hypothetical, but plausible to varying > degrees. Note that many of them use instances of existing platform > classes. > > // Test a list to see if it is observable, and get access > // to the observable methods. > > Observable o = list.getExtension(Observable.class); > > // Test a file to see if supports metadata, and get access > // to the metadata methods. > > FileMetadata fm = file.getExtension(FileMetadata.class); > > // Test file metadata to see if Mac OS file metadata is > // supported. Note that the file might be on another > // machine, so this call might succeed even on a non-Mac system. > > MacOSFileMetadata mfm = fm.getExtension(MacOSFileMetadata.class); > > // Test a file to see if it supports the new File API. > // Note that using this approach the new File API does > // not have to be an extension of the old API. > > java.nio.File nf = file.getExtension(java.nio.File.class); > > // Test a file to see if it is a directory, and get access to > // the directory methods. > > Directory dir = file.getExtension(Directory.class); > > // Test a file to see if it is a symlink, and get access to > // the symlink methods. > > Symlink s = file.getExtension(Symlink.class); > > // Test a file to see if it a directory and whether it provides > // read and update access to the directory contents using the > // List API (!). > > List fs = (List) file.getExtension(List.class); > > DETAILS > > The default definition in class Object would be: > > public T getExtension(Class c) > { > try { > return (T) this; > } catch (ClassCastException ex) { > return null; > } > } > > Thus, if not overridden, the method has the same effect as the type cast. > Thus it can be used in place of type casts even on instances of existing > classes. > > Once this method is in place, programmers should be discouraged from using > type casts for the purpose of testing for optional behavior. > > SPECIFICATION: > > JLS 4.3.2 would be changed to define this method. > > I'm not aware of other changes. > > MIGRATION: > > It would be advisable to convert appropriate type casts to invocations of > this method in existing code. > > Once this method is available in class Object, other Java platform classes > and APIs can be changed to take advantage of it. > > COMPATIBILITY > > BREAKING CHANGES: > > No matter what name is chosen for this method, some existing program could > fail to compile if it defines a method with the same name and signature > but (say) a different return type. Methods with class parameters are > presumably uncommon. > > According to JLS 13.4.12, binary compatibility should not be broken > because the method is public. > > EXISTING PROGRAMS: > > Existing classes automatically support this method to the same extent that > they current support type casts for accessing optional behavior. > > > > From fw at deneb.enyo.de Sun Mar 29 05:23:19 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 29 Mar 2009 14:23:19 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: (Reinier Zwitserloot's message of "Thu, 26 Mar 2009 22:13:00 +0100") References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> Message-ID: <87fxgwzfew.fsf@mid.deneb.enyo.de> * Reinier Zwitserloot: > final list = foo ? new LinkedList() : new ArrayList(); > > the type of 'list' is what, exactly? It's the type specified in section 15.25 of the JLS. I can't find a definition of lub(T1, T2) in the spec, but "lub" probably stands for "least upper bound", and lub(LinkedList, ArrayList) would be AbstractList & Serializable & Cloneable (if I got the types right). > Serializable? Cloneable? List? They're all valid, so that wouldn't > work. Intersection types are already part of the language, so I don't see any problem. The following compiles: interface I1 {} interface I2 {} static class C1 implements I1, I2 {} static class C2 implements I1, I2 {} static void foo1(T foo) { } static void foo1(boolean foo) { foo1(foo ? new C1() : new C2()); } Existence of intersection types also leaks to the surface during overload resolution. It's just that you can't write down the type of some expressions using Java type notation. For local variables, this isn't a problem; only debugging information needs to be updated slightly. The effect for fields would be more pronounced, and I guess to stay within COIN's scope, a proposal would have to exclude inference for fields. From rssh at gradsoft.com.ua Sun Mar 29 06:54:27 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Sun, 29 Mar 2009 16:54:27 +0300 (EEST) Subject: PROPOSAL: Simple Operator Overloading Message-ID: Permanent URL: http://docs.google.com/Doc?id=dhhvggr8_18djp85shk Proof of concept implementation: http://code.google.com/p/jsoo-coin/ Submission as text: OVERVIEW: FEATURE SUMMARY: Add possibility to overloaded common subset of operators for java classes. Submission define @Operator method annotation for methods, which can be called as operators in classes and interfaces. MAJOR ADVANTAGE: In many cases (especially for Collections and own subtypes of numeric) using operator syntax is more clear and simple, than call by name of method. This proposal allows use operator ovlerloading, and at same time avoid complexity by defining operator overloading as thin layer on top of usual method calls. MAJOR DISADVANTAGE Inaccurate usage of this feature can cause producing of code which hard to read. Compiler is slightly complex then before. ALTERNATIVES: Live without operators as before. EXAMPLES SIMPLE EXAMPLE: Example 1 import javax.lang.Operator; public class Z3 { public Z3(int value) { this.value = (value%3); } public Z3(Z3 z3) { this.value = z3.value; } @Operator("+") public Z3 plus(Z3 x) { return new Z3(value + x.value); } @Operator("+=") public Z3 plusAssign(Z3 x) { value=((value+x.value)%3); } @Operator("-") public Z3 minus(Z3 x) { return new Z3(value-x.value); } @Operator("-=") public Z3 minusAssign(Z3 x) { value=((value-x.value)%3); } private int value; } Usage: Z3 z3 = new Z3(2); Z3 z4 = z3+z3; Example 2 public interface Named { public String getName(); } public class IndexedCollection { IndexedCollection(int capacity) { byIndexes=new T[capacity]; byNames=new TreeMap(); } @Operator("[]") public T get(int i) { return byIndexes[i]; } @Operator("[]") public T get(String name) { return byNames.get(name); } @Operator("[]=") public void set(int i, T t) { byIndexes[i]=t; byNames.put(t.getName(),t); } private T[] byIndexes; private Map byNames; } Usage: class NVPair extends Named { public NVPair(String name, Object value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } private String name; private String value; } IndexedCollection pairs = new IndexedCollection(10); pairs[0]=new NVPair("CISCO-AV-Pair","lcp:interface=1"); pairs[1]=new NVPair("X",4); pairs[2]=new NVPair("Y",5); NVPair pair1=pairs[1]; NVPair pair2=pairs["X"]; ADVANCED EXAMPLE: public interface StringAppendable { @Operator("+=") public void append(String x); } public class X implements StringAppendable { .... public void append(String x) { value+=x; } } X x; x+="qqq"; public interface X { @Operator("+="); public void addZ(Z z) } public interface Y { @Operator("+="); public void plusZ(Z z) } public class XY implements X, Y { public void addZ(Z z); public void plusZ(Z z); } XY xy; xy+=z; // compile-time error. (ambiguity of operator call resolution) DETAILS: Add to Java Library @Operator method annotation with next signature: package java.lang.Annotation @Documented @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface Operator { public String value(); } JLS changed. Add 9.6.1.7 about Operator annotation: The annotation type annotation.Operator(v) is used to indicate, that annotated method can be shortcated as operator in program test. v is String, which can be one of: ( "[]", "[]=", "+", "-", "~", "!", "*", "/", "%", "+=", "-=", "*=", "/=", %= ) Signature of operator method must be compatible with signature of operator, which means that methods, annotated as binary operators must be nonstatic member functions with one argument; unary operators - as nonstatic member functions without arguments. Add to 15.12.1. Compile-Time Step 1: Determine Class or Interface to Search Case for search of method for operator expression: If the form is OperatorExpression then classe for search is first operand of expression. Change 15.12.2.1 Identify Potentially Applicable Methods to A member method is potentially applicable to a method invocation if and only if all of the following are true: * Names of operator or method are matched, i.e. o When analyzed invocation is method invocation by name: + the name of the member is identical to the name of the method in the method invocation. o if method invocation is call of overloaded operator, + method is annotated with @Operator annotations with operator name as in operator expression or + method is override or implements method in superclass or superinterfaces, annotated with @Operator annotation with the name same as in operator expression. * The member is accessible (§6.6) to the class or interface in which the method invocation appears. * The arity of the member is lesser or equal to the arity of the method invocation. * If the member is a variable arity method with arity n, the arity of the method invocation is greater or equal to n-1. * If the member is a fixed arity method with arity n, the arity of the method invocation is equal to n. * If the method invocation includes explicit type parameters, and the member is a generic method, then the number of actual type parameters is equal to the number of formal type parameters. To chapter 15.13 to next form: The type of the array reference expression must be an array type (call it T[], an array whose components are of type T) or type of class with methods, annotated by @Operator("[]") or @Operator("[]=") annotations(call one class array reference expression) or a compile-time error occurs. Chapter 15.13.1 (Runtime Evaluation of Array Access) to next form: An array access expression is evaluated using the following procedure: * First, the array reference expression is evaluated. If this evaluation completes abruptly, then the array access completes abruptly for the same reason and the index expression is not evaluated. * Otherwise, o if array reference is array + the index expression is evaluated. If this evaluation completes abruptly, then the array access completes abruptly for the same reason. + Otherwise, if the value of the array reference expression is null, then a NullPointerException is thrown. + Otherwise, the value of the array reference expression indeed refers to an array. If the value of the index expression is less than zero, or greater than or equal to the array's length, then an ArrayIndexOutOfBoundsException is thrown. + Otherwise, the result of the array access is the variable of type T, within the array, selected by the value of the index expression. (Note that this resulting variable, which is a component of the array, is never considered final, even if the array reference expression is a final variable. o if array reference is class-array-reference exception + if exists method, annotated as @Operator("[]=") and if such expression is situated at the left part of plain assigment expression X=Y, than this subexpression does not evaluated itself, instead components of array access expression take part in process of assigment. + otherwise, if exists set of methods for such class, annotated by @Operator("[]"), than better candidate from set of appropriative annotated methods is called, as specified in 15.12 (Method Invocation Expression). 15.15.5 Bitwise Complement Operator ~ The type of the operand expression of the unary ~ operator must be a type that is convertible (§5.1.8) to a primitive integral type, or class, which declare or override or implement non-static member functions without arguments, annotated by @Operator("~") , or a compile-time error occurs. If operand expression is convertable to a primitive integram type, than * Unary numeric promotion (§) is performed on the operand. The type of the unary bitwise complement expression is the promoted type of the operand. * At run time, the value of the unary bitwise complement expression is the bitwise complement of the promoted value of the operand; note that, in all cases, ~x equals (-x)-1 If operand expression is class, where methods annotated by @Operator("~") are accessible, than appropriative methods is called, as specified in 15.12 ( except check for name of method step) and result type is type of method invocaton. 15.15.6 Logical Complement Operator ! The type of the operand expression of the unary ! operator must be boolean or Boolean, or class, which declare, override or implements function without arguments, annotated by @Operator("!") , or a compile-time error occurs. When type of the operand expression is boolean or Boolean, than * type unary logical complement expression is boolean, * At run time, the operand is subject to unboxing conversion (§5.1.8) if necessary; the value of the unary logical complement expression is true if the (possibly converted) operand value is false and false if the (possibly converted) operand value is true When type of the operand expression is class, which have non-static member functions without arguments, annotated by @Operator("!") than expression is processed as invocation of appropriative method. 15.17 Multiplicative Operators The operators *, /, and % are called the multiplicative operators. They have the same precedence and are syntactically left-associative (they group left-to-right). MultiplicativeExpression: UnaryExpression MultiplicativeExpression * UnaryExpression MultiplicativeExpression / UnaryExpression MultiplicativeExpression % UnaryExpression The type of each of the operands of a multiplicative operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or type of first operand must be a class, which contains (or implements or override) accessible methods with one argument, annotated by @Operator("*" or "/" or "%"), or compile-time error occurs. In case of types, convertible to promitive numeric type: Binary numeric promotion is performed on the operands (§5.6.2). The type of a multiplicative expression is the promoted type of its operands. If this promoted type is int or long, then integer arithmetic is performed; if this promoted type is float or double, then floating-point arithmetic is performed. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13). Chapter 15.17.1, 15.17.2, 15.17.3 just rename to Primitive Numeric Multiplication Operator, Primitive Numeric Division Operator and Primitive Numeric Remind operator. Add 15.17.4 Multiplicative Operators for class with operator-annotated methods. In case when type of first operand is class with method, annotated by appropreative annotations, than expression is processed as invocation expression ($15.2) from set of appropriative annotated methods. 15.18 Additive Operators The operators + and - are called the additive operators. They have the same precedence and are syntactically left-associative (they group left-to-right). AdditiveExpression: MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression If the type of either operand of a + operator is String, then the operation is string concatenation. Otherwise, the type of each of the operands of the + operator must be a type that is convertible (§5.1.8) to a primitive numeric type. In every case, the type of each of the operands of the binary - operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or a compile-time error occurs. Otheriwise, the type of first operand must be a class, which contains or override or implement nonstatic member function with one argument, annotated by @Operator("+" or "-") or compile-time error occurs. add 15.18.3 Additive Operators for class with operator-annotated methods: In case when type of first operand is class with method, annotated by appropreative annotations, than expression is processed as invocation expression from set of appropriative annotated methods. 15.26 There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a. AssignmentExpression: ConditionalExpression Assignment Assignment: LeftHandSide AssignmentOperator AssignmentExpression LeftHandSide: ExpressionName FieldAccess ArrayAccess AssignmentOperator: one of = *= /= %= += -= <<= >>= >>>= &= ^= |= The result of the first operand of an assignment operator must be a variable, or class array reference expression ($15.3), or a compile-time error occurs. Variable operand may be a named variable, such as a local variable or a field of the current object or class, or it may be a computed variable, as can result from a field access (§15.11) or an array access (§15.13). The type of the assignment expression is the type of the variable after capture conversion (§5.1.10). 15.26.1 Simple Assignment Operator = A compile-time error occurs when * left hand operand expression is a value and the type of the right-hand operand cannot be converted to the type of the variable by assignment conversion (§5.2) * left hand operand expression is class array reference expression and type of right-hand operator cannot be converted to the type of second argument for one of methods, annotated with @Operator("[]=") annotation. At run time, the expression is evaluated in one of three ways: * If the left-hand operand expression is a field access expression (§15.11) e.f, possibly enclosed in one or more pairs of parentheses, then: o First, the expression e is evaluated. If evaluation of e completes abruptly, the assignment expression completes abruptly for the same reason. o Next, the right hand operand is evaluated. If evaluation of the right hand expression completes abruptly, the assignment expression completes abruptly for the same reason. o Then, if the field denoted by e.f is not static and the result of the evaluation of e above is null, then a NullPointerException is thrown. o Otherwise, the variable denoted by e.f is assigned the value of the right hand operand as computed above. * If the left-hand operand is an array access expression (§15.13), possibly enclosed in one or more pairs of parentheses, then: * o If array reference expression is array type + First, the array reference subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no assignment occurs. + Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no assignment occurs. + Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs. + Otherwise, if the value of the array reference subexpression is null, no assignment occurs and a NullPointerException is thrown. + Otherwise, the value of the array reference subexpression indeed refers to an array. If the value of the index subexpression is less than zero, or greater than or equal to the length of the array, then no assignment occurs and an ArrayIndexOutOfBoundsException is thrown. + Otherwise, the value of the index subexpression is used to select a component of the array referred to by the value of the array reference subexpression. This component is a variable; call its type SC. Also, let TC be the type of the left-hand operand of the assignment operator as determined at compile time. + If TC is a primitive type, then SC is necessarily the same as TC. The value of the right-hand operand is converted to the type of the selected array component, is subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the array component. + If TC is a reference type, then SC may not be the same as TC, but rather a type that extends or implements TC. Let RC be the class of the object referred to by the value of the right-hand operand at run time. The compiler may be able to prove at compile time that the array component will be of type TC exactly (for example, TC might be final). But if the compiler cannot prove at compile time that the array component will be of type TC exactly, then a check must be performed at run time to ensure that the class RC is assignment compatible (§5.2) with the actual type SC of the array component. This check is similar to a narrowing cast (§5.5, §15.16), except that if the check fails, an ArrayStoreException is thrown rather than a ClassCastException. Therefore: # If class RC is not assignable to type SC, then no assignment occurs and an ArrayStoreException is thrown. + Otherwise, the reference value of the right-hand operand is stored into the selected array component. o If array reference expression is class reference expression ($15.13), than + First, the first operand of array reference expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the index subexpression (of the left-hand operand array access expression) and the right-hand operand are not evaluated and no array assigmnent methods are called. + Otherwise, the index subexpression of the left-hand operand array access expression is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and the right-hand operand is not evaluated and no array assignment methods are called. + Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no call of array assignment method occurs. + Otherwise, invocation of appropriateve method, (which annotated by @Operator("[]=") or override or implement methods, annotated by Operator("[]=")) is called on first operand of array reference with index subexpression and righ hand operators as reference. + If appropriative method is not found, than compile-time error occurs. (to prevent call single assigment on result of method, annotated by Operator("[]") * Otherwise, three steps are required: o First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs. o Otherwise, the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs. 15.16.2 Compound Assignment Operators A compound assignment expression of the form E1 op= E2 is when * type of E1 is Primitive Numeric Types or Booleans or String, then this is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once. * type of E1 is Class, which have methods m, annotated by @Operator("op="), than compound assigment evaluates exactly as invocation expression of appropriatev methods, with method names. COMPILATION: During compilation overloaded operators will be translated to set of appropriative annotated methods. I.e. for Example 1 Z3 z3 = new Z3(2); Z3 z4 = z3+z3; which will be translated to: Z3 z3 = new Z3(2); Z3 z4 = Z3.plus(z3,z3); Example 2 IndexedCollection pairs = new IndexedCollection(10); pairs[0]=new NVPair("CISCO-AV-Pair","lcp:interface=1"); pairs[1]=new NVPair("X",4); pairs[2]=new NVPair("Y",5); NVPair pair1=pairs[1]; NVPair pair2=pairs["X"]; will be equal to: IndexedCollection pairs = new IndexedCollection(10); pairs.set(0,new NVPair("CISCO-AV-Pair","lcp:interface=1")); pairs.set(1,new NVPair("X",4)); pairs.set(2,new NVPair("Y",5)); NVPair pair1=pairs.get(1); NVPair pair2=pairs.get("X"); TESTING Implementation must provide set of tests for each of operators and possible confilcts for overriding/implementation and chained invocations. LIBRARY SUPPORT: @Operator annotation must be added to standard library. Also, not required but be practical to annotate standard Collection classes; BigDecimal and BigInteger. REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4905919 IMPLEMENTATION PROTOTYPE URL Proof of concept implementation, implemented as preprocessor, is published at http://code.google.com/p/jsoo-coin/ From joshua.suereth at gmail.com Sun Mar 29 07:55:38 2009 From: joshua.suereth at gmail.com (Josh Suereth) Date: Sun, 29 Mar 2009 10:55:38 -0400 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> Message-ID: <55b774930903290755y58cbb544nb61044c4c3b5d83b@mail.gmail.com> John, I'm curious as to why you chose to not allow catching checked exception from Dynamic method calls. I think it would be nice to make a dynamic method call and try to catch, e.g. JdbcExceptions vs. MethodMissing exceptions. I haven't lookied into MethodHandles + InvokeDynamic in depth yet, so if they are wrapping checked exceptions with unchecked exceptions, then ignore this comment. I really like this proposal and am looking forward to seeing it make it into the Java Language. - Josh On Sun, Mar 29, 2009 at 2:53 AM, John Rose wrote: > Hello, colleagues. Here is a proposal which is linked to JSR 292 > (invokedynamic). > > http://wikis.sun.com/display/mlvm/ProjectCoinProposal > http://blogs.sun.com/jrose/entry/jsr_292_support_in_javac > > Here's the teaser (from my blog): > > In order to work with dynamic types, method handles, and invokedynamic > I have made some provisional changes to javac as part of the Da Vinci > Machine Project. The mlvm wiki has a full description for Project > COIN. It is most desirable, of course, to program invokedynamic call > sites as Java expressions, not just ASM code, and that's what those > langtools patches are for. > The essential features are four: > > ? The type java.dyn.Dynamic will accept any method call and turn it > into an invokedynamic instruction, and the full range of such > instructions can be spelled from Java code. > ? The type java.dyn.MethodHandle will accept any argument and return > types for a call to the method named invoke, which means that Java > code can spell the full range of method handle invocations. > ? The full range of bytecode names acceptable to the JVM can be > spelled from Java code, using an exotic identifier quoting syntax. > ? The type java.dyn.Dynamic serves as a bare reference type: > Anything > implicitly converts to it, and it can be cast to anything, but it is > not a subtype of java.lang.Object. Its methods, of course, are those > from point #1, so it is handy for forming invokedynamic calls. > The rationale is pretty simple: If we put some minimal support into > Java for defining and using names in other languages, then Java can be > used as a system programming language for implementing them. > Otherwise, the system programming language will be assembled bytecode. > (I like to visit ASM, but don't want to live there.) > > Do check out the wiki page; it has the full Project COIN proposal > format. > > Best wishes, > > -- John Rose (Da Vinci Machine Project) > > From jeroen at entreact.com Sun Mar 29 04:26:42 2009 From: jeroen at entreact.com (Jeroen van Maanen) Date: Sun, 29 Mar 2009 13:26:42 +0200 Subject: Submission: switch (...) instanceof feature Message-ID: <49CF5AF2.8020408@entreact.com> I'd like to coin a switch (...) instanceof statement as a new feature of the Java language. Please accept the attached proposal for review. Regards, Jeroen -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: coin-proposal.txt Url: http://mail.openjdk.java.net/pipermail/coin-dev/attachments/20090329/84e22716/coin-proposal.txt From neal at gafter.com Sun Mar 29 11:06:45 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Mar 2009 11:06:45 -0700 Subject: Ergonomic Issues with ARM blocks Message-ID: <15e8b9d20903291106l73caa4dej4724a35cd2f14a09@mail.gmail.com> Here are some notes on ergonomic (usability) issues I found during my attempt to retrofit some code with ARM blocks based on its latest spec. (1) "try" is not a natural keyword for the intended semantics. The use of the try keyword for this construct is natural while migrating existing code, because the existing solution already requires a try-finally statement. But it is a non sequitur (in some cases shockingly inappropriate) when reading code or when writing new code. The problem is that it calls attention to the exceptional case rather than the normal case, distracting the reader from the flow of the business logic. That is the very problem this construct should be designed to solve. This violates the principle that a language construct should be designed to integrate well with the language as it appears with the addition, rather than being designed to fit into the language as it existed before the addition. The try statement is already the most complex statement form in Java; we should avoid making it even more complex. It would be better to use a new context-sensitive keyword to define a new construct. For example, one might select the syntax identifier (DeclSeq) Statement Where the identifier would be semantically restricted to "using". This form is unambiguous with the existing language. I believe it can be parsed without additional look-ahead by accepting a superset of the grammar and post-filtering. By selecting a syntax with no overlap to existing forms, a context-sensitive keyword would not break backward compatibility. Java 7 will already be using context-sensitive keyword(s) for the modularity extension, so the approach isn't novel. (2) Checked exceptions from close() should be discarded for some clients. Experience with the previous prototype of the previous (now 3-year-old) ARM proposal raised issues of handling exceptions from closing resources (some APIs wanted exceptions from close() discarded, others did not). Others have raised the same concern this time around. At the time, Josh's position was "It was certainly my intention that the programmer not be required to deal with exceptions thrown when terminating a resource...". That works out very nicely for some clients, and is a killer for others. The latest proposal abandons the set of use cases well served by the previous specification, and attempts to serve the set of use cases where exceptions on termination are best addressed by the programmer. From my (admittedly limited) experience, I found more cases where it was appropriate to discard checked exceptions from close() than otherwise. A revision of the proposal addressing this was promised. The earlier solution was two distinct but related statement forms. (3) The nesting of new behavior with old behavior in the try statement is a poor fit for many clients. Another issue arises due to the nesting of new behavior with existing behavior in the try statement. By retrofitting the construct onto an existing statement form, the language has made a decision on the relative nesting of the two behaviors. Is the resource variable in scope in the catch block? Is it in scope in the finally block? Any particular answer to these questions is a good match for some clients and a poor match for others. Given the currently specified nesting, the following code becomes more awkward when retrofitted with the ARM construct: LineNumberReader reader = getInput(); try { parseInput(reader); } catch (CharacterCodingException ex) { report("character encoding error at line " + reader.getLineNumber()); } finally { try { reader.close(); } catch (IOException ex) {} } The proposal should not take a position on a "preferred" way of combining/nesting resource usage with catch and finally. This problem is easily solved by separating the new construct from existing statement forms. Then the programmer can mix or match the separate language constructs as required for the application. (4) The proposed construct doesn't retrofit onto many APIs in the profile of use-cases for which it was designed. A separate conversation regarding an analysis of the use cases was moved off-list, ultimately identifying widely used APIs that ought to be retrofittable with this construct. See . One result of that analysis was that the proposal is incompatible with a number of widely used types that ought to be retrofitted. A revision of the proposal addressing this was promised. (5) Such ergonomic issues require significant time and experience to resolve A language construct that affects so many distinct APIs with varying patterns of use requires a significant body of experience to build confidence that it is usable with them. What little experience we have with the present proposal suggests more work is needed. In addition, proposed (but not yet specified) solutions to the retrofitting issue and promised solutions to other issues are novel enough that they should not be adopted without a significant period of time for experience with them to develop, and for the language construct to evolve based on that experience. We would do a disservice to Java programmers by shoving an untried solution in a rush through a process designed to handle small, simple, noncontroversial changes. From fw at deneb.enyo.de Sun Mar 29 11:37:11 2009 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 29 Mar 2009 20:37:11 +0200 Subject: Ergonomic Issues with ARM blocks In-Reply-To: <15e8b9d20903291106l73caa4dej4724a35cd2f14a09@mail.gmail.com> (Neal Gafter's message of "Sun, 29 Mar 2009 11:06:45 -0700") References: <15e8b9d20903291106l73caa4dej4724a35cd2f14a09@mail.gmail.com> Message-ID: <87prg0kwfc.fsf@mid.deneb.enyo.de> * Neal Gafter: > (1) "try" is not a natural keyword for the intended semantics. > > The use of the try keyword for this construct is natural while > migrating existing code, because the existing solution already > requires a try-finally statement. But it is a non sequitur (in some > cases shockingly inappropriate) when reading code or when writing new > code. I'm also not convinced that a construct which adds another indentation level is desirable. It adds quite a bit of syntactic clutter, and I think the clutter is one of the reasons why we see too little use of explicit resource management. > (2) Checked exceptions from close() should be discarded for some clients. > > Experience with the previous prototype > > of the previous (now 3-year-old) ARM proposal > raised > issues of handling exceptions from closing resources (some APIs wanted > exceptions from close() discarded, others did not). I think this is related to the lack of an initializer in the old proposal. If you need to specify an initializer to use the construct, it's very likely that the initializer will throw, too (at least for IOException). > (3) The nesting of new behavior with old behavior in the try statement > is a poor fit for many clients. > > Another issue arises due to the nesting of new behavior with existing > behavior in the try statement. By retrofitting the construct onto an > existing statement form, the language has made a decision on the > relative nesting of the two behaviors. Is the resource variable in > scope in the catch block? Is it in scope in the finally block? Any > particular answer to these questions is a good match for some clients > and a poor match for others. I agree that these are strong arguments against an approach based on "try". > (4) The proposed construct doesn't retrofit onto many APIs in the > profile of use-cases for which it was designed. > > A separate conversation regarding an analysis of the use cases was > moved off-list, ultimately identifying widely used APIs that ought to > be retrofittable with this construct. See > . > One result of that analysis was that the proposal is incompatible > with a number of widely used types that ought to be retrofitted. A > revision of the proposal addressing this was promised. There are still a few ones missing from that document (java.lang.Process, for instance). And there are some cases where the lack of an explicit release is rather close to an API bug (roughly anything which acquires native resources, I guess), which was not deemed worth fixing because explicit resource management cannot reasonably be forced on users. In other words, I expect that there will be many more users of this functionality once it is available in the language, more than what is suggested by current APIs. > We would do a disservice to Java programmers by shoving an untried > solution in a rush through a process designed to handle small, > simple, noncontroversial changes. Is there are chance to move this into some channel which can deal with more long-term, significant language changes, but is as accessible as COIN? From abies at adres.pl Sun Mar 29 12:38:52 2009 From: abies at adres.pl (Artur Biesiadowski) Date: Sun, 29 Mar 2009 21:38:52 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CF5AF2.8020408@entreact.com> References: <49CF5AF2.8020408@entreact.com> Message-ID: <49CFCE4C.10808@adres.pl> 1) Why case void: instead of case null: ? 2) What is a expected behavior in case of multiple matches ? For example switch(collection) instanceof { case RandomAccess: ... case List: ... case Collection: ... } Do I need to put switch cases in correct order because of top-to-down evaluation or most specific one will be used? Or maybe all matching ones ? 3) I think you have forgotten to put 'break' in your examples, unless you plan to disallow fall-through. Regards, Artur Biesiadowski From develop4lasu at gmail.com Sun Mar 29 12:58:27 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 29 Mar 2009 21:58:27 +0200 Subject: PROPOSAL: 'forget' keyword Message-ID: <28bca0ff0903291258s51ea07d6p89ccc3667878166a@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: 'forget' keyword allows to erase variable from current context, or it means that field should not be used. MAJOR ADVANTAGE: This change makes language be more WYSIWYG. MAJOR BENEFIT(s): - It makes people be able to erase 'variable' from current context, while now it's: --> impossible for final variables (only by comments), --> impossible for arguments (for not final Object we can assign null), --> impossible for fields. --> local fields need more or 'less' artificial blocks (two lines wasted and one indent level). - Declaring that variable should not be used, or does not contain valid information for further use will be possible. - Code quality does not fall so drastically after we leave it, comparing to '=null', 'only comments' or 'weird blocks'. MAJOR DISADVANTAGE: New keyword == Someone can have declared method/field/variable named 'forget'. ALTERNATIVES: It's already listed. EXAMPLES SIMPLE / ADVANCED EXAMPLE(s): public static void main(final String[] args) { System.out.println(Arrays.toString(args)); forget args; // 'args' cannot be used anymore String[] args; // Error: Duplicate local variable args ... } public class Forget { private ArrayList criticKeys; public void addKey(String newKey){ forget this.criticKeys; // use synchronized method ONLY ... // validate ... // add } } public static void main(final String[] arguments) { int sum = 0; for (String s : arguments) { sum += Integer.parseInt(s); System.out.println(sum); forget s; // OK forget args; // OK: arguments variable is final forget sum; // Error: cannot erase variable it it will still can be used ... } System.out.println(arguments.length); // Error: erased context } DETAILS SPECIFICATION: forget VariableIdentifier; or forget this. FieldIdentifier; Forbid using given identifier in all followed expressions, in all blocks in which variable could be used in current method scope. If variable is not final then forget expression cannot occurs in loop block if variable was declared in wider block, it's because variable should not be forgotten if it will be used again. If field is not final than forget expression cannot occurs in any loop block (can be reconsidered). COMPILATION: Variable is not erased (but it can be, if it's not field), it's just protected from access that should not happen for any reason. What's more, handling variable, as if it still exists, prevents a situation when a programmer creates new variable with the same name and then removes forget statement. TESTING: It's the same as testing effects of exiting from the block for variables. For fields, it's just an access control. LIBRARY SUPPORT: None. REFLECTIVE APIS: None. OTHER CHANGES: None. MIGRATION: None. COMPATIBILITY New keyword can be problem. There is not other impact. REFERENCES http://lasu2string.blogspot.com/2009/03/forget-keyword-proposal_27.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Sun Mar 29 13:13:52 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 29 Mar 2009 22:13:52 +0200 Subject: PROPOSAL: 'forget' keyword (beta) In-Reply-To: References: <28bca0ff0903270702r52d610a5j792e1912781722d6@mail.gmail.com> Message-ID: <28bca0ff0903291313w241def37r68f75938a55c0267@mail.gmail.com> W dniu 27 marca 2009 18:38 u?ytkownik Daniel Cheng napisa?: > On Fri, Mar 27, 2009 at 10:02 PM, Marek Kozie? wrote: >> ? I do not know if there is point to describe this proposal in >> details, because it require to introduce new keyword which may be >> impossible for project Coin scope.? > > You are encourage going against the ?CERT Secure Programming Practice: > ?https://www.securecoding.cert.org/confluence/display/java/SCP03-J.+Do+not+reuse+names > > Almost all modern programming style manual against reuseing variable name, eg: > ?http://www.cs.cmu.edu/~pattis/15-1XX/15-200/lectures/style/index.html > > Thanks, this helped me a lot. http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001093.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From javalists at cbfiddle.com Sun Mar 29 13:26:53 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Sun, 29 Mar 2009 13:26:53 -0700 (PDT) Subject: PROPOSAL: Improved Support for Optional Object Behaviors at Runtime Message-ID: <53771.69.239.104.86.1238358413.squirrel@69.239.104.86> Derek, I will respond to your two points in separate messages. You raise the issue that this proposal will weaken the guarantee in current Java that requires the caller of a method to consider (catch or declare in its own signature) the exceptions thrown by the methods that it calls. I do not see how this would happen. Any method that declares a checked exception will require an exception handler or declaration, as in current Java. Any method that throws an unchecked exception will not, as in current Java. Your example method getFoo2() does not declare that it throws a checked exception. Thus, as in current Java, there is no guarantee that the caller will consider the possibility of an exception being thrown by this method. If you want callers of your API to be forced to consider a possible exceptional condition, you must declare the methods to throw checked exceptions. There is no change here. Yes, it is true that someone could write a method that throws an unchecked exception when it would have been more appropriate to throw the superclass checked exception. That does not seem any different than throwing a Runtime exception when a checked exception would have been more appropriate. It is bad programming, for which there is no help from the compiler. Anyway, I'm sure that you wouldn't put a method like that in your API, and I'll bet you're not likely to do it by mistake (which is where compiler support would be relevant). Alan On Mar 28, 2009, at 5:43 PM, Derek Foster wrote: Although I appreciate what you are trying to do with this proposal, and I have certainly been inconvenienced by the problem that you are trying to solve, I am also very concerned with unintended consequences of your proposal. Your proposal describes its intended effect, and it certainly seems able to solve that use case, but does not seem to really delve into other impacts of this change in behavior which might be less positive. One of the reasons I typically use checked exceptions in programs is to ensure that all callers of an API must consider and handle the various error conditions that can occur. Thus if I have a method like: void getFoo() throws FooDoesNotExistException; I can be assured that anyone who calls getFoo() will be forced to consider what to do if the Foo object does not exist. They may choose to ignore the error condition, but at least they will have been forced to consider it (by adding a 'catch' clause somewhere in the program for it or one of its supertypes). This is one of the most important reasons to use checked exceptions in the first place: They allow the compiler to do what amounts to essentially a compile-time proof that all checked exceptions will eventually be handled by someone. Your proposal seems to have the potential to break this guarantee, so that someone could have a method like: void getFoo2(); // throws UncheckedSubtypeOfFooDoesNotExistException; then if I call it in my code: Foo getStuff() { ????return getFoo2(); } I am never forced to add a catch clause for FooDoesNotExistException anywhere. From javalists at cbfiddle.com Sun Mar 29 13:29:12 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Sun, 29 Mar 2009 13:29:12 -0700 (PDT) Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions Message-ID: <53780.69.239.104.86.1238358552.squirrel@69.239.104.86> [Oops... wrong subject line on the previous message.] Derek, I will respond to your two points in separate messages. You raise the issue that this proposal will weaken the guarantee in current Java that requires the caller of a method to consider (catch or declare in its own signature) the exceptions thrown by the methods that it calls. I do not see how this would happen. Any method that declares a checked exception will require an exception handler or declaration, as in current Java. Any method that throws an unchecked exception will not, as in current Java. Your example method getFoo2() does not declare that it throws a checked exception. Thus, as in current Java, there is no guarantee that the caller will consider the possibility of an exception being thrown by this method. If you want callers of your API to be forced to consider a possible exceptional condition, you must declare the methods to throw checked exceptions. There is no change here. Yes, it is true that someone could write a method that throws an unchecked exception when it would have been more appropriate to throw the superclass checked exception. That does not seem any different than throwing a Runtime exception when a checked exception would have been more appropriate. It is bad programming, for which there is no help from the compiler. Anyway, I'm sure that you wouldn't put a method like that in your API, and I'll bet you're not likely to do it by mistake (which is where compiler support would be relevant). Alan On Mar 28, 2009, at 5:43 PM, Derek Foster wrote: Although I appreciate what you are trying to do with this proposal, and I have certainly been inconvenienced by the problem that you are trying to solve, I am also very concerned with unintended consequences of your proposal. Your proposal describes its intended effect, and it certainly seems able to solve that use case, but does not seem to really delve into other impacts of this change in behavior which might be less positive. One of the reasons I typically use checked exceptions in programs is to ensure that all callers of an API must consider and handle the various error conditions that can occur. Thus if I have a method like: void getFoo() throws FooDoesNotExistException; I can be assured that anyone who calls getFoo() will be forced to consider what to do if the Foo object does not exist. They may choose to ignore the error condition, but at least they will have been forced to consider it (by adding a 'catch' clause somewhere in the program for it or one of its supertypes). This is one of the most important reasons to use checked exceptions in the first place: They allow the compiler to do what amounts to essentially a compile-time proof that all checked exceptions will eventually be handled by someone. Your proposal seems to have the potential to break this guarantee, so that someone could have a method like: void getFoo2(); // throws UncheckedSubtypeOfFooDoesNotExistException; then if I call it in my code: Foo getStuff() { ????return getFoo2(); } I am never forced to add a catch clause for FooDoesNotExistException anywhere. From javalists at cbfiddle.com Sun Mar 29 13:30:13 2009 From: javalists at cbfiddle.com (Alan Snyder) Date: Sun, 29 Mar 2009 13:30:13 -0700 (PDT) Subject: PROPOSAL: Unchecked Exceptions as Subclasses of Checked Exceptions Message-ID: <53796.69.239.104.86.1238358613.squirrel@69.239.104.86> Derek, You have raised an interesting point. The programs that I have written do not suffer from this problem. They already contain the required exception handlers (which are legitimate), and my goal is to avoid having to add additional clauses to those existing (and legitimate) exception handlers. But, as you point out, there is a language specification issue here. If an exception handler catches a checked exception that is not final, the compiler can no longer assume that the exception will not be thrown, because a method could throw an instance of an unchecked subclass of that exception. I looked through the JLS to see where this compiler error comes from. Section 14.20 says: It is a compile-time error if a catch clause catches checked exception type E1 but there exists no checked exception type E2 such that all of the following hold: ... The try block corresponding to the catch clause can throw E2 My proposal would be to change "checked exception type E2" to "exception type E2". The effect of this change would be to make most exception handlers legal, unless E1 was declared final. I would also propose that the current compiler error message be changed to a warning message in cases where the previously illegal exception handler is now legal. Perhaps the warning could be suppressed when E1 is known to have an unchecked subclass. Some people might not like this change. I actually think this message should have been a warning instead of an error from the beginning. When code is under development and in flux, I often find myself having to comment out exception handlers and try blocks to keep the compiler happy while I am experimenting with code changes. This is busy work that does nothing to make my programs more reliable. Furthermore, while some might argue it is misleading to have an exception handler that can never catch an exception, perhaps I want it there because I think that a future version of the code or of the code I am calling might starting throwing this exception. Alan On Mar 28, 2009, at 5:43 PM, Derek Foster wrote: Furthermore, I in many ways CAN'T add a catch clause for the base type in outside code, as your proposal suggests is its goal: Foo getStuff() { ????try { ????????return getFoo2(); ????} catch (FooDoesNotExistException e) { ?// This is a compiler error. Exception is never thrown in try block. ????????// handle exception here ????} } The only time it would be legal for me to add a catch clause for the base type would be if there was another method also being called in the same try..catch block which DID throw the base exception. From jeroen at lexau.org Sun Mar 29 13:43:02 2009 From: jeroen at lexau.org (Jeroen van Maanen) Date: Sun, 29 Mar 2009 22:43:02 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CFCE4C.10808@adres.pl> References: <49CF5AF2.8020408@entreact.com> <49CFCE4C.10808@adres.pl> Message-ID: <49CFDD56.8070802@lexau.org> Artur Biesiadowski wrote: > 1) Why case void: instead of case null: ? Yes, I agree that it is potentially confusing. At the other hand, null is an instance not a type. It would also be possible to add a type or even a keyword to describe the type of null, but that would increase the impact of the change and it would mean another type with no instances. I thought that void would pretty much fit the descrition of what I would like: a keyword that indicates a type that would not have any actual instances. I suppose that if we are stretching the exact meaning of the terms anyway, then 'case null:' would probably just be as well and easier to remember. > 2) What is a expected behavior in case of multiple matches ? For example I propose to do strict top-down first-match-only evaluation, because if the given variable matches many of the labels and the types of the labes belong to a complicated hierarchy of interfaces, then reordering the cases according to inheritance could lead to unpredictable results. I don't think that executing all matching blocks would be a good idea, because I think that many code readers would not expect this from a switch statement. Although it would be possible to allow a fallthrough from a specific type to a super type, I am afraid that allowing such highly constrained constructions would lead to code that is hard to read and easy to misunderstand. > switch(collection) instanceof { > > case RandomAccess: > ... > > case List: > ... > > case Collection: > ... > > > } > > Do I need to put switch cases in correct order because of top-to-down > evaluation or most specific one will be used? Or maybe all matching ones ? > > 3) I think you have forgotten to put 'break' in your examples, unless > you plan to disallow fall-through. Ah, I should have made that explicit. No breaks necessary and no lists of labels before a statement block. I could not think of a way to get the casts right in a fallthrough situation. Maybe it would be less confusing to make break a compulsory statement at the end of each statement block. That is: TypeSwitchBlockStatementGroup: TypeSwitchLabel BlockStatements break ; What do you think? > Regards, > Artur Biesiadowski I just thought about another situation that needs to be clarified: 4) How does the switch instanceof statement handle generics? I would like to see switch (model) instanceof { FreeMarkerModel: template.process(..., model); Map: template.process(..., toFMM(model)) } translated as if (model instanceof FreeMarkerModel) { FreeMarkerModel model$1 = (FreeMarkerModel) model; template.process(..., model$1); } else if (model instanceof Map) { Map model$2 = (Map) model; template.process(..., toFMM(model$2)); } So each type parameter that we cannot guess would be specified as ?. The following would be illegal, because the specification allows no type parameters after the type name in a label. switch (model) instanceof { ... Map: ... } This is fine, because I can't think of a way where the desugared code would be free of "unchecked" warnings. Regards, Jeroen From develop4lasu at gmail.com Sun Mar 29 14:22:40 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Sun, 29 Mar 2009 23:22:40 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <87fxgwzfew.fsf@mid.deneb.enyo.de> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> Message-ID: <28bca0ff0903291422s77f11c44j4ddf6ea45ec0b669@mail.gmail.com> 2009/3/29 Florian Weimer : > * Reinier Zwitserloot: > >> final list = foo ? new LinkedList() : new ArrayList(); >> >> the type of 'list' is what, exactly? > > It's the type specified in section 15.25 of the JLS. ?I can't find a > definition of lub(T1, T2) in the spec, but "lub" probably stands for > "least upper bound", and lub(LinkedList, ArrayList) would be > AbstractList & Serializable & Cloneable (if I got the types right). > >> Serializable? Cloneable? List? ?They're all valid, so that wouldn't >> work. > > Intersection types are already part of the language, so I don't see > any problem. ?The following compiles: > > ? ?interface I1 {} > ? ?interface I2 {} > > ? ?static class C1 implements I1, I2 {} > ? ?static class C2 implements I1, I2 {} > > ? ?static void foo1(T foo) { > ? ?} > > ? ?static void foo1(boolean foo) { > ? ? ? ?foo1(foo ? new C1() : new C2()); > ? ?} > > Existence of intersection types also leaks to the surface during > overload resolution. > > It's just that you can't write down the type of some expressions using > Java type notation. ?For local variables, this isn't a problem; only > debugging information needs to be updated slightly. ?The effect for > fields would be more pronounced, and I guess to stay within COIN's > scope, a proposal would have to exclude inference for fields. > You got it wrong. Java do not support intersection types, or we use different definition. T extends I1 & I2 : not intersection I1 & I2: intersection interface I1 {} interface I2 {} void noInterection(T t,K k){ if (boo)t=k; // Type mismatch: cannot convert from K to T ... } void intersection( I1&I2 t, I1&I2 k){ if (boo)t=k; // OK I1 i1 = t; // OK I2 i2 = t; // OK } http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#108433 "is not possible to write an intersection type directly as part of a program; no syntax supports this." -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From matthew at mastracci.com Sun Mar 29 14:41:10 2009 From: matthew at mastracci.com (Matt Mastracci) Date: Sun, 29 Mar 2009 15:41:10 -0600 Subject: PROPOSAL: Conditional Statement Message-ID: <7B58F3A4-3880-49C6-A81E-AE0822D07BB3@mastracci.com> Conditional Statement ===================== Richly formatted version available at: http://docs.google.com/Doc?id=dgthwhwr_2hs2hknhf AUTHOR(S): Matt Mastracci OVERVIEW FEATURE SUMMARY: Allows an analogue of the conditional expression to exist at the statement level, with relaxed restrictions on the type of its second and third operands. MAJOR ADVANTAGE: Ability to use conditional operator for choosing between two statement-level expressions (ie: two different method invocations). MAJOR BENEFIT: Simplifies code that executes one of two expression statements given a boolean input. MAJOR DISADVANTAGE: Turns the conditional operator into two different constructs in the Java language with different rules. ALTERNATIVES: Continue using if/else (this feature is sugar only). See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25 for the definition of the original conditional expression. EXAMPLES // even() and odd() are defined as "public void" public void onEvenOrOdd(int i) { (i % 1 == 0) ? even() : odd(); } // Two methods with different return types, valid public void oneOfTwoMethodsWithDifferentReturnTypes(boolean b) { b ? methodReturningObject() : methodReturningVoid(); } Examples that fail to compile: // Invalid because operands are not valid StatementExpressions public void invalid1() { b ? 1 : 2; } // Invalid because third operand is not a valid StatementExpression public void invalid2() { b ? method() : null; } DETAILS SPECIFICATION: This change requires two modifications to the Java Language Specification: 1. A ConditionalStatement is added to the specification. A ConditionalStatement takes a boolean expression as its first operand and two StatementExpressions as the second (if-true) and third (if- false) operands: ConditionalStatement Expression ? ConditionalStatementOperand : ConditionalStatementOperand ConditionalStatementOperand ( ConditionalStatementOperand ) StatementExpression There are no restrictions on the output type of the StatementExpression. Any valid statement expression today is valid as an operand of the conditional statement. The conditional statement is right-associative like the conditional expression. 2. The definition of StatementExpression is changed to allow the conditional operator statement as one of its alternatives (this might be better to add to the StatementWithoutTrailingSubstatement block instead): StatementExpression: Assignment PreIncrementExpression PreDecrementExpression PostIncrementExpression PostDecrementExpression MethodInvocation ClassInstanceCreationExpression + ConditionalStatement COMPILATION: The ConditionalStatement may always be desugared to a standard if/else construct: boolean-expression ? statement-expression-1 : statement-expression-2 desugars to: if (boolean-expression) statement-expression-1; else statement-expression-2; TESTING: Add a conditional statement to the files tested during complation. Test that a conditional statement fails to compile when operands are not valid StatementExpressions. LIBRARY SUPPORT: None. REFLECTIVE APIS: No changes. OTHER CHANGES: No changes. MIGRATION: An IDE may offer to automatically simplify if/else constructs with two expression statements: if (condition) { expression-statement-1; } else { expression-statement-2; } to: condition ? expression-statement-1 : expression-statement-2; COMPATIBILITY BREAKING CHANGES: None EXISTING PROGRAMS: No issues. REFERENCES EXISTING BUGS: None found. From brucechapman at paradise.net.nz Sun Mar 29 15:43:23 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Mon, 30 Mar 2009 11:43:23 +1300 (NZDT) Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CF5AF2.8020408@entreact.com> References: <49CF5AF2.8020408@entreact.com> Message-ID: <1238366603.49cff98bc5e2f@www.paradise.net.nz> Quoting Jeroen van Maanen : > I'd like to coin a switch (...) instanceof statement as a new feature of > the Java language. Please accept the attached proposal for review. > > Regards, Jeroen > +1 for this idea. I had thought about writing up something similar but have run out of time. At this stage I'd call your proposal a draft, there is a lot of work to bring it up to the required standard IMHO. A/ Specifically you syntax sugaring is deficient in a number of areas. 1/ there is no enclosing switch, while, do or for around the statemnt, therefor the meaning of any "break" statement in the original switch either changes or becomes invalid. A nasty hack would to to wrap a "do {} while(true);" around the desugaring. 2/ Using "else if" means drop through doesn't work. Drop through in this case is problematic unless <> is a supertype of <>. You need to specify what happens if there is no break. 3/ Your synthetic variable gives surprising results if <> appears on the LHS of an assignment operator, because you will assign to the synthetic variable, not the obvious one. Solutions are to only allow identifiers declared "final" (and make the synthetic variable fine) OR don't use a synthetic variable and instead insert the case everywhere the identifier is used (except on LHS of assignment). It might be better to drop the desugaring from the definition and just explain the semantics. B/ I think it is essential that the meaning of identifier has the case's type inside the statements - you are doing this. C/ The syntax I was thinking of was more like switch(<> instanceof ?) {... which is a little less surprising than yours, since all that is changing is what is inside the parenthesis, not adding something between the parenthesis and braces. D/ For what it is worth, I think we can save 50% of the pain of existing use cases using an API and closures. I did a jug talk on it back in June 2007 See http://jug.wellington.net.nz/presentations/Java_Tidbits.pdf#page=37 for example s of my dream syntax, and how to do it with closures. You might find parts of that presentation useful for the major benefit / major advantage sections. Show people the pain and the amount of "repeating yourself" with the current code. E/ You may well need to address the definite assignment rules since they get tricky around switch statements IIRC. F/ If we are doing String switches in coin, then instanceof seems just as valuable (indeed more valuable when you look at how you need to do it today). Regards Bruce From brucechapman at paradise.net.nz Sun Mar 29 15:47:52 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Mon, 30 Mar 2009 11:47:52 +1300 (NZDT) Subject: Submission: switch (...) instanceof feature In-Reply-To: <1238366603.49cff98bc5e2f@www.paradise.net.nz> References: <49CF5AF2.8020408@entreact.com> <1238366603.49cff98bc5e2f@www.paradise.net.nz> Message-ID: <1238366872.49cffa9879911@www.paradise.net.nz> Quoting myself, who looks like they were sending an SMS message > 3/ Your synthetic variable gives surprising results if <> > appears on > the LHS of an assignment operator, because you will assign to the > synthetic > variable, not the obvious one. Solutions are to only allow identifiers > declared > "final" (and make the synthetic variable fine) OR don't use a synthetic > variable > and instead insert the case everywhere the identifier is used (except on > LHS of > assignment). > should say 3/ Your synthetic variable gives surprising results if <> appears on the LHS of an assignment operator, because you will assign to the synthetic variable, not the obvious one. Solutions are to only allow identifiers declared "final" (and make the synthetic variable final) OR don't use a synthetic variable and instead insert the cast everywhere the identifier is used (except on LHS of assignment). B :) From develop4lasu at gmail.com Sun Mar 29 15:55:20 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 00:55:20 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CF5AF2.8020408@entreact.com> References: <49CF5AF2.8020408@entreact.com> Message-ID: <28bca0ff0903291555h170ae0b8x13335b78e3c8e427@mail.gmail.com> This is death path. As I already said every month you will need switch to more complex operations and Java will be come Pyton. 1. String 2. instance of ... n. Unsigned String n+1. ... This syntax should support all those, and even more: http://lasu2string.blogspot.com/2008/12/string-switch-small-language-changes-on.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Sun Mar 29 15:57:56 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Mon, 30 Mar 2009 11:57:56 +1300 (NZDT) Subject: Mgmt query re Integer Literals Message-ID: <1238367476.49cffcf4e340f@www.paradise.net.nz> Joe, from talking to various people it seems that using underscore as a meaningless separator (as proposed in the binary literals proposal) inside all integer literals would be of great value. Is the coin management sufficiently flexible to say accept all the integer literal proposals for further work then produce a blended proposal, or should I incorporate that feature in my two alternate proposals, or write up another proposal just for the underscore separator? Bruce From develop4lasu at gmail.com Sun Mar 29 16:27:19 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 01:27:19 +0200 Subject: PROPOSAL: Enhanced while statement Message-ID: <28bca0ff0903291627h2433b042sb2d7f42b018451a@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: Enhanced while statement allow to iterate through iterator. MAJOR ADVANTAGE: People will stop working around for-each loop. MAJOR BENEFIT(s):Allow to easy express operation on iterator(s), and iterating over non linear Iterators would be easier. MAJOR DISADVANTAGE: Automatic loop over Iterator my be problem for some peoples. ALTERNATIVES: Using while loop. EXAMPLES SIMPLE EXAMPLE: String toString(Iterator list){ if (!list.hasNext()) return "[]"; StringBuilder ret = new StringBuilder(); ret.append('[').append(list.next()); while (String string : list) { ret.append(',').append(list.next()); } return ret.append(']').toString(); } ADVANCED EXAMPLE: String toString(Iterator list){ while (Transfer t : list) { ArrayList data = new ArrayList(); if ( t.isOpeningTag() ) while (Transfer t : list){ if (t.isClosingTag()) break; data.add(t.getData()); } else { list.remove(); // OK: no interactions throw new Exception("..."); } list.remove(); // warning list here can refer to last element of inner loop // Process chunk } } DETAILS SPECIFICATION: Same as JLS 14.14.2, except: The Expression must either have type Iterator, or a compile-time error occurs. Let I be the type of the expression Expression If Expression is directly field or variable or parameter (ExpressionVariable) then additional checking is performed: If Variable is used as Expression for while-each loop inside while-each loop over same Variable then Variable occurring after inner while-each loop (but in outer while-each loop) will compile with warning ?Variable state refer to inner loop?. COMPILATION: Same as for-each (almost). TESTING: Same as while loops. LIBRARY SUPPORT: None. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: None. COMPATIBILITY Except code, which is only forward compatibility. REFERENCES Enhanced for each loop iteration control -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From akuhn at iam.unibe.ch Sun Mar 29 16:29:28 2009 From: akuhn at iam.unibe.ch (Adrian Kuhn) Date: Mon, 30 Mar 2009 01:29:28 +0200 Subject: Proposal idea - generators Message-ID: <57FE03F2-112F-46A5-BC25-79B08E2DC37A@iam.unibe.ch> Tim Peierls wrote > My sense (bolstered by a quick Google code search) is that people > have been coming up with this kind of functionality on their own as > they encounter a need for it. Is it really something that needs > special language support? Using another thread to do the generation > is quite reasonable. You can build a nice coroutine-style facility > with a pair of SynchronousQueues (or, more generally and flexibly, > with TransferQueues, expected for Java 7; or maybe with Phasers). > Using that as a building block you could then rewrite your example > below as something like this: Language support for generators is a must have! Threads are a workaround only. With proper language support generators can be realized as state machine. See the following article (Jon Skeet to the rescue :) http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx cheers, AA -- Adrian Kuhn Software Composition Group University of Bern, Switzerland http://www.iam.unibe.ch/~akuhn From forax at univ-mlv.fr Sun Mar 29 16:45:52 2009 From: forax at univ-mlv.fr (=?UTF-8?B?UsOpbWkgRm9yYXg=?=) Date: Mon, 30 Mar 2009 01:45:52 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <28bca0ff0903291422s77f11c44j4ddf6ea45ec0b669@mail.gmail.com> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> <28bca0ff0903291422s77f11c44j4ddf6ea45ec0b669@mail.gmail.com> Message-ID: <49D00830.30604@univ-mlv.fr> I have a mixed feeling about this feature but a long time ago, i've written blog entry about that with a link to a prototype, see http://weblogs.java.net/blog/forax/archive/2006/12/call_me_santa.html The prototype use ':=' instead of 'final. R?mi From shams.mahmood at gmail.com Sun Mar 29 17:12:15 2009 From: shams.mahmood at gmail.com (Shams Mahmood) Date: Sun, 29 Mar 2009 17:12:15 -0700 (PDT) Subject: Proposal: Indexing access syntax for Lists and Maps Message-ID: <350193.71588.qm@web36708.mail.mud.yahoo.com> Indexing access syntax for Lists and Maps VERSION This is version 1.0. AUTHOR(S): Shams Mahmood Imam OVERVIEW FEATURE SUMMARY: Collection classes are among the most frequently used in the Java SDK. Currently Lists and Maps do not provide any additional language feature to access individual elements unlike Arrays. This proposal aims to provide these Collection citizens of java additional language support to access elements like Arrays have currently. MAJOR ADVANTAGE: Will provide a consistent syntax for accessing elements of Arrays, Lists and Maps. In addition, the language grammar will not change much since the subscript operator is already supported for Arrays. MAJOR BENEFIT: Apart from the consistency mentioned above, implementation fo this feature will result in fewer characters needed to be typed to achieve simple access to elements in Maps/Lists. MAJOR DISADVANTAGE: Like the for-each loop construct, it will expose the client to NullPointerException(NPE)s when used with a null List/Map. However, this shouldn't be such a major issue as NPEs are also generated by arrays when the operator is used in a null array. ALTERNATIVES: The comparatively more verbose get/set methods for Lists and get/put methods for Maps. EXAMPLES SIMPLE EXAMPLE: public class Main { public static void main(String[] arguments) { List l1 = Arrays.asList(new String[] {"a", "b", "c"}); String firstElement = l1[0]; Map m1 = new HashMap(4); m1[Integer.valueOf(1)] = "One"; } } ADVANCED EXAMPLE: public class Main { public static void main(String[] arguments) { List l1 = Arrays.asList(new String[] {"a", "b", "c"}); Map m1 = new HashMap(4); Map m2 = new HashMap(4); m2[l1[2]] = m2[m1[1]] = 4; // same as m2.put(l1.get(2), m2.put(m1.get(1), 4)); } } DETAILS SPECIFICATION: Java Language Specification changes: 15.29 (NEW CHAPTER): Collection Access Expressions A collection access expression contains two subexpressions, the List/Map reference expression (before the left bracket) and the index expression (within the brackets). Note that the List/Map reference expression may be a name or any expression that evaluates to a List/Map. The index experssion is expected to evaluate to an int for Lists and a valid key type for Maps. CollectionAccess: Expression [ Expression ] 15.8 Primary Expressions original: --------- PrimaryNoNewArray: Literal Type . class void . class this ClassName.this ( Expression ) ClassInstanceCreationExpression FieldAccess MethodInvocation ArrayAccess replaced with: -------------- PrimaryNoNewArray: Literal Type . class void . class this ClassName.this ( Expression ) ClassInstanceCreationExpression FieldAccess MethodInvocation ArrayAccess CollectionAccess 15.26 Assignment Operators original: --------- LeftHandSide: ExpressionName FieldAccess ArrayAccess replaced with: -------------- LeftHandSide: ExpressionName FieldAccess ArrayAccess CollectionAccess COMPILATION: After successful creation of the AST handling the additional grammar for Collection Access expressions, the syntactic sugar will be replaced by JDK1.4 compatible code during the Code Generation phase. This is consistent with how JDK5.0 constructs like the for-each loop is handled by the compiler. e.g. public class TestConcise { public static void main(String[] args) { java.util.Map m1 = new java.util.HashMap(); m1[2] = "two"; java.util.LinkedList l1 = java.util.Arrays.asList( new String[] {"a", "b", "c" }); m1[3] = l1[2]; l1[0] = m1[0]; l1[1] = "one"; } } is converted to public class TestConcise { public TestConcise() { super(); } public static void main(String[] args) { java.util.Map m1 = new java.util.HashMap(); m1.put(Integer.valueOf(2), "two"); java.util.LinkedList l1 = java.util.Arrays.asList( new String[] {"a", "b", "c" }); m1.put(Integer.valueOf(3), l1.get(2)); l1.set(0, m1.get(Integer.valueOf(0))); l1.set(1, "one"); } } TESTING: LIBRARY SUPPORT: No additional library support is needed. REFLECTIVE APIS: This proposal does not require any reflective API changes. OTHER CHANGES: No changes required. MIGRATION: No migration is needed. COMPATIBILITY BREAKING CHANGES: No breaking changes. EXISTING PROGRAMS: Existing programs are not affected by this change. REFERENCES My Java7 Wishlist regarding Collections, http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html Implementation of My Java7 Wishlist, http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html EXISTING BUGS: None. URL FOR PROTOTYPE (optional): Projects kijaro's concisecollections branch: https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/ From forax at univ-mlv.fr Sun Mar 29 17:34:43 2009 From: forax at univ-mlv.fr (=?windows-1252?Q?R=E9mi_Forax?=) Date: Mon, 30 Mar 2009 02:34:43 +0200 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <15e8b9d20903290055p399a724al786f34b8188a62d2@mail.gmail.com> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> <15e8b9d20903290055p399a724al786f34b8188a62d2@mail.gmail.com> Message-ID: <49D013A3.60505@univ-mlv.fr> John, your proposal doesn't cleanly separate the four parts of the proposal thus this is really hard to read (at 2 am :) Correct me if i'm wrong, the purpose of Dynamic as a type is to 1) be able to do an invokedynamic wich is receiverless using a dot. Dynamic x=... x.m() // is translated to invokedynamic m(Dynamic) 2) to have more conversions from/to Dynamic than from/to Object. Else, I would prefer null not being infered as Void instead the compiler should raise an error and let the user cast it to Object, Dynamic etc. R?mi Neal Gafter a ?crit : > John- > > Could you please send the proposal to this list? > > I don't really understand the intended specification with respect to > Dynamic. It is one the one hand described as an object type (e.g. > section 1.9) but on the other hand it doesn't inherit from Object > (section 1.1). You can't have it both ways. I can't tell, for > example, whether Dynamic is a valid type in a generic type parameter. > If the answer is yes, then it must have Object as a supertype. You > might find it useful to review what C# has done in this area with > their type "dynamic". In short, it occupies the same location in C#'s > type lattice as Object, but it has some additional conversions defined > that are not subtype relationships. > > I don't believe this is a "small change". However, if it is going to > happen anyway in JDK 7 to support jsr292, I can see the sense in > having it dealt with in the same expert group as four or so other > small, local changes. > > Regards, > Neal > > On Sat, Mar 28, 2009 at 11:53 PM, John Rose wrote: > >> Hello, colleagues. Here is a proposal which is linked to JSR 292 >> (invokedynamic). >> >> http://wikis.sun.com/display/mlvm/ProjectCoinProposal >> http://blogs.sun.com/jrose/entry/jsr_292_support_in_javac >> >> Here's the teaser (from my blog): >> >> In order to work with dynamic types, method handles, and invokedynamic >> I have made some provisional changes to javac as part of the Da Vinci >> Machine Project. The mlvm wiki has a full description for Project >> COIN. It is most desirable, of course, to program invokedynamic call >> sites as Java expressions, not just ASM code, and that's what those >> langtools patches are for. >> The essential features are four: >> >> ? The type java.dyn.Dynamic will accept any method call and turn it >> into an invokedynamic instruction, and the full range of such >> instructions can be spelled from Java code. >> ? The type java.dyn.MethodHandle will accept any argument and return >> types for a call to the method named invoke, which means that Java >> code can spell the full range of method handle invocations. >> ? The full range of bytecode names acceptable to the JVM can be >> spelled from Java code, using an exotic identifier quoting syntax. >> ? The type java.dyn.Dynamic serves as a bare reference type: Anything >> implicitly converts to it, and it can be cast to anything, but it is >> not a subtype of java.lang.Object. Its methods, of course, are those >> from point #1, so it is handy for forming invokedynamic calls. >> The rationale is pretty simple: If we put some minimal support into >> Java for defining and using names in other languages, then Java can be >> used as a system programming language for implementing them. >> Otherwise, the system programming language will be assembled bytecode. >> (I like to visit ASM, but don't want to live there.) >> >> Do check out the wiki page; it has the full Project COIN proposal >> format. >> >> Best wishes, >> >> -- John Rose (Da Vinci Machine Project) >> >> >> > > From develop4lasu at gmail.com Sun Mar 29 17:43:29 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 02:43:29 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <49D00830.30604@univ-mlv.fr> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> <28bca0ff0903291422s77f11c44j4ddf6ea45ec0b669@mail.gmail.com> <49D00830.30604@univ-mlv.fr> Message-ID: <28bca0ff0903291743h25704ac2l751bd6f847a34d09@mail.gmail.com> 2009/3/30 R?mi Forax : > I have a mixed feeling about this feature but > a long time ago, i've written blog entry about that with a link to a > prototype, see > http://weblogs.java.net/blog/forax/archive/2006/12/call_me_santa.html > > The prototype use ':=' instead of 'final. > > R?mi > > > Could you specify the problems that you see? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Sun Mar 29 17:47:09 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Mon, 30 Mar 2009 13:47:09 +1300 (NZDT) Subject: Submission: switch (...) instanceof feature In-Reply-To: <28bca0ff0903291555h170ae0b8x13335b78e3c8e427@mail.gmail.com> References: <49CF5AF2.8020408@entreact.com> <28bca0ff0903291555h170ae0b8x13335b78e3c8e427@mail.gmail.com> Message-ID: <1238374029.49d0168d7c12f@www.paradise.net.nz> Quoting Marek Kozie?? : > This is death path. > As I already said every month you will need switch to more complex > operations and Java will be come Pyton. > 1. String > 2. instance of > > ... > > n. Unsigned String WTF? > > n+1. ... > > This syntax should support all those, and even more: It doesn't support the instanceof form because one feature (the most important feature IMHO) is the implicit downcast of the variable to the type specified by the case. It is also different because it is switching on a variable or identifier, not an expression. Personally I think closures gives us a good enough (though by no means ideal) solution to this problem. But there is a decision to make, - do we keep adding special language syntax for all verbose idioms, or do we add a few language features that mean we can solve these problems adequately with an API. The fact that ARM has made the first cut suggests the former, so therefore, given this (IMHO poor) choice, I'd at least like my pet issues to have an opportunity to be dealt with in similar fashion. Bruce > > http://lasu2string.blogspot.com/2008/12/string-switch-small-language-changes-on.html > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie?? > > http://lasu2string.blogspot.com/ > > From shams.mahmood at gmail.com Sun Mar 29 18:07:06 2009 From: shams.mahmood at gmail.com (Shams Mahmood) Date: Sun, 29 Mar 2009 18:07:06 -0700 (PDT) Subject: Proposal: Concise Collection Initialization Syntax Message-ID: <648483.25660.qm@web36703.mail.mud.yahoo.com> Concise Collection Initialization Syntax VERSION This is version 1.0. AUTHOR(S): Shams Mahmood Imam OVERVIEW FEATURE SUMMARY: Collection classes are among the most frequently used in the Java SDK and share common features with Arrays. However, unlike arrays Collections do not have any additional language features for instantiation and populating ( filling elements into the Collection). This proposal aims to provide these Collection citizens of java additional language support to provide a concise syntax for populating them during instantiation. MAJOR ADVANTAGE: Will provide a concise syntax to populate Collections during initialization. MAJOR BENEFIT: New syntax will lead to fewer lines of code to populate Collections easing the use of Collections. MAJOR DISADVANTAGE: The language grammar needs to be extended. ALTERNATIVES: The comparatively more verbose add/set methods for Collection classes and put methods for Maps. EXAMPLES SIMPLE EXAMPLE: public class Main { public static void main(String[] arguments) { List l1 = new LinkedList()["a", "b", "c" ]; } } ADVANCED EXAMPLE: public class TestConcise { public static void main(String[] args) { boolean b = new java.util.LinkedList() ["a", "b", "c" ].add("d"); param(new java.util.ArrayList() { public boolean add(String e) { return super.add(e); } } ["a", "b", "c" ] ); java.util.Map m1 = retMap(); java.util.LinkedList l1 = new java.util.LinkedList()["a", "b", "c" ]; } private static void param( final java.util.Collection coll){ System.out.println(coll); } private static java.util.Map retMap() { return new java.util.HashMap() {} [1:"a", 2:"b", ]; } } DETAILS SPECIFICATION: Java Language Specification changes: 15.XX Collection Instance Creation Expressions ---------------------------------------------- Collection Instance Creation Expressions are similar to Class Instance Creation Expressions except that they can be used to create instances of Collections only and are followed by a mandatory '[ ArgumentList opt ]'. e.g. java.util.LinkedList l1 = new java.util.LinkedList()["a", "b", "c" ]; CollectionInstanceCreationExpression: new TypeArguments opt ClassOrInterfaceType ( ArgumentList opt ) ClassBodyopt [ ArgumentList opt ] Primary. new TypeArguments opt Identifier TypeArguments opt ( ArgumentList opt ) ClassBodyopt [ ArgumentList opt ] ArgumentList: Expression ArgumentList , Expression 15.YY Map Instance Creation Expressions --------------------------------------- Map Instance Creation Expressions are similar to Class Instance Creation Expressions except that they can be used to create instances of Maps only and are followed by a mandatory '[ MapArgumentList opt ]'. Map argument List are individually a pair of colon separated expressions. e.g. java.util.Map m1 = new java.util.HashMap() {} [1:"a", 2:"b", ]; MapInstanceCreationExpression: new TypeArguments opt ClassOrInterfaceType ( ArgumentList opt ) ClassBodyopt [ MapArgumentList opt ] Primary. new TypeArguments opt Identifier TypeArguments opt ( ArgumentList opt ) ClassBodyopt [ MapArgumentList opt ] MapArgumentList: Expression : Expression MapArgumentList , Expression : Expression 15.8 Primary Expressions original: --------- PrimaryNoNewArray: Literal Type . class void . class this ClassName.this ( Expression ) ClassInstanceCreationExpression FieldAccess MethodInvocation ArrayAccess replaced with: -------------- PrimaryNoNewArray: Literal Type . class void . class this ClassName.this ( Expression ) ClassInstanceCreationExpression CollectionInstanceCreationExpression MapInstanceCreationExpression FieldAccess MethodInvocation ArrayAccess COMPILATION: After successful creation of the AST handling the additional grammar for Collection and Map instantiation expressions, the syntactic sugar will be replaced by JDK1.4 compatible code during the Code Generation phase. This is consistent with how JDK5.0 constructs like the for-each loop is handled by the compiler. e.g. public class TestConcise { public static void main(String[] args) { boolean b = new java.util.LinkedList() ["a", "b", "c" ].add("d"); param(new java.util.ArrayList() { public boolean add(String e) { return super.add(e); } } ["a", "b", "c" ] ); java.util.Map m1 = retMap(); java.util.LinkedList l1 = new java.util.LinkedList()["a", "b", "c" ]; } private static void param( final java.util.Collection coll){ System.out.println(coll); } private static java.util.Map retMap() { return new java.util.HashMap() {} [1:"a", 2:"b", ]; } } is converted to: class TestConcise$1 extends java.util.ArrayList { TestConcise$1() { super(); } public boolean add(String e) { return super.add(e); } /*synthetic*/ public boolean add(Object x0) { return this.add((String)x0); } }, class TestConcise$2 extends java.util.HashMap { TestConcise$2() { super(); } }, public class TestConcise { public TestConcise() { super(); } public static void main(String[] args) { boolean b = java.util.CollectionUtil.fillCollection( new java.util.LinkedList(), new String[]{"a", "b", "c"}).add("d"); param(java.util.CollectionUtil.fillCollection( new TestConcise$1(), new String[]{"a", "b", "c"})); java.util.Map m1 = retMap(); java.util.LinkedList l1 = java.util.CollectionUtil.fillCollection( new java.util.LinkedList(), new String[]{"a", "b", "c"}); } private static void param( final java.util.Collection coll) { System.out.println(coll); } private static java.util.Map retMap() { return java.util.CollectionUtil.fillMap( new TestConcise$2(), new Integer[]{Integer.valueOf(1), Integer.valueOf(2)}, new String[]{"a", "b"}); } } TESTING: LIBRARY SUPPORT: Two new utility methods are required to support filling the Collection and Map instances with the following signatures: public static Collection fillCollection(Collection theCol, T[] theEls); public static Map fillCollection(Map theMap, K[] theKeys, V[] theVals); The Collections class is a perfect place to add these methods. REFLECTIVE APIS: This proposal does not require any reflective API changes. OTHER CHANGES: No changes required. MIGRATION: No migration is needed. COMPATIBILITY BREAKING CHANGES: No breaking changes. EXISTING PROGRAMS: Existing programs are not affected by this change. REFERENCES My Java7 Wishlist regarding Collections, http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html Implementation of My Java7 Wishlist, http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html EXISTING BUGS: None. URL FOR PROTOTYPE (optional): Projects kijaro's concisecollections branch: https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/ From neal at gafter.com Sun Mar 29 18:54:27 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Mar 2009 18:54:27 -0700 Subject: PROPOSAL: Conditional Statement In-Reply-To: <7B58F3A4-3880-49C6-A81E-AE0822D07BB3@mastracci.com> References: <7B58F3A4-3880-49C6-A81E-AE0822D07BB3@mastracci.com> Message-ID: <15e8b9d20903291854x165b8d71gf93d7bd14ea783e6@mail.gmail.com> I don't understand the benefit over the existing if statement. On Sun, Mar 29, 2009 at 2:41 PM, Matt Mastracci wrote: > Conditional Statement > ===================== > > Richly formatted version available at: > http://docs.google.com/Doc?id=dgthwhwr_2hs2hknhf > > > AUTHOR(S): Matt Mastracci > > OVERVIEW > > FEATURE SUMMARY: Allows an analogue of the conditional expression to > exist at the statement level, with relaxed restrictions on the type of > its second and third operands. > > MAJOR ADVANTAGE: Ability to use conditional operator for choosing > between two statement-level expressions (ie: two different method > invocations). > > MAJOR BENEFIT: Simplifies code that executes one of two expression > statements given a boolean input. > > MAJOR DISADVANTAGE: Turns the conditional operator into two different > constructs in the Java language with different rules. > > ALTERNATIVES: Continue using if/else (this feature is sugar only). > > See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25 > ?for the definition of the original conditional expression. > > > EXAMPLES > > // even() and odd() are defined as "public void" > public void onEvenOrOdd(int i) { > ? ? (i % 1 == 0) ? even() : odd(); > } > > // Two methods with different return types, valid > public void oneOfTwoMethodsWithDifferentReturnTypes(boolean b) { > ? ? b ? methodReturningObject() : methodReturningVoid(); > } > > > Examples that fail to compile: > > // Invalid because operands are not valid StatementExpressions > public void invalid1() { > ? ? b ? 1 : 2; > } > > // Invalid because third operand is not a valid StatementExpression > public void invalid2() { > ? ? b ? method() : null; > } > > > DETAILS > > SPECIFICATION: This change requires two modifications to the Java > Language Specification: > > 1. ?A ConditionalStatement is added to the specification. ?A > ConditionalStatement takes a boolean expression as its first operand > and two StatementExpressions as the second (if-true) and third (if- > false) operands: > > ConditionalStatement > ? ?Expression ? ConditionalStatementOperand : > ConditionalStatementOperand > > ConditionalStatementOperand > ? ?( ConditionalStatementOperand ) > ? ?StatementExpression > > There are no restrictions on the output type of the > StatementExpression. ?Any valid statement expression today is valid as > an operand of the conditional statement. > > The conditional statement is right-associative like the conditional > expression. > > > 2. ?The definition of StatementExpression is changed to allow the > conditional operator statement as one of its alternatives (this might > be better to add to the StatementWithoutTrailingSubstatement block > instead): > > ?StatementExpression: > ? ? ? ? ?Assignment > ? ? ? ? ?PreIncrementExpression > ? ? ? ? ?PreDecrementExpression > ? ? ? ? ?PostIncrementExpression > ? ? ? ? ?PostDecrementExpression > ? ? ? ? ?MethodInvocation > ? ? ? ? ?ClassInstanceCreationExpression > + ? ? ? ?ConditionalStatement > > COMPILATION: The ConditionalStatement may always be desugared to a > standard if/else construct: > > boolean-expression ? statement-expression-1 : statement-expression-2 > > desugars to: > > if (boolean-expression) > ? statement-expression-1; > else > ? statement-expression-2; > > > TESTING: Add a conditional statement to the files tested during > complation. ?Test that a conditional statement fails to compile when > operands are not valid StatementExpressions. > > LIBRARY SUPPORT: None. > > REFLECTIVE APIS: No changes. > > OTHER CHANGES: No changes. > > MIGRATION: > > An IDE may offer to automatically simplify if/else constructs with two > expression statements: > > if (condition) { > ? ? ?expression-statement-1; > } else { > ? ? ?expression-statement-2; > } > > to: > > condition ? expression-statement-1 : expression-statement-2; > > > COMPATIBILITY > > BREAKING CHANGES: None > EXISTING PROGRAMS: No issues. > > > REFERENCES > > EXISTING BUGS: None found. > > > > From matthew at mastracci.com Sun Mar 29 19:11:16 2009 From: matthew at mastracci.com (Matt Mastracci) Date: Sun, 29 Mar 2009 20:11:16 -0600 Subject: PROPOSAL: Conditional Statement In-Reply-To: <15e8b9d20903291854x165b8d71gf93d7bd14ea783e6@mail.gmail.com> References: <7B58F3A4-3880-49C6-A81E-AE0822D07BB3@mastracci.com> <15e8b9d20903291854x165b8d71gf93d7bd14ea783e6@mail.gmail.com> Message-ID: Neal, There are a number of small benefits, IMHO: 1. The conditional syntax takes up a single line for simple choice, vs. 3 or 5 lines (depending on whether your IDE inserts braces for simple if statements) using the normal if syntax. This makes it easier to scan source, but doesn't decrease readability. 2. When changing the return value of a function that uses conditionals from int to void, you currently have to expand the conditional out or assign the value to an unused temporary: public int foo() { return flag ? bar() : baz(); } Old refactorings: public void foo() { if (flag) { bar(); } else { baz(); } } @SuppressWarnings("unused") public void foo() { int unused = flag ? bar() : baz(); } New refactoring: public void foo() { flag ? bar() : baz(); } 3. Consistency with the conditional expression. There's no way to take advantage of the conditional operator for functions with void return types. By creating a construct where this is possible, it makes the language more consistent. On 29-Mar-09, at 7:54 PM, Neal Gafter wrote: > I don't understand the benefit over the existing if statement. > > On Sun, Mar 29, 2009 at 2:41 PM, Matt Mastracci > wrote: >> Conditional Statement >> ===================== >> >> Richly formatted version available at: >> http://docs.google.com/Doc?id=dgthwhwr_2hs2hknhf >> >> >> AUTHOR(S): Matt Mastracci >> >> OVERVIEW >> >> FEATURE SUMMARY: Allows an analogue of the conditional expression to >> exist at the statement level, with relaxed restrictions on the type >> of >> its second and third operands. >> >> MAJOR ADVANTAGE: Ability to use conditional operator for choosing >> between two statement-level expressions (ie: two different method >> invocations). >> >> MAJOR BENEFIT: Simplifies code that executes one of two expression >> statements given a boolean input. >> >> MAJOR DISADVANTAGE: Turns the conditional operator into two different >> constructs in the Java language with different rules. >> >> ALTERNATIVES: Continue using if/else (this feature is sugar only). >> >> See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25 >> for the definition of the original conditional expression. >> >> >> EXAMPLES >> >> // even() and odd() are defined as "public void" >> public void onEvenOrOdd(int i) { >> (i % 1 == 0) ? even() : odd(); >> } >> >> // Two methods with different return types, valid >> public void oneOfTwoMethodsWithDifferentReturnTypes(boolean b) { >> b ? methodReturningObject() : methodReturningVoid(); >> } >> >> >> Examples that fail to compile: >> >> // Invalid because operands are not valid StatementExpressions >> public void invalid1() { >> b ? 1 : 2; >> } >> >> // Invalid because third operand is not a valid StatementExpression >> public void invalid2() { >> b ? method() : null; >> } >> >> >> DETAILS >> >> SPECIFICATION: This change requires two modifications to the Java >> Language Specification: >> >> 1. A ConditionalStatement is added to the specification. A >> ConditionalStatement takes a boolean expression as its first operand >> and two StatementExpressions as the second (if-true) and third (if- >> false) operands: >> >> ConditionalStatement >> Expression ? ConditionalStatementOperand : >> ConditionalStatementOperand >> >> ConditionalStatementOperand >> ( ConditionalStatementOperand ) >> StatementExpression >> >> There are no restrictions on the output type of the >> StatementExpression. Any valid statement expression today is valid >> as >> an operand of the conditional statement. >> >> The conditional statement is right-associative like the conditional >> expression. >> >> >> 2. The definition of StatementExpression is changed to allow the >> conditional operator statement as one of its alternatives (this might >> be better to add to the StatementWithoutTrailingSubstatement block >> instead): >> >> StatementExpression: >> Assignment >> PreIncrementExpression >> PreDecrementExpression >> PostIncrementExpression >> PostDecrementExpression >> MethodInvocation >> ClassInstanceCreationExpression >> + ConditionalStatement >> >> COMPILATION: The ConditionalStatement may always be desugared to a >> standard if/else construct: >> >> boolean-expression ? statement-expression-1 : statement-expression-2 >> >> desugars to: >> >> if (boolean-expression) >> statement-expression-1; >> else >> statement-expression-2; >> >> >> TESTING: Add a conditional statement to the files tested during >> complation. Test that a conditional statement fails to compile when >> operands are not valid StatementExpressions. >> >> LIBRARY SUPPORT: None. >> >> REFLECTIVE APIS: No changes. >> >> OTHER CHANGES: No changes. >> >> MIGRATION: >> >> An IDE may offer to automatically simplify if/else constructs with >> two >> expression statements: >> >> if (condition) { >> expression-statement-1; >> } else { >> expression-statement-2; >> } >> >> to: >> >> condition ? expression-statement-1 : expression-statement-2; >> >> >> COMPATIBILITY >> >> BREAKING CHANGES: None >> EXISTING PROGRAMS: No issues. >> >> >> REFERENCES >> >> EXISTING BUGS: None found. >> >> >> >> From glenn.a.marshall at gmail.com Sun Mar 29 19:12:09 2009 From: glenn.a.marshall at gmail.com (Glenn A.P. Marshall) Date: Sun, 29 Mar 2009 22:12:09 -0400 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration Message-ID: PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Glenn Marshall *OVERVIEW FEATURE SUMMARY: Make open and close brace optional for single statement try, catch, finally, method declaration. (the relatively rarely used single statement static initializer would still require braces under this proposal, due to its relative rarity). MAJOR ADVANTAGE: Simple, single statement try blocks, catch blocks, and single statement methods (for example, getter methods) are very common in Java code. Unlike if, while and do statements, the open and close braces are mandatory even when the target of the keyword is a single statement. This requirement needlessly clutters the code with unneeded open and close braces, increases code complexity slightly and decreases readability. Removing this requirement addresses a syntactic inconsistency in Java, whereby braces are required for some single statement keyword targets but not others. MAJOR BENEFIT: More readable code, needless syntactic 'noise' removed, consistent treatment of common single statement keyword targets. Since single statement try, catch, method are very common, these benefits could be applied many times to a typical large Java program. MAJOR DISADVANTAGE: Implementation cost is not 0. Benefits are relatively minor, to be fair, per instance. Single statement keyword targets still exist - static initializers; the syntax is still not 100% consistent as regards single statement keyword targets. ALTERNATIVES: None. * EXAMPLES SIMPLE EXAMPLE: try connection.close(); catch (SQLException se) handleException("close failed", se); ... public String getName() return name; ADVANCED EXAMPLE: (this proposal is very simple; there are no advanced examples) *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. The grammar would be modified to make braces optional for single statement try, catch, finally, method declarations. The block still exists, when braces are omitted; it is a single statement. This is exactly analogous to (for example) single statement while statements without braces. This is purely a syntactic change - the type system, meaning of expressions and statements remain unchanged. COMPILATION: How would the feature be compiled to class files? The simplest implementation would be for the Java source code parser to recognize when the braces have been omitted and add them back, internally, conceptually. This eliminates any downstream impact. TESTING: How can the feature be tested? Extend the source code samples processed by the compiler test suite to include samples of code using this feature. Remember to handle the null statement. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No. 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 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. MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. Look for sequences of if try { ; } and replace with try . Also for catch, method definitions, finally. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. All existing programs remain valid. 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 semantics of existing class files are unchanged. Source code that previously omitted these required braces would not compile due to a syntax error; this source will now compile. Compiler test cases that tested this behaviour, expecting to fail, will now pass. * REFERENCES EXISTING BUGS: (none found) URL FOR PROTOTYPE (optional): No prototype at this time. From neal at gafter.com Sun Mar 29 19:27:44 2009 From: neal at gafter.com (Neal Gafter) Date: Sun, 29 Mar 2009 19:27:44 -0700 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration Message-ID: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> The proposed syntax is ambiguous. If one writes try try stmt; catch(...) stmt; catch(...) stmt; finally stmt; To which try statement is the second catch block attached? Please provide an unambiguous syntactic grammar if you still would like your proposal evaluated. Regards, Neal -----Original Message----- From: Glenn A.P.Marshall Sent: Sunday, March 29, 2009 7:12 PM To: coin-dev at openjdk.java.net Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Glenn Marshall *OVERVIEW FEATURE SUMMARY: Make open and close brace optional for single statement try, catch, finally, method declaration. (the relatively rarely used single statement static initializer would still require braces under this proposal, due to its relative rarity). MAJOR ADVANTAGE: Simple, single statement try blocks, catch blocks, and single statement methods (for example, getter methods) are very common in Java code. Unlike if, while and do statements, the open and close braces are mandatory even when the target of the keyword is a single statement. This requirement needlessly clutters the code with unneeded open and close braces, increases code complexity slightly and decreases readability. Removing this requirement addresses a syntactic inconsistency in Java, whereby braces are required for some single statement keyword targets but not others. MAJOR BENEFIT: More readable code, needless syntactic 'noise' removed, consistent treatment of common single statement keyword targets. Since single statement try, catch, method are very common, these benefits could be applied many times to a typical large Java program. MAJOR DISADVANTAGE: Implementation cost is not 0. Benefits are relatively minor, to be fair, per instance. Single statement keyword targets still exist - static initializers; the syntax is still not 100% consistent as regards single statement keyword targets. ALTERNATIVES: None. * EXAMPLES SIMPLE EXAMPLE: try connection.close(); catch (SQLException se) handleException("close failed", se); ... public String getName() return name; ADVANCED EXAMPLE: (this proposal is very simple; there are no advanced examples) *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. The grammar would be modified to make braces optional for single statement try, catch, finally, method declarations. The block still exists, when braces are omitted; it is a single statement. This is exactly analogous to (for example) single statement while statements without braces. This is purely a syntactic change - the type system, meaning of expressions and statements remain unchanged. COMPILATION: How would the feature be compiled to class files? The simplest implementation would be for the Java source code parser to recognize when the braces have been omitted and add them back, internally, conceptually. This eliminates any downstream impact. TESTING: How can the feature be tested? Extend the source code samples processed by the compiler test suite to include samples of code using this feature. Remember to handle the null statement. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No. 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 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. MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. Look for sequences of if try { ; } and replace with try . Also for catch, method definitions, finally. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. All existing programs remain valid. 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 semantics of existing class files are unchanged. Source code that previously omitted these required braces would not compile due to a syntax error; this source will now compile. Compiler test cases that tested this behaviour, expecting to fail, will now pass. * REFERENCES EXISTING BUGS: (none found) URL FOR PROTOTYPE (optional): No prototype at this time. From vapor1 at teleport.com Sun Mar 29 20:13:45 2009 From: vapor1 at teleport.com (Derek Foster) Date: Sun, 29 Mar 2009 23:13:45 -0400 (EDT) Subject: PROPOSAL: abstract enums Message-ID: <25275917.1238382825309.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> AUTHOR: Derek Foster OVERVIEW The Java Enumerated type feature is unlike similar features in any other language which preceded it. In prior languages, an enumerated type was simply a collection of integer constants. In contrast, Java's enumerated type is a rich datatype that has more in common with classes than it has with a simple constants. Enumerated types can contain complex data, as well as methods to operate on that data. Individual enumerators may be subclasses of the enumeration class that contains them, and may override methods to provide enumerator-specific behavior. Unfortunately, there is one striking difference between Java's enumerations and classes that can become a significant inconvenience: While classes allow use of a superclass to hold data and methods which are shared between a variety of subclasses, Java enumerations have no such feature. In particular, every Java enumerated type must explicitly specify all of its data and methods that are not inherited from the base class Enum. If there are a number of enumerations that share related behavior, each enumeration must specify it redundantly. The only way to share behavior between these enumerations is to manually implement use delegation. For instance, imagine a system in which enumerations are used to access columns of tables in a relational database. There might be one enumeration for each table, and the enumerators of each type might represent the columns in that table. Presumably, each enumerator would contain the name of the table, as well as the name of a specific column, and perhaps other metadata, such as access privileges. It would seem natural to model such a system like this: enum Access { PUBLIC, PRIVATE }; /** * This holds the shared definition of what it means * to be a database table column identifier */ abstract enum TableColumnDef { private String tableName; private String columnName; private Access access; protected DatabaseEnum(String tablename, String columnName, Access access) { this.tableName = tableName; this.columnName = columnName; this.access = access; } public String getTableName() { return tableName; } public String getColumnName() { return columnName; } public Access getAccess() { return access; } @Override final String toString() { return tableName + "." + columnName; } } /** A specific table */ enum PersonTable extends TableColumnDef { NAME_COLUMN("Name", Access.PUBLIC), AGE_COLUMN("Age", Access.PRIVATE), WEIGHT_COLUMN("Weight", ACCESS.PUBLIC); private PersonTable(String columnName, Access access) { super("PersonTable", columnName, access); } } /** Another specific table */ enum PetTable extends TableColumnDef { PETNAME_COLUMN("PetName", Access.PUBLIC), SPECIES_COLUMN("Species", Access.PUBLIC); private PersonTable(String columnName, Access access) { super("PetTable", columnName, access); } } However, this cannot be done in Java, because inheritance is not supported for enumerated types. The closest equivalent is to model the system something like this, using delegation instead of inheritance: class TableEnumGuts { private String tableName; private String columnName; private Access access; protected DatabaseEnum(String tablename, String columnName, Access access) { this.tableName = tableName; this.columnName = columnName; this.access = access; } public String getTableName() { return tableName; } public String getColumnName() { return columnName; } public Access getAccess() { return access; } @Override final String toString() { return tableName + "." + columnName; } } enum PersonTable { NAME_COLUMN("Name"), AGE_COLUMN("Age"), WEIGHT_COLUMN("Weight"); private TableEnumGuts guts; private PersonTable(String columnName, Access access) { guts = new TableEnumGuts("PersonTable", columnName, access); } public String getTableName() { return guts.getTableName(); } public String getColumnName() { return guts.getColumnName(); } public Access getAccess() { return guts.getAccess(); } @Override final String toString() { return guts.toString(); } } enum PetTable extends TableEnum { PETNAME_COLUMN("PetName"), SPECIES_COLUMN("Species"); private TableEnumGuts guts; private PersonTable(String columnName) { guts = new TableEnumGuts("PersonTable", columnName, access); } public String getTableName() { return guts.getTableName(); } public String getColumnName() { return guts.getColumnName(); } public Access getAccess() { return guts.getAccess(); } @Override final String toString() { return guts.toString(); } } Note how much more code (and worst of all, boilerplate duplicate code) is required in the second example, since each enumerated type must provide forwarding methods for each method in the 'TableEnumGuts' class. In one example that the author of this proposal was forced to deal with, there were 30 such enumerated types which conceptually extended the same base class, each of which had to implement that conceptual inheritance by delegating four or so methods to an internal "guts" object. This meant that any time time the signature of any of those four methods had to be changed, the change had to take place in 30 different forwarding methods. In another case (working for a different company) there were 10 such methods, duplicated over four conceptual subclasses, with similar problems. The alternative to delegation is, of course, to duplicate code in each enumerated type. This sort of "cut and paste programming" introduces its own maintenance problems. This proposal attempts to define the semantics of abstract enumerated types, and what it means for an enumerated type to have a supertype, so as to allow code similar to the first example to work as expected in a Java compiler. FEATURE SUMMARY: Defines the meaning of inheritance from abstract supertypes for enumerated types. Note that this proposal specifically does not allow abstract enumerated types to have enumerators, since the semantics of these create difficult problems with inheritance (and open, in the words of one evaluator to a Sun bug submission, "a can of worms"). MAJOR ADVANTAGE: Eliminates a missing feature between java enumerations and java classes, and restores a feature of the "typesafe enumeration" pattern that is not supported by Java enumerations as they are currently implemented. MAJOR BENEFIT: Elimination of duplicate code when related enumerated types need to be declared. Allows subclassing within enumeration types. Eases maintenance of families of enumerated types. MAJOR DISADVANTAGE: There will be some work in the compiler necessary to implement this feature. ALTERNATIVES: Note the delegation workaround being used above. This allows subtypes to share code, but results in potentially large numbers of forwarding methods and difficulties with code maintenance. EXAMPLES SIMPLE EXAMPLE: abstract enum SuperEnum { int getTheAnswerToTheUltimateQuestion() { return 42; } } enum MyEnum extends SuperEnum { MY_ENUMERATOR; } class DeepThought { Object returnTheAnswer() { return MY_ENUMERATOR.getTheAnswerToTheUltimateQuestion(); } } ADVANCED EXAMPLE: abstract enum Base1 { protected final int sharedData; public int getSharedData() {return sharedData;} protected Base1(int sharedData) { this.sharedData = sharedData; } } abstract enum Base2 extends Base1 { protected final int otherSharedData; public int getOtherSharedData() {return sharedData;} protected Base2(int sharedData, int otherSharedData) { super(sharedData); this.otherSharedData = sharedData; } } enum Instances extends Base2 { INSTANCE1(10, 100), INSTANCE2(20, 200), INSTANCE3(30, 300) { public int getSharedData() { return 40; } } private Instances(int sharedData, int otherSharedData) { super(sharedData, otherSharedData); } } class AClient { void someFunc() { assert INSTANCE1.getSharedData()==10; assert INSTANCE2.getSharedData()==20; assert INSTANCE3.getSharedData()==40; Instances[] values = instances.values(); // OK Instances value = Instances.valueOf("INSTANCE1")); // OK Base2[] values2 = Base2.values(); // COMPILER ERROR: No such method. Base2 value2 = Base2.valueOf("INSTANCE1"); // COMPILER ERROR: No such method. } } DETAILS SPECIFICATION: A concept of an "abstract enum" shall be added to the Java language, denoted by prepending the word "abstract" to an enumerated type declaration, with restrictions as described below. Rule 1: An enumerated type (abstract or not) shall either declare no supertype, or shall declare a supertype which is an abstract enumerated type. Rule 2: It shall be a compile-time error for an ordinary class to extend an enumerated type, either abstract or not. Rule 3: Both abstract and non-abstract enumerated types implicitly have a supertype (not necessarily a direct supertype) of Enum>. Thus, within the body of an abstract enumerated type, access to methods of this supertype (ordinal(), name(), etc.) is allowed. Rule 4: Abstract enumerated types shall not declare enumerators. The body of an abstract enumerated type shall be syntactically and semantically the same as that of an ordinary abstract class which extends its declared supertype (as per the COMPILATION section below), except with the restriction that all constructors must be declared 'protected'. Rule 5: The compiler shall not generate the methods that it would automatically generate for a non-abstract enumerated type, such as the "values()" or "valueOf(String)" methods, for an abstract enumerated type. COMPILATION: An abstract enumerated type with no declared supertype, such as: abstract enum Foo { ... } shall be desugared to code resembling: abstract class Foo> extends Enum { ... } An abstract or non-abstract enumerated type with a declared supertype which is an abstract enumerated type, such as: abstract enum Foo extends Bar { ... } shall be desugared to code resembling: abstract class Foo> extends Bar { ... } The Java compiler currently generates certain methods, such as values() and valueOf(String) for enumerated types. It shall not generate these for abstract enumerated types. SIMPLE EXAMPLE: These classes might be desugared to: abstract class SuperEnum> extends Enum { int getTheAnswerToTheUltimateQuestion() { return 42; } } class MyEnum extends SuperEnum { // The body of this non-abstract enumerated type, // including generated methods, is exactly // the same as the Java compiler would generate // prior to this proposal. However, note that due to // this proposal, it has a supertype of "SuperEnum" // instead of "Enum". } ADVANCED EXAMPLE: These classes might be desugared to: abstract class Base1> extends Enum { protected final int sharedData; public int getSharedData() {return sharedData;} protected Base1(int sharedData) { this.sharedData = sharedData; } } abstract class Base2> extends Base1 { protected final int otherSharedData; public int getOtherSharedData() {return sharedData;} protected Base2(int sharedData, int otherSharedData) { super(sharedData); this.otherSharedData = sharedData; } } class Instances extends Base2 { // The body of this non-abstract enumerated type, // including generated methods, is exactly // the same as the Java compiler would generate // prior to this proposal. However, note that due to // this proposal, it has a supertype of "Base2" // instead of "Enum". } TESTING: Testing can be accomplished by declaring various abstract enumerated types, having them extend each other, and having non-abstract enumerated types extend them. Normal inheritance relations (method overriding, etc.) should exist among the resulting types. LIBRARY SUPPORT: No changes to supporting libraries are needed. REFLECTIVE APIS: The "Class.isEnum()" method might need to be adjusted to detect abstract enums as well as non-abstract ones. Note, however, that anonymous classes extending enumeration types are not considered enum types according to this method, so it is an open question as to whether abstract enumerated types should return 'true' or 'false' for this method. (I am leaning towards it returning 'false') OTHER CHANGES: Javadoc might possibly need to be updated to handle the possibility of an abstract enumerated type. MIGRATION: New abstract enumerated types can be created, as desired, to do code sharing between existing non-abstract enumerated types in an existing code base. COMPATIBILITY BREAKING CHANGES: Since this syntax was previously considered a syntax error, no previously valid programs will be invalidated by it. EXISTING PROGRAMS: This feature should not change the semantics of existing class files. The features being added should desugar to normal method calls, class declarations, etc. Hence, I do not anticipate problems interacting with existing class files. REFERENCES EXISTING BUGS: Add language support for abstract Enum's http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6507006 allow "abstract enum AbstractEnum" and "enum MyEnum extends AbstractEnum" http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6222244 Support for public abstract enum declaration http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766 (The original enum proposal, the comments for which allude to the possibility of abstract enums) Bug ID: 4401321 Add type-safe enums to Java http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4401321 URL FOR PROTOTYPE (optional): None. From Joe.Darcy at Sun.COM Sun Mar 29 20:18:47 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Mar 2009 20:18:47 -0700 Subject: PROPOSAL: Conditional Statement In-Reply-To: References: <7B58F3A4-3880-49C6-A81E-AE0822D07BB3@mastracci.com> <15e8b9d20903291854x165b8d71gf93d7bd14ea783e6@mail.gmail.com> Message-ID: <49D03A17.4060304@sun.com> Matt Mastracci wrote: > Neal, > > There are a number of small benefits, IMHO: > > 1. The conditional syntax takes up a single line for simple choice, > vs. 3 or 5 lines (depending on whether your IDE inserts braces for > simple if statements) using the normal if syntax. This makes it > easier to scan source, but doesn't decrease readability. > > 2. When changing the return value of a function that uses > conditionals from int to void, you currently have to expand the > conditional out or assign the value to an unused temporary: > > public int foo() { > return flag ? bar() : baz(); > } > > Old refactorings: > > public void foo() { > if (flag) { > bar(); > } else { > baz(); > } > } > > @SuppressWarnings("unused") > public void foo() { > int unused = flag ? bar() : baz(); > } > > New refactoring: > > public void foo() { > flag ? bar() : baz(); > } > > 3. Consistency with the conditional expression. There's no way to > take advantage of the conditional operator for functions with void > return types. By creating a construct where this is possible, it > makes the language more consistent. > I don't find these benefits to be sufficiently large to warrant adding a new statement form. -Joe From Joe.Darcy at Sun.COM Sun Mar 29 20:54:08 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Mar 2009 20:54:08 -0700 Subject: PROPOSAL: abstract enums In-Reply-To: <25275917.1238382825309.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <25275917.1238382825309.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <49D04260.2010001@sun.com> Derek Foster wrote: > AUTHOR: Derek Foster > > OVERVIEW > > The Java Enumerated type feature is unlike similar features in any other language which preceded it. In prior languages, an enumerated type was simply a collection of integer constants. In contrast, Java's enumerated type is a rich datatype that has more in common with classes than it has with a simple constants. Enumerated types can contain complex data, as well as methods to operate on that data. Individual enumerators may be subclasses of the enumeration class that contains them, and may override methods to provide enumerator-specific behavior. > > [snip] > OTHER CHANGES: > > Javadoc might possibly need to be updated to handle the possibility of an abstract enumerated type. > > This proposal is incomplete. There are many other possible impacts of this change, including serialization; see "So you want to change the Java Programming Language..." http://blogs.sun.com/darcy/entry/so_you_want_to_change for an account of all the aspects of the system adding regular enums involved. Of the extensible and non-extensible version of enum pattern, the JSR 201 expert group chose the non-extensible variant and many other decisions and details of the original enum design flow from that fundamental decision. Revisiting that decision now is impractical. Additionally, some of the advantages of extensible enums can be had by making different enum classes implement a common interface; for some discussion of that general pattern see "Mixing-in an Enum" http://blogs.sun.com/darcy/entry/enums_and_mixins as well as an item in the 2nd edition of "Effective Java." -Joe From tim.keith at gmail.com Sun Mar 29 22:40:31 2009 From: tim.keith at gmail.com (Tim Keith) Date: Sun, 29 Mar 2009 22:40:31 -0700 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <350193.71588.qm@web36708.mail.mud.yahoo.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> Message-ID: Is it possible to include Set as well? E.g. "bool = set[x]" meaning "bool = set.contains(x)" and "set[x] = bool" meaning "bool ? set.add(x) : set.remove(x)" -- Tim On Sun, Mar 29, 2009 at 5:12 PM, Shams Mahmood wrote: > Indexing access syntax for Lists and Maps > > VERSION > This is version 1.0. > > AUTHOR(S): > Shams Mahmood Imam > > OVERVIEW > > FEATURE SUMMARY: > Collection classes are among the most frequently used in the Java SDK. > Currently Lists and Maps do not provide any additional language > feature to access individual elements unlike Arrays. This proposal > aims to provide these Collection citizens of java additional > language support to access elements like Arrays have currently. > > MAJOR ADVANTAGE: > Will provide a consistent syntax for accessing elements of Arrays, > Lists and Maps. In addition, the language grammar will not change > much since the subscript operator is already supported for Arrays. > > MAJOR BENEFIT: > Apart from the consistency mentioned above, implementation fo this > feature will result in fewer characters needed to be typed to achieve > simple access to elements in Maps/Lists. > > MAJOR DISADVANTAGE: > Like the for-each loop construct, it will expose the client to > NullPointerException(NPE)s when used with a null List/Map. However, > this shouldn't be such a major issue as NPEs are also generated > by arrays when the operator is used in a null array. > > ALTERNATIVES: > The comparatively more verbose get/set methods for Lists and get/put > methods for Maps. > > EXAMPLES > > SIMPLE EXAMPLE: > > public class Main { > public static void main(String[] arguments) { > List l1 = Arrays.asList(new String[] {"a", "b", "c"}); > String firstElement = l1[0]; > Map m1 = new HashMap(4); > m1[Integer.valueOf(1)] = "One"; > } > } > > ADVANCED EXAMPLE: > > public class Main { > public static void main(String[] arguments) { > List l1 = Arrays.asList(new String[] {"a", "b", "c"}); > Map m1 = new HashMap(4); > Map m2 = new HashMap(4); > > m2[l1[2]] = m2[m1[1]] = 4; // same as m2.put(l1.get(2), > m2.put(m1.get(1), 4)); > } > } > > DETAILS > > SPECIFICATION: > Java Language Specification changes: > > 15.29 (NEW CHAPTER): Collection Access Expressions > A collection access expression contains two subexpressions, the List/Map > reference expression (before the left bracket) and the index expression > (within the brackets). Note that the List/Map reference expression may be a > name or any expression that evaluates to a List/Map. The index experssion is > expected to evaluate to an int for Lists and a valid key type for Maps. > > CollectionAccess: > Expression [ Expression ] > > 15.8 Primary Expressions > original: > --------- > PrimaryNoNewArray: > Literal > Type . class > void . class > this > ClassName.this > ( Expression ) > ClassInstanceCreationExpression > FieldAccess > MethodInvocation > ArrayAccess > > replaced with: > -------------- > PrimaryNoNewArray: > Literal > Type . class > void . class > this > ClassName.this > ( Expression ) > ClassInstanceCreationExpression > FieldAccess > MethodInvocation > ArrayAccess > CollectionAccess > > 15.26 Assignment Operators > original: > --------- > LeftHandSide: > ExpressionName > FieldAccess > ArrayAccess > > replaced with: > -------------- > LeftHandSide: > ExpressionName > FieldAccess > ArrayAccess > CollectionAccess > > > COMPILATION: > > After successful creation of the AST handling the additional grammar for > Collection Access expressions, the syntactic sugar will be replaced by > JDK1.4 compatible code during the Code Generation phase. This is consistent > with how JDK5.0 constructs like the for-each loop is handled by the > compiler. > > e.g. > public class TestConcise { > public static void main(String[] args) { > java.util.Map m1 = new java.util.HashMap String>(); > m1[2] = "two"; > > java.util.LinkedList l1 = java.util.Arrays.asList( new String[] > {"a", "b", "c" }); > m1[3] = l1[2]; > l1[0] = m1[0]; > l1[1] = "one"; > } > } > > is converted to > public class TestConcise { > public TestConcise() { > super(); > } > > public static void main(String[] args) { > java.util.Map m1 = new java.util.HashMap String>(); > m1.put(Integer.valueOf(2), "two"); > > java.util.LinkedList l1 = java.util.Arrays.asList( new String[] > {"a", "b", "c" }); > m1.put(Integer.valueOf(3), l1.get(2)); > l1.set(0, m1.get(Integer.valueOf(0))); > l1.set(1, "one"); > } > } > > > TESTING: > > LIBRARY SUPPORT: > No additional library support is needed. > > REFLECTIVE APIS: > This proposal does not require any reflective API changes. > > OTHER CHANGES: > No changes required. > > MIGRATION: > No migration is needed. > > COMPATIBILITY > > BREAKING CHANGES: > No breaking changes. > > EXISTING PROGRAMS: > Existing programs are not affected by this change. > > REFERENCES > My Java7 Wishlist regarding Collections, > http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html > Implementation of My Java7 Wishlist, > http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html > > EXISTING BUGS: > None. > > URL FOR PROTOTYPE (optional): > Projects kijaro's concisecollections branch: > https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/ > > > > > From Joe.Darcy at Sun.COM Sun Mar 29 22:41:08 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Sun, 29 Mar 2009 22:41:08 -0700 Subject: PROPOSAL: Enhanced while statement In-Reply-To: <28bca0ff0903291627h2433b042sb2d7f42b018451a@mail.gmail.com> References: <28bca0ff0903291627h2433b042sb2d7f42b018451a@mail.gmail.com> Message-ID: <49D05B74.807@sun.com> Marek Kozie? wrote: > AUTHOR: Lasu aka Marek Kozie? > > OVERVIEW > > FEATURE SUMMARY: > Enhanced while statement allow to iterate through iterator. > > [snip] > Using while loop. > > > EXAMPLES > > SIMPLE EXAMPLE: > String toString(Iterator list){ > if (!list.hasNext()) return "[]"; > StringBuilder ret = new StringBuilder(); > ret.append('[').append(list.next()); > while (String string : list) { > ret.append(',').append(list.next()); > } > return ret.append(']').toString(); > } > > ADVANCED EXAMPLE: > String toString(Iterator list){ > while (Transfer t : list) { > ArrayList data = new ArrayList(); > if ( t.isOpeningTag() ) > while (Transfer t : list){ > if (t.isClosingTag()) break; > data.add(t.getData()); > } > else { > list.remove(); // OK: no interactions > throw new Exception("..."); > } > list.remove(); // warning list here can refer to last element of > inner loop > // Process chunk > } > > } > DETAILS > > SPECIFICATION: > Same as JLS 14.14.2, except: > The Expression must either have type Iterator, or a compile-time error occurs. > Let I be the type of the expression Expression > > > If Expression is directly field or variable or parameter > (ExpressionVariable) then additional checking is performed: > If Variable is used as Expression for while-each loop inside > while-each loop over same Variable then Variable occurring after inner > while-each loop (but in outer while-each loop) will compile with > warning ?Variable state refer to inner loop?. > > COMPILATION: > Same as for-each (almost). > This is another vague and incomplete proposal. -Joe From develop4lasu at gmail.com Mon Mar 30 00:44:56 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 09:44:56 +0200 Subject: PROPOSAL: Enhanced while statement In-Reply-To: <49D05B74.807@sun.com> References: <28bca0ff0903291627h2433b042sb2d7f42b018451a@mail.gmail.com> <49D05B74.807@sun.com> Message-ID: <28bca0ff0903300044v5efc617bvcb59ceeed1ba6ed4@mail.gmail.com> 2009/3/30 Joseph D. Darcy : > > > This is another vague and incomplete proposal. > > -Joe > Yes it is ;) I just wanted to show some alternative solution, but this is not possible on current Iterator model; -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Joe.Darcy at Sun.COM Mon Mar 30 00:47:07 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 00:47:07 -0700 Subject: PROPOSAL: Enhanced while statement In-Reply-To: <28bca0ff0903300044v5efc617bvcb59ceeed1ba6ed4@mail.gmail.com> References: <28bca0ff0903291627h2433b042sb2d7f42b018451a@mail.gmail.com> <49D05B74.807@sun.com> <28bca0ff0903300044v5efc617bvcb59ceeed1ba6ed4@mail.gmail.com> Message-ID: <49D078FB.5000104@sun.com> Marek Kozie? wrote: > 2009/3/30 Joseph D. Darcy : > >> This is another vague and incomplete proposal. >> >> -Joe >> >> > > Yes it is ;) > Repeated submission of vague and incomplete proposals is not a positive contribution to the Project Coin effort. -Joe From Joe.Darcy at Sun.COM Mon Mar 30 00:48:28 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 00:48:28 -0700 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <350193.71588.qm@web36708.mail.mud.yahoo.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> Message-ID: <49D0794C.7090400@sun.com> Hello. Shams Mahmood wrote: > Indexing access syntax for Lists and Maps > > VERSION > This is version 1.0. > > AUTHOR(S): > Shams Mahmood Imam > > OVERVIEW > > FEATURE SUMMARY: > Collection classes are among the most frequently used in the Java SDK. > Currently Lists and Maps do not provide any additional language > feature to access individual elements unlike Arrays. This proposal > aims to provide these Collection citizens of java additional > language support to access elements like Arrays have currently. > I was going to type up a proposal along these lines from scratch, but I'm happy you sent in your proposal first, especially since there is a prototype already :-) While collections are certainly very widely used and should have this indexing support IMO, I think it is also important that indexing support not be strictly limited to just classes implementing java.util.{List, Map}. For example, if this kind of capability is added, I'd like enough flexibility to give library developers the ability to in effect write a 64-bit array class. (Semantically, a Java array today is basically just a map from int to some other type.) The mechanism to indicate indexing is supported on a class must at least support Lists and Maps: java.util.List read: E get(int) write: E set(int, E) java.util.Map read: V get(Object) write: V put(K, V) So variation in both the names of the methods must be accommodated as well as the typing of the methods. The compiler needs a few pieces of information to perform the indexing translating including "Should this type get indexing support?" and "If this type gets indexing support, what methods do read and write operations get mapped to?" The most magical way to indicate the indexing support bit is to have a marker interface (or even an annotation) and then to have the names of the get/set methods indicated as annotation values. As a strawman something like public interface java.lang.Indexable {} @Documented @Target(TYPE) @Retention(RUNTIME) @Inherited public @interface java.lang.IndexableNames { String reader() default "get"; String writer(); } where then, say, java.util.List would be changed from public interface List extends Collection to @IndexableNames(writer="set") public interface List extends Collection extends Indexable However, this feels a bit too magical and there would be complications about getting the indexable method names since annotation inheritance only works along superclasses, not superinterfaces. A better approach is probably to create at least two new superinterfaces in java.lang for the List and Map signatures. However, some care and analysis will be needed to ensure a migration compatibility issue is not introduced. (In support of the enhanced for loop in JDK 5, a superintface of java.util.Iterator, java.lang.Iterator (lacking a remove method), was introduced being being subsequently removed for migration compatibility conflicts.) -Joe From prunge at velocitynet.com.au Mon Mar 30 01:08:42 2009 From: prunge at velocitynet.com.au (Peter Runge) Date: Mon, 30 Mar 2009 19:08:42 +1100 (EST) Subject: PROPOSAL: Allow the class literal of the surrounding class to be referenced with the 'class' keyword Message-ID: <34374.122.49.204.51.1238400522.squirrel@webmail.velocity.net.au> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 AUTHOR(S): Peter Runge prunge at velocitynet dot com dot au OVERVIEW FEATURE SUMMARY: Allow the class literal of the surrounding class to be referenced with the 'class' keyword. Sometimes it is useful to be able to reference the class literal of class containing a body of code. Right now the name of the surrounding class with '.class' is used, but it would be beneficial not having to repeat the class name for this. This makes it easier to rename the class later as the name does not need changing in multiple places. A typical place this feature would provide benefit is create loggers in logging code. When expanded, this shortened class literal form is equivalent to its expanded class literal. MAJOR ADVANTAGE: Improves code maintainability - makes it easier to rename classes since the class name is not repeated in the code. Also helps defend against blind copy and pasters. MAJOR BENEFIT: Less repeated code - logging code is quite common. MAJOR DISADVANTAGE: Requires change to JLS. Need to weigh up cost of implementing feature with amount of benefit it would provide. ALTERNATIVES: Most IDEs nowadays can automatically rename .class referenced in code without too much trouble. EXAMPLES Show us the code! SIMPLE EXAMPLE: For example, when using logging APIs, a Logger object is often created as a static variable within a class that is used to generate logging information in the context of that class. class MyClass { private static Logger log = Logger.getLogger(MyClass.class); ... } With the proposal, this can be changed to: class MyClass { private static Logger log = Logger.getLogger(class); ... } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. Inner/nested classes: class MyClass { private static Logger log = Logger.getLogger(class); class MyInnerClass { Logger innerLog = Logger.getLogger(class); //Refers to MyInnerClass.class ... } } Anonymous inner classes: class MyClass { public myMethod() { something.invoke(new MyInterface() { //Refers to the class of the anonymous inner class //(not that I've ever needed this, but is there another way //short of reflection of accessing this class at //the moment apart from getClass()?) Logger log = Logger.getLogger(class); public void interfaceMethod() { ... } }); } } DETAILS SPECIFICATION: JLS3 15.8 Primary Expressions: add new syntax for these new class literals: PrimaryNoNewArray: Literal Type.class >class< void.class this ClassName.this ( Expression ) ClassInstanceCreationExpression FieldAccess MethodInvocation ArrayAccess Add description of new class literals to JLS3 15.8.2 (or perhaps add new section): ... The class keyword may be used to refer to the class literal for its enclosing type. In the case of nested and inner classes, the closest or 'innermost' class is referenced. The class keyword may be used by itself to refer to its enclosing class, and behaves equivalently to the usage of a .class literal. ... COMPILATION: Potentially these 'class' literals would be resolved and translated into class literals in their current form using context information. Therefore no bytecode changes are required. The exception is anonymous inner classes which have no equivalent class literal representation in their current form. It probably wouldn't be a huge loss if this feature was not allowed to be used in anonymous inner classes if this was a huge issue, however in bytecode this probably could be done as easy as any class since all classes anonymous or otherwise have a binary name which can be loaded in the constant pool. TESTING: A test case that uses the new feature can be created. LIBRARY SUPPORT: No. REFLECTIVE APIS: No reflective API changes are needed. OTHER CHANGES: The non-public javac tree API may need a change for this feature (investigation needed - LiteralTree). MIGRATION: All class literals inside a class that refer to that class can be changed to use the new feature. COMPATIBILITY BREAKING CHANGES: No existing programs should break - 'class' as a keyword is currently not allowed within an expression. EXISTING PROGRAMS: No known issues. REFERENCES EXISTING BUGS: None known. URL FOR PROTOTYPE (optional): None available. From develop4lasu at gmail.com Mon Mar 30 01:17:26 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 10:17:26 +0200 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49C56020.2070207@joda.org> References: <49C56020.2070207@joda.org> Message-ID: <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> As you can see i was thinking about it for while: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001105.html And i found few problems. New iterator Interface is wrong path, because people will be not able to use it with their iterators. So from your proposal I would remove Interface-s and link iterator through label, label type is return type of .iterator() method. like: ArrayList some ....; ... i: for (Strign s:some){ if ( (s==null) || (s.equals("bad")) )) i.remove(); ... i.next(); // compile time error ? i.hasNext(); // OK Iterator s = i; // error i is not variable (it just allow to access it;) } String[] array ...; i: for (String s:array){ i.getIndex;//? } -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From develop4lasu at gmail.com Mon Mar 30 01:25:54 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 10:25:54 +0200 Subject: PROPOSAL: Enhanced while statement In-Reply-To: <49D078FB.5000104@sun.com> References: <28bca0ff0903291627h2433b042sb2d7f42b018451a@mail.gmail.com> <49D05B74.807@sun.com> <28bca0ff0903300044v5efc617bvcb59ceeed1ba6ed4@mail.gmail.com> <49D078FB.5000104@sun.com> Message-ID: <28bca0ff0903300125t12d87840l8c43269989d74a0f@mail.gmail.com> 2009/3/30 Joseph D. Darcy : > Marek Kozie? wrote: >> >> 2009/3/30 Joseph D. Darcy : >> >>> >>> This is another vague and incomplete proposal. >>> >>> -Joe >>> >>> >> >> Yes it is ;) >> > > Repeated submission of vague and incomplete proposals is not a positive > contribution to the Project Coin effort. > > -Joe > I just wanted to help Stephen with his proposal. (Calling this as proposal was unproper): http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000737.html http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001122.html -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Mon Mar 30 01:27:32 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Mon, 30 Mar 2009 21:27:32 +1300 Subject: Updated: Language Escape Operator Message-ID: <49D08274.5050502@paradise.net.nz> Following feedback, I have changed the proposal to use \ (was `) for the operator and expanded some of the background on that choice. Unfortunately there is some added complexity in the spec tiptoing around the unicode escape - and a little more might still be needed. Bruce Title Language Escape Operator latest html version at http://docs.google.com/Doc?docid=dcvp3mkv_9gdg3jfhg AUTHOR(S): Bruce Chapman OVERVIEW FEATURE SUMMARY: There is great potential for syntactic sugars to be implemented in tools rather than the Java language. One requirement of such a mechanism is that the sugared form is NOT valid java source code (otherwise the meaning is ambiguous - is a piece of code intended as is, or intended to be desugared). In order to future proof such mechanisms it is also desirable that such a syntactic sugar form will never become a valid java form due to some unanticipated future language change. A simple way to ensure this is to reserve a character as a language escape, effectively it indicates that source code is at that point escaping from the java language. Such a character should be a printable ascii character to enable it to be typed and read, and it should have no existing defined meaning in the java language within the contexts in which it may be used. Inside commments, String literals and character literals all printable ascii characters have meaning and therefore there is no way we can escape from these. This is not thought to be an overly burdensome restriction. The candidate characters for the escape operator are therefore # (hash), \ (backslash) and ` (back quote). Neither # or ` have any currently defined meaning in the Java language specification. \ does have defined meanings but only as a unicode escape and inside String and character literals and so is also suitable. The intention of this proposal is to reserve one of these three characters for a range of uses that are outside the language. Although the syntactic sugar example is mentioned above it is but one example. A crystal ball would be advantageous here - alas we are limited to our ability to dream. Several proposals and ideas are circulating which suggest uses for each of these few remaining characters which are becoming a precious resource for language developers due to their scarcity. It is the author's belief that use of any one of these characters as a language escape operator offers far more long term value than use in a single new syntactic form. Let us reserve one of the three characters as a language escape and let all other language proposals squabble over the remaining two. Either of the three characters could be used equally from a technical point of view Of the three characters # has a legitimate claim against it for JSR 292 Support, and worthy proposed uses for method, field and possibly type references. It is also aesthetically least attractive of the three as an escape operator since the other two already have escape like meaning in the language or other contexts. It has been pointed out that ` is hard to type on many European language keyboards so \ would be the preferred language escape character. \ has both an advantage and disadvantage as being THE java escape character. There is a conceptual advantage from its use as the String and character escape code. Its existing use as a unicode escape is slightly problematic because a single \ followed by 'u' must either be a unicode escape (the subsequent 4 characters are all hex digits) or a compiler error is raised. This implies that it would be unwise to have a language escape where the escaped text started with u. To prevent the compiler error in this case, the \ must be escaped. That is probably a price worth paying compared with the always difficult to type on European keyboards problem with `. For the rest of this proposal it is assumed the back-slash character is the language escape operator. MAJOR ADVANTAGE: Shuts the gate before the horse has bolted. Once all these characters are assigned meaning by the language, then there is no single character that can be used as a language escape. MAJOR DISADVANTAGE: Prevents the back-slash character from being used in other language features, other than its already defined meaning as a unicode escape, and String and character literal escape. However any anticipated other use would have the same unicode escaping issue as mentioned for this use above. Further, any other use would tend to fight against the "\ is escape" concept. So back-slash is probably undesirable for other uses unrelated to escaping. ALTERNATIVES: Alternative characters have been discussed above. Another alternative is to do nothing and let language tools develop further (using any of the three available characters) in order to get a slightly better idea of where this might be heading before committing to a language change. The risk with this approach is that all three characters might get defined uses by other language changes before one can be reserved as a language escape. At that point it would be too late and would restrict language tools. EXAMPLES SIMPLE EXAMPLE: \Property String name; is not valid Java source code, and can be automatically desugared by an IDE. See references section. ADVANCED EXAMPLE: N/A DETAILS SPECIFICATION: Add new section 3.13 after 3.12 operators. 3.12 Language Escape When used outside of comments, String and character literals ,the backslash character \ is reserved for use by tools that process mixed language content to indicate to their parsers, while parsing java source code, the start of something that is not Java source code. It is the responsibility of such tools to pass only java source to the java compiler. Note that \ has meaning as a unicode escape. Uses of language escape should attempt to not follow the \ with a u (otherwise the \ will need to be escaped to \\). It is a compile time error for a \ character to appear in other than a comment, a String literal or a Character literal. COMPILATION: Generate the error if the \ character is encountered in other than a comment, String or Character literal. While the protoype does this, a more specific error message might be useful. TESTING: Test for the compiler error. LIBRARY SUPPORT: No library support required. REFLECTIVE APIS: N/A OTHER CHANGES: N/A MIGRATION: N/A COMPATIBILITY BREAKING CHANGES: N/A EXISTING PROGRAMS: N/A REFERENCES http://docs.google.com/Doc?docid=dcvp3mkv_8sn3ccbkk describes a working proof of concept tool which uses ` as a language escape. http://weblogs.java.net/blog/brucechapman/archive/JUG%20Aug%202008%20Mark%20II%20Pecha%20Kucha.ppt backgrounds and justifies one possible use case EXISTING BUGS: ? URL FOR PROTOTYPE (optional): JDK6's javac is the protoype implementation for this language change. http://java.sun.com/javase/downloads From rssh at gradsoft.com.ua Mon Mar 30 01:29:54 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 30 Mar 2009 11:29:54 +0300 (EEST) Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <350193.71588.qm@web36708.mail.mud.yahoo.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> Message-ID: > Indexing access syntax for Lists and Maps > > VERSION > This is version 1.0. > > AUTHOR(S): > Shams Mahmood Imam > > OVERVIEW > > FEATURE SUMMARY: > Collection classes are among the most frequently used in the Java SDK. > Currently Lists and Maps do not provide any additional language > feature to access individual elements unlike Arrays. This proposal > aims to provide these Collection citizens of java additional > language support to access elements like Arrays have currently. > > MAJOR ADVANTAGE: > Will provide a consistent syntax for accessing elements of Arrays, > Lists and Maps. In addition, the language grammar will not change Often we nee something 'less' than List or Map. I. e. I would be good to see i additional to lists and maps some 'minimal' get/set interface. > much since the subscript operator is already supported for Arrays. > .... > DETAILS > > SPECIFICATION: > Java Language Specification changes: > > 15.29 (NEW CHAPTER): Collection Access Expressions > A collection access expression contains two subexpressions, the List/Map > reference expression (before the left bracket) and the index expression > (within the brackets). Note that the List/Map reference expression may be > a name or any expression that evaluates to a List/Map. The index > experssion is expected to evaluate to an int for Lists and a valid key > type for Maps. > > CollectionAccess: > Expression [ Expression ] > > 15.8 Primary Expressions > original: > --------- > PrimaryNoNewArray: > Literal > Type . class > void . class > this > ClassName.this > ( Expression ) > ClassInstanceCreationExpression > FieldAccess > MethodInvocation > ArrayAccess > > replaced with: > -------------- > PrimaryNoNewArray: > Literal > Type . class > void . class > this > ClassName.this > ( Expression ) > ClassInstanceCreationExpression > FieldAccess > MethodInvocation > ArrayAccess > CollectionAccess > Ara syntax to ArrayAccess and CollectionAccess difer ? If not, this is one expression in grammar > 15.26 Assignment Operators > original: > --------- > LeftHandSide: > ExpressionName > FieldAccess > ArrayAccess > > replaced with: > -------------- > LeftHandSide: > ExpressionName > FieldAccess > ArrayAccess > CollectionAccess > The same note as previous. > Also JLS contains specifivation of behavious of assigment. I changed this specification for class-array-assigment (in simular proposal, but more general and annotation-based instead interface-based as you) http://docs.google.com/Doc?id=dhhvggr8_18djp85shk Part of 15.13 and 15.26.1 of JLS must be rewritten in you case. (I guess you can get this changes from text of my proposal and slightly adopt, semantics would be the same) > COMPILATION: > > After successful creation of the AST handling the additional grammar for > Collection Access expressions, the syntactic sugar will be replaced by > JDK1.4 compatible code during the Code Generation phase. This is > consistent with how JDK5.0 constructs like the for-each loop is handled by > the compiler. > > e.g. > public class TestConcise { > public static void main(String[] args) { > java.util.Map m1 = new java.util.HashMap String>(); > m1[2] = "two"; > > java.util.LinkedList l1 = java.util.Arrays.asList( new > String[] {"a", "b", "c" }); > m1[3] = l1[2]; > l1[0] = m1[0]; > l1[1] = "one"; > } > } > > is converted to > public class TestConcise { > public TestConcise() { > super(); > } > > public static void main(String[] args) { > java.util.Map m1 = new java.util.HashMap String>(); > m1.put(Integer.valueOf(2), "two"); > > java.util.LinkedList l1 = java.util.Arrays.asList( new > String[] {"a", "b", "c" }); > m1.put(Integer.valueOf(3), l1.get(2)); > l1.set(0, m1.get(Integer.valueOf(0))); > l1.set(1, "one"); > } > } > > > TESTING: > > LIBRARY SUPPORT: > No additional library support is needed. > > REFLECTIVE APIS: > This proposal does not require any reflective API changes. > > OTHER CHANGES: > No changes required. > > MIGRATION: > No migration is needed. > > COMPATIBILITY > > BREAKING CHANGES: > No breaking changes. > > EXISTING PROGRAMS: > Existing programs are not affected by this change. > > REFERENCES > My Java7 Wishlist regarding Collections, > http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html > Implementation of My Java7 Wishlist, > http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html > > EXISTING BUGS: > None. > > URL FOR PROTOTYPE (optional): > Projects kijaro's concisecollections branch: > https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/ > > > > > From vapor1 at teleport.com Mon Mar 30 01:35:09 2009 From: vapor1 at teleport.com (Derek Foster) Date: Mon, 30 Mar 2009 04:35:09 -0400 (EDT) Subject: PROPOSAL: abstract enums Message-ID: <11338735.1238402109941.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> >From: "Joseph D. Darcy" >Sent: Mar 29, 2009 11:54 PM >To: Derek Foster >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: abstract enums > >This proposal is incomplete. There are many other possible impacts of >this change, including serialization; see > > "So you want to change the Java Programming Language..." > http://blogs.sun.com/darcy/entry/so_you_want_to_change > >for an account of all the aspects of the system adding regular enums >involved. Hi, Joe. Thanks for the pointer. Actually, I read that page before I submitted my proposal, and I even paraphrased some of its contents in my proposal. That page, for instance, was what prompted me to suggest that Class.isEnum() should return false for abstract enumeration supertypes, in an attempt to stay consistent with your decision with regards to how anonymous subclasses associated with enum constants are handled. >Of the extensible and non-extensible version of enum pattern, the JSR >201 expert group chose the non-extensible variant and many other >decisions and details of the original enum design flow from that >fundamental decision. Revisiting that decision now is impractical. With respect, I think you have misread my proposal. Please read it again, with the following caveat in mind: My proposal is NOT about extensible enums. In fact, I specifically put language in my proposal to forbid the type of extensibility that you appear to be concerned about. My proposal is intending to make a relatively minor change to how enums work, as opposed to the major change that adding extensible enums would entail. In particular, my proposal endeavors to make as few as possible changes to how the enumeration leaf classes behave, which is where the vast majority of the problems with designing the enum proposal came from. The term "abstract enum" is vague, and can mean several different things. I have often found, in online discussions about the subject, that the people discussing it think that they are talking about the same interpretation of those two words, but in fact one subgroup of the conversation is talking about one interpretation of the phrase, and another is talking about a different one. The discussions in the bug reports I submitted are prime examples of this. This has led to a great deal of miscommunication about this subject. The most common meanings that people attribute to the phrase "abstract enum" are: 1) ("extensible enums") An abstract enum would allow the declaration of enum constants in a superclass, and then additional enum constants in a subclass. Superclass/subclass relationships would apply to the constants, and it would be possible to create additional enumerated values in a subclass of an enumerated type declared in a superclass. This would have a variety of useful consequences such as the ability to add new enum constants to an existing type by subclassing. However, this causes severe problems as well, such as the inability for a supertype to ever know the full set of its enumerated constants as defined by all possible subtypes (even those which might not be loaded at the time), as well as various serialization problems and so forth. It creates nasty problems with serialization and causes quite a number of other unpleasant side effects. versus: 2) ("abstract enums" as per my proposal) An abstract enum would NOT allow the declaration of enum constants in a supertype. The supertype isn't really an "enum" at all, any more than Enum is -- it's really just an abstract super"class", which is declared with the enum keyword only because Java syntax happens to create a somewhat artifical distinction between the terms "enum" and "class", and because this allows a little bit of syntactic sugar to happen so the user doesn't have to know about the generic type parameter. Regardless, these supertypes are really just classes which happen to extend Enum and have subtypes which really ARE enums. Only these leaf enum types would be allowed to declare enum constants, in the exact same manner that they are currently able to, including serialization and so forth. I am aware of the battles that have been fought over extensible enums, and also that while it is a nice-sounding idea, that it is incredibly difficult (maybe impossible) to implement correctly. My proposal was specifically designed not to retread this ground. I am proposing something different, which unfortunately has a name that strikes a similar chord in many people's minds. I am interested in IMPLEMENTATION code sharing among enum classes using inheritance. I am not interested in creating hierarchies of enumeration constants, the ability to add new enumeration constants at runtime, in altering enum serialization, or in other changes affecting the INTERFACE to enumerated constants, which was what the whole furor about extensible enums was about. With the above said, in reviewing your comment regarding serialization, I did notice something in the serialization document that I had previously missed: that introducing or removing a new superclass into an enumerated type will alter the serialization of the leaf class enumeration constants (due to the ObjectStreamClass of the enum leaf class mentioning its supertype(s)). This is analogous to (and no worse than) what happens with ordinary classes, and I don't think it would be horrible to just let this happen ("if you add or remove supertypes, your enum serialization will change"). However, in this case it is probably not necessary or useful to break serialization at all, since unlike ordinary classes, enums have no state to serialize (just a name) so there is no reason to include the supertype hierarchy in the serialization either. So thank you, since you did find a weakness in my proposal which I will address in a later version. This problem appears to be relatively easy to fix, however. (Just require that enum constants be serialized as if the immediate supertype of the leaf class that declares them was Enum, even if it isn't. Since all that's being serialized is the name of the enum constant in the leaf class, the addition/deletion of a supertype should not affect serialization, and with this change, would not). I will also add a section noting that abstract enums can be entered as perfectly normal abstract classes in class files, with only a single marking bit needed to annotate it so that the compiler can distinguish it from an identically formed Java class for the purposes of forbidding cross-inheritance between enums and classes. I will also clarify the rules regarding what is considered a valid supertype of an abstract or non-abstract, enum (basically, must be abstract, must extend Enum, etc.), with reference to class file formats instead of just to source code. With these changes, are there other areas in which you feel my proposal is unclear? If so, please let me know what they are. Derek From John.Rose at Sun.COM Mon Mar 30 01:41:36 2009 From: John.Rose at Sun.COM (John Rose) Date: Mon, 30 Mar 2009 01:41:36 -0700 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> Message-ID: <6F835C91-A2F2-4050-BD03-DB1B462C2B4F@sun.com> 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. BACKGROUND: At the JVM level, an invokedynamic instruction is used to call methods which have linkage and dispatch semantics defined by non-Java languages. Again, a JVM-level invokevirtual instruction has slightly altered linkage rules when the target class method is java.dyn.MethodHandle.invoke: The change is that any type signature is acceptable, and the JVM will make a type-safe method call, regardless of the signature. In addition, the JVM already accepts (since Java 5) any of a large set of strings as field, method, and class identifiers, and many languages will use such identifiers beyond the limits of the Java identifier syntax. Finally, the JVM verifier already accepts (since the beginning) arbitrary reference values for any interface type, and it is useful to allow at least one interface type to serve as a wild-card type. FEATURE SUMMARY: We will make small, localized modifications the Java language to make it easy to with with these JVM features (old and new). This will allow Java code to interoperate with and/or implement libraries in non- Java languages. The changes are as follows: 1. dynamic invocation, general case The interface java.dyn.Dynamic may be used with the static call syntax to form an invokedynamic call site. The method name may be any Java identifier (including an exotic one; see point 3). The arguments may be of any number and type. A type argument can optionally supply the return type, in the existing syntax. In effect, java.dyn.Dynamic appears to have an infinite number of methods, of every possible name and signature. More details are given below, but here is a first example: Object x = Dynamic.getMeSomething(); (As defined by JSR 292, an invokedynamic call site is linked to a target method under the control of an application-defined bootstrap method. The linkage state is determined by a method handle with the same type descriptor as the call site itself.) 2. method handle invocation Method handles (class java.dyn.MethodHandle) provide the "plumbing" behind any invokedynamic instruction. There are library routines for creating and adapting them, as specified by JSR 292. In addition, it is necessary to provide a way of invoking a method handle as an explicit target, rather than implicitly as the linked target of an invokedynamic instruction. Since a method handle invocation (like invokedynamic itself) can have any argument types and return value, method handles also need a special extension for invocation. As for type Dynamic, the type MethodHandle accepts an infinite variety of non- static calls to the method named "invoke". The argument and return types for the descriptor presented to the JVM are determined as for invokedynamic calls. Here is a first example: MethodHandle mh = ...; mh.invoke(); 3. exotic identifiers The grammar for Java identifiers is extended to include "exotic identifiers", whose spellings can be any sequence of characters, as long as they avoid certain minor restrictions imposed by the JVM. An exotic identifier is introduced by a hash mark, which is immediately followed by a string literal. No special treatment is given to the identifier, other than ensuring that its spelling contains exactly the character sequence denoted by the string literal. Details are given below; here is an example: int #"strange variable name" = 42; System.out.println(#"strange variable name"); // prints 42 4. conversion rules for interface Dynamic The type Dynamic has another use which is synergistically related to its role in encoding invokedynamic calls. It also serves as a dynamic version of a wildcard type. It is a bare reference with no regular methods, not even those of java.lang.Object. As a bare reference, it can be freely converted from any other type and to Object. With a cast, it can be converted to any other type. This works together with the invokedynamic syntax to allow dynamic method calls to be chained. (As a point of comparison, C# 4.0 has a similar integration between a new type "dynamic" and DLR call sites.) More details are below; here is an example: Dynamic x = (any type of expression can go here); Object y = x.foo("ABC").bar(42).baz(); MAJOR ADVANTAGE: These changes allow full access to invokedynamic and related new JVM features from JSR 292. This allows Java to interoperate with new JVM languages. It also enables Java to serve well as an language implementation or systems programming language. MAJOR BENEFIT: Much greater ease of creating, for the JVM, with javac, new programming languages and language runtimes. (The potential opportunity cost is that language implementors who presently use Java as a systems programming language will be forced to stay down at the bytecode assembly level, making them slower to adopt the JVM for their work.) MAJOR DISADVANTAGE: The JLS gets more complicated. ALTERNATIVES: The only viable alternative is assembly coding parts of the system which must interoperate with new languages. This will discourage the creation of common runtimes and libraries, and greatly reduce the synergy between languages. EXAMPLES: See above and below (in the specification) for one-line examples demonstrating each aspect of the syntax and type rules. void test(MethodHandle mh) { mh.invoke("world", 123); // previous line generates invokevirtual MethodHandle.invoke(String,int)Object Dynamic.greet("hello", "world", 123); // previous line generates invokedynamic greet(Object,String,int)Object // enclosing class must register a bootstrap method (handle) to link Dynamic.greet } BEFORE/AFTER There are no concise before/after examples for these language features per se, because without the new syntax, dynamic language implementors must resort to assembly code. But, here is a mocked up example that shows how call site caches can be created before and after JSR 292. This is for no particular language; call it MyScript. Note the use of the proposed features to form and manage dynamic call sites. class Foo { // compiled method for lambda (x) { print "Hello, "+x } private static Object method1(Object x) { System.out.println("Hello, "+x); return null; } // function pointer, old style: public static Method1 method1Ref() { return new Method1() { // there is a new classfile per expression reference public Object apply(Object arg) { return method1(arg); } } } // function pointer, new style: public static MethodHandle method1Ref() { // it all happens in one classfile return MethodHandles.findStatic(Foo.class, "method1", MethodTypes.makeGeneric(1)); } } class Bar { // compiled method for lambda (x) { x.ready? } // call-site cache, old style: private static Method1 csc42 = null; private static Object method2(Object x) { Method1 tem = csc42; // complex machinery with little hope of optimization if (tem == null) csc42 = tem = MOP.resolveCallSite(Foo.class, "ready?", x); return tem.apply(x); } // call-site cache, new style: private static Dynamic method2(Dynamic x) { // native to the JVM and the JIT return x.#"myscript:ready?"(); } static { Linkage.registerBootstrapMethod("bootstrapDynamic"); } private static Object bootstrapDynamic(java.dyn.CallSite site, Object... args) { return MOP.executeCallSite(site, args); } } class MOP { // shared logic for resolving call sites public static executeCallSite(java.dyn.CallSite site, Object... args) { MethodHandle target = site.target(); if (target == null) { target = resolveCallSite(site.callerClass(), site.name(), args); site.setTarget(target); // next time it will be a direct call } return MethodHandles.invoke(target, args); } } SIMPLE EXAMPLE: This example greets the world using (a) normal static linkage, (b) direct method handle invocation, and (c) a lazily linked call site (invokedynamic). The output from the "bootstrap" routine appears only once, after which the linked call site runs by directly calling the target method, with no reflection. import java.dyn.*; public class Hello { public static void main(String... av) { if (av.length == 0) av = new String[] { "world" }; greeter(av[0] + " (from a statically linked call site)"); for (String whom : av) { greeter.invoke(whom); // strongly typed direct call // previous line generates invokevirtual MethodHandle.invoke(String)void Dynamic x = whom; x.hail(); // weakly typed invokedynamic // previous line generates invokedynamic MethodHandle.invoke(Dynamic)Dynamic } } static void greeter(String x) { System.out.println("Hello, "+x); } // intentionally pun between the method and its reified handle: static MethodHandle greeter = MethodHandles.findStatic(Hello.class, "greeter", MethodType.make(void.class, String.class)); // Set up a class-local bootstrap method. static { Linkage.registerBootstrapMethod("bootstrapDynamic"); } private static Object bootstrapDynamic(CallSite site, Object... args) { assert(args.length == 1 && site.name() == "hail"); // in lieu of MOP System.out.println("set target to adapt "+greeter); MethodHandle target = MethodHandles.convertArguments(greeter, site.type()); site.setTarget(target); System.out.println("calling the slow path; this should be the last time!"); return MethodHandles.invoke(target, args); } } ADVANCED EXAMPLE: (See before-and-after MOP example above.) DETAILS SPECIFICATION: 1.1 The type java.dyn.Dynamic shall be defined as an empty interface with no supertypes. It is an error if Dynamic is defined as a class, or if it has any supertypes, or if it defines any members. It does not have the usual implicit supertype of Object. package java.dyn; public interface Dynamic /*must be empty*/ { /*must be empty*/ } (The complete lack of supertypes makes it an unusual type, on a par with Object. Of course the JVM verifier will allow free interconversion between Object and Dynamic. This unusual "sterility" allows Java complete access to all degrees of freedom in the JVM's invokedynamic instruction.) 1.2 The type name Dynamic may be qualified with any method name whatever, and invoked on any number and type of arguments. The compiler generates an invokedynamic call site with the given name and a descriptor (symbolic type signature) derived from the erasure of the static types of all the arguments. In this way, an invokedynamic instruction can be written in Java to use any of the full range of calling sequences (i.e., descriptors) supported by the JVM. Neither the JVM instruction nor the Java syntax is limited in its use of argument types. Dynamic.anyNameWhatever(); // no argument types Dynamic.anotherName("foo", 42); // argument types (String, int) 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.) 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 1.6 In order to support chained invokedynamic expressions, any reference of type Dynamic may also be qualified with any name and invoked on any number and type of arguments. Since the invokedynamic instruction is receiverless (symmetrical in all arguments), the target value of the method invocation expression is pushed first on the stack before the other arguments, while its static type (which is always Dynamic) is prepended to the call descriptor presented to the JVM. Dynamic x = ...; boolean z = Dynamic.myEquals(x, 42); // type (Dynamic, int) -> boolean boolean z = x.myEquals(y); // identical meaning with previous line x.foo().bar().baz(); // 3 invokedynamic calls of type (Dynamic) -> Dynamic 1.7 As with any other expression of Dynamic type, qualifying it with a method name has precisely the same effect as qualifying the type Dynamic itself, and inserting the previously qualified expression as the first method argument. In particular, there is no special check for null references. Dynamic.looksBad((Dynamic)null, 42); // type (Dynamic, int) -> Dynamic ((Dynamic)null).looksBad(42); // identical meaning with previous line 1.8 No other member selection expressions involving Dynamic are allowed, including selection of fields, or of methods of java.lang.Object. 1.9 Although it is perhaps not very useful, Dynamic can be used in other Java constructs that accept interface types, with unchanged meaning. A class or interface may specify Dynamic as a supertype, and the effect is similar to any other empty interface appearing as a supertype: No new methods are defined, and the instanceof and cast expressions work as they always have. (Non-inheritance of invokedynamic methods prevents Dynamic from disturbing static scoping of any type other than Dynamic itself.) Java code may declare variables, arrays, fields, arguments, and return values of type Dynamic or its subtypes. 2.1 The class java.dyn.MethodHandle shall be defined (external to this specification) without any method named "invoke". It is an error if it or any of its supertypes define a method named "invoke". (In any case, such supertypes are a fixed part of the Java APIs and/or implementations. JSR 292 happens to define a method named "type" on method handles.) package java.dyn; public class MethodHandle { ... } 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.) 2.3 A method handle call on "invoke" accepts an optional type parameter to specify the return type. As with Dynamic, the type parameter to MethodHandle.invoke may be any type, including void or a primitive type. If it is omitted it defaults to Dynamic. MethodHandle mh1, mh2, mh3, mh4; ... Dynamic x = mh1.invoke(); // type () -> Dynamic mh2.invoke(x); // type (Dynamic) -> void int y = mh3.invoke((Object)x); // type (Object) -> int boolean z = mh4.invoke(x, y); // type (Dynamic, int) -> boolean 2.4 As with Dynamic, otherwise untyped null argument values are treated as if they were of type Void. mh1.invoke(null); // type (Void) -> Dynamic mh2.invoke((String)null, null); // type (String, Void) -> void 2.5 No checked exceptions are produced by the call expression. try { mh.invoke(); } catch (Exception ee) { } // a compile-time error 2.6 As usual, if a null value typed as a method handle is qualified with the method name "invoke", the expression must terminate abnormally with a NullPointerException. MethodHandle nmh = null; nmh.invoke(); // must produce a NullPointerException 2.7 If a class extends MethodHandle, it does not inherit any of the implicitly defined "invoke" methods. To invoke a subclass of a method handle, it must first be cast to MethodHandle per se. (Non- inheritance of "invoke" methods prevents MethodHandle from disturbing static scoping of any type other than MethodHandle itself. Note that public method handle subclasses are not necessarily a feature of JSR 292.) class DirectMethodHandle extends MethodHandle { ... } DirectMethodHandle dmh = mh; mh.invoke(); // must be rejected: special MH.invoke not visible here 2.8 The bytecode emitted for any call to MethodHandle.invoke is an invokevirtual instruction, exactly as if a public virtual method of the desired descriptor were already present in java.dyn.MethodHandle. mh.invoke(1); // produces an invokevirtual instruction class MethodHandle { ... public abstract void invoke(int x); ... } // hypothetical overloading of 'invoke' mh.invoke(1); // would produce an identical invokevirtual, if that overloading could exist 3.1 The two-character sequence '#' '"' (hash and string-quote, or ASCII code points 35 and 24) introduces a new token similar in structure to a Java string literal. The token is in fact an identifier (JLS 3.8), which may be used for all the same syntactic purposes as ordinary identifiers are used for. int #"strange variable name" = 42; System.out.println(#"strange variable name"); // prints 42 This is true whether or not the characters are alphanumeric, or whether they happen (when unquoted) to spell any Java Java keyword or token. int #"+", #"\\", #"42" = 24; System.out.println(#"42" * 100); // prints 2400 // another take on java.lang.Integer: class #"int" extends Number { final int #"int"; #"int"(int #"int") { this.#"int" = #"int"; } static #"int" valueOf(int #"int") { return new #"int"(#"int"); } public int intValue() { return #"int"; } public long longValue() { return #"int"; } public float floatValue() { return #"int"; } public double doubleValue() { return #"int"; } public String toString() { return String.valueOf(#"int"); } } 3.2 The spelling of the identifier is obtained by collecting all the characters between the string quotes. Every string escape sequence (JLS 3.10.6) is replaced by the characters they refer to. As with other tokens, this character collection occurs after Unicode escape replacement is complete (JLS 3.3). int #"\'\t" = 5; // a two-character identifier System.out.println(#"'\u0009"); // prints 5 3.3 In particular, if the resulting sequence of characters happens to be a previously valid Java identifier, both normal and exotic forms of the same identifier token may be freely mixed. int #"num" = 42, scale = 100; System.out.println(num * #"scale"); // prints 4200 3.4 An exotic identifier may not be empty. That is, there must be at least one character between the opening and closing quotes. int #""; // must be rejected 3.5 Certain characters are treated specially within exotic identifiers even though they are not specially treated in string or character literals. The following so-called "dangerous characters" are illegal in an exotic identifier unless preceded by a backslash: / . ; < > [ ]. If a dangerous character is preceded by a backslash, the backslash is elided and the character is collected anyway. Depending on the ultimate use of the identifier, the program may be eventually rejected with an error. This must happen if and only if the escaped character would otherwise participate in a bytecode name forbidden by the Java 5 JVM specification. class #"foo/Bar" { } // not a package qualifier, must be rejected class #"foo.Bar" { } // not a package qualifier, must be rejected x.#""(); // not a method call; must be rejected x.#"f(Ljava/lang/Long;)"(0); // not a method descriptor; must be rejected 3.5.1 Specifically, the compiler must reject a program containing an exotic identifier with an escaped dangerous character happen if any of these is true: (a) the identifier is used as part or all of the bytecode name of a class or interface, and it contains any of / . ; [, or (b) the identifier is used as a part or all of the bytecode name of a method, and it contains any of / . ; < >, or (c) the identifier is used as a part or all of the bytecode name of a field, and it contains any of / . ;. Note that close bracket ] will always pass through; it is included in these rules simply for symmetry with open bracket ]. class #"java/io" { } // must be rejected class #"java\/io" { } // must be rejected (perhaps in an assembly phase) class #"" { } // must be rejected class #"\" { } // legal (but probably a bad idea) void f() { int #"¥" = '\u00A5'; } // must be rejected void f() { int #"¥\;" = '\u00A5'; } // legal (but probably a bad idea) class #"]" { int #"]"; void #"]"() {} } // must be rejected class #"\]" { int #"\]"; void #"\]"() {} } // legal (but probably a bad idea) These rules support the need for avoiding dangerous characters as a general rule, while permitting occasional expert use of names known to be legal to the JVM. However, there is no provision for uttering the method names "" or "". Nor may package prefixes ever be encoded within exotic identifiers. 3.6 Any ASCII punctuation character not otherwise affected by these rules may serve as a so-called "exotic escape character". That is, it may be preceded by a backslash; in this case both it and the backslash is collected (as a pair of characters) into the exotic identifier. Specifically, these characters are ! # $ % & ( ) * + , - : = ? @ ^ _ ` { | } ~ and no others. int #"=" = 42; int #"\=" = 99; System.out.println(#"="); // must print 42 not 99 These escapes are passed through to the bytecode level for further use by reflective applications, such as a bootstrap linker for invokedynamic. Such escapes are necessary at the level of bytecode names in order to encode (mangle) the dangerous characters. By sending both the backslash and the exotic escape character through to the bytecode level, we avoid the problem of multiple escaping (as is seen, for example, with regexp packages). Although Java has not worked this way in the past, the need for multiple phases of escaping motivates it here and now. Compare this quoting behavior with that of the Unix shells, which perform delayed escaping for similar reasons: $ echo "test: \$NL = '\12'" test: $NL = '\12' (See http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm for a proposal that manages bytecode-level mangling of exotic names. This proposal is independent of the present specification.) 3.7 Here is the combined grammar for exotic identifiers, starting with a new clause for Identifier (JLS 3.8): Identifier: ... ExoticIdentifier ExoticIdentifier: # " ExoticIdentifierCharacters " ExoticIdentifierCharacters: ExoticIdentifierCharacter ExoticIdentifierCharacters ExoticIdentifierCharacter: StringCharacter but not DangerousCharacter \ DangerousCharacter /* the backslash is elided and the character is collected */ \ ExoticEscapeChar /* both the backslash and the character are collected */ DangerousCharacter: one of / . ; < > [ ] ExoticEscapeChar: one of ! # $ % & ( ) * + , - : = ? @ ^ _ ` { | } ~ 3.8 This construct does not conflict with any other existing or proposed use of the hash character. In particular, if the hash character were to be defined as a new sort of Java operator, it would not conflict with this specification. Even if it were to be a construct which could validly be followed by a normal Java string literal, any ambiguity between the constructs could be resolved in favor of the operator by inserting whitespace between the hash and the opening quote of the string literal. 3.9 Exotic identifiers are occasionally useful for creating dynamically linkable classes or methods whose names are determined by naming scheme external to Java. (They may also be used for occasionally avoiding Java keywords, although a leading underscore will usually do just as well.) They are most crucially useful for forming invokedynamic calls, when the method name must refer to an entity in another language, or must contain structured information relevant to a metaobject protocol. package my.xml.tags; class #"\" { ... } package my.sql.bindings; interface Document { String title(); Text #"abstract"(); int #"class"(); ... } Dynamic mySchemeVector = ...; Dynamic x = Dynamic.#"scheme:vector-ref"(mySchemeVector, 42); 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 define a "dynamic expression" as an expression of static type Dynamic. Dynamic expressions can also be readily qualified to form invokedynamic calls. We extend the usefulness of dynamic expressions by allowing them to interact with other Java expressions and statements. Dynamic x = (any reference expression can go here); 4.2 The types Dynamic and Object may be freely interconverted, even though neither is a supertype of the other. (The JVM verifier already allows this, for any interface and Object, or any two interfaces. We expose one specific instance of this general principle by special- casing Dynamic.) No runtime check is emitted when an Object is converted to Dynamic. (That is, the compiler must never emit a checkcast to java.dyn.Dynamic.) Object x = (Object) "foo"; Dynamic y = x; Object z = y; System.out.println(x); // prints "foo" System.out.println(y); // prints "foo" System.out.println(z); // prints "foo" The middle line shows the limited way in which static overloading interacts with dynamic typing. The dynamic argument selects the Object overloading of "println" because Dynamic implicitly converts to Object. It also converts to any of the other types accepted by overloading of "println", but those other types would require a cast. Specifically, although the reference happens to be of type String, the String overloading of "println" will not be selected. As it happens, "println" produces consistent results anyway. 4.3 Any type may be undergo argument, assignment, or casting conversion to Dynamic, by first converting to Object. If the original type is a primitive, it undergoes boxing conversion. Dynamic x = 42; // (Dynamic) (Object) Integer.valueOf(42) Dynamic x = "foo"; // (Dynamic) (Object) "foo" (No bytecode need be emitted for such conversions, except for boxing. The compiler must not emit a checkcast to Dynamic.) 4.4 Dynamic expressions can be cast to any reference type, by first converting to Object, then casting, if that latter cast would be legal. (There is no special support for casting Dynamic to generic type instances.) Dynamic x = ...; String y = (String) x; // (String) (Object) x (The compiler must not emit a checkcast to java.dyn.Dynamic.) 4.5 Dynamic expressions can be cast to any primitive type, by first casting to the corresponding wrapper type then unboxing. Dynamic x = ...; int y = (int) x; // (int) (Integer) (Object) x 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. (In general, Java expressions which detects object reference identity will not work directly on dynamic expressions. Such expressions may be explicitly cast to Object, however.) COMPILATION: See JSR 292 for the specification of invokedynamic instructions. In brief, they begin with a new opcode, a CONSTANT_NameAndType index, and end with two required zero bytes. Method handle invocation is just an ordinary invokevirtual instruction, whose class is java.dyn.MethodHandle, whose name is "invoke", and whose descriptor is completely arbitrary; this requires no special compilation support beyond putting a loophole in the method lookup logic. Exotic identifiers require no compilation support beyond the lexer. (This assumes Unicode-clean symbol tables all the way to the backend.) There must be a final validity check in the class file assembler; this can (and should) be copied from the JVM specification. TESTING: Testing will be done the usual way, via unit tests exercising a broad variety of signatures and name spellings, and by early access customers experimenting with the new facilities. LIBRARY SUPPORT: The JVM-level behavior of the types java.dyn.Dynamic and java.dyn.MethodHandle are defined by JSR 292. Their language integration should be defined by an expert group with language expertise. JSR 292 per se involves extensive libraries for the functionality it defines, but they are not prerequisites to the features specified here. Other than exotic identifiers, the features described here have no impact except when the java.dyn types exist in the compilation environment. 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. OTHER CHANGES: Javap needs to disassemble invokedynamic instructions. Javap needs to be robust about unusual identifier spellings. (It already is, mostly.) MIGRATION: The feature is for new code only. These language features, along with the related JVM extensions, will make it possible for dynamic language implementations (a) to continue to be coded in Java, but (b) to avoid the performance and complexity overhead of the Core Reflection API. COMPATIBILITY BREAKING CHANGES: None. All changes are associated with previously unused types and/or syntaxes. EXISTING PROGRAMS: No special interaction. In earlier class files invokedynamic is an illegal opcode, and java.dyn.Dynamic is a previously unused type name. REFERENCES EXISTING BUGS: 6754038: writing libraries in Java for non-Java languages requires method handle invocation 6746458: writing libraries in Java for non-Java languages requires support for exotic identifiers 00TBD00: writing libraries in Java for non-Java languages requires permissive Dynamic type URL FOR PROTOTYPE: General: http://hg.openjdk.java.net/mlvm/mlvm/langtools http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/nb-javac/ Invokedynamic and method handles: http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/meth.txt http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/meth.patch Exotic identifiers: http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/quid.txt http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/quid.patch Casting rules for Dynamic: http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/dyncast.txt http://hg.openjdk.java.net/mlvm/mlvm/langtools/file/tip/dyncast.patch From david.goodenough at linkchoose.co.uk Mon Mar 30 01:53:57 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Mon, 30 Mar 2009 09:53:57 +0100 Subject: For further consideration... In-Reply-To: <200903250929.20256.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903250929.20256.david.goodenough@linkchoose.co.uk> Message-ID: <200903300953.59282.david.goodenough@linkchoose.co.uk> On Wednesday 25 March 2009, David Goodenough wrote: > On Tuesday 24 March 2009, Joe Darcy wrote: > > Greetings. > > > > In the first three weeks of Project Coin over two dozen proposals have > > been sent to the mailing list for evaluation. The proposals have ranged > > the gamut from new kinds of expressions, to new statements forms, to > > improved generics support. Thanks to everyone who has sent in > > interesting, thoughtful proposals and contributed to informative > > discussions on the list! > > > > While there is a bit less than a week left in the call for proposals > > period, there has been enough discussion on the list to winnow the slate > > of proposals sent in so far to those that merit further consideration > > for possible inclusion in the platform. > > > > First, Bruce Chapman's proposal to extend the scope of imports to > > include package annotations will be implemented under JLS maintenance so > > further action is unnecessary on this matter as part of Project Coin. > > Second, since the JSR 294 expert group is discussing adding a module > > level of accessibility to the language, the decision of whether or not > > to include Adrian Kuhn's proposal of letting "package" explicitly name > > the default accessibility level will be deferred to that body. Working > > with Alex, I reviewed the remaining proposals. Sun believes that the > > following proposals are small enough, have favorable estimated reward to > > effort ratios, and advance the stated criteria of making things > > programmers do everyday easier or supporting platform changes in JDK 7: > > > > * Strings in switch, Joe Darcy > > * Improved Exception Handling for Java, Neal Gafter > > * Automatic Resource Management, Josh Bloch > > * Improved Type Inference for Generic Instance Creation, > > Jeremy Manson > > * Elvis and Other Null-Safe Operators, > > Written by Neal Gafter and submitted by Stephen Colebourne > > * Simplified Varargs Method Invocation, Bob Lee > > > > As this is just an initial cut and the proposals are not yet in a form > > suitable for direct inclusion in the JLS, work should continue to refine > > these proposed specifications and preferably also to produce prototype > > implementations to allow a more thorough evaluation of the utility and > > scope of the changes. The email list should focus on improving the > > selected proposals and on getting any remaining new proposals submitted; > > continued discussion of the other proposals is discouraged. > > > > The final list of small language changes will be determined after the > > call for proposals is over so proposals sent in this week are certainly > > still in the running! The final list will only have around five items > > so it is possible not all the changes above will be on the eventual > > final list. > > > > -Joe > > I realise that as you say the list is not final, but looking at the list of > items my lightweight properties proposal is (at least to my eyes) > considerably smaller than most of the provisional list. It is smaller > in respect to all of the changes to the language, the changes to the > library and the changes to the compiler. > > I realise that anything mentioning properties is mired in history and > that there seems to be a "do it all or don't touch it" approach to the > problem which is a problem because the result is that it will not happen > for (to be realistic) at least 5 years. > > I also realise that the proposal is perhaps not written with detail updates > to the JLS etc, but I have never been involved in such things and would > hesitate to try to write them up properly. If this is needed then I am > sure it can be done. I am more than happy to work with anyone prepared to > give constructive help. > > I would therefore be interested to know why my proposal is not being > considered. I believe I have shown need (BeanBindings, Criteria and > PropertyChangeSupport uncheckable string literals for field names). > It is also in the spirit of Java and one of great strengths (compiler/ide > checkability). > > David It is a shame that no-one has seen fit to reply to this note. It does make the decision making process appear somewhat arbitrary. David From Joe.Darcy at Sun.COM Mon Mar 30 02:00:29 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 02:00:29 -0700 Subject: For further consideration... In-Reply-To: <200903300953.59282.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903250929.20256.david.goodenough@linkchoose.co.uk> <200903300953.59282.david.goodenough@linkchoose.co.uk> Message-ID: <49D08A2D.2010809@sun.com> David Goodenough wrote: > On Wednesday 25 March 2009, David Goodenough wrote: > >> On Tuesday 24 March 2009, Joe Darcy wrote: >> >>> Greetings. >>> >>> In the first three weeks of Project Coin over two dozen proposals have >>> been sent to the mailing list for evaluation. The proposals have ranged >>> the gamut from new kinds of expressions, to new statements forms, to >>> improved generics support. Thanks to everyone who has sent in >>> interesting, thoughtful proposals and contributed to informative >>> discussions on the list! >>> >>> While there is a bit less than a week left in the call for proposals >>> period, there has been enough discussion on the list to winnow the slate >>> of proposals sent in so far to those that merit further consideration >>> for possible inclusion in the platform. >>> >>> First, Bruce Chapman's proposal to extend the scope of imports to >>> include package annotations will be implemented under JLS maintenance so >>> further action is unnecessary on this matter as part of Project Coin. >>> Second, since the JSR 294 expert group is discussing adding a module >>> level of accessibility to the language, the decision of whether or not >>> to include Adrian Kuhn's proposal of letting "package" explicitly name >>> the default accessibility level will be deferred to that body. Working >>> with Alex, I reviewed the remaining proposals. Sun believes that the >>> following proposals are small enough, have favorable estimated reward to >>> effort ratios, and advance the stated criteria of making things >>> programmers do everyday easier or supporting platform changes in JDK 7: >>> >>> * Strings in switch, Joe Darcy >>> * Improved Exception Handling for Java, Neal Gafter >>> * Automatic Resource Management, Josh Bloch >>> * Improved Type Inference for Generic Instance Creation, >>> Jeremy Manson >>> * Elvis and Other Null-Safe Operators, >>> Written by Neal Gafter and submitted by Stephen Colebourne >>> * Simplified Varargs Method Invocation, Bob Lee >>> >>> As this is just an initial cut and the proposals are not yet in a form >>> suitable for direct inclusion in the JLS, work should continue to refine >>> these proposed specifications and preferably also to produce prototype >>> implementations to allow a more thorough evaluation of the utility and >>> scope of the changes. The email list should focus on improving the >>> selected proposals and on getting any remaining new proposals submitted; >>> continued discussion of the other proposals is discouraged. >>> >>> The final list of small language changes will be determined after the >>> call for proposals is over so proposals sent in this week are certainly >>> still in the running! The final list will only have around five items >>> so it is possible not all the changes above will be on the eventual >>> final list. >>> >>> -Joe >>> >> I realise that as you say the list is not final, but looking at the list of >> items my lightweight properties proposal is (at least to my eyes) >> considerably smaller than most of the provisional list. It is smaller >> in respect to all of the changes to the language, the changes to the >> library and the changes to the compiler. >> >> I realise that anything mentioning properties is mired in history and >> that there seems to be a "do it all or don't touch it" approach to the >> problem which is a problem because the result is that it will not happen >> for (to be realistic) at least 5 years. >> >> I also realise that the proposal is perhaps not written with detail updates >> to the JLS etc, but I have never been involved in such things and would >> hesitate to try to write them up properly. If this is needed then I am >> sure it can be done. I am more than happy to work with anyone prepared to >> give constructive help. >> >> I would therefore be interested to know why my proposal is not being >> considered. I believe I have shown need (BeanBindings, Criteria and >> PropertyChangeSupport uncheckable string literals for field names). >> It is also in the spirit of Java and one of great strengths (compiler/ide >> checkability). >> >> David >> > > It is a shame that no-one has seen fit to reply to this note. Especially since there has been no other recent traffic on the list to read or respond to! -Joe From brucechapman at paradise.net.nz Mon Mar 30 02:11:19 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Mon, 30 Mar 2009 22:11:19 +1300 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: References: Message-ID: <49D08CB7.4070308@paradise.net.nz> The naked dot notation is an interesting one. Thank you for sharing the idea. But now I want to steal it ;) One idea that has been floating in the back of my mind relates to a syntax for referring to the receiver of a method inside arguments to the method. If we coded such a behaviour using "that" as a keyword analogous to "this" (bear with me on this thought exercise) it could look like x.some().longish().expression().dosomething(that.ACONSTANT, that.ANOTHER_CONSTANT) but we can't really add a new keyword "that", but we could use a "naked dot" to mean the same thing. x.some().longish().expression().dosomething(.ACONSTANT, .ANOTHER_CONSTANT) or like this with a few semantic tweaks to allow access to static methods on the "receiver" of a constructor Thingamy t = new Thingamy(getBuilder().width(10).height(20).color(.YELLOW)); It wouldn't affect the algorithm for determining which method is intended, since the receiver has already been determined. This might also have value in fluent APIs. So Please don't specify "naked dot" behaviour until we have explored all useful meanings and determined which one has most value. No this is not intended as a proposal. Bruce Alexandre MAKARENKO wrote: > Naked dot > > AUTHOR(S): MAKARENKO Alexandre > OVERVIEW > FEATURE SUMMARY: Accessing object fields through unqualified "." > > MAJOR ADVANTAGE: Obsoletes attribute naming conventions. > > MAJOR BENEFIT: Makes Java programs visually more readable and eventually > less error-prone (see ?Strict mode? in details). > > To avoid name collisions and make source codes more maintainable > developers either hold with a convention for attribute names or prefix > members by ?this.? when refer to. Any naming convention, since not a part > of the language, offers only a weak distinction between local variable and > object field. Moreover it introduces extra characters and makes the source > code not very natural. Using ?this.? is absolutely safe but makes the > source code too much heavy. > Assessing object fields through unqualified ?.? may be an elegant > trade-off between readability and strictness. > > MAJOR DISADVANTAGE: May look assemblish. > > ALTERNATIVES: > Use "this.aField" or m_aField, or _aField, or any other naming convention > to distinguish between local variables and object fields. > > EXAMPLES > public class Point > { > public Point( double x, double y ) > { > .x = x; // compiles like this.x = x; > .y = y; // compiles like this.y = y; > } > private double x, y; > } > > DETAILS > SPECIFICATION: > During the name lookup process a package-less ?.? will be considered as > ?this.?. So that > ?.fieldName? will be equivalent to ?this.fieldName?. > > COMPILATION: The compiler detects unqualified dots and (if not a start of > floating point value) inserts an imaginary ?this?. > > TESTING: Not relevant > > LIBRARY SUPPORT: Not relevant. > > REFLECTIVE APIS: Not relevant > > OTHER CHANGES: Not relevant > > MIGRATION: > Weak mode (default). Attribute name look-up is carried out as it is > mentioned in the current language specification. For example > public class Point > { > ... > public move( double dx, double dy ) > { > .x += dx; // resolves .x to this.x > y += dy; // resolves y to this.y > } > private double x, y; > } > Strict mode (optional). For enterprises who would like to enforce > in-house coding styles, there may be a kind of -XStrictMemberAccess > compiler option. In this case the unqualified attribute references will > fail to compile. For example > > public class Point > { > ... > public move( double dx, double dy ) > { > .x += dx; // only local and static variables may > // be referred to without ?.? > y += dy; // compile time error: unknown y > } > private double x, y; > } > COMPATIBILITY > Ascending source level compatibility (in Weak mode) with existing Java > programs. > Absolute binary compatibility with all existing Java software. > Disassemblers may produce both ?this.? and ?.? (since they are > equivalent). > REFERENCES > None > > ************************************************************************* > This message and any attachments (the "message") are confidential, intended solely for the addressee(s), and may contain legally privileged information. > Any unauthorised use or dissemination is prohibited. E-mails are susceptible to alteration. > Neither SOCIETE GENERALE nor any of its subsidiaries or affiliates shall be liable for the message if altered, changed or > falsified. > ************ > Ce message et toutes les pieces jointes (ci-apres le "message") sont confidentiels et susceptibles de contenir des informations couvertes > par le secret professionnel. > Ce message est etabli a l'intention exclusive de ses destinataires. Toute utilisation ou diffusion non autorisee est interdite. > Tout message electronique est susceptible d'alteration. > La SOCIETE GENERALE et ses filiales declinent toute responsabilite au titre de ce message s'il a ete altere, deforme ou falsifie. > ************************************************************************* > > From John.Rose at Sun.COM Mon Mar 30 02:12:23 2009 From: John.Rose at Sun.COM (John Rose) Date: Mon, 30 Mar 2009 02:12:23 -0700 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <55b774930903290755y58cbb544nb61044c4c3b5d83b@mail.gmail.com> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> <55b774930903290755y58cbb544nb61044c4c3b5d83b@mail.gmail.com> Message-ID: On Mar 29, 2009, at 7:55 AM, Josh Suereth wrote: > I'm curious as to why you chose to not allow catching checked > exception from > Dynamic method calls That's a very good point. In fact, invokedynamic (like any other invokex) can throw any kind of exception at the JVM level. Since at the Java level it is untyped and therefore not statically checked, it must be possible, though not required, to catch checked exceptions. Thanks! On Mar 29, 2009, at 12:55 AM, Neal Gafter wrote: > Could you please send the proposal to this list? Done. > I don't really understand the intended specification with respect to > Dynamic. It is one the one hand described as an object type (e.g. > section 1.9) Dynamic is a reference type, but not a subtype of Object. This means it does not have the methods of Object. I don't think I used a phrase meaning "object type". > but on the other hand it doesn't inherit from Object > (section 1.1). You can't have it both ways. I can't tell, for > example, whether Dynamic is a valid type in a generic type parameter. I haven't decided yet if the language of the JLS for GTP's should have special pleading to allow Dynamic to have a type upper bound (and to erase) to Object, analogous to the special pleading I wrote that Dynamic[] is a subtype of Object[]. The JLS rules as they stand today make it impossible to have List. > If the answer is yes, then it must have Object as a supertype. Unless the type bound is itself Dynamic; then the JSL rules as written currently would allow Dynamic itself as a GTP. What they won't allow (as written) is Dynamic to be the GTP for a type variable bound by Object (or something else other than Dynamic). Hmm... If it's useful to have a field or return value or array element of type Dynamic, it is equally useful to have List. So I guess, yes, there needs to be a special pleading, a tweak about Dynamic and type bounds. The kind of tweak which won't cause a cascade of further tweaks--I don't know yet if that is possible. Can you give me a reference to what C# does about dynamic vs. type bounds? I suppose we could declare that Dynamic *does* have Object as a super class, but somehow hides all the inherited methods, even the ones that are final. That would be a different tack. That would require some special pleading in rules for method resolution; maybe that would be simpler. Regardless of the specification details, the overall goal is to make Dynamic into a type which has even less static content than Object, but allows any method call to be switched through invokedynamic. > You > might find it useful to review what C# has done in this area with > their type "dynamic". Yes, while working on this proposal I just saw Jim Hugunin present at PyCon; he gave a brief introduction to dynamic in C# 4.0. For my part, it was another funny case of parallel evolution between C# and Java. Not so funny for us, actually, that C# is releasing while Java is just cogitating. Snail-like pace is the price of multi-vendor standarization. Or of the compatibility requirements of success. Or of downsizing. Or something. > In short, it occupies the same location in C#'s > type lattice as Object, but it has some additional conversions defined > that are not subtype relationships. That's exactly what I am trying to do, if what you mean by "same location" is "peers at the same depth". If they were truly at the same location in the type lattice, wouldn't they be the same type? Perhaps I'm missing something here. Thanks for the prompt and incisive comments, Neal. -- John From rssh at gradsoft.com.ua Mon Mar 30 02:15:43 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 30 Mar 2009 12:15:43 +0300 (EEST) Subject: For further consideration... In-Reply-To: <200903300953.59282.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903250929.20256.david.goodenough@linkchoose.co.uk> <200903300953.59282.david.goodenough@linkchoose.co.uk> Message-ID: <8ffe17f2c83730648b2118acb1f73321.squirrel@wmail.gradsoft.ua> I belive Sun (in face of Joe Darcy) have dictator right do any decisions op proposal, just because Java it's child of Sun, and does not exists and contract duty on Sun decision making process about Sun product. Also I think that if we have 40 proposal and can implement only 10, than some valuable proposal be left and difference between accepted and rejected proposal will be fully subjective. I.e. this is Open Source. All service is AS-IS. If you don't like Java - fork one (GPL allows this) or create other language (I guess most subscriber of the list have own languages) But from other side, I will be happy to see some 'post-mortal' analysis of project, i. e. - split proposal on two parts: - too vague or understable. - for understable proposals - Sun string anticipate this proposal (why ?) - Sun provide some guidelines for future work and resubmission (made coin-s regular, one-s a year ?) Also I understand, that doing such post-mortal analysis is a lot of work, so I can only to ask something simular but do not require. > On Wednesday 25 March 2009, David Goodenough wrote: >> On Tuesday 24 March 2009, Joe Darcy wrote: >> > Greetings. >> > >> > In the first three weeks of Project Coin over two dozen proposals >> have >> > been sent to the mailing list for evaluation. The proposals have >> ranged >> > the gamut from new kinds of expressions, to new statements forms, to >> > improved generics support. Thanks to everyone who has sent in >> > interesting, thoughtful proposals and contributed to informative >> > discussions on the list! >> > >> > While there is a bit less than a week left in the call for proposals >> > period, there has been enough discussion on the list to winnow the >> slate >> > of proposals sent in so far to those that merit further consideration >> > for possible inclusion in the platform. >> > >> > First, Bruce Chapman's proposal to extend the scope of imports to >> > include package annotations will be implemented under JLS maintenance >> so >> > further action is unnecessary on this matter as part of Project Coin. >> > Second, since the JSR 294 expert group is discussing adding a module >> > level of accessibility to the language, the decision of whether or not >> > to include Adrian Kuhn's proposal of letting "package" explicitly name >> > the default accessibility level will be deferred to that body. >> Working >> > with Alex, I reviewed the remaining proposals. Sun believes that the >> > following proposals are small enough, have favorable estimated reward >> to >> > effort ratios, and advance the stated criteria of making things >> > programmers do everyday easier or supporting platform changes in JDK >> 7: >> > >> > * Strings in switch, Joe Darcy >> > * Improved Exception Handling for Java, Neal Gafter >> > * Automatic Resource Management, Josh Bloch >> > * Improved Type Inference for Generic Instance Creation, >> > Jeremy Manson >> > * Elvis and Other Null-Safe Operators, >> > Written by Neal Gafter and submitted by Stephen Colebourne >> > * Simplified Varargs Method Invocation, Bob Lee >> > >> > As this is just an initial cut and the proposals are not yet in a form >> > suitable for direct inclusion in the JLS, work should continue to >> refine >> > these proposed specifications and preferably also to produce prototype >> > implementations to allow a more thorough evaluation of the utility and >> > scope of the changes. The email list should focus on improving the >> > selected proposals and on getting any remaining new proposals >> submitted; >> > continued discussion of the other proposals is discouraged. >> > >> > The final list of small language changes will be determined after the >> > call for proposals is over so proposals sent in this week are >> certainly >> > still in the running! The final list will only have around five items >> > so it is possible not all the changes above will be on the eventual >> > final list. >> > >> > -Joe >> >> I realise that as you say the list is not final, but looking at the list >> of >> items my lightweight properties proposal is (at least to my eyes) >> considerably smaller than most of the provisional list. It is smaller >> in respect to all of the changes to the language, the changes to the >> library and the changes to the compiler. >> >> I realise that anything mentioning properties is mired in history and >> that there seems to be a "do it all or don't touch it" approach to the >> problem which is a problem because the result is that it will not happen >> for (to be realistic) at least 5 years. >> >> I also realise that the proposal is perhaps not written with detail >> updates >> to the JLS etc, but I have never been involved in such things and would >> hesitate to try to write them up properly. If this is needed then I am >> sure it can be done. I am more than happy to work with anyone prepared >> to >> give constructive help. >> >> I would therefore be interested to know why my proposal is not being >> considered. I believe I have shown need (BeanBindings, Criteria and >> PropertyChangeSupport uncheckable string literals for field names). >> It is also in the spirit of Java and one of great strengths >> (compiler/ide >> checkability). >> >> David > > It is a shame that no-one has seen fit to reply to this note. It does > make > the decision making process appear somewhat arbitrary. > > David > > From r.spilker at gmail.com Mon Mar 30 02:29:17 2009 From: r.spilker at gmail.com (Roel Spilker) Date: Mon, 30 Mar 2009 11:29:17 +0200 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <49D08CB7.4070308@paradise.net.nz> References: <49D08CB7.4070308@paradise.net.nz> Message-ID: You might consider a block scope object to use in the naked dot notation: with (someObject ) { .method(.CONSTANT); } The "this" could be the default object for methods, the class for static methods. That said, the only real benefit for this or class is when you have a local variable and a field with the same name. In those cases, the this qualifier is more clear than a naked dot. IMHO, people that use the this qualifier for all field and method access AND complain about it being too verbose will find a reason not to like the naked dot for some reason. From david.goodenough at linkchoose.co.uk Mon Mar 30 02:35:52 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Mon, 30 Mar 2009 10:35:52 +0100 Subject: For further consideration... In-Reply-To: <49D08A2D.2010809@sun.com> References: <49C95DB5.6020202@sun.com> <200903300953.59282.david.goodenough@linkchoose.co.uk> <49D08A2D.2010809@sun.com> Message-ID: <200903301035.53534.david.goodenough@linkchoose.co.uk> On Monday 30 March 2009, Joseph D. Darcy wrote: > David Goodenough wrote: > > On Wednesday 25 March 2009, David Goodenough wrote: > >> On Tuesday 24 March 2009, Joe Darcy wrote: > >>> Greetings. > >>> > >>> In the first three weeks of Project Coin over two dozen proposals have > >>> been sent to the mailing list for evaluation. The proposals have ranged > >>> the gamut from new kinds of expressions, to new statements forms, to > >>> improved generics support. Thanks to everyone who has sent in > >>> interesting, thoughtful proposals and contributed to informative > >>> discussions on the list! > >>> > >>> While there is a bit less than a week left in the call for proposals > >>> period, there has been enough discussion on the list to winnow the > >>> slate of proposals sent in so far to those that merit further > >>> consideration for possible inclusion in the platform. > >>> > >>> First, Bruce Chapman's proposal to extend the scope of imports to > >>> include package annotations will be implemented under JLS maintenance > >>> so further action is unnecessary on this matter as part of Project > >>> Coin. Second, since the JSR 294 expert group is discussing adding a > >>> module level of accessibility to the language, the decision of whether > >>> or not to include Adrian Kuhn's proposal of letting "package" > >>> explicitly name the default accessibility level will be deferred to > >>> that body. Working with Alex, I reviewed the remaining proposals. Sun > >>> believes that the following proposals are small enough, have favorable > >>> estimated reward to effort ratios, and advance the stated criteria of > >>> making things programmers do everyday easier or supporting platform > >>> changes in JDK 7: > >>> > >>> * Strings in switch, Joe Darcy > >>> * Improved Exception Handling for Java, Neal Gafter > >>> * Automatic Resource Management, Josh Bloch > >>> * Improved Type Inference for Generic Instance Creation, > >>> Jeremy Manson > >>> * Elvis and Other Null-Safe Operators, > >>> Written by Neal Gafter and submitted by Stephen Colebourne > >>> * Simplified Varargs Method Invocation, Bob Lee > >>> > >>> As this is just an initial cut and the proposals are not yet in a form > >>> suitable for direct inclusion in the JLS, work should continue to > >>> refine these proposed specifications and preferably also to produce > >>> prototype implementations to allow a more thorough evaluation of the > >>> utility and scope of the changes. The email list should focus on > >>> improving the selected proposals and on getting any remaining new > >>> proposals submitted; continued discussion of the other proposals is > >>> discouraged. > >>> > >>> The final list of small language changes will be determined after the > >>> call for proposals is over so proposals sent in this week are certainly > >>> still in the running! The final list will only have around five items > >>> so it is possible not all the changes above will be on the eventual > >>> final list. > >>> > >>> -Joe > >> > >> I realise that as you say the list is not final, but looking at the list > >> of items my lightweight properties proposal is (at least to my eyes) > >> considerably smaller than most of the provisional list. It is smaller > >> in respect to all of the changes to the language, the changes to the > >> library and the changes to the compiler. > >> > >> I realise that anything mentioning properties is mired in history and > >> that there seems to be a "do it all or don't touch it" approach to the > >> problem which is a problem because the result is that it will not happen > >> for (to be realistic) at least 5 years. > >> > >> I also realise that the proposal is perhaps not written with detail > >> updates to the JLS etc, but I have never been involved in such things > >> and would hesitate to try to write them up properly. If this is needed > >> then I am sure it can be done. I am more than happy to work with anyone > >> prepared to give constructive help. > >> > >> I would therefore be interested to know why my proposal is not being > >> considered. I believe I have shown need (BeanBindings, Criteria and > >> PropertyChangeSupport uncheckable string literals for field names). > >> It is also in the spirit of Java and one of great strengths > >> (compiler/ide checkability). > >> > >> David > > > > It is a shame that no-one has seen fit to reply to this note. > > Especially since there has been no other recent traffic on the list to > read or respond to! > > -Joe I realise that there have been a lot of new proposals to consider, but I am trying to understand what it is that needs to be improved in my proposal in order to get it considered. Without feedback that is very difficult. That is why I asked the questions about, and was dissapointed not to get a reply. David From develop4lasu at gmail.com Mon Mar 30 03:00:05 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 12:00:05 +0200 Subject: For further consideration... In-Reply-To: <200903301035.53534.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903300953.59282.david.goodenough@linkchoose.co.uk> <49D08A2D.2010809@sun.com> <200903301035.53534.david.goodenough@linkchoose.co.uk> Message-ID: <28bca0ff0903300300j5bb5e621r85a0b9187fc7f382@mail.gmail.com> 2009/3/30 David Goodenough : > > I realise that there have been a lot of new proposals to consider, but > I am trying to understand what it is that needs to be improved in my > proposal in order to get it considered. ? Without feedback that is very > difficult. ?That is why I asked the questions about, and was dissapointed > not to get a reply. > > David > > I think that JLS should have section: "Rejected parts of language" with explanation, because they are the same important as accepted. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From Ulf.Zibis at gmx.de Mon Mar 30 04:12:31 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 13:12:31 +0200 Subject: Simply implicit method chaining Message-ID: <49D0A91F.2080701@gmx.de> AUTHOR(S): Ulf Zibis, Cologne, Germany OVERVIEW FEATURE SUMMARY: Simply implicit method chaining. MAJOR ADVANTAGE: - Avoids casting in many situations. - Code would become more legible. MAJOR BENEFIT: This proposal would programmers motivate to write short, compact and best legible code. Because of the need of casting, programmers often avoid the method-chaining, as it sacrifices one legibility win against an other. Additionally Semantic of, in fact, void methods would become more clear. Secondly legibility would increase, if multiple repetition of initial referred instance identifier could be avoided. MAJOR DISADVANTAGE: Many existing methods should be reviewed, by refactoring return types to void, to profit from this feature. ALTERNATIVES: No EXAMPLES SIMPLE EXAMPLE: After this change: CharBuffer X = CharBuffer.allocate(26).position(2).put("C").position(25).put("Z"); Before this change: CharBuffer X = ((CharBuffer)((CharBuffer)CharBuffer.allocate(26) .position(2)).put("C").position(25)).put("Z"); or: CharBuffer X = CharBuffer.allocate(26); X.position(2); X.put("C").position(25); X.put("Z"); Comment: nit-pickers would say, that position(int pos, char c) could be used in this example, but everyone who has ever worked with nio buffers should know, of which worries I'm speaking about. ADVANCED EXAMPLE: After this change: String mySub = myVeryLongNamedString.subString(.indexOf("C"), .indexOf("Q")); Before this change: String mySub = myVeryLongNamedString.subString( myVeryLongNamedString.indexOf("C"), myVeryLongNamedString.indexOf("Q")); DETAILS SPECIFICATION: Grammar should allow that method invocation could refer backward to instance of initial identifier. '.' starting expressions should refer to initial identifier. COMPILATION: Compile: CharBuffer X = CharBuffer.allocate(26).position(2).put("C").position(25).put("Z"); to: CharBuffer X = CharBuffer.allocate(26); X.position(2); X.put("C"); X.position(25); X.put("Z"); Compile: CharBuffer X = CharBuffer.allocate(26); CharBuffer Y = X.position(2); to: CharBuffer X = CharBuffer.allocate(26); CharBuffer Y = X; Y.position(2); Compile: String mySub = myVeryLongNamedString.subString(.indexOf("C"), .indexOf("Q")); to: String mySub = myVeryLongNamedString.subString( myVeryLongNamedString.indexOf("C"), myVeryLongNamedString.indexOf("Q")); Compiler should skip castings from legacy code. Class file format would not be affected. Bytecode would not be affected. TESTING: Compiler should compile given examples without errors. Bytecode of 1. example should be same than before if casting would be eliminated. Bytecode of 2. example should be identical. LIBRARY SUPPORT: No supporting libraries are needed for the feature? REFLECTIVE APIS: There should not be any affection to reflection API. OTHER CHANGES: Legacy API methods returning this should be refactored to void. A list of affected APIs should be published (see MIGRATION). MIGRATION: A list of refactored APIs should be published. To take advantage of this change, programmers should scan their code base for usage of those APIs, and refactor the regarding statements manually or by usage of regex patterns. Anyway no refactoring is needed to stay compatible. COMPATIBILITY BREAKING CHANGES: No previously valid programs are now invalid. 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-March/000107.html https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?messageID=15541&forumID=1463 EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6451131 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774077 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=799586 URL FOR PROTOTYPE (optional): From Thomas.Hawtin at Sun.COM Mon Mar 30 04:15:00 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Mon, 30 Mar 2009 12:15:00 +0100 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> Message-ID: <49D0A9B4.3070003@sun.com> Neal Gafter wrote: > The proposed syntax is ambiguous. If one writes > > try > try stmt; > catch(...) stmt; > catch(...) stmt; > finally stmt; > > To which try statement is the second catch block attached? Please provide an unambiguous syntactic grammar if you still would like your proposal evaluated. There is obvious precedent in the infamous dangling-else ambiguity - catch/finally go with the innermost appropriate try. (FWIW, IMO there should be a lint warning for any "missing braces" (non-block statement) on a if/else/while/do/for.) Tom Hawtin From glenn.a.marshall at gmail.com Mon Mar 30 04:45:42 2009 From: glenn.a.marshall at gmail.com (Glenn A. Marshall) Date: Mon, 30 Mar 2009 07:45:42 -0400 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> Message-ID: <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> 1. This example is syntactically invalid since the first try does not have a catch nor finally clause; it is not ambiguous. Good example tho. The existing scoping of a catch, finally in the same scope corresponding to the immediately preceding try is not affected by this proposal. The existing requirement that a try be immediately followed by its catch, finally is not affected by this proposal. 2. The optional omission of the braces is only applicable to simple, single statement try, catch, finally (and method declaration). Braces are still allowed, and are required for disambiguation, as well as for multiple statement try, catch finally (and method declaration). They are are needed in this example. On Sun, Mar 29, 2009 at 10:27 PM, Neal Gafter wrote: > The proposed syntax is ambiguous. If one writes > > try > try stmt; > catch(...) stmt; > catch(...) stmt; > finally stmt; > > To which try statement is the second catch block attached? Please provide > an unambiguous syntactic grammar if you still would like your proposal > evaluated. > > Regards, > Neal > > -----Original Message----- > From: Glenn A.P.Marshall > Sent: Sunday, March 29, 2009 7:12 PM > To: coin-dev at openjdk.java.net > Subject: PROPOSAL: open and close brace optional for single statement try, > catch, finally, method declaration > > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Glenn Marshall > > *OVERVIEW > > FEATURE SUMMARY: > > Make open and close brace optional for single statement try, catch, > finally, method declaration. > > (the relatively rarely used single statement static initializer would > still require braces under this proposal, due to its relative rarity). > > MAJOR ADVANTAGE: > > Simple, single statement try blocks, catch blocks, and single > statement methods (for example, getter methods) are very common in > Java code. Unlike if, while and do statements, the open and close > braces are mandatory even when the target of the keyword is a single > statement. This requirement needlessly clutters the code with > unneeded open and close braces, increases code complexity slightly > and decreases readability. Removing this requirement addresses a > syntactic inconsistency in Java, whereby braces are required for some > single statement keyword targets but not others. > > MAJOR BENEFIT: > > More readable code, needless syntactic 'noise' removed, consistent > treatment of common single statement keyword targets. Since single > statement try, catch, method are very common, these benefits could be > applied many times to a typical large Java program. > > MAJOR DISADVANTAGE: > > Implementation cost is not 0. Benefits are relatively minor, to be > fair, per instance. Single statement keyword targets still exist - > static initializers; the syntax is still not 100% consistent as > regards single statement keyword targets. > > ALTERNATIVES: > > None. > > * EXAMPLES > > SIMPLE EXAMPLE: > > try connection.close(); > catch (SQLException se) handleException("close failed", se); > > ... > > public String getName() return name; > > > ADVANCED EXAMPLE: > > (this proposal is very simple; there are no advanced examples) > > *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. > > The grammar would be modified to make braces optional for single > statement try, catch, finally, method declarations. The block still > exists, when braces are omitted; it is a single statement. This is > exactly analogous to (for example) single statement while statements > without braces. > > This is purely a syntactic change - the type system, meaning of > expressions and statements remain unchanged. > > COMPILATION: How would the feature be compiled to class files? > > The simplest implementation would be for the Java source code parser > to recognize when the braces have been omitted and add them back, > internally, conceptually. This eliminates any downstream impact. > > TESTING: How can the feature be tested? > > Extend the source code samples processed by the compiler test suite > to include samples of code using this feature. Remember to handle > the null statement. > > LIBRARY SUPPORT: Are any supporting libraries needed for the feature? > > No. > > 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 > > 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. > > MIGRATION: Sketch how a code base could be converted, manually or > automatically, to use the new feature. > > Look for sequences of if try { ; } and replace with > try . > > Also for catch, method definitions, finally. > > COMPATIBILITY > BREAKING CHANGES: Are any previously valid programs now invalid? If so, > list one. > > All existing programs remain valid. > > 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 semantics of existing class files are unchanged. Source code > that previously omitted these required braces would not compile due > to a syntax error; this source will now compile. Compiler test cases > that tested this behaviour, expecting to fail, will now pass. > > * REFERENCES > > EXISTING BUGS: > > (none found) > > URL FOR PROTOTYPE (optional): > > No prototype at this time. > > > From Ulf.Zibis at gmx.de Mon Mar 30 04:56:32 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 13:56:32 +0200 Subject: Simply implicit method chaining In-Reply-To: <49D0A91F.2080701@gmx.de> References: <49D0A91F.2080701@gmx.de> Message-ID: <49D0B370.1060608@gmx.de> Correction: Am 30.03.2009 13:12, Ulf Zibis schrieb: > DETAILS > SPECIFICATION: > Grammar should allow that method invocation could refer backward to > instance of initial identifier, if direct preceeding method returns void. > '.' starting expressions should refer to initial identifier. > > From Thomas.Hawtin at Sun.COM Mon Mar 30 06:25:01 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Mon, 30 Mar 2009 14:25:01 +0100 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> Message-ID: <49D0C82D.1000208@sun.com> Glenn A. Marshall wrote: > 1. This example is syntactically invalid since the first try does not have > a catch nor finally clause; it is not ambiguous. Good example tho. Neal's example: >> try >> try stmt; >> catch(...) stmt; >> catch(...) stmt; >> finally stmt; Under the proposal "try stmt; catch(...) stmt;" is a statement. So the above is equivalent to: try stmt2; catch(...) stmt; finally stmt; But "try stmt; catch(...) stmt; catch(...) stmt;" is also a statement. So the example is also equivalent to: try stmt2; finally stmt; Which is different. Which is it? This is similar to the dangling-else ambiguity. http://en.wikipedia.org/wiki/Dangling_else > 2. The optional omission of the braces is only applicable to simple, single > statement try, catch, finally (and method declaration). Braces are still > allowed, and are required for disambiguation, as well as for multiple > statement try, catch finally (and method declaration). They are are needed > in this example. That reads as if you think of a block statement (in for example the typical while usage) as not a type of statement. A block is a statement. You could ammend the grammar so the proposal uses non-block statement, but this is not how the rest of the language works. BTW: Does anyone have a good suggestion for tool and basic Java grammar to check that syntax modifications are still parseable? Tom From glenn.a.marshall at gmail.com Mon Mar 30 06:29:07 2009 From: glenn.a.marshall at gmail.com (Glenn A. Marshall) Date: Mon, 30 Mar 2009 09:29:07 -0400 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> Message-ID: <980366fa0903300629n6a75f89ci5e1427908575e2a3@mail.gmail.com> retry of point 2 (hey, it was early :) ): s/for disambiguation/to indicate that the non default scope applies/ in full: 2. The optional omission of the braces is only applicable to simple, single statement try, catch, finally (and method declaration). Braces are still allowed, and are required to indicate that the non default scope applies, as well as for multiple statement try, catch finally (and method declaration). They are are needed in this example. On Mon, Mar 30, 2009 at 7:45 AM, Glenn A. Marshall < glenn.a.marshall at gmail.com> wrote: > 1. This example is syntactically invalid since the first try does not have > a catch nor finally clause; it is not ambiguous. Good example tho. > > The existing scoping of a catch, finally in the same scope corresponding to > the immediately preceding try is not affected by this proposal. > > The existing requirement that a try be immediately followed by its catch, > finally is not affected by this proposal. > > 2. The optional omission of the braces is only applicable to simple, > single statement try, catch, finally (and method declaration). Braces are > still allowed, and are required for disambiguation, as well as for multiple > statement try, catch finally (and method declaration). They are are needed > in this example. > > > On Sun, Mar 29, 2009 at 10:27 PM, Neal Gafter wrote: > >> The proposed syntax is ambiguous. If one writes >> >> try >> try stmt; >> catch(...) stmt; >> catch(...) stmt; >> finally stmt; >> >> To which try statement is the second catch block attached? Please provide >> an unambiguous syntactic grammar if you still would like your proposal >> evaluated. >> >> Regards, >> Neal >> >> -----Original Message----- >> From: Glenn A.P.Marshall >> Sent: Sunday, March 29, 2009 7:12 PM >> To: coin-dev at openjdk.java.net >> Subject: PROPOSAL: open and close brace optional for single statement >> try, catch, finally, method declaration >> >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): Glenn Marshall >> >> *OVERVIEW >> >> FEATURE SUMMARY: >> >> Make open and close brace optional for single statement try, catch, >> finally, method declaration. >> >> (the relatively rarely used single statement static initializer would >> still require braces under this proposal, due to its relative rarity). >> >> MAJOR ADVANTAGE: >> >> Simple, single statement try blocks, catch blocks, and single >> statement methods (for example, getter methods) are very common in >> Java code. Unlike if, while and do statements, the open and close >> braces are mandatory even when the target of the keyword is a single >> statement. This requirement needlessly clutters the code with >> unneeded open and close braces, increases code complexity slightly >> and decreases readability. Removing this requirement addresses a >> syntactic inconsistency in Java, whereby braces are required for some >> single statement keyword targets but not others. >> >> MAJOR BENEFIT: >> >> More readable code, needless syntactic 'noise' removed, consistent >> treatment of common single statement keyword targets. Since single >> statement try, catch, method are very common, these benefits could be >> applied many times to a typical large Java program. >> >> MAJOR DISADVANTAGE: >> >> Implementation cost is not 0. Benefits are relatively minor, to be >> fair, per instance. Single statement keyword targets still exist - >> static initializers; the syntax is still not 100% consistent as >> regards single statement keyword targets. >> >> ALTERNATIVES: >> >> None. >> >> * EXAMPLES >> >> SIMPLE EXAMPLE: >> >> try connection.close(); >> catch (SQLException se) handleException("close failed", se); >> >> ... >> >> public String getName() return name; >> >> >> ADVANCED EXAMPLE: >> >> (this proposal is very simple; there are no advanced examples) >> >> *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. >> >> The grammar would be modified to make braces optional for single >> statement try, catch, finally, method declarations. The block still >> exists, when braces are omitted; it is a single statement. This is >> exactly analogous to (for example) single statement while statements >> without braces. >> >> This is purely a syntactic change - the type system, meaning of >> expressions and statements remain unchanged. >> >> COMPILATION: How would the feature be compiled to class files? >> >> The simplest implementation would be for the Java source code parser >> to recognize when the braces have been omitted and add them back, >> internally, conceptually. This eliminates any downstream impact. >> >> TESTING: How can the feature be tested? >> >> Extend the source code samples processed by the compiler test suite >> to include samples of code using this feature. Remember to handle >> the null statement. >> >> LIBRARY SUPPORT: Are any supporting libraries needed for the feature? >> >> No. >> >> 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 >> >> 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. >> >> MIGRATION: Sketch how a code base could be converted, manually or >> automatically, to use the new feature. >> >> Look for sequences of if try { ; } and replace with >> try . >> >> Also for catch, method definitions, finally. >> >> COMPATIBILITY >> BREAKING CHANGES: Are any previously valid programs now invalid? If so, >> list one. >> >> All existing programs remain valid. >> >> 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 semantics of existing class files are unchanged. Source code >> that previously omitted these required braces would not compile due >> to a syntax error; this source will now compile. Compiler test cases >> that tested this behaviour, expecting to fail, will now pass. >> >> * REFERENCES >> >> EXISTING BUGS: >> >> (none found) >> >> URL FOR PROTOTYPE (optional): >> >> No prototype at this time. >> >> >> > From shams.mahmood at gmail.com Mon Mar 30 06:32:04 2009 From: shams.mahmood at gmail.com (Shams Mahmood) Date: Mon, 30 Mar 2009 08:32:04 -0500 Subject: Proposal: Indexing access syntax for Lists and Maps Message-ID: <36c722e00903300632y305509e6qe9da9692239d900e@mail.gmail.com> The proposed syntax for Set seems counter intuitive to me. While in the case of Arrays, Lists and Maps it will be to access the elements the Set ones will perform a contains check. Perhaps this should be proposed in a separate proposal with a different operator. e.g. set?[x] ---------- Forwarded message ---------- From: Tim Keith To: coin-dev at openjdk.java.net Date: Sun, 29 Mar 2009 22:40:31 -0700 Subject: Re: Proposal: Indexing access syntax for Lists and Maps Is it possible to include Set as well? E.g. "bool = set[x]" meaning "bool = set.contains(x)" and "set[x] = bool" meaning "bool ? set.add(x) : set.remove(x)" -- Tim On Sun, Mar 29, 2009 at 5:12 PM, Shams Mahmood wrote: > Indexing access syntax for Lists and Maps > > VERSION > This is version 1.0. > > AUTHOR(S): > Shams Mahmood Imam > > OVERVIEW > > FEATURE SUMMARY: > Collection classes are among the most frequently used in the Java SDK. > Currently Lists and Maps do not provide any additional language > feature to access individual elements unlike Arrays. This proposal > aims to provide these Collection citizens of java additional > language support to access elements like Arrays have currently. > > MAJOR ADVANTAGE: > Will provide a consistent syntax for accessing elements of Arrays, > Lists and Maps. In addition, the language grammar will not change > much since the subscript operator is already supported for Arrays. > > MAJOR BENEFIT: > Apart from the consistency mentioned above, implementation fo this > feature will result in fewer characters needed to be typed to achieve > simple access to elements in Maps/Lists. > > MAJOR DISADVANTAGE: > Like the for-each loop construct, it will expose the client to > NullPointerException(NPE)s when used with a null List/Map. However, > this shouldn't be such a major issue as NPEs are also generated > by arrays when the operator is used in a null array. > > ALTERNATIVES: > The comparatively more verbose get/set methods for Lists and get/put > methods for Maps. > > EXAMPLES > > SIMPLE EXAMPLE: > > public class Main { > public static void main(String[] arguments) { > List l1 = Arrays.asList(new String[] {"a", "b", "c"}); > String firstElement = l1[0]; > Map m1 = new HashMap(4); > m1[Integer.valueOf(1)] = "One"; > } > } > > ADVANCED EXAMPLE: > > public class Main { > public static void main(String[] arguments) { > List l1 = Arrays.asList(new String[] {"a", "b", "c"}); > Map m1 = new HashMap(4); > Map m2 = new HashMap(4); > > m2[l1[2]] = m2[m1[1]] = 4; // same as m2.put(l1.get(2), > m2.put(m1.get(1), 4)); > } > } > > DETAILS > > SPECIFICATION: > Java Language Specification changes: > > 15.29 (NEW CHAPTER): Collection Access Expressions > A collection access expression contains two subexpressions, the List/Map > reference expression (before the left bracket) and the index expression > (within the brackets). Note that the List/Map reference expression may be a > name or any expression that evaluates to a List/Map. The index experssion is > expected to evaluate to an int for Lists and a valid key type for Maps. > > CollectionAccess: > Expression [ Expression ] > > 15.8 Primary Expressions > original: > --------- > PrimaryNoNewArray: > Literal > Type . class > void . class > this > ClassName.this > ( Expression ) > ClassInstanceCreationExpression > FieldAccess > MethodInvocation > ArrayAccess > > replaced with: > -------------- > PrimaryNoNewArray: > Literal > Type . class > void . class > this > ClassName.this > ( Expression ) > ClassInstanceCreationExpression > FieldAccess > MethodInvocation > ArrayAccess > CollectionAccess > > 15.26 Assignment Operators > original: > --------- > LeftHandSide: > ExpressionName > FieldAccess > ArrayAccess > > replaced with: > -------------- > LeftHandSide: > ExpressionName > FieldAccess > ArrayAccess > CollectionAccess > > > COMPILATION: > > After successful creation of the AST handling the additional grammar for > Collection Access expressions, the syntactic sugar will be replaced by > JDK1.4 compatible code during the Code Generation phase. This is consistent > with how JDK5.0 constructs like the for-each loop is handled by the > compiler. > > e.g. > public class TestConcise { > public static void main(String[] args) { > java.util.Map m1 = new java.util.HashMap String>(); > m1[2] = "two"; > > java.util.LinkedList l1 = java.util.Arrays.asList( new String[] > {"a", "b", "c" }); > m1[3] = l1[2]; > l1[0] = m1[0]; > l1[1] = "one"; > } > } > > is converted to > public class TestConcise { > public TestConcise() { > super(); > } > > public static void main(String[] args) { > java.util.Map m1 = new java.util.HashMap String>(); > m1.put(Integer.valueOf(2), "two"); > > java.util.LinkedList l1 = java.util.Arrays.asList( new String[] > {"a", "b", "c" }); > m1.put(Integer.valueOf(3), l1.get(2)); > l1.set(0, m1.get(Integer.valueOf(0))); > l1.set(1, "one"); > } > } > > > TESTING: > > LIBRARY SUPPORT: > No additional library support is needed. > > REFLECTIVE APIS: > This proposal does not require any reflective API changes. > > OTHER CHANGES: > No changes required. > > MIGRATION: > No migration is needed. > > COMPATIBILITY > > BREAKING CHANGES: > No breaking changes. > > EXISTING PROGRAMS: > Existing programs are not affected by this change. > > REFERENCES > My Java7 Wishlist regarding Collections, > http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html > Implementation of My Java7 Wishlist, > http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html > > EXISTING BUGS: > None. > > URL FOR PROTOTYPE (optional): > Projects kijaro's concisecollections branch: > https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/ > > > > > -- Shams Mahmood From shams.mahmood at gmail.com Mon Mar 30 06:38:07 2009 From: shams.mahmood at gmail.com (Shams Mahmood) Date: Mon, 30 Mar 2009 08:38:07 -0500 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <36c722e00903300637r707bd913j5af4fbfeaf862fb2@mail.gmail.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> <49D0794C.7090400@sun.com> <36c722e00903300637r707bd913j5af4fbfeaf862fb2@mail.gmail.com> Message-ID: <36c722e00903300638l70454df2hb0f9aff1ad34f09a@mail.gmail.com> Hi Joe, Haven't used too many annotations in Java code. I had fiddled with the idea of Indexable (yes even I had come up with the same name - our vocabularies are so limited ;) ), but I decided otherwise for the following reasons: 1) Java traditionally has wanted to avoid operator overloading (Indexable means compiler providing operator support for Indexable marked classes). Although for each loops have special handling cases for Iterable types. 2) get/set implementation of Lists and Maps will need to change. In fact Map doesn't even have a set, so a new method will be added to the interface breaking backwards compatibility. Shams. On Mon, Mar 30, 2009 at 2:48 AM, Joseph D. Darcy wrote: > Hello. > > Shams Mahmood wrote: > >> Indexing access syntax for Lists and Maps >> >> VERSION >> This is version 1.0. >> >> AUTHOR(S): >> Shams Mahmood Imam >> >> OVERVIEW >> >> FEATURE SUMMARY: >> Collection classes are among the most frequently used in the Java SDK. >> Currently Lists and Maps do not provide any additional language feature to >> access individual elements unlike Arrays. This proposal aims to provide >> these Collection citizens of java additional language support to access >> elements like Arrays have currently. >> > > I was going to type up a proposal along these lines from scratch, but I'm > happy you sent in your proposal first, especially since there is a prototype > already :-) > > While collections are certainly very widely used and should have this > indexing support IMO, I think it is also important that indexing support not > be strictly limited to just classes implementing java.util.{List, Map}. For > example, if this kind of capability is added, I'd like enough flexibility to > give library developers the ability to in effect write a 64-bit array class. > (Semantically, a Java array today is basically just a map from int to some > other type.) > > The mechanism to indicate indexing is supported on a class must at least > support Lists and Maps: > > java.util.List > read: E get(int) > write: E set(int, E) > > java.util.Map > read: V get(Object) > write: V put(K, V) > > So variation in both the names of the methods must be accommodated as well > as the typing of the methods. > > The compiler needs a few pieces of information to perform the indexing > translating including "Should this type get indexing support?" and "If this > type gets indexing support, what methods do read and write operations get > mapped to?" > > The most magical way to indicate the indexing support bit is to have a > marker interface (or even an annotation) and then to have the names of the > get/set methods indicated as annotation values. As a strawman something > like > > public interface java.lang.Indexable {} > > @Documented > @Target(TYPE) > @Retention(RUNTIME) > @Inherited > public @interface java.lang.IndexableNames { > String reader() default "get"; > String writer(); > } > > where then, say, java.util.List would be changed from > > public interface List extends Collection > > to > > @IndexableNames(writer="set") > public interface List extends Collection extends Indexable > > However, this feels a bit too magical and there would be complications > about getting the indexable method names since annotation inheritance only > works along superclasses, not superinterfaces. > > A better approach is probably to create at least two new superinterfaces in > java.lang for the List and Map signatures. However, some care and analysis > will be needed to ensure a migration compatibility issue is not introduced. > (In support of the enhanced for loop in JDK 5, a superintface of > java.util.Iterator, java.lang.Iterator (lacking a remove method), was > introduced being being subsequently removed for migration compatibility > conflicts.) > > -Joe > -- Shams Mahmood -- Shams Mahmood From Thomas.Hawtin at Sun.COM Mon Mar 30 06:37:58 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Mon, 30 Mar 2009 14:37:58 +0100 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <49C91576.1010706@sun.com> References: <49C91576.1010706@sun.com> Message-ID: <49D0CB36.6030204@sun.com> Joseph D. Darcy wrote: > Alexandre MAKARENKO wrote: >> .x = x; // compiles like this.x = x; > I don't think being about to elide "this" in such situations would be > very helpful; at least having to write out "this.x" gives some clear > indication you aren't assigning x to itself! I would be more inclined to add a proposal for longer syntax to refer to local variables: this.x = local.x; Unfortunately I've not been able to come up with a reasonable syntax (without introducing a new keyword). Tom Hawtin From shams.mahmood at gmail.com Mon Mar 30 06:42:17 2009 From: shams.mahmood at gmail.com (Shams Mahmood) Date: Mon, 30 Mar 2009 08:42:17 -0500 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: References: <350193.71588.qm@web36708.mail.mud.yahoo.com> Message-ID: <36c722e00903300642v32804a4eh2eb24f42003b43b1@mail.gmail.com> Regarding get/set interface please see my refer to Joe in this same thread. Re Part of 15.13 and 15.26.1, thanks I will look into it today evening when I get back home :). Re Ara syntax to ArrayAccess and CollectionAccess differ - yes the syntax is very similar. I only added different Grammar elements as the names can be misleading as now Lists and Maps will also have subscript access. AFAIK if you see the kijaro code, I've implemented them in the same Visitor method that handles arrays. Will need a complete change in names or clone the Array access node to a List or Map node in the later stages of the compilation process once type info can be determined - i.e. Array, List or Map. 2009/3/30 > > Indexing access syntax for Lists and Maps > > > > VERSION > > This is version 1.0. > > > > AUTHOR(S): > > Shams Mahmood Imam > > > > OVERVIEW > > > > FEATURE SUMMARY: > > Collection classes are among the most frequently used in the Java SDK. > > Currently Lists and Maps do not provide any additional language > > feature to access individual elements unlike Arrays. This proposal > > aims to provide these Collection citizens of java additional > > language support to access elements like Arrays have currently. > > > > MAJOR ADVANTAGE: > > Will provide a consistent syntax for accessing elements of Arrays, > > Lists and Maps. In addition, the language grammar will not change > > Often we nee something 'less' than List or Map. > I. e. I would be good to see i additional to lists and maps some 'minimal' > get/set interface. > > > much since the subscript operator is already supported for Arrays. > > > > .... > > DETAILS > > > > SPECIFICATION: > > Java Language Specification changes: > > > > 15.29 (NEW CHAPTER): Collection Access Expressions > > A collection access expression contains two subexpressions, the List/Map > > reference expression (before the left bracket) and the index expression > > (within the brackets). Note that the List/Map reference expression may be > > a name or any expression that evaluates to a List/Map. The index > > experssion is expected to evaluate to an int for Lists and a valid key > > type for Maps. > > > > CollectionAccess: > > Expression [ Expression ] > > > > 15.8 Primary Expressions > > original: > > --------- > > PrimaryNoNewArray: > > Literal > > Type . class > > void . class > > this > > ClassName.this > > ( Expression ) > > ClassInstanceCreationExpression > > FieldAccess > > MethodInvocation > > ArrayAccess > > > > replaced with: > > -------------- > > PrimaryNoNewArray: > > Literal > > Type . class > > void . class > > this > > ClassName.this > > ( Expression ) > > ClassInstanceCreationExpression > > FieldAccess > > MethodInvocation > > ArrayAccess > > CollectionAccess > > > > Ara syntax to ArrayAccess and CollectionAccess difer ? > If not, this is one expression in grammar > > > > 15.26 Assignment Operators > > original: > > --------- > > LeftHandSide: > > ExpressionName > > FieldAccess > > ArrayAccess > > > > replaced with: > > -------------- > > LeftHandSide: > > ExpressionName > > FieldAccess > > ArrayAccess > > CollectionAccess > > > > The same note as previous. > > > > > Also JLS contains specifivation of behavious of assigment. > I changed this specification for class-array-assigment (in simular > proposal, but more general and annotation-based instead interface-based > as you) > http://docs.google.com/Doc?id=dhhvggr8_18djp85shk > > Part of 15.13 and 15.26.1 of JLS must be rewritten in you case. (I guess > you can get this changes from text of my proposal and slightly adopt, > semantics would be the same) > > > > > COMPILATION: > > > > After successful creation of the AST handling the additional grammar for > > Collection Access expressions, the syntactic sugar will be replaced by > > JDK1.4 compatible code during the Code Generation phase. This is > > consistent with how JDK5.0 constructs like the for-each loop is handled > by > > the compiler. > > > > e.g. > > public class TestConcise { > > public static void main(String[] args) { > > java.util.Map m1 = new java.util.HashMap > String>(); > > m1[2] = "two"; > > > > java.util.LinkedList l1 = java.util.Arrays.asList( new > > String[] {"a", "b", "c" }); > > m1[3] = l1[2]; > > l1[0] = m1[0]; > > l1[1] = "one"; > > } > > } > > > > is converted to > > public class TestConcise { > > public TestConcise() { > > super(); > > } > > > > public static void main(String[] args) { > > java.util.Map m1 = new java.util.HashMap > String>(); > > m1.put(Integer.valueOf(2), "two"); > > > > java.util.LinkedList l1 = java.util.Arrays.asList( new > > String[] {"a", "b", "c" }); > > m1.put(Integer.valueOf(3), l1.get(2)); > > l1.set(0, m1.get(Integer.valueOf(0))); > > l1.set(1, "one"); > > } > > } > > > > > > TESTING: > > > > LIBRARY SUPPORT: > > No additional library support is needed. > > > > REFLECTIVE APIS: > > This proposal does not require any reflective API changes. > > > > OTHER CHANGES: > > No changes required. > > > > MIGRATION: > > No migration is needed. > > > > COMPATIBILITY > > > > BREAKING CHANGES: > > No breaking changes. > > > > EXISTING PROGRAMS: > > Existing programs are not affected by this change. > > > > REFERENCES > > My Java7 Wishlist regarding Collections, > > > http://shamsmi.blogspot.com/2008/04/my-java7-wishlist-regarding-collections.html > > Implementation of My Java7 Wishlist, > > > http://shamsmi.blogspot.com/2008/05/implementation-of-my-java7-wishlist.html > > > > EXISTING BUGS: > > None. > > > > URL FOR PROTOTYPE (optional): > > Projects kijaro's concisecollections branch: > > > https://kijaro.dev.java.net/source/browse/kijaro/branches/concisecollections/ > > > > > > > > > > > > > -- Shams Mahmood From Ulf.Zibis at gmx.de Mon Mar 30 06:45:18 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 15:45:18 +0200 Subject: Simply implicit method invocation chaining In-Reply-To: <49D0A91F.2080701@gmx.de> References: <49D0A91F.2080701@gmx.de> Message-ID: <49D0CCEE.9010807@gmx.de> Another correction: Am 30.03.2009 13:12, Ulf Zibis schrieb: > OVERVIEW > FEATURE SUMMARY: Simply implicit method invocation chaining. > > From mthornton at optrak.co.uk Mon Mar 30 06:51:06 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Mon, 30 Mar 2009 14:51:06 +0100 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <36c722e00903300638l70454df2hb0f9aff1ad34f09a@mail.gmail.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> <49D0794C.7090400@sun.com> <36c722e00903300637r707bd913j5af4fbfeaf862fb2@mail.gmail.com> <36c722e00903300638l70454df2hb0f9aff1ad34f09a@mail.gmail.com> Message-ID: <49D0CE4A.2090700@optrak.co.uk> Shams Mahmood wrote: > Hi Joe, > > Haven't used too many annotations in Java code. I had fiddled with the idea > of Indexable (yes even I > had come up with the same name - our vocabularies are so limited ;) ), but I > decided otherwise for the > following reasons: > > 1) Java traditionally has wanted to avoid operator overloading (Indexable > means compiler providing > operator support for Indexable marked classes). Although for each loops have > special handling cases > for Iterable types. > 2) get/set implementation of Lists and Maps will need to change. In fact Map > doesn't even have a > set, so a new method will be added to the interface breaking backwards > compatibility. > > Shams. > > The advantage of using an annotation is that the List/Map interfaces DON'T need to change other than the addition of the annotation to specify the methods to be used for indexed get and set. So Map becomes something like: interface Map { @indexedGet V get(Object key); @indexedSet V put(K key, V value); // rest unchanged } interface List { @indexedGet E get(int index); @indexedSet E set(int index, e element); } Implementations of these interfaces don't need to change at all. A marker interface could be used as well, but doesn't seem to me to be strictly necessary (I'll post some more suggestions on this later). Regards, Mark Thornton From neal at gafter.com Mon Mar 30 07:25:09 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Mar 2009 07:25:09 -0700 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <49D0C82D.1000208@sun.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> Message-ID: <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> On Mon, Mar 30, 2009 at 6:25 AM, Tom Hawtin wrote: > This is similar to the dangling-else ambiguity. > http://en.wikipedia.org/wiki/Dangling_else Perhaps, but the Java grammar does not have a dangling-else ambiguity. The grammar was carefully written to be unambiguous. This proposal would make the grammar ambiguous. Regards, Neal From belingueres at gmail.com Mon Mar 30 07:31:11 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Mon, 30 Mar 2009 11:31:11 -0300 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CF5AF2.8020408@entreact.com> References: <49CF5AF2.8020408@entreact.com> Message-ID: IMO I'm against this. First, it is against current best practices for the design of object-oriented software to make easier to code something with a case statement on types/classes. Second: void log(Object object) { switch (object) instanceof { case String: logger.debug("'" + object + "'"); case Date: logger.debug(object.getTime()); case void: logger.debug("null"); default: logger.debug("<" + object.toString() + ">"); } } It think it is clearer (when possible) writing it with several overloaded methods and double dispatching. Third: } catch (Exception exception) { switch (exception.getCause()) instanceof { case ParseException: log.warn("Could not get status for '" + id + ": " + exception.getCause()); default: log.warn("Could not get status for '" + id + ", exception); } } in the case you intentionally left out the break statement, then the switch statement is not any clearer than doing an if. in the case that you wanted the break statement on the ParseException case, it is even clearer to use two catch blocks (one for ParseException and other for Throwable. 2009/3/29 Jeroen van Maanen : > I'd like to coin a switch (...) instanceof statement as a new feature of the > Java language. Please accept the attached proposal for review. > > Regards, Jeroen > > PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 > > AUTHOR(S): Jeroen van Maanen > > OVERVIEW > > FEATURE SUMMARY: The instanceof switch statement allows for clear and > concise > handling of alternatives that depend on the type of a given object. > > MAJOR ADVANTAGE: The instanceof switch statement removes the need for > different > names for the same object with different types and the extra declarations > and > casts to define those names. > > MAJOR BENEFIT: Why is the platform better if the proposal is adopted? > > MAJOR DISADVANTAGE: Coders, reviewers, and IDE's need to be able to read the > new statement and interpret and treat it correclty. > > ALTERNATIVES: There are no alternatives. > > EXAMPLES > > SIMPLE EXAMPLE: > > ?void log(Object object) { > ? ?switch (object) instanceof { > ? ?case String: > ? ? ?logger.debug("'" + object + "'"); > ? ?case Date: > ? ? ?logger.debug(object.getTime()); > ? ?case void: > ? ? ?logger.debug("null"); > ? ?default: > ? ? ?logger.debug("<" + object.toString() + ">"); > ? ?} > ?} > > ADVANCED EXAMPLE: > > ?public StatusEnum getStatus(String id) { > ? ?StatusEnum result; > ? ?try { > ? ? ?result = internalGetStatus(id); > ? ?} catch (Exception exception) { > ? ? ?switch (exception.getCause()) instanceof { > ? ? ?case ParseException: > ? ? ? ?log.warn("Could not get status for '" + id + ": " + > exception.getCause()); > ? ? ?default: > ? ? ? ?log.warn("Could not get status for '" + id + ", exception); > ? ? ?} > ? ?} > ?} > > public class PrettyPrinter { > ?private Writer writer; > > ?public PrettyPrinter(Writer writer) { > ? ?this.writer = writer; > ?} > > ?public write(Object object) { > ? ?switch (object) instanceof { > ? ? ?case String: > ? ? ? ?writer.write(stringDenotation(object)); > ? ? ?case Collection: > ? ? ? ?writer.write(object.getClass().getSimpleName() + ": ["); > ? ? ? ?for (Object element : object) { > ? ? ? ? ?write(element); > ? ? ? ? ?writer.write(","); > ? ? ? ?} > ? ? ? ?writer.write("]"); > ? ? ?case Map: > ? ? ? ?write(object.entrySet()); > ? ? ?case Map.Entry: > ? ? ? ?write(object.getKey()); > ? ? ? ?writer.write(":"); > ? ? ? ?write(object.getValue()); > ? ? ?case void: > ? ? ? ?writer.write("null"); > ? ? ?default: > ? ? ? ?// TODO: deal with arrays of unknown base type > ? ? ? ?writer.write("<" + object.toString() + ">"); > ? ?} > ?} > > ?private stringDenotation(String str) { > ? ?... > ?} > > } > > DETAILS > > SPECIFICATION: The switch instanceof feature adds an alternative to the > switch > statement to the grammar. > > ?SwitchStatement: > ? ?switch ( Expression ) SwitchBlock > ? ?switch ( Identifier ) instanceof TypeSwitchBlock > > ?TypeSwitchBlock: > ? ?{ TypeSwitchBlockStatementGroups? TypeSwitchLabels? } > > ?TypeSwitchBlockStatementGroups: > ? ?TypeSwitchBlockStatementGroup > ? ?TypeSwitchBlockStatementGroups TypeSwitchBlockStatementGroup > > ?TypeSwitchBlockStatementGroup: > ? ?TypeSwitchLabel BlockStatements > > ?TypeSwitchLabel: > ? ?case Type : > ? ?case void : > ? ?default : > > COMPILATION: The statement > > ?switch (<>) instanceof { > ?case <>: > ? ?<> > ?case <>: > ? ?<> > ?... > ?case void: > ? ?<> > ?... > ?default: > ? ?<> > ?} > > Would be compiled by desugaring it to > > ?if (<> instanceof <>) { > ? ?<> <> = (<>) <>; > ? ?<> > ?} > ?else if (<> instanceof <>) { > ? ?<> <> = (<>) <>; > ? ?<> > ?} > ?... > ?else if (<> == null) { > ? ?<> > ?} > ?... > ?else { > ? ?<> > ?} > > TESTING: The feature can be tested by compiling and running the examples and > comparing the results with the had coded expected desugared versions. > > LIBRARY SUPPORT: The feature needs no additional library support. > > REFLECTIVE APIS: The feature does not affect reflective api's. > > OTHER CHANGES: The feature does not need other changes. > > MIGRATION: This feature does not invalidate existing code. An existing code > base could be scanned for type casts. Occurrences of type casts should be > manually evaluated and, if desired, recoded using the new feature. > > COMPATIBILITY > > BREAKING CHANGES: This feature does not invalidate existing code. > > EXISTING PROGRAMS: This feature has no impact on existing code. > > REFERENCES > > EXISTING BUGS: There are no existing Sun bug ids related to this proposal. > > URL FOR PROTOTYPE: Not available. > > > > From Ulf.Zibis at gmx.de Mon Mar 30 08:01:49 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 17:01:49 +0200 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> Message-ID: <49D0DEDD.6070304@gmx.de> Am 30.03.2009 16:25, Neal Gafter schrieb: > > Perhaps, but the Java grammar does not have a dangling-else ambiguity. Neal, I don't understand. Please explain why Java does not have the dangling-else ambiguiaty. if (..) if (..) ...; else ...; is in fact: if (..) { if (..) ...; else ...; } and not: if (..) { if (..) ...; } else ...; Following "solution" should be a compile error: if (..) if (..) ...; ; else ...; -Ulf From Thomas.Hawtin at Sun.COM Mon Mar 30 08:07:04 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Mon, 30 Mar 2009 16:07:04 +0100 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> Message-ID: <49D0E018.6020909@sun.com> Neal Gafter wrote: > On Mon, Mar 30, 2009 at 6:25 AM, Tom Hawtin wrote: >> This is similar to the dangling-else ambiguity. >> http://en.wikipedia.org/wiki/Dangling_else > > Perhaps, but the Java grammar does not have a dangling-else ambiguity. I think that is inappropriately pedantic. JLS 3rd Ed, 14.5/p368: 'the if statement of the Java programming language suffers from the so-called "dangling else problme,".' I don't know how parser implementations tend to handle the issue. > The grammar was carefully written to be unambiguous. This proposal > would make the grammar ambiguous. The proposal is insufficiently detailed to tell whether the grammar would become ambiguous. A more detailed version could use the same hack to remove the ambiguity (although multiple usage of the hack grows the grammar non-linearly). Tom Hawtin From Ulf.Zibis at gmx.de Mon Mar 30 08:13:05 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 17:13:05 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: References: <49CF5AF2.8020408@entreact.com> Message-ID: <49D0E181.1040909@gmx.de> Am 30.03.2009 16:31, Gabriel Belingueres schrieb: > IMO I'm against this. > > First, it is against current best practices for the design of > object-oriented software to make easier to code something with a case > statement on types/classes. > > Second: > void log(Object object) { > switch (object) instanceof { > case String: > logger.debug("'" + object + "'"); > case Date: > logger.debug(object.getTime()); > case void: > logger.debug("null"); > default: > logger.debug("<" + object.toString() + ">"); > } > } > > This, IMHO, would be better: void log(Object object) { switch (object instanceof) { case String: logger.debug("'" + object + "'"); case Date: logger.debug(object.getTime()); case null: logger.debug("null"); default: logger.debug("<" + object.toString() + ">"); } } -Ulf > It think it is clearer (when possible) writing it with several > overloaded methods and double dispatching. > > Third: > } catch (Exception exception) { > switch (exception.getCause()) instanceof { > case ParseException: > log.warn("Could not get status for '" + id + ": " + > exception.getCause()); > default: > log.warn("Could not get status for '" + id + ", exception); > } > } > > in the case you intentionally left out the break statement, then the > switch statement is not any clearer than doing an if. > in the case that you wanted the break statement on the ParseException > case, it is even clearer to use two catch blocks (one for > ParseException and other for Throwable. > > > 2009/3/29 Jeroen van Maanen : > >> I'd like to coin a switch (...) instanceof statement as a new feature of the >> Java language. Please accept the attached proposal for review. >> >> Regards, Jeroen >> >> PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 >> >> AUTHOR(S): Jeroen van Maanen >> >> OVERVIEW >> >> FEATURE SUMMARY: The instanceof switch statement allows for clear and >> concise >> handling of alternatives that depend on the type of a given object. >> >> MAJOR ADVANTAGE: The instanceof switch statement removes the need for >> different >> names for the same object with different types and the extra declarations >> and >> casts to define those names. >> >> MAJOR BENEFIT: Why is the platform better if the proposal is adopted? >> >> MAJOR DISADVANTAGE: Coders, reviewers, and IDE's need to be able to read the >> new statement and interpret and treat it correclty. >> >> ALTERNATIVES: There are no alternatives. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> >> void log(Object object) { >> switch (object) instanceof { >> case String: >> logger.debug("'" + object + "'"); >> case Date: >> logger.debug(object.getTime()); >> case void: >> logger.debug("null"); >> default: >> logger.debug("<" + object.toString() + ">"); >> } >> } >> >> ADVANCED EXAMPLE: >> >> public StatusEnum getStatus(String id) { >> StatusEnum result; >> try { >> result = internalGetStatus(id); >> } catch (Exception exception) { >> switch (exception.getCause()) instanceof { >> case ParseException: >> log.warn("Could not get status for '" + id + ": " + >> exception.getCause()); >> default: >> log.warn("Could not get status for '" + id + ", exception); >> } >> } >> } >> >> public class PrettyPrinter { >> private Writer writer; >> >> public PrettyPrinter(Writer writer) { >> this.writer = writer; >> } >> >> public write(Object object) { >> switch (object) instanceof { >> case String: >> writer.write(stringDenotation(object)); >> case Collection: >> writer.write(object.getClass().getSimpleName() + ": ["); >> for (Object element : object) { >> write(element); >> writer.write(","); >> } >> writer.write("]"); >> case Map: >> write(object.entrySet()); >> case Map.Entry: >> write(object.getKey()); >> writer.write(":"); >> write(object.getValue()); >> case void: >> writer.write("null"); >> default: >> // TODO: deal with arrays of unknown base type >> writer.write("<" + object.toString() + ">"); >> } >> } >> >> private stringDenotation(String str) { >> ... >> } >> >> } >> >> DETAILS >> >> SPECIFICATION: The switch instanceof feature adds an alternative to the >> switch >> statement to the grammar. >> >> SwitchStatement: >> switch ( Expression ) SwitchBlock >> switch ( Identifier ) instanceof TypeSwitchBlock >> >> TypeSwitchBlock: >> { TypeSwitchBlockStatementGroups? TypeSwitchLabels? } >> >> TypeSwitchBlockStatementGroups: >> TypeSwitchBlockStatementGroup >> TypeSwitchBlockStatementGroups TypeSwitchBlockStatementGroup >> >> TypeSwitchBlockStatementGroup: >> TypeSwitchLabel BlockStatements >> >> TypeSwitchLabel: >> case Type : >> case void : >> default : >> >> COMPILATION: The statement >> >> switch (<>) instanceof { >> case <>: >> <> >> case <>: >> <> >> ... >> case void: >> <> >> ... >> default: >> <> >> } >> >> Would be compiled by desugaring it to >> >> if (<> instanceof <>) { >> <> <> = (<>) <>; >> <> >> } >> else if (<> instanceof <>) { >> <> <> = (<>) <>; >> <> >> } >> ... >> else if (<> == null) { >> <> >> } >> ... >> else { >> <> >> } >> >> TESTING: The feature can be tested by compiling and running the examples and >> comparing the results with the had coded expected desugared versions. >> >> LIBRARY SUPPORT: The feature needs no additional library support. >> >> REFLECTIVE APIS: The feature does not affect reflective api's. >> >> OTHER CHANGES: The feature does not need other changes. >> >> MIGRATION: This feature does not invalidate existing code. An existing code >> base could be scanned for type casts. Occurrences of type casts should be >> manually evaluated and, if desired, recoded using the new feature. >> >> COMPATIBILITY >> >> BREAKING CHANGES: This feature does not invalidate existing code. >> >> EXISTING PROGRAMS: This feature has no impact on existing code. >> >> REFERENCES >> >> EXISTING BUGS: There are no existing Sun bug ids related to this proposal. >> >> URL FOR PROTOTYPE: Not available. >> >> >> >> >> > > > From Joe.Darcy at Sun.COM Mon Mar 30 08:20:03 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 08:20:03 -0700 Subject: For further consideration... In-Reply-To: <200903301035.53534.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903300953.59282.david.goodenough@linkchoose.co.uk> <49D08A2D.2010809@sun.com> <200903301035.53534.david.goodenough@linkchoose.co.uk> Message-ID: <49D0E323.3000601@sun.com> David Goodenough wrote: > On Monday 30 March 2009, Joseph D. Darcy wrote: > >> David Goodenough wrote: >> >>> On Wednesday 25 March 2009, David Goodenough wrote: >>> >>>> On Tuesday 24 March 2009, Joe Darcy wrote: [snip] >>> It is a shame that no-one has seen fit to reply to this note. >>> >> Especially since there has been no other recent traffic on the list to >> read or respond to! >> >> -Joe >> > > I realise that there have been a lot of new proposals to consider, but > I am trying to understand what it is that needs to be improved in my > proposal in order to get it considered. Without feedback that is very > difficult. That is why I asked the questions about, and was dissapointed > not to get a reply. > When the subject of your proposal is listed as being out of scope before the project starts, http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size you should not be surprised when your proposal doesn't move forward. -Joe From david.goodenough at linkchoose.co.uk Mon Mar 30 08:47:45 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Mon, 30 Mar 2009 16:47:45 +0100 Subject: For further consideration... In-Reply-To: <49D0E323.3000601@sun.com> References: <49C95DB5.6020202@sun.com> <200903301035.53534.david.goodenough@linkchoose.co.uk> <49D0E323.3000601@sun.com> Message-ID: <200903301647.46821.david.goodenough@linkchoose.co.uk> On Monday 30 March 2009, Joseph D. Darcy wrote: > David Goodenough wrote: > > On Monday 30 March 2009, Joseph D. Darcy wrote: > >> David Goodenough wrote: > >>> On Wednesday 25 March 2009, David Goodenough wrote: > >>>> On Tuesday 24 March 2009, Joe Darcy wrote: > > [snip] > > >>> It is a shame that no-one has seen fit to reply to this note. > >> > >> Especially since there has been no other recent traffic on the list to > >> read or respond to! > >> > >> -Joe > > > > I realise that there have been a lot of new proposals to consider, but > > I am trying to understand what it is that needs to be improved in my > > proposal in order to get it considered. Without feedback that is very > > difficult. That is why I asked the questions about, and was dissapointed > > not to get a reply. > > When the subject of your proposal is listed as being out of scope before > the project starts, > > http://blogs.sun.com/darcy/entry/guidance_measure_language_change_size > > you should not be surprised when your proposal doesn't move forward. > > -Joe As I pointed out before, what you actually said was:- +Properties: While a detailed judgment would have to be made against a +specific proposal, as a new kind of type properties would most likely be at +least medium-sized. This is NOT the same as saying it is listed as out of scope, and the reason given is that it is likely to be "at least medium sized". My proposal is (at least to my eyes) smaller than many that are being accepted, and so would therefore seem to fall INSIDE the scope, NOT outside it. What I am asking for is what you said in your blog, that a detailed judgment should be make against this specific proposal. David From neal at gafter.com Mon Mar 30 09:11:45 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Mar 2009 09:11:45 -0700 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <49D0E018.6020909@sun.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> <49D0E018.6020909@sun.com> Message-ID: <15e8b9d20903300911q44b3c1c6md4c5bfe431c416a4@mail.gmail.com> On Mon, Mar 30, 2009 at 8:07 AM, Tom Hawtin wrote: > Neal Gafter wrote: >> >> On Mon, Mar 30, 2009 at 6:25 AM, Tom Hawtin wrote: >>> >>> This is similar to the dangling-else ambiguity. >>> http://en.wikipedia.org/wiki/Dangling_else >> >> Perhaps, but the Java grammar does not have a dangling-else ambiguity. > > I think that is inappropriately pedantic. JLS 3rd Ed, 14.5/p368: 'the if > statement of the Java programming language suffers from the so-called > "dangling else problme,".' I don't know how parser implementations tend to > handle the issue. Parser implementations tend to handle the issue by following the grammar in the JLS, which is not ambiguous. See the discussion following your quote. From Thomas.Hawtin at Sun.COM Mon Mar 30 09:28:29 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Mon, 30 Mar 2009 17:28:29 +0100 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <15e8b9d20903300911q44b3c1c6md4c5bfe431c416a4@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <15e8b9d20903300725o69dd9446h7288812d30a531f0@mail.gmail.com> <49D0E018.6020909@sun.com> <15e8b9d20903300911q44b3c1c6md4c5bfe431c416a4@mail.gmail.com> Message-ID: <49D0F32D.9050607@sun.com> Neal Gafter wrote: > On Mon, Mar 30, 2009 at 8:07 AM, Tom Hawtin wrote: >> I think that is inappropriately pedantic. JLS 3rd Ed, 14.5/p368: 'the if >> statement of the Java programming language suffers from the so-called >> "dangling else problme,".' I don't know how parser implementations tend to >> handle the issue. > > Parser implementations tend to handle the issue by following the > grammar in the JLS, which is not ambiguous. See the discussion > following your quote. A reason why I wasn't sure is that there are two Java grammars in the JLS. The (non-normative, IIRC) Chapter 18/p585 states: "The grammar presented piecemeal in the preceding chapters is much better for exposition, but it is not well suited as a basis for a parser. The grammar presented in this chapter is the basis for the reference implementation." The grammer contains: Statement: if ParExpression Statement [else Statement] I believe that causes an ambiguity. Are the quoted statements dated, wrong or something else? Tom Hawtin From Joe.Darcy at Sun.COM Mon Mar 30 09:43:43 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 09:43:43 -0700 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <49D0C82D.1000208@sun.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> Message-ID: <49D0F6BF.2040805@sun.com> Tom Hawtin wrote: > Glenn A. Marshall wrote: > > [snip] > BTW: Does anyone have a good suggestion for tool and basic Java grammar > to check that syntax modifications are still parseable? > Besides the hand-written recursive descent parser in javac living over in http://hg.openjdk.java.net/jdk7/jdk7/langtools the Compiler Grammar project http://openjdk.java.net/projects/compiler-grammar/ produced an ANTLR grammar that may be more amenable to checking. -Joe From the.ront at gmail.com Sun Mar 29 22:15:19 2009 From: the.ront at gmail.com (Ron Thomas) Date: Sun, 29 Mar 2009 23:15:19 -0600 Subject: Proposal: Generic Specification by Method Message-ID: <79d69e110903292215y1b0395bck6fa538ad726d70f6@mail.gmail.com> I would like to propose an extension to generics that would allow a generic type to be specified by methods in addition to the current inheritance/implementations. Generics by Method AUTHOR(S): Ron Thomas OVERVIEW FEATURE SUMMARY: Generics by Method allows for the use of Generics when using a common interface or super class is not an option. MAJOR ADVANTAGE: This would allow the use of generics based off of methods instead of off of classes/interfaces. MAJOR BENEFIT: Generics by Method will allow working with different classes with similar methods easier and more concise. Instead of relying on instanceof checks and class wrappers a generic type would suffice. While using Generics by Interface or super class is preferred, it is not always an option when dealing with 3rd party APIs. MAJOR DISADVANTAGE: Reflection will be used in order to achieve this goal, and the corresponding performance hit will be incurred. ALTERNATIVES: Use wrappers and class composition and use generics as-is. EXAMPLES SIMPLE EXAMPLE: The following method calls the close method on a list of resources. Unfortunately using the Closeable interface is no an option because one of the resources is supplied by a 3rd party resource does not implement the interface. public void closeAllResources(List resources) { for (T t : resources) { t.close(); } } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. The following example requires two methods, one of which throws an exception. public boolean checkResources(List resources, String host, int port) throws ResourceException { for (T t : resources) { int status = t.open(host, port); if (status < 0) { return false; } t.close(); } return true; } DETAILS SPECIFICATION: A having generic specification shall be added in the form: having(METHOD_SIG) METHOD_SIG := METHOD_NAME([[PARAM_TYPE,]* PARAM_TYPE]*) : [RETURN_TYPE] [throws [[EXCEPTION,]* EXCEPTION]* METHOD_NAME := java legal method name PARAM_TYPE := java legal parameter type RETURN_TYPE := java legal return type EXCEPTION := java level exception The following generic expressions become legal: Simple specification with no parameters. matches classes with: void method() Simple specifiation with parameters. matches classes with: int method(int, String) Constructor specification matches classes with constructor that have an int and String parameter Specification with exception matches classes with : int method(int, String) throws AException OR int method(int, String) COMPILATION: The compiler would use reflection to handle calling of the generic methods themselves. For example: public void closeAllResources(List resources) { for (T t : resources) { t.close(); } } Would effectively become: void closeAllResources(List resources) { for (T t : resources) { try { t.getClass().getMethod("close").invoke(t); } catch (IllegalAccessException ex) { throw new RuntimeException("Method close not found"); } catch (InvocationTargetException ex) { throw new RuntimeException("Method close not found"); } catch (NoSuchMethodException ex) { throw new RuntimeException("Method close not found"); } } } The compiler would also check all uses of this feature, and generate a compiler error if any usage does not match the criteria given. TESTING: The feature can be tested by compiling and running programs that exercise the feature. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. The use of this feature is compile time only. OTHER CHANGES: No. MIGRATION: No. This is a new feature and no existing code should be affected. COMPATIBILITY BREAKING CHANGES: No. EXISTING PROGRAMS: This is an addition to generics, and this change would be transparent to them. REFERENCES EXISTING BUGS: From Ulf.Zibis at gmx.de Mon Mar 30 11:31:02 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 20:31:02 +0200 Subject: Extend switch .. case statement for Object types and simple expressions Message-ID: <49D10FE6.3000404@gmx.de> AUTHOR(S): Ulf Zibis, Cologne, Germany OVERVIEW FEATURE SUMMARY: Extend switch .. case statement for Object types and simple expressions. MAJOR ADVANTAGE: - Increases readability of source in concurrence to if .. else if .. else syntax. - Sophisticated jumps. 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: (1): switch( primitiveInt) { case == 10 : doOnlyIf10(); // alternative syntax for 'case 10:' case < 10 : case >= 20 : break; default : doOnlyInRange(); } (2): switch( primitiveInt) { case (>= 10 && < 20) : doOnlyInRange(); default : throw new Exception("Out of range"); } (3): switch( myString) { case contains("foo") : doSomething(); break; case regionMatches(true, 2, otherString, 4, 6) : doSomethingElse(); break; default : doSomethingDefault(); } (4): switch( myString.equals()) { // alternative: myString.equals(..) case "foo" : foo(); break; case "bar" : bar(); break; default : dontCare(); } (5): switch( className.startsWith("String", ..)) { // alternative: className.startsWith("String", ?) case 0 : doForSimpleName(); break; case 9 : doForFullName(); break; default : canNotDecide(); } (6): 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); } (7): 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: switch( myString) { // note the '.', I personally would prefer this alternative! case .equals("red") : stop(); break; case .equals("green") : go(); break; default : openYourEyesForCrossingTraffic(); } 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. 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://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ⲁ EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5012262 URL FOR PROTOTYPE (optional): From crazybob at crazybob.org Mon Mar 30 11:39:17 2009 From: crazybob at crazybob.org (Bob Lee) Date: Mon, 30 Mar 2009 11:39:17 -0700 Subject: For further consideration... In-Reply-To: <200903301647.46821.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903301035.53534.david.goodenough@linkchoose.co.uk> <49D0E323.3000601@sun.com> <200903301647.46821.david.goodenough@linkchoose.co.uk> Message-ID: David, On Mon, Mar 30, 2009 at 8:47 AM, David Goodenough < david.goodenough at linkchoose.co.uk> wrote: > This is NOT the same as saying it is listed as out of scope, and the reason > given is that it is likely to be "at least medium sized". My proposal is > (at least to my eyes) smaller than many that are being accepted, and > so would therefore seem to fall INSIDE the scope, NOT outside it. > While your proposal may be small on syntax and library changes (I actually don't think it's small myself), based on the feedback you received, properties in general are obviously big on controversy. Bob From Ulf.Zibis at gmx.de Mon Mar 30 11:39:00 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 20:39:00 +0200 Subject: Proposal: Generic Specification by Method In-Reply-To: <79d69e110903292215y1b0395bck6fa538ad726d70f6@mail.gmail.com> References: <79d69e110903292215y1b0395bck6fa538ad726d70f6@mail.gmail.com> Message-ID: <49D111C4.3050202@gmx.de> I more would prefer java like syntax: having(void close()) -Ulf Am 30.03.2009 07:15, Ron Thomas schrieb: > I would like to propose an extension to generics that would allow a > generic type to be specified by methods in addition to the current > inheritance/implementations. > > Generics by Method > > AUTHOR(S): > > Ron Thomas > > OVERVIEW > > FEATURE SUMMARY: > > Generics by Method allows for the use of Generics when using a common > interface or super class is not an option. > > MAJOR ADVANTAGE: > > This would allow the use of generics based off of methods instead of > off of classes/interfaces. > > MAJOR BENEFIT: > > Generics by Method will allow working with different classes with > similar methods easier and more concise. Instead of relying on > instanceof checks and class wrappers a generic type would suffice. > While using Generics by Interface or super class is preferred, it is > not always an option when dealing with 3rd party APIs. > > MAJOR DISADVANTAGE: > > Reflection will be used in order to achieve this goal, and the > corresponding performance hit will be incurred. > > ALTERNATIVES: > > Use wrappers and class composition and use generics as-is. > > EXAMPLES > > SIMPLE EXAMPLE: > > The following method calls the close method on a list of resources. > Unfortunately using the Closeable interface is no an option because > one of the resources is supplied by a 3rd party resource does not > implement the interface. > > public > void closeAllResources(List resources) { > for (T t : resources) { > t.close(); > } > } > > ADVANCED EXAMPLE: Show advanced usage(s) of the feature. > > The following example requires two methods, one of which throws an exception. > public ResourceException : int)> > boolean checkResources(List resources, String host, int port) > throws ResourceException { > for (T t : resources) { > int status = t.open(host, port); > if (status < 0) { > return false; > } > t.close(); > } > return true; > } > > DETAILS > > SPECIFICATION: > > A having generic specification shall be added in the form: > having(METHOD_SIG) > > METHOD_SIG := METHOD_NAME([[PARAM_TYPE,]* PARAM_TYPE]*) : > [RETURN_TYPE] [throws [[EXCEPTION,]* EXCEPTION]* > METHOD_NAME := java legal method name > PARAM_TYPE := java legal parameter type > RETURN_TYPE := java legal return type > EXCEPTION := java level exception > > The following generic expressions become legal: > > Simple specification with no parameters. > > matches classes with: void method() > > Simple specifiation with parameters. > > matches classes with: int method(int, String) > > Constructor specification > > matches classes with constructor that have an int and String parameter > > Specification with exception > > matches classes with : int method(int, String) throws AException > OR int method(int, String) > > > COMPILATION: > > The compiler would use reflection to handle calling of the generic > methods themselves. > > For example: > public > void closeAllResources(List resources) { > for (T t : resources) { > t.close(); > } > } > > Would effectively become: > > void closeAllResources(List resources) { > for (T t : resources) { > try { > t.getClass().getMethod("close").invoke(t); > } catch (IllegalAccessException ex) { > throw new RuntimeException("Method close not found"); > } catch (InvocationTargetException ex) { > throw new RuntimeException("Method close not found"); > } catch (NoSuchMethodException ex) { > throw new RuntimeException("Method close not found"); > } > } > } > > The compiler would also check all uses of this feature, and generate a > compiler error if any usage does not match the criteria given. > > TESTING: > > The feature can be tested by compiling and running programs that > exercise the feature. > > LIBRARY SUPPORT: > > No. > > REFLECTIVE APIS: > > No. The use of this feature is compile time only. > > OTHER CHANGES: > > No. > > MIGRATION: > > No. This is a new feature and no existing code should be affected. > > COMPATIBILITY > > BREAKING CHANGES: > > No. > > EXISTING PROGRAMS: > > This is an addition to generics, and this change would be transparent to them. > > REFERENCES > > EXISTING BUGS: > > > From Ulf.Zibis at gmx.de Mon Mar 30 11:43:24 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 20:43:24 +0200 Subject: Extend switch .. case statement for Object types and simple expressions In-Reply-To: <49D10FE6.3000404@gmx.de> References: <49D10FE6.3000404@gmx.de> Message-ID: <49D112CC.8080705@gmx.de> 3rd advantage: - maybe in some cases javac and hotspot has chance to compute better optimized code. -Ulf Am 30.03.2009 20:31, Ulf Zibis schrieb: > AUTHOR(S): Ulf Zibis, Cologne, Germany > > OVERVIEW > FEATURE SUMMARY: Extend switch .. case statement for Object types and simple expressions. > MAJOR ADVANTAGE: > - Increases readability of source in concurrence to if .. else if .. else syntax. > - Sophisticated jumps. > 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: > (1): > switch( primitiveInt) { > case == 10 : doOnlyIf10(); // alternative syntax for 'case 10:' > case < 10 : > case >= 20 : break; > default : doOnlyInRange(); > } > (2): > switch( primitiveInt) { > case (>= 10 && < 20) : doOnlyInRange(); > default : throw new Exception("Out of range"); > } > (3): > switch( myString) { > case contains("foo") : doSomething(); break; > case regionMatches(true, 2, otherString, 4, 6) : doSomethingElse(); break; > default : doSomethingDefault(); > } > (4): > switch( myString.equals()) { // alternative: myString.equals(..) > case "foo" : foo(); break; > case "bar" : bar(); break; > default : dontCare(); > } > (5): > switch( className.startsWith("String", ..)) { // alternative: className.startsWith("String", ?) > case 0 : doForSimpleName(); break; > case 9 : doForFullName(); break; > default : canNotDecide(); > } > (6): > 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); > } > (7): > 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: > switch( myString) { // note the '.', I personally would prefer this alternative! > case .equals("red") : stop(); break; > case .equals("green") : go(); break; > default : openYourEyesForCrossingTraffic(); > } > 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. > 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://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ⲁ > EXISTING BUGS: > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5012262 > URL FOR PROTOTYPE (optional): > > > > > From evildeathmath at yahoo.com Mon Mar 30 11:51:12 2009 From: evildeathmath at yahoo.com (evildeathmath at yahoo.com) Date: Mon, 30 Mar 2009 11:51:12 -0700 (PDT) Subject: PROPOSAL: checked exception handling enhancement Message-ID: <339521.96354.qm@web112202.mail.gq1.yahoo.com> AUTHOR(S): Eugene Ray OVERVIEW FEATURE SUMMARY: A new class-level modifier keyword, "wtf", is added to the language, eliminating the need to explicitly handle every checked exception in the class. MAJOR ADVANTAGE: Increases readability of code. MAJOR BENEFIT: The absence of this feature has resulted in many people writing copious quantities of do-nothing catch blocks.? Also reserving "wtf" as a keyword encourages good variable naming practice by forbidding programmers from naming identifiers "wtf". MAJOR DISADVANTAGE: Many people will no longer write do-nothing catch blocks, freeing up programmer time. ALTERNATIVES: Continue writing do-nothing catch blocks. EXAMPLES SIMPLE EXAMPLE: In the class shown here, no catch blocks are necessary due to the "wtf" modifier at the beginning of the class. public wtf class Amazing { ?? ?public void readFile (String f) { ?? ??? ?BufferedReader in = new BufferedReader (new FileReader (in)); ?? ??? ?String i_should_really_have_used_nio = in.readLine (); ?? ??? ?String there_might_only_be_one_line_but_i_don_t_care = in.readLine (); ??????????????? in.close (); ??????????????? String no_exception_just_die = in.readLine (); ?? ?} } Currently, this would be written as: public wtf class Amazing { ?? ?public void readFile (String f) { ?? ??? ?try { ?? ??? ??? ?BufferedReader in = new BufferedReader (new FileReader (in)); ?? ??? ??? ?String i_should_really_have_used_nio = in.readLine (); ?? ??? ??? ?String there_might_only_be_one_line_but_i_don_t_care = in.readLine (); ?? ???????????????? in.close (); ?? ???????????????? String no_exception_just_die = in.readLine (); ?? ??? ?} ?? ??? ?catch (Exception e) { ?? ??? ?} ?? ?} } ADVANCED EXAMPLE: Optionally, class-wide error handling is possible via declaring a static "wtf" method, which will automatically be called anytime an exception is thrown in a wtf class. public wtf class Amazing { ?? ?public void readFile (String f) { ?? ??? ?BufferedReader in = new BufferedReader (new FileReader (in)); ?? ??? ?String i_should_really_have_used_nio = in.readLine (); ?? ??? ?String there_might_only_be_one_line_but_i_don_t_care = in.readLine (); ??????????????? in.close (); ??????????????? String no_exception_just_die = in.readLine (); ?? ?} ?? ?public void writeFile (String f) { ?? ??? ?FileOutputStream out = new FileOutputStream ("*.*"); ?? ??? ?out.write (new byte [90090]); ?? ??? ?out.close (); ?? ?} ?? ?public static void wtf (Throwable e, Object instance) { ?? ??? ?System.out.println ("You sure screwed up something, man"); ?? ?} } DETAILS SPECIFICATION: A new keyword, "wtf", is added to the language.? This is to be used as a modifier for a class declaration and indicates that any checked exception thrown within the body of any method in the class is to be automatically caught and handled in one of two ways.? If the class declares a public static method named "wtf" which takes in exactly one Throwable and one Object parameter, this method will be called every time a checked exception occurs with the exception as the Throwable parameter, and the instance of the class on which the method was called as the Object parameter (or null, if the exception occurs in a static method.)? If no such method is found, no error handling code of any kind is invoked and the exception simply vanishes into the aether.? The method in which the exception occurs will immediately return.? If the method returns an object type, it will return null.? If the method returns a numeric type, it will return the minimum value of the appropriate type, and if the method returns a boolean, it will return false. The "wtf" keyword is not context-sensitive; it is simply illegal to use it anywhere other than as described, and "wtf" is no longer a valid identifier name. COMPILATION: This feature will be implemented via a desugaring step by generating catch blocks in each instance method as follows: public int someInstanceMethod () { ?? ?// do something ?? ?return 42; } becomes: public int someInstanceMethod () { ?? ?try { ?? ??? ?// do something ?? ??? ?return 42; ?? ?} ?? ?catch (Exception e) { ?? ??? ?wtf (e, this); ?? ??? ?return Integer.MIN_VALUE; ?? ?} } and, for static methods: public static List writeBoringNovelConsistingEntirelyOfPronouns () { ?? ?List list = new ArrayList (); ?? ?// do something; ?? ?return list; } becomes: public static List writeBoringNovelConsistingEntirelyOfPronouns () { ?? ?try { ?? ??? ?List list = new ArrayList (); ?? ??? ?// do something; ?? ??? ?return list; ?? ?} ?? ?catch (Exception e) { ?? ??? ?wtf (e, null); ?? ??? ?return null; ?? ?} } If no public static void wtf (Throwable, Object) method is defined, an empty one will be generated as follows: public static void wtf (Throwable e, Object instance) { } TESTING Testing can be accomplished by taking an incredibly complex piece of existing software,systemically removing all exception-handling code, and placing the wtf keyword in all class definitions.? If the resulting application fails in difficult-to-diagnose ways for no discernable reason and with no error messages, the wtf keyword has been implemented successfully. LIBRARY SUPPORT: Entirely unnecessary. REFLECTIVE APIS: Entirely unnecessary. OTHER CHANGES: Entirely unnecessary. MIGRATION: See "TESTING" section above, and hire five additional programmers to implement. COMPATIBILITY BREAKING CHANGES: Programs that currently use "wtf" as an identifier will have to be altered, as "wtf" will no longer be a legal identifier name.? The authors of such code should be sternly reprimanded if this sort of thing is discovered. REFERENCES EXISTING BUGS None, but I will gladly file one if there is sufficient interest. URL FOR PROTOTYPE (optional): None yet, although "vi" can be adapted to perform the desugaring step. From david.goodenough at linkchoose.co.uk Mon Mar 30 11:50:40 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Mon, 30 Mar 2009 19:50:40 +0100 Subject: For further consideration... In-Reply-To: References: <49C95DB5.6020202@sun.com> <200903301647.46821.david.goodenough@linkchoose.co.uk> Message-ID: <200903301950.47544.david.goodenough@linkchoose.co.uk> On Monday 30 March 2009, Bob Lee wrote: > David, > > On Mon, Mar 30, 2009 at 8:47 AM, David Goodenough < > > david.goodenough at linkchoose.co.uk> wrote: > > This is NOT the same as saying it is listed as out of scope, and the > > reason given is that it is likely to be "at least medium sized". My > > proposal is (at least to my eyes) smaller than many that are being > > accepted, and so would therefore seem to fall INSIDE the scope, NOT > > outside it. > > While your proposal may be small on syntax and library changes (I actually > don't think it's small myself), based on the feedback you received, > properties in general are obviously big on controversy. > > Bob One tiny little bit of desugaring is all that is needed, and the library code is just one short class of just 180 lines so I can not see that it can be seen as anything but small. And to borrow (with small modification) the syntax description from the Field and Method literals proposal is just a few lines to be added to the JLS. I think that questions of controversy seem to be being used as a smoke screen to block sensible discussion of something which is genuinely needed. David From Ulf.Zibis at gmx.de Mon Mar 30 11:52:49 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 20:52:49 +0200 Subject: Strings in switch Message-ID: <49D11501.9000805@gmx.de> Hi Joe, I refer to your proposal: http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html If your proposal would unchanged be taken into JDK 7, there won't be any compatible way to implement my more general proposal "Extend switch .. case statement for Object types and simple expressions" 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. -Ulf From Joe.Darcy at Sun.COM Mon Mar 30 12:01:24 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 12:01:24 -0700 Subject: Strings in switch In-Reply-To: <49D11501.9000805@gmx.de> References: <49D11501.9000805@gmx.de> Message-ID: <49D11704.4060907@sun.com> Ulf Zibis wrote: > Hi Joe, > > I refer to your proposal: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html > > If your proposal would unchanged be taken into JDK 7, there won't be > any compatible way to implement my more general proposal "Extend > switch .. case statement for Object types and simple expressions" 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. While pattern matching is a fine feature in some languages, I don't think retrofitting that flavor of facility onto Java much over and above the existing capabilities of the switch statement is the right direction to evolve Java. -Joe From Joe.Darcy at Sun.COM Mon Mar 30 12:08:41 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Mon, 30 Mar 2009 12:08:41 -0700 Subject: PROPOSAL: checked exception handling enhancement In-Reply-To: <339521.96354.qm@web112202.mail.gq1.yahoo.com> References: <339521.96354.qm@web112202.mail.gq1.yahoo.com> Message-ID: <49D118B9.5010206@sun.com> evildeathmath at yahoo.com wrote: > AUTHOR(S): > > Eugene Ray > > OVERVIEW > > FEATURE SUMMARY: > > A new class-level modifier keyword, "wtf", is added to the language, eliminating the need to explicitly handle every checked exception in the class. > I think the wide possible use of the name in question must disqualify the proposal from consideration. -Joe From mthornton at optrak.co.uk Mon Mar 30 12:35:47 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Mon, 30 Mar 2009 20:35:47 +0100 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <49D0794C.7090400@sun.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> <49D0794C.7090400@sun.com> Message-ID: <49D11F13.10401@optrak.co.uk> Joseph D. Darcy wrote: > The compiler needs a few pieces of information to perform the indexing > translating including "Should this type get indexing support?" and "If > this type gets indexing support, what methods do read and write > operations get mapped to?" > public class java.lang.reflect.IndexedType { public static boolean isIndexable(Class type); public static IndexedType get(Class type); public Class getDeclaringClass(); public Class[] getIndexTypes(); public Method getReadMethod(); // or public String getReader(); public Method getWriteMethod(); } The compiler can implement a compile time analog of this. Assuming the use of annotations to indicate the methods, it will need to scan super interfaces. A marker interface would be one way of optimising this scan (only have to scan super interfaces that extend the marker). Alternatively the runtime could be extended so that the Class object holds a reference to IndexedType (for indexable types) which is populated at class load time. The method getIndexTypes() returns an array to allow n-D access. If this isn't desired replace by Class getIndexType(). > The most magical way to indicate the indexing support bit is to have a > marker interface (or even an annotation) and then to have the names of > the get/set methods indicated as annotation values. As a strawman > something like > > public interface java.lang.Indexable {} > > @Documented > @Target(TYPE) > @Retention(RUNTIME) > @Inherited > public @interface java.lang.IndexableNames { > String reader() default "get"; > String writer(); > } > or perhaps a pair of annotations: @Documented @Target(TYPE) @Retention(RUNTIME) @Inherited public @interface java.lang.IndexedRead { } @Documented @Target(TYPE) @Retention(RUNTIME) @Inherited public @interface java.lang.IndexedWrite { } > where then, say, java.util.List would be changed from > > public interface List extends Collection > > to > public interface List extends Collection { @indexedRead public E get(int index); @indexedWrite public E set(int index, E value); // ... } In addition, I would like to be able to declare something like this: public interface Matrix2D { @indexedRead public double get(int i, int j); @indexedWrite public void set(int i, int j, double value); } and then write Matrix2D m; double x = m[i,j]; m[i,j] = 2*x; Other notes: * Can an class inherit indexable capability more than once? * Can the read/write methods be overloaded? Regards, Mark Thornton From crazybob at crazybob.org Mon Mar 30 12:46:19 2009 From: crazybob at crazybob.org (Bob Lee) Date: Mon, 30 Mar 2009 12:46:19 -0700 Subject: For further consideration... In-Reply-To: <200903301950.47544.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903301647.46821.david.goodenough@linkchoose.co.uk> <200903301950.47544.david.goodenough@linkchoose.co.uk> Message-ID: On Mon, Mar 30, 2009 at 11:50 AM, David Goodenough < david.goodenough at linkchoose.co.uk> wrote: > I think that questions of controversy seem to be being used as a smoke > screen to block sensible discussion of something which is genuinely > needed. > I think we need a comprehensive solution that doesn't depend so heavily on reflection, if anything. A Coin proposal needs to be small, but it also needs to be a good, tasteful, generally useful solution, and it shouldn't preclude future better solutions. I'm sorry, but I read through your proposal and didn't find it very attractive in general, so I'm not interested in debating it point by point. Bob From Ulf.Zibis at gmx.de Mon Mar 30 12:46:32 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 21:46:32 +0200 Subject: Strings in switch In-Reply-To: <49D11704.4060907@sun.com> References: <49D11501.9000805@gmx.de> <49D11704.4060907@sun.com> Message-ID: <49D12198.30806@gmx.de> Am 30.03.2009 21:01, Joseph D. Darcy schrieb: > Ulf Zibis wrote: >> Hi Joe, >> >> I refer to your proposal: >> http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html >> >> >> If your proposal would unchanged be taken into JDK 7, there won't be >> any compatible way to implement my more general proposal "Extend >> switch .. case statement for Object types and simple expressions" 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. > > While pattern matching is a fine feature in some languages, I don't > think retrofitting that flavor of facility onto Java much over and > above the existing capabilities of the switch statement is the right > direction to evolve Java. > > -Joe > > Joe, thanks for your fast answer. 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, ...). Your syntax would lead programmers to stay on widely spreaded String literals. 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. There are 40 votes on Bug ID: 5012262 Please note, that these votes are for "Strings AND Objects in switch", and not for just "Strings in switch". -Ulf From Ulf.Zibis at gmx.de Mon Mar 30 13:47:35 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 22:47:35 +0200 Subject: Extend switch .. case statement for Object types and simple expressions In-Reply-To: <49D10FE6.3000404@gmx.de> References: <49D10FE6.3000404@gmx.de> Message-ID: <49D12FE7.80407@gmx.de> Another advanced example to minimize chance for NPE: switch( .equals(myString)) { // alternative: ?.equals(myString) case "foo" : foo(); break; case "bar" : bar(); break; default : dontCare(); } Am 30.03.2009 20:31, Ulf Zibis schrieb: > AUTHOR(S): Ulf Zibis, Cologne, Germany > > OVERVIEW > FEATURE SUMMARY: Extend switch .. case statement for Object types and simple expressions. > MAJOR ADVANTAGE: > - Increases readability of source in concurrence to if .. else if .. else syntax. > - Sophisticated jumps. > 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: > (1): > switch( primitiveInt) { > case == 10 : doOnlyIf10(); // alternative syntax for 'case 10:' > case < 10 : > case >= 20 : break; > default : doOnlyInRange(); > } > (2): > switch( primitiveInt) { > case (>= 10 && < 20) : doOnlyInRange(); > default : throw new Exception("Out of range"); > } > (3): > switch( myString) { > case contains("foo") : doSomething(); break; > case regionMatches(true, 2, otherString, 4, 6) : doSomethingElse(); break; > default : doSomethingDefault(); > } > (4): > switch( myString.equals()) { // alternative: myString.equals(..) > case "foo" : foo(); break; > case "bar" : bar(); break; > default : dontCare(); > } > (5): > switch( className.startsWith("String", ..)) { // alternative: className.startsWith("String", ?) > case 0 : doForSimpleName(); break; > case 9 : doForFullName(); break; > default : canNotDecide(); > } > (6): > 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); > } > (7): > 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: > switch( myString) { // note the '.', I personally would prefer this alternative! > case .equals("red") : stop(); break; > case .equals("green") : go(); break; > default : openYourEyesForCrossingTraffic(); > } > 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. > 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://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ⲁ > EXISTING BUGS: > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5012262 > URL FOR PROTOTYPE (optional): > > > > > From david.goodenough at linkchoose.co.uk Mon Mar 30 13:51:23 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Mon, 30 Mar 2009 21:51:23 +0100 Subject: For further consideration... In-Reply-To: References: <49C95DB5.6020202@sun.com> <200903301950.47544.david.goodenough@linkchoose.co.uk> Message-ID: <200903302151.24925.david.goodenough@linkchoose.co.uk> On Monday 30 March 2009, Bob Lee wrote: > On Mon, Mar 30, 2009 at 11:50 AM, David Goodenough < > > david.goodenough at linkchoose.co.uk> wrote: > > I think that questions of controversy seem to be being used as a smoke > > screen to block sensible discussion of something which is genuinely > > needed. > > I think we need a comprehensive solution that doesn't depend so heavily on > reflection, if anything. A Coin proposal needs to be small, but it also > needs to be a good, tasteful, generally useful solution, and it shouldn't > preclude future better solutions. I'm sorry, but I read through your > proposal and didn't find it very attractive in general, so I'm not > interested in debating it point by point. > > Bob By that arguement we never do anything because any solution will never be perfect. If the full solution is not available I would rather have a half way house that fulfills my need than wait indefinitely (and I call 5 years as near to indefinitely as matters). I need compiler checkability for field references now. David From rssh at gradsoft.com.ua Mon Mar 30 13:52:02 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Mon, 30 Mar 2009 23:52:02 +0300 (EEST) Subject: PROPOSAL: checked exception handling enhancement In-Reply-To: <339521.96354.qm@web112202.mail.gq1.yahoo.com> References: <339521.96354.qm@web112202.mail.gq1.yahoo.com> Message-ID: May be extend coin-project to include April 1-st ? //in wait for proposals about adding plain C preprocessor ;) > AUTHOR(S): > > Eugene Ray > > OVERVIEW > > FEATURE SUMMARY: > > A new class-level modifier keyword, "wtf", is added to the language, > eliminating the need to explicitly handle every checked exception in the > class. > > MAJOR ADVANTAGE: > > Increases readability of code. > > MAJOR BENEFIT: > > The absence of this feature has resulted in many people writing copious > quantities of do-nothing catch blocks.? Also reserving "wtf" as a keyword > encourages good variable naming practice by forbidding programmers from > naming identifiers "wtf". > > MAJOR DISADVANTAGE: > > Many people will no longer write do-nothing catch blocks, freeing up > programmer time. > > ALTERNATIVES: > > Continue writing do-nothing catch blocks. > > EXAMPLES > > SIMPLE EXAMPLE: > > In the class shown here, no catch blocks are necessary due to the "wtf" > modifier at the beginning of the class. > > > public wtf class Amazing { > > ?? ?public void readFile (String f) { > ?? ??? ?BufferedReader in = new BufferedReader (new FileReader (in)); > ?? ??? ?String i_should_really_have_used_nio = in.readLine (); > ?? ??? ?String there_might_only_be_one_line_but_i_don_t_care = in.readLine > (); > ??????????????? in.close (); > ??????????????? String no_exception_just_die = in.readLine (); > ?? ?} > > } > > > Currently, this would be written as: > > public wtf class Amazing { > > ?? ?public void readFile (String f) { > ?? ??? ?try { > ?? ??? ??? ?BufferedReader in = new BufferedReader (new FileReader (in)); > ?? ??? ??? ?String i_should_really_have_used_nio = in.readLine (); > ?? ??? ??? ?String there_might_only_be_one_line_but_i_don_t_care = > in.readLine (); > ?? ???????????????? in.close (); > ?? ???????????????? String no_exception_just_die = in.readLine (); > ?? ??? ?} > ?? ??? ?catch (Exception e) { > ?? ??? ?} > ?? ?} > > } > > > ADVANCED EXAMPLE: > > Optionally, class-wide error handling is possible via declaring a static > "wtf" method, which will automatically be called anytime an exception is > thrown in a wtf class. > > public wtf class Amazing { > > ?? ?public void readFile (String f) { > ?? ??? ?BufferedReader in = new BufferedReader (new FileReader (in)); > ?? ??? ?String i_should_really_have_used_nio = in.readLine (); > ?? ??? ?String there_might_only_be_one_line_but_i_don_t_care = in.readLine > (); > ??????????????? in.close (); > ??????????????? String no_exception_just_die = in.readLine (); > ?? ?} > > ?? ?public void writeFile (String f) { > ?? ??? ?FileOutputStream out = new FileOutputStream ("*.*"); > ?? ??? ?out.write (new byte [90090]); > ?? ??? ?out.close (); > ?? ?} > > ?? ?public static void wtf (Throwable e, Object instance) { > ?? ??? ?System.out.println ("You sure screwed up something, man"); > ?? ?} > > } > > > DETAILS > > SPECIFICATION: > > A new keyword, "wtf", is added to the language.? This is to be used as a > modifier for a class declaration and indicates that any checked exception > thrown within the body of any method in the class is to be automatically > caught and handled in one of two ways.? If the class declares a public > static method named "wtf" which takes in exactly one Throwable and one > Object parameter, this method will be called every time a checked > exception occurs with the exception as the Throwable parameter, and the > instance of the class on which the method was called as the Object > parameter (or null, if the exception occurs in a static method.)? If no > such method is found, no error handling code of any kind is invoked and > the exception simply vanishes into the aether.? The method in which the > exception occurs will immediately return.? If the method returns an object > type, it will return null.? If the method returns a numeric type, it will > return the minimum value of > the appropriate type, and if the method returns a boolean, it will return > false. > > The "wtf" keyword is not context-sensitive; it is simply illegal to use it > anywhere other than as described, and "wtf" is no longer a valid > identifier name. > > COMPILATION: > > This feature will be implemented via a desugaring step by generating catch > blocks in each instance method as follows: > > public int someInstanceMethod () { > ?? ?// do something > ?? ?return 42; > } > > becomes: > > public int someInstanceMethod () { > ?? ?try { > ?? ??? ?// do something > ?? ??? ?return 42; > ?? ?} > ?? ?catch (Exception e) { > ?? ??? ?wtf (e, this); > ?? ??? ?return Integer.MIN_VALUE; > ?? ?} > } > > and, for static methods: > > public static List writeBoringNovelConsistingEntirelyOfPronouns > () { > ?? ?List list = new ArrayList (); > ?? ?// do something; > ?? ?return list; > } > > becomes: > > public static List writeBoringNovelConsistingEntirelyOfPronouns > () { > ?? ?try { > ?? ??? ?List list = new ArrayList (); > ?? ??? ?// do something; > ?? ??? ?return list; > ?? ?} > ?? ?catch (Exception e) { > ?? ??? ?wtf (e, null); > ?? ??? ?return null; > ?? ?} > } > > > If no public static void wtf (Throwable, Object) method is defined, an > empty one will be generated as follows: > > public static void wtf (Throwable e, Object instance) { > } > > TESTING > > Testing can be accomplished by taking an incredibly complex piece of > existing software,systemically removing all exception-handling code, and > placing the wtf keyword in all class definitions.? If the resulting > application fails in difficult-to-diagnose ways for no discernable reason > and with no error messages, the wtf keyword has been implemented > successfully. > > LIBRARY SUPPORT: > > Entirely unnecessary. > > REFLECTIVE APIS: > > Entirely unnecessary. > > OTHER CHANGES: > > Entirely unnecessary. > > MIGRATION: > > See "TESTING" section above, and hire five additional programmers to > implement. > > COMPATIBILITY > > BREAKING CHANGES: > > Programs that currently use "wtf" as an identifier will have to be > altered, as "wtf" will no longer be a legal identifier name.? The authors > of such code should be sternly reprimanded if this sort of thing is > discovered. > > REFERENCES > > EXISTING BUGS > > None, but I will gladly file one if there is sufficient interest. > > URL FOR PROTOTYPE (optional): > > None yet, although "vi" can be adapted to perform the desugaring step. > > > > > > From develop4lasu at gmail.com Mon Mar 30 14:26:16 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Mon, 30 Mar 2009 23:26:16 +0200 Subject: PROPOSAL: 'final' without explicit type (update) Message-ID: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: MAJOR ADVANTAGE: It allows people to concentrate on logic during operating on heavy generics and to use values which are more intuitive for them than variables. MAJOR BENEFIT(s): - It allows to avoid duplicating unnecessarily types of declaration. - It increase a concentration on 'what I've got' than on 'what type is that' (we decrease size by one to obtain last element index, not because we can do this = it's int), while for variables we still keep concentrate on: 'what type is that' / 'what I can put there'. - Editing existing code to get some value from method chain is easier. - That method can be itself multi-thread with this, but it's a far future. - Using of Generics is easier. MAJOR DISADVANTAGE: Certainly, some people will overuse this solution. Consider operator is easier to read. It might be a problem if a person does not know how to give proper names for values. ALTERNATIVES: Normal variables. EXAMPLES SIMPLE / ADVANCED EXAMPLE: public Map> readMaping(){ final map = new HashMap>(); for( final row : readLine() ){ String key = row.get(0); row.remove(0); map.put(key, row); } return map; } public Map> readMaping(){ final map; //compile time error map= new HashMap>(); for( final row : readLine() ){ String key = row.get(0); row.remove(0); map.put(key, row); } return map; } public class Final { static final maping = new HashMap>(); } public class Final { static final maping = (Map>)loadMap(); } DETAILS SPECIFICATION: FieldDeclaration FieldDeclaration would be extended to allow omitting Type declaration if field is final and it's directly followed by assignment of new class instance creation(created object type would be used), or by Anonymous Constructors (JLS 15.9.5.1 )(direct superclass S would be used), or Enum constants preceded by EnumType (JLS 8.9) (Enum type would be used), or CastExpression (JLS 15.16) (ReferenceType would be used). SPECIFICATION: LocalVariableDeclarationStatement (JLS 14.4) Local Variable Declaration Statements would be extended to allow omitting Type declaration if field is final and listed rules taking place: - VariableInitializer appears. - Variable is not initialized directly with null (this can be discussed). - VariableInitializer type is neither primitive nor Object. --> primitive : they should not be mixed with Object-s to easy. --> Object : when object type is Object, we mostly deal with situation 'Unknown type', so this should not be hidden. - If VariableInitializer - Expression type is intersection type (we always omit Object type in intersection), then: --> If intersected types have common ancestor then this ancestor is used as type. --> If effect of intersected types is one Interface, then this interface is used as type. --> In other way, an error occurs. COMPILATION: Just as today, value type only need to be determined. TESTING: The same as final-s variables. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: None. COMPATIBILITY Only code is no forward compatible. REFERENCES RFE: Add Immutable types to Java: http://bugs.sun.com/view_bug.do?bug_id=4459053 Typedef (alias): http://bugs.sun.com/view_bug.do?bug_id=4983159 http://lasu2string.blogspot.com/2009/03/final-without-explicit-type-proposal.html From mthornton at optrak.co.uk Mon Mar 30 14:32:02 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Mon, 30 Mar 2009 22:32:02 +0100 Subject: For further consideration... In-Reply-To: <200903302151.24925.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903301950.47544.david.goodenough@linkchoose.co.uk> <200903302151.24925.david.goodenough@linkchoose.co.uk> Message-ID: <49D13A52.1020709@optrak.co.uk> David Goodenough wrote: > 5 years as near to indefinitely as matters). I need compiler checkability > for field references now. > > Define an annotation @interface @fieldReference { String name(); } class MyClass { @fieldReference("myField") static FieldRef FIELD_REF; static { // use reflection to set initialise static fields with @fieldReference annotations } } You could use an annotation processor to verify that the @fieldReference named valid fields and was attached to a suitable reference field. There are probably other ways of doing this, but it does give you the compile time check you want without requiring a language change. Regards Mark Thornton From Ulf.Zibis at gmx.de Mon Mar 30 14:43:07 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Mon, 30 Mar 2009 23:43:07 +0200 Subject: Simply implicit method invocation chaining (update) Message-ID: <49D13CEB.50208@gmx.de> AUTHOR(S): Ulf Zibis, Cologne, Germany OVERVIEW FEATURE SUMMARY: Simply implicit method invocation chaining. MAJOR ADVANTAGE: - Avoids casting in many situations. - Code would become more legible. MAJOR BENEFIT: This proposal would programmers motivate to write short, compact and best legible code. Because of the need of casting, programmers often avoid the method-chaining, as it sacrifices one legibility win against an other. Additionally Semantic of, in fact, void methods would become more clear. Secondly legibility would increase, if multiple repetition of initial referred instance identifier could be avoided. MAJOR DISADVANTAGE: Many existing methods should be reviewed, by refactoring return types to void, to profit from this feature. ALTERNATIVES: No EXAMPLES SIMPLE EXAMPLE: After this change: CharBuffer X = CharBuffer.allocate(26).position(2).put("C").position(25).put("Z"); Before this change: CharBuffer X = ((CharBuffer)((CharBuffer)CharBuffer.allocate(26) .position(2)).put("C").position(25)).put("Z"); or: CharBuffer X = CharBuffer.allocate(26); X.position(2); X.put("C").position(25); X.put("Z"); Comment: nit-pickers would say, that position(int pos, char c) could be used in this example, but everyone who has ever worked with nio buffers should know, of which worries I'm speaking about. ADVANCED EXAMPLE: After this change: String mySub = myVeryLongNamedString.subString(.indexOf("C"), .indexOf("Q")); Before this change: String mySub = myVeryLongNamedString.subString( myVeryLongNamedString.indexOf("C"), myVeryLongNamedString.indexOf("Q")); DETAILS SPECIFICATION: Grammar should allow that method invocation could refer backward to instance of most right suitable object identifier, if direct preceding method returns void. '.' starting expressions should refer to most right suitable object identifier. COMPILATION: Compile: CharBuffer X = CharBuffer.allocate(26).position(2).put("C").position(25).put("Z"); to: CharBuffer X = CharBuffer.allocate(26); X.position(2); X.put("C"); X.position(25); X.put("Z"); Compile: CharBuffer X = CharBuffer.allocate(26); CharBuffer Y = X.position(2); to: CharBuffer X = CharBuffer.allocate(26); CharBuffer Y = X; Y.position(2); Compile: String mySub = myVeryLongNamedString.subString(.indexOf("C"), .indexOf("Q")); to: String mySub = myVeryLongNamedString.subString( myVeryLongNamedString.indexOf("C"), myVeryLongNamedString.indexOf("Q")); Compiler should skip castings from legacy code. Class file format would not be affected. Bytecode would not be affected. TESTING: Compiler should compile given examples without errors. Bytecode of 1. example should be same than before if casting would be eliminated. Bytecode of 2. example should be identical. LIBRARY SUPPORT: No supporting libraries are needed for the feature? REFLECTIVE APIS: There should not be any affection to reflection API. OTHER CHANGES: Legacy API methods returning this should be refactored to void. A list of affected APIs should be published (see MIGRATION). MIGRATION: A list of refactored APIs should be published. To take advantage of this change, programmers should scan their code base for usage of those APIs, and refactor the regarding statements manually or by usage of regex patterns. Anyway no refactoring is needed to stay compatible. COMPATIBILITY BREAKING CHANGES: No previously valid programs are now invalid. 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-March/000107.html https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?messageID=15541&forumID=1463 EXISTING BUGS: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6451131 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774077 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=799586 URL FOR PROTOTYPE (optional): From schulz at e-spirit.de Mon Mar 30 15:03:30 2009 From: schulz at e-spirit.de (Stefan Schulz) Date: Tue, 31 Mar 2009 00:03:30 +0200 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> References: <49C56020.2070207@joda.org> <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> Message-ID: <49D141B2.1050808@e-spirit.de> I don't particularly like the enriched for each iteration control. While the J5-for-each loop only adds as syntactic sugar for convenient looping, iteration control adds overhead to the loop by creating two instances per for-each, counting the index, etc. Hence, as a developer in most cases one would be better off with doing the iterator stuff oneself. Frankly, I cannot see a great advantage of: for (Foo foo : fooList : it) { ... } saving two lines of code over: Iterator it = fooList.iterator(); while (it.hasNext()) { Foo foo = it.next(); ... } by adding two wrappers and stuff to the code in the background. The idea to employ a label to access the iterator I find even worse. A label does not relate to anything at runtime but a location in code. Stefan Marek Kozie? schrieb: > As you can see i was thinking about it for while: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001105.html > > And i found few problems. > New iterator Interface is wrong path, because people will be not able > to use it with their iterators. > > > So from your proposal I would remove Interface-s and link iterator > through label, > label type is return type of .iterator() method. > > > like: > > ArrayList some ....; > ... > i: for (Strign s:some){ > if ( (s==null) || (s.equals("bad")) )) i.remove(); > ... > i.next(); // compile time error ? > i.hasNext(); // OK > Iterator s = i; // error i is not variable (it just allow > to access it;) > } > > String[] array ...; > i: for (String s:array){ > i.getIndex;//? > } > > > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From Ulf.Zibis at gmx.de Mon Mar 30 15:13:59 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 31 Mar 2009 00:13:59 +0200 Subject: Extend switch .. case statement for all types and simple expressions (update) Message-ID: <49D14427.5070105@gmx.de> 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 Ulf.Zibis at gmx.de Mon Mar 30 15:19:02 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 31 Mar 2009 00:19:02 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49D0E181.1040909@gmx.de> References: <49CF5AF2.8020408@entreact.com> <49D0E181.1040909@gmx.de> Message-ID: <49D14556.1010708@gmx.de> Jeroen, I've included your proposal in my more general: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001182.html -Ulf From markmahieu at googlemail.com Mon Mar 30 15:36:56 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Mon, 30 Mar 2009 23:36:56 +0100 Subject: PROPOSAL: Rethrows Clause Message-ID: HTML version + prototype available at: http://slm888.com Rethrows Clause v0.1 AUTHOR(S): Mark Mahieu OVERVIEW FEATURE SUMMARY: Should be suitable as a summary in a language tutorial. A new clause on method declarations which allows exception translations (wrapping and rethrowing as a different type) to be cleanly defined separately from the body of the method. In many cases, checked exception type names do not then need to be repeated in a method's throws clause and in a throw statement in the method body. MAJOR ADVANTAGE: What makes the proposal a favorable change? The proposal adds direct support for a common idiom in daily use by Java programmers worldwide, allowing them to express their intentions with greater clarity and ease. In comparison with some proposals, this is an attempt to make dealing with checked exceptions easier by increasing the expressiveness of exception handling code in general, rather than by attempting to deprecate checked exceptions in favour of unchecked exceptions. MAJOR BENEFIT: Why is the platform better if the proposal is adopted? There is a reduction in the amount of boilerplate Java programmers have to read and write for code dealing with checked exceptions. Declarations specifying both thrown and rethrown (wrapped) exceptions are kept together, aiding comprehension of the code. MAJOR DISADVANTAGE: There is always a cost. As with any syntax sugar which enables an alternative way of expressing an existing idiom, programmers may be tempted to use it even when the existing idiom would be more appropriate. 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. Before: void before() throws ConfigException { try { Class.forName("where.is.the.Code"); } catch (ClassNotFoundException e) { throw new ConfigException(e); } } After: void after() catch ClassNotFoundException throw ConfigException { Class.forName("here.is.the.Code"); } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. Before: void suspendAccount() throws AuthorizationException, PersistenceException { try { checkMyAuthoritah(); db.update(/*...*/); log.recordInfo(/*...*/); } catch (InfernalDBException e) { throw new PersistenceException(e); } catch (InfernalLogException e) { throw new RuntimeException(e); } } After: void suspendAccount() throws AuthorizationException catch InfernalDBException throw PersistenceException, InfernalLogException throw RuntimeException { checkMyAuthoritah(); db.update(/*...*/); log.recordInfo(/*...*/); } 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. The syntactic grammar is modified to allow an optional rethrows clause immediately prior to a MethodBody: MethodDeclaratorRest: FormalParameters {[]} [throws QualifiedIdentifierList] ( ( [catch ExceptionTranslationList] MethodBody ) | ; ) ExceptionTranslationList: QualifiedIdentifier throw QualifiedIdentifier { , ExceptionTranslationList } A rethrows clause lists one or more exception translations, each translation consisting of a caught type C and a translated type T for which all of the following must hold: * C <: java.lang.Exception * T < java.lang.Throwable * Neither C nor T is a type variable. * T has an accessible constructor suitable for rethrowing a value of type C (see below). * T is not the same type as C. Any exceptions thrown by the method body which are a subtype of a caught exception type in the rethrows clause, are rethrown as the corresponding translated exception type. For a given translated type T with corresponding caught type C, if T has an accessible constructor accepting a value of type C, then the translation is equivalent to the following: catch (C e) { throw new T(e); } Otherwise it must have an accessible no argument constructor, and the translation is equivalent to: catch (C e) { throw new T().initCause(e); } The set of exception types declared to be thrown by a method is the union of: * the types in the throws clause * the translated types in the rethrow clause * the types thrown by the translated types' selected constructors For the purposes of exception analysis, the set of checked exception types which may be thrown by the method's body is the union of: * the types in the throws clause * the caught types in the rethrows clause It is a compile-time error if a rethrows clause contains a translation from a checked exception type C but there exists no checked exception type E such that all of the following hold: * E <: C * The method body can throw E * No preceding translation in the rethrow clause catches E or a supertype of E unless C is the class java.lang.Exception. A rethrows clause does not restrict which types may appear in a throws clause for the same method. In particular, for a given caught type C in the rethrows clause, it is permitted for some type C1 :> C to also be listed in the throws clause. 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! A simple desugaring could consist of enclosing the method body's statements in a try statement, with catch clauses for each translated exception type. For example, the following method: Method findMethod() catch ClassNotFoundException throw ConfigException, NoSuchMethodException throw ConfigException { Class c = Class.forName("some.Thing"); return c.getDeclaredMethod("execute", null); } would be desugared to: Method findMethod() throws ConfigException { try { Class c = Class.forName("some.Thing"); return c.getDeclaredMethod("execute", null); } catch (ClassNotFoundException e) { throw new ConfigException(e); } catch (MethodNotFoundException e) { throw new ConfigException(e); } } No changes to the classfile format are required. TESTING: How can the feature be tested? An initial set of jtreg tests is included in the prototype. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No 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. com.sun.source.tree.MethodTree would require updates to access the rethrows clause's caught and translated types. 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 MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. Catch clauses which simply wrap and rethrow an exception as another exception type not caught in an enclosing scope, can be trivially replaced with a rethrows clause, either manually or automatically. It should be possible for tools to offer bidirectional conversions such that an exception translation may be moved back into the method body if it is subsequently decided that additional logic is required. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. No 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 semantics of existing class files and legal source files are unchanged by this feature. REFERENCES EXISTING BUGS: Please include a list of any existing Sun bug ids related to this proposal. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6534270 (similar, but emphasizes unchecked exceptions) URL FOR PROTOTYPE (optional): http://slm888.com/javac From develop4lasu at gmail.com Mon Mar 30 15:43:44 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 00:43:44 +0200 Subject: PROPOSAL: Return 'this' (update) Message-ID: <28bca0ff0903301543i2492aa74n42958941445c82db@mail.gmail.com> AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: It allows the method to return reference to 'this' object. MAJOR ADVANTAGE: Simplification of ?return this? statement. 'void' can be easy replaced with 'this'. MAJOR BENEFIT(s): It would prevent NullPointerException, and make some 'builder' like interfaces look really clear and simple. MAJOR DISADVANTAGE: Returned value cannot be changed while inheritance, also other objects cannot be returned (in my opinion it's benefit). ALTERNATIVES: Self-bounded generics, This type, change returned type for every method on each inheritance. EXAMPLES SIMPLE/ADVANCED EXAMPLE: public class Builder { String text = ""; public this add (char c){text+=c;} public this add (String c){ if (c==null){ text +="null"; return; // this will be returned } text+=c; } public static void test(Builder builder) { builder.add('.').add("test()").add(':'); } } package test; public class ReturnThis { static class A { public this test() { } } static class B extends A { } static Class getReturnedType(Class classs) { try { return classs.getMethod("test").getReturnType(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(getReturnedType(A.class)); // will print: class returnThis.ReturnThis$A System.out.println(getReturnedType((new A()).getClass())); // will print: class returnThis.ReturnThis$A System.out.println(getReturnedType(B.class)); // will print: class returnThis.ReturnThis$B System.out.println(getReturnedType((new B()).getClass())); // will print: class returnThis.ReturnThis$B } } DETAILS SPECIFICATION: JLS 8.4 ResultType: Type void this A method declaration either specifies the type of value that the method returns, uses the keyword void to indicate that the method does not return a value, or uses the keyword this to indicate that the method return the reference to 'this' object. Keyword this cannot occurs if method is static. JLS 14.17 ReturnStatement: return Expressionopt ; A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value (?8.4), or in the body of a method that is declared, using the keyword this , to return this reference (?8...),or in the body of a constructor (?8.8). Method Overriding: Method with 'this' as ResultType can be override only with method with the same ResultType (proposal in this form can be, however, extended to work with backward covariant return types in future) COMPILATION: Method just before exiting from it's scope returns 'this'. Returned object type is ALWAYS actual object type. Method in compiled form have special 'this' type as ResultType, which is exchanged during loading to be actual object type: interface A{ this sample(); } interface B extends A { } class C implements B { this sample(){...}; } So compiled classes contain only methods with A and C, but after loading they are extended to ensure that Method.getReturnType() will be always actual object type. TESTING: Most efforts need to be focused on ensuring that Method.getReturnType() will work in a correct way. LIBRARY SUPPORT: No. REFLECTIVE APIS: No: From this perspective methods are simply overridden in runtime. OTHER CHANGES: Javadoc: return type is visible as 'this' and linked to current class. MIGRATION: None. COMPATIBILITY Backward: full; Forward: can be handled like other void type to be partial compatibile. REFERENCES Bug: 6479372 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6479372 http://java.net/cs/user/view/cs_msg/37432 http://lasu2string.blogspot.com/2009/03/return-this-proposal.html From belingueres at gmail.com Mon Mar 30 15:45:25 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Mon, 30 Mar 2009 19:45:25 -0300 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> Message-ID: Hi Marek: - VariableInitializer type is neither primitive nor Object. --> primitive : they should not be mixed with Object-s to easy. --> Object : when object type is Object, we mostly deal with situation 'Unknown type', so this should not be hidden. I still don't get why it is so bad to do something like this: final a = 1; // static type is int or final o = new Object(); // static type is Object, no doubt I still don't see the point on not making this feature more orthogonal (unless some convincing argument is presented against it.) 2009/3/30 Marek Kozie? : > AUTHOR: Lasu aka Marek Kozie? > > OVERVIEW > > FEATURE SUMMARY: > > MAJOR ADVANTAGE: > It allows people to concentrate on logic during operating on heavy > generics and to use values which are more intuitive for them than > variables. > > MAJOR BENEFIT(s): > - It allows to avoid duplicating unnecessarily types of declaration. > - It increase a concentration on 'what I've got' than on 'what type is > that' (we decrease size by one to obtain last element index, not > because we can do this = it's int), while for variables we still keep > concentrate on: 'what type is that' / 'what I can put there'. > - Editing existing code to get some value from method chain is easier. > - That method can be itself multi-thread with this, but it's a far future. > - Using of Generics is easier. > > > MAJOR DISADVANTAGE: > Certainly, some people will overuse this solution. > Consider operator is easier to read. > It might be a problem if a person does not know how to give proper > names for values. > > ALTERNATIVES: > Normal variables. > > > EXAMPLES > > SIMPLE / ADVANCED EXAMPLE: > ?public Map> readMaping(){ > ? ?final map = new HashMap>(); > ? ?for( final row : readLine() ){ > ? ? ?String key = row.get(0); > ? ? ?row.remove(0); > ? ? ?map.put(key, row); > ? ?} > ? ?return map; > ?} > > ?public Map> readMaping(){ > ? ?final map; //compile time error > ? ?map= new HashMap>(); > ? ?for( final row : readLine() ){ > ? ? ?String key = row.get(0); > ? ? ?row.remove(0); > ? ? ?map.put(key, row); > ? ?} > ? ?return map; > ?} > > public class Final { > ?static final maping = new HashMap>(); > } > > public class Final { > ?static final maping = (Map>)loadMap(); > } > > DETAILS > > SPECIFICATION: FieldDeclaration > FieldDeclaration would be extended to allow omitting Type declaration > if field is final and it's directly followed by assignment of new > class instance creation(created object type would be used), or by > Anonymous Constructors (JLS 15.9.5.1 )(direct superclass S would be > used), or Enum constants preceded by EnumType (JLS 8.9) (Enum type > would be used), or CastExpression (JLS 15.16) (ReferenceType would be > used). > > SPECIFICATION: LocalVariableDeclarationStatement > (JLS 14.4) Local Variable Declaration Statements would be extended to > allow omitting Type declaration if field is final and listed rules > taking place: > - VariableInitializer appears. > - Variable is not initialized directly with null (this can be discussed). > - VariableInitializer type is neither primitive nor Object. > ?--> primitive : they should not be mixed with Object-s to easy. > ?--> Object : when object type is Object, we mostly deal with > situation 'Unknown type', so this should not be hidden. > - If VariableInitializer - Expression type is intersection type (we > always omit Object type in intersection), then: > ?--> If intersected types have common ancestor then this ancestor is > used as type. > ?--> If effect of intersected types is one Interface, then this > interface is used as type. > ?--> In other way, an error occurs. > > > COMPILATION: > Just as today, value type only need to be determined. > > TESTING: > The same as final-s variables. > > LIBRARY SUPPORT: > No. > > REFLECTIVE APIS: > No. > > OTHER CHANGES: > No. > > MIGRATION: > None. > > COMPATIBILITY > Only code is no forward compatible. > > REFERENCES > ? RFE: Add Immutable types to Java: > http://bugs.sun.com/view_bug.do?bug_id=4459053 > > ? Typedef (alias): > http://bugs.sun.com/view_bug.do?bug_id=4983159 > > http://lasu2string.blogspot.com/2009/03/final-without-explicit-type-proposal.html > > From Ulf.Zibis at gmx.de Mon Mar 30 15:46:42 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 31 Mar 2009 00:46:42 +0200 Subject: Byte and Short Integer Literal Suffixes Message-ID: <49D14BD2.7010100@gmx.de> Comment for: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000905.html I suggest h and H for hex literal, instead of y and Y. -Ulf From brucechapman at paradise.net.nz Mon Mar 30 15:59:55 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Tue, 31 Mar 2009 11:59:55 +1300 (NZDT) Subject: Byte and Short Integer Literal Suffixes In-Reply-To: <49D14BD2.7010100@gmx.de> References: <49D14BD2.7010100@gmx.de> Message-ID: <1238453995.49d14eebae4b7@www.paradise.net.nz> Quoting Ulf Zibis : > Comment for: > http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000905.html > > I suggest h and H for hex literal, instead of y and Y. > > -Ulf > > > Ulf, The suffix specifies the type, not the number base. We are wanting to specify a type of byte (and short). The number base is already defined and is determined by the left hand characters, not the suffix. Bruce From develop4lasu at gmail.com Mon Mar 30 16:09:21 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 01:09:21 +0200 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> Message-ID: <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> W dniu 31 marca 2009 00:45 u?ytkownik Gabriel Belingueres napisa?: > Hi Marek: > > - VariableInitializer type is neither primitive nor Object. > ?--> primitive : they should not be mixed with Object-s to easy. > ?--> Object : when object type is Object, we mostly deal with > situation 'Unknown type', so this should not be hidden. > > I still don't get why it is so bad to do something like this: > final a = 1; // static type is int > or > final o = new Object(); // static type is Object, no doubt > > I still don't see the point on not making this feature more orthogonal > (unless some convincing argument is presented against it.) > > For primitives I would prefer: primitive a = 1; // a is int / short / byte rather than: final a = 1; // static type is int Primitives represent other level of abstraction and mixing them will make people to be confused (more or less). final o = new Object(); // in this form it's ok here I see problem: final o = some.getBoo().getLocalization(); // o is Object For some reason we did not ensured valid type to be returned, so we should care about it while declaring 'o', or say that we do not care: final o = (Localization) some.getBoo().getLocalization(); final Object o = some.getBoo().getLocalization(); If we allow final to be ANY type, then backing to declaration will be required just to make correction, this will piss off programmers. So primitives and Object-s are special types and should be handled in this way. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From martin.dobmeier at googlemail.com Mon Mar 30 13:04:04 2009 From: martin.dobmeier at googlemail.com (Martin Dobmeier) Date: Mon, 30 Mar 2009 22:04:04 +0200 Subject: For further consideration... In-Reply-To: <49C95DB5.6020202@sun.com> References: <49C95DB5.6020202@sun.com> Message-ID: <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> Hey everybody, I'm sorta missing some kind of explanation why some of the other proposals were not considered (e.g. enhanced string literals, enhanced for loop iteration control, etc.). Something along the lines of: Do they entail too big of a language change? Do they address no real pain points in the language? Were they not specified thoroughly enough? In short: What's Sun's opinion on those proposals? However, though I've read a lot of the mails posted to this list, I might have just missed those things. Anyway, my first impression when reading the short list was that it looks almost exactly like the language changes that have been floating around on some Sun blogs for some time now. I admit that it occured to me that it looks a bit "planned" (no offense though). I'm pretty much happy with almost all of the stuff on the short list. On the other hand I'd really like to hear some opinions on why one proposal was chosen over the other. There are maybe to many to go into too much detail, but just a few thoughts? Also, what about a List/Map literal proposal? Did I miss that? Cheers, Martin 2009/3/24 Joe Darcy > Greetings. > > In the first three weeks of Project Coin over two dozen proposals have > been sent to the mailing list for evaluation. The proposals have ranged > the gamut from new kinds of expressions, to new statements forms, to > improved generics support. Thanks to everyone who has sent in > interesting, thoughtful proposals and contributed to informative > discussions on the list! > > While there is a bit less than a week left in the call for proposals > period, there has been enough discussion on the list to winnow the slate > of proposals sent in so far to those that merit further consideration > for possible inclusion in the platform. > > First, Bruce Chapman's proposal to extend the scope of imports to > include package annotations will be implemented under JLS maintenance so > further action is unnecessary on this matter as part of Project Coin. > Second, since the JSR 294 expert group is discussing adding a module > level of accessibility to the language, the decision of whether or not > to include Adrian Kuhn's proposal of letting "package" explicitly name > the default accessibility level will be deferred to that body. Working > with Alex, I reviewed the remaining proposals. Sun believes that the > following proposals are small enough, have favorable estimated reward to > effort ratios, and advance the stated criteria of making things > programmers do everyday easier or supporting platform changes in JDK 7: > > * Strings in switch, Joe Darcy > * Improved Exception Handling for Java, Neal Gafter > * Automatic Resource Management, Josh Bloch > * Improved Type Inference for Generic Instance Creation, > Jeremy Manson > * Elvis and Other Null-Safe Operators, > Written by Neal Gafter and submitted by Stephen Colebourne > * Simplified Varargs Method Invocation, Bob Lee > > As this is just an initial cut and the proposals are not yet in a form > suitable for direct inclusion in the JLS, work should continue to refine > these proposed specifications and preferably also to produce prototype > implementations to allow a more thorough evaluation of the utility and > scope of the changes. The email list should focus on improving the > selected proposals and on getting any remaining new proposals submitted; > continued discussion of the other proposals is discouraged. > > The final list of small language changes will be determined after the > call for proposals is over so proposals sent in this week are certainly > still in the running! The final list will only have around five items > so it is possible not all the changes above will be on the eventual > final list. > > -Joe > > > From martin.dobmeier at googlemail.com Mon Mar 30 13:08:02 2009 From: martin.dobmeier at googlemail.com (Martin Dobmeier) Date: Mon, 30 Mar 2009 22:08:02 +0200 Subject: For further consideration... In-Reply-To: <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> References: <49C95DB5.6020202@sun.com> <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> Message-ID: <56df81890903301308m269c2dc9n7e8cff18bc825357@mail.gmail.com> > > Also, what about a List/Map literal proposal? Did I miss that? Oh well, nevermind, seems I really did miss it ;) From Ulf.Zibis at gmx.de Mon Mar 30 16:27:14 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 31 Mar 2009 01:27:14 +0200 Subject: Multiple return values Message-ID: <49D15552.9030301@gmx.de> Hi all, there is another interesting Proposal: http://forums.java.net/jive/thread.jspa?messageID=15761㶑 As I don't have time to fill in the requested form, I ask for volunteers to do that before deadline (30 of March 2009). (Now it's 23:00 h here in Germany, I have to go to bed for sleeping ;-) ) See http://openjdk.java.net/projects/coin/ and http://blogs.sun.com/darcy/category/Java, and post it to coin-dev at openjdk.java.net. -Ulf From jjb at google.com Mon Mar 30 16:30:14 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 30 Mar 2009 16:30:14 -0700 Subject: Proposal: Collection Literals Message-ID: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> Folks, Hi. I'd like to throw one more proposal into the Coin purse. This proposal is intended to coexist with indexing access syntax for lists and maps. It is similar to Shams Mahmood Imam's Concise Collection Initialization Syntax proposal, but represents a different point in the design space. It is safer (in that it only produces immutable collections) and more concise (in that you need not specify the implementation type). It is likely to be higher in space and time performance, in that the compiler can choose efficient implementations for small collections (such as empty collections and singletons). On the other hand, it is less flexible, in that you cannot specify the implementation type. The proposal can be found here: http://docs.google.com/Doc?id=ddv8ts74_4cbnn5mhj , and is reproduced below as required by the submission guidelines. Regards, Josh Collection Literals *AUTHOR: *Joshua Bloch *OVERVIEW* FEATURE SUMMARY: Add support for immutable List, Set, and Map literals, with a syntax similar to that of array initializers. MAJOR ADVANTAGE: Reduces verbosity and adds clarity when creating small lists, sets, and maps and whose contents are known at compile time. This feature is well-liked in the many languages that support it (e.g., Perl, Python). MAJOR DISADVANTAGE: The facility can be abused to simulate named parameters, resulting in loss of type safety. Hopefully people won't do this. ALTERNATIVES: Typically programmers create an empty collection and insert the initial elements or mappings. Sometimes they use Arrays.asList. It is also possible to abuse anonymous classes to reduce verbosity ("crazybob's contraption"). Arguably the current best practice for creating immutable collections is to use the builder pattern, as demonstrated by the immutable collections in the Google Collections project. *EXAMPLES* SIMPLE EXAMPLES: Here is a code fragment to create an immutable list as it would be done today: final List piDigits = Collections.unmodifiableList(Arrays.asList( 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9 )); The method invocations (Collections.unmodifiableList(Arrays.asList) are just noise. With list literals, it would look like this: final List piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9]; By substituting curly braces for the square brackets, you get a set literal in place of a list: final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; Here is the empty set literal: Set honestSenators = {}; Here is a code fragment to create an immutable map as it would be done today: final Map platonicSolids; static { solids = new LinkedHashMap; solids.put(4, "tetrahedron"); solids.put(6, "cube"); solids.put(8, "octahedron"); solids.put(12, "dodecahedron"); solids.put(20, "icosahedron"); platonicSolids = Collections.immutableMap(solids); } Here?s how it would look with map literals: final Map platonicSolids = { 4 : "tetrahedron", 6 : "cube", 8 : "octahedron", 12 : "dodecahedron", 20 : "icosahedron" }; Here is the empty map literal, which has a slightly irregular syntax to make it differ from the empty set: Map noJokeHere = { : }; In all cases, the iteration order of collection literal corresponds to the order in which the elements or keys appear in the code. Collections literals are serializable (assuming their elements, keys or values are serializable). List literals implement java.util.RandomAccess (dynamically, but not statically). COMPLEX EXAMPLES: Here is a nested list literal: List> pascalsTriangle = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]; Note that the element type of the list literal (and the key and value types of the map literal) are inferred by the compiler. As is the case when invoking parameterized methods, the compiler cannot always infer the desired type. For example this list literal will not compile, as the compiler will infer the wrong element type: final List numbers = [ 2, 2.718281828 ]; (Instead of Number, the compiler will infer Number & Comparable>.) Therefore, we provide a similar "escape hatch" that lets you specify the element (or key and value) types manually. Like its method invocation analogue, it isn't pretty, and programmers will rarely have to use it in practice: final List numbers = ** [ 2, 2.718281828 ]; *DETAILS* * * SPECIFICATION: What follows is not intended to be a formal JLS-quality specification. It emphasizes brevity and clarity over thoroughness. SYNTAX: Two new expression types would be defined in JLS 15, *List Literals* , *Set Literals*, and *Map Literals*: *ListLiteral*: *NonWildTypeArgument**opt** [* *List**ElementInitializers**opt ] * *ListElementInitializers*: *Expression* *List**ElementInitializers ,* *Expression* *NonWildTypeArgument:* * *< *ReferenceType *> *SetLiteral*: *NonWildTypeArgument**opt** *{ *SetElementInitializers**opt } * *SetElementInitializers*: *AugmentedConstant**Expression* *SetE**lementInitializers ,* *AugmentedConstant**Expression* *NonWildTypeArgument:* * *< *ReferenceType *> *MapLiteral*: *NonWildTypeArgumentPair**opt** *{ *Entry**Initializers** } * * NonWildTypeArgumentPairopt EmptyMapLiteral* *EntryInitializers*: *AugmentedConstant**Expression* : *Expression* Entry*Initializers ,* *EntryInitializer* *NonWildTypeArgumentPair:* * *<* ReferenceType , ReferenceType *> *EmptyMapLiteral* * *{ : } The following expression type would be added to (or immediately following) JLS ?15.28, which currently defines the term constant expression, and the corresponding nonterminal symbol *ConstantExpression*: *AugmentedConstant**Expression:* An *augmented constant expression* is a generalization of a constant expression that allows several additional kinds of expressions: - enum constants (JLS ?8.9) - class literals (JLS ?8.9) - set literals (JLS 15.8.2) - lists literals all of whose element initializers are themselves augmented constant expressions - map literals all of whose value initializers are themselves augmented constant expressions SEMANTICS and COMPILATION: A list literal behaves roughly as if replaced by the following "desugaring": Arrays. *NonWildTypeArguments**opt* asUnmodifiableList( * ElementInitializers* ) This desugaring assumes the existence of a new library method, asUnmodifiableList, described below under Library Support. Note that type inference of the element type for the list literal is exactly as if the following method were invoked with *ElementInitializers *as as actual parameters: void foo(E... args) { } A set literal b*ehaves roughly as if replaced by the following desugaring:* Collections.unmodifiableSet(Arrays. *NonWildTypeArguments**opt* asList( *ElementInitializers* )) *It is a compile time error for a set literal to contain multiple equal element values.* Therefore, the size of the set (as reported by the size method) is the number of element initializers. In both desugarings above, the wiggle word "roughly" is used in that there is no guarantee that the indicated methods (Arrays.asUnmodifiableList, Collections.unmodifiableSet, Arrays.asList) methods are actually called. Moreover,* there **are no guarantees as to the implementation types of the collections produced by collection literals.* The compiler can call any public Java SE APIs to construct any List, Set, or Map implementations with the correct semantics (immutability, iteration order, serializability and, in the case of lists, RandomAccess). So, for example, if a list literal has no elements, the compiler can emit a call to Collections.emptyList. Similarly, if a list literal has a single element, the compiler can emit a call to Collections.singletonList. Many other such optimizations are possible, and new ones may become available in subsequent releases. A map literal behaves as if replaced by the following desugaring: Arrays. *NonWildTypeArguments**opt* #unmodifiableMap( * #gather( k0, k1, ... kn-1 ),* * #gather( v0, v1, ... vn-1 ))* where ki and vi are the keys and value expressions in the ith EntryInitializer in EntryInitializers, and #gather and #unmodifiableMap are the following hypothetical methods: private static T[] #gather(T... args) { return args; } private static Map #unmodifiableMap(K[] keys, V[] vals) { Map m = new LinkedHashMap(2 * keys.length); for (int i = 0; i < keys.length; i++) m.put(keys[i], vals[i]); return Collections.unmodifiableMap(m); } The compiler does not actually emit calls to the methods #unmodifiableMap and #gather (which don't exist), but emulates their behavior. These methods are merely an artifice to describe the semantics of the construct, including type inference. *It is a compile time error for a map literal to contain multiple equal key values.* Therefore, the size of the map (as reported by the size method) is the number of entry initializers. TYPE SYSTEM: The proposal has no effect on the type system. TESTING: The proposed construct can be tested by writing list and map literals to generate lists and maps of various lengths (say 0 through 100) and types, and ensuring that these collections have the correct behavior by using preexisting tests for immutable collections, which are part of the Google Collections project. (These tests will have to be modified slightly, but it will be straightforward.) LIBRARY SUPPORT: The following method (which is trivial to implement) will be added to java.util.arrays: /** * Returns a fixed-size, unmodifiable list backed by the specified array. * (Any changes to the array "write through" to the list.) Attempting to * modify the list will result in an {@link UnsupportedOperationException}. * *

The returned list is serializable and implements {@link RandomAccess}. * * @param a the array by which the list will be backed * @return an unmodifiable list view of the specified array */ public static List asUnmodifiableList(T... a); The compiler may (but is not required to) emit calls to this method in the implementation of list literals. It may also be desirable to add some library support for immutable sets or lists (akin to that provided by the Google Collections project), but this isn't necessary for the proposal to go forward, and the compiler can take advantage of such support in whatever release it happens to be added. REFLECTIVE APIS: This proposal has no effect on core reflective APIs. The tree API inside javac would require a minor extension. OTHER CHANGES: No other parts of the platform need be to be updated. MIGRATION: Existing manual list, set, and map construction code could be replaced by more concise list and map literals, but this is not necessary. *COMPATIBILITY* * * BREAKING CHANGES: All previously valid programs remain valid, and their semantics is unaffected. * * EXISTING PROGRAMS: Source and class files of earlier versions are unaffected by the feature. No new overloadings or overridings can occur. *REFERENCES* * * EXISTING BUGS: 4632701 , 6237556 . *FUTURE DIRECTIONS* Assuming we make sure that no syntactic ambiguity would result, a future release could allow certain collection literals as annotation values. This is *not *proposed for Project Coin, but should inform the work. From Joe.Darcy at Sun.COM Mon Mar 30 16:38:21 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 30 Mar 2009 16:38:21 -0700 Subject: For further consideration... In-Reply-To: <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> References: <49C95DB5.6020202@sun.com> <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> Message-ID: <49D157ED.4010200@sun.com> Martin Dobmeier wrote: > Hey everybody, > > I'm sorta missing some kind of explanation why some of the other proposals > were not considered (e.g. enhanced string literals, enhanced for loop > iteration control, etc.). Something along the lines of: Do they entail too > big of a language change? Do they address no real pain points in the > language? Were they not specified thoroughly enough? In short: What's Sun's > opinion on those proposals? However, though I've read a lot of the mails > posted to this list, I might have just missed those things. Anyway, my first > impression when reading the short list was that it looks almost exactly like > the language changes that have been floating around on some Sun blogs for > some time now. I admit that it occured to me that it looks a bit "planned" > (no offense though). I'm pretty much happy with almost all of the stuff on > the short list. On the other hand I'd really like to hear some opinions on > why one proposal was chosen over the other. There are maybe to many to go > into too much detail, but just a few thoughts? I have generally at least briefly commented on all the proposals that were sent in before the "for further consideration" determination was made. (On the mailing list website you can view the list traffic sorted by author.) I do *not* plan to develop a detailed analysis of why each proposal was or was not chosen; however, within a few weeks I do want to post a summary of my reactions to the proposal process, including common aspects (not properties ;-) of proposals that led them to not be selected. -Joe From jodastephen at gmail.com Mon Mar 30 16:40:20 2009 From: jodastephen at gmail.com (Stephen Colebourne) Date: Tue, 31 Mar 2009 00:40:20 +0100 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <49D0794C.7090400@sun.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> <49D0794C.7090400@sun.com> Message-ID: <49D15864.9000009@gmail.com> I'm surprised annotation solutions are being considered given the general approach taken to annotations affecting the language. For this feature, if it went ahead, I would strongly request having four new interfaces IndexedGet IndexedSet MappedGet MappedPut Each with one method. The existing Collection and Map classes would then be retofitted. It might be a good time to retrofit a Sized interface too, defining the size() method. Finally, arrays must "implement" the new indexed interfaces. This is critical to allow code like this to work: public void process(IndexedGet getter) { .. } This would take in any List or array, or used defined implementation of IndexedGet. I would note that arrays should also "implement" Sized and Iterable (were remove on the iterator would throw UOE). I should really write up the Coin proposal for making arrays implement more interfaces, but its almost 2am, and it wouldn't make much sense. Suffice it to say that I've had to code this since Java 5 on more than one occasion: public void process(Iterable it) { ... } public void process(Object[] array) { ... } Stephen Joseph D. Darcy wrote: > I was going to type up a proposal along these lines from scratch, but > I'm happy you sent in your proposal first, especially since there is a > prototype already :-) > > While collections are certainly very widely used and should have this > indexing support IMO, I think it is also important that indexing support > not be strictly limited to just classes implementing java.util.{List, > Map}. For example, if this kind of capability is added, I'd like enough > flexibility to give library developers the ability to in effect write a > 64-bit array class. (Semantically, a Java array today is basically just > a map from int to some other type.) > > The mechanism to indicate indexing is supported on a class must at least > support Lists and Maps: > > java.util.List > read: E get(int) > write: E set(int, E) > > java.util.Map > read: V get(Object) > write: V put(K, V) > > So variation in both the names of the methods must be accommodated as > well as the typing of the methods. > > The compiler needs a few pieces of information to perform the indexing > translating including "Should this type get indexing support?" and "If > this type gets indexing support, what methods do read and write > operations get mapped to?" > > The most magical way to indicate the indexing support bit is to have a > marker interface (or even an annotation) and then to have the names of > the get/set methods indicated as annotation values. As a strawman > something like > > public interface java.lang.Indexable {} > > @Documented > @Target(TYPE) > @Retention(RUNTIME) > @Inherited > public @interface java.lang.IndexableNames { > String reader() default "get"; > String writer(); > } > > where then, say, java.util.List would be changed from > > public interface List extends Collection > > to > > @IndexableNames(writer="set") > public interface List extends Collection extends Indexable > > However, this feels a bit too magical and there would be complications > about getting the indexable method names since annotation inheritance > only works along superclasses, not superinterfaces. > > A better approach is probably to create at least two new superinterfaces > in java.lang for the List and Map signatures. However, some care and > analysis will be needed to ensure a migration compatibility issue is not > introduced. (In support of the enhanced for loop in JDK 5, a > superintface of java.util.Iterator, java.lang.Iterator (lacking a remove > method), was introduced being being subsequently removed for migration > compatibility conflicts.) > > -Joe > > > From scolebourne at joda.org Mon Mar 30 16:46:04 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 31 Mar 2009 00:46:04 +0100 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49D141B2.1050808@e-spirit.de> References: <49C56020.2070207@joda.org> <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> <49D141B2.1050808@e-spirit.de> Message-ID: <49D159BC.6070804@joda.org> Stefan Schulz wrote: > Frankly, I cannot see a great advantage of: > for (Foo foo : fooList : it) { > ... > } > saving two lines of code over: > Iterator it = fooList.iterator(); > while (it.hasNext()) { > Foo foo = it.next(); > ... > } The former captures the *intent* of the loop. The latter is all about plumbing. > by adding two wrappers and stuff to the code in the background. The proposal discusses possible optimisations, however I suspect that hohtspot can probably cope with two additional objects being created. Remember, the extra overhead only happens if you add the optional iterator reference. Stephen From scolebourne at joda.org Mon Mar 30 16:51:43 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 31 Mar 2009 00:51:43 +0100 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> References: <49C56020.2070207@joda.org> <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> Message-ID: <49D15B0F.7030105@joda.org> Marek Kozie? wrote: > So from your proposal I would remove Interface-s and link iterator > through label, > label type is return type of .iterator() method. > String[] array ...; > i: for (String s:array){ > i.getIndex;//? > } While I understand that this may seem appealing, it really isn't. Labels are in a different namespace IIRC, and using that for psuedo method calls is really an abuse. I accept that my proposal doesn't allow custom iterators, but I don't believe that to be a major problem. Consider it that my proposal tackles 80%+ of the problem (which was part of the 20% of the original looping problem, and still a good number of LOC in a reasonable system). Stephen From markmahieu at googlemail.com Mon Mar 30 17:04:13 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 31 Mar 2009 01:04:13 +0100 Subject: UPDATED: Rethrows Clause Message-ID: <39084932-B2CC-4B91-97EA-006FE21301F0@googlemail.com> Forgot my JLS references in the first one... HTML version + prototype available at: http://slm888.com Rethrows Clause v0.1.1 AUTHOR(S): Mark Mahieu OVERVIEW FEATURE SUMMARY: Should be suitable as a summary in a language tutorial. A new clause on method declarations which allows exception translations (wrapping and rethrowing as a different type) to be cleanly defined separately from the body of the method. In many cases, checked exception type names do not then need to be repeated in a method's throws clause and in a throw statement in the method body. MAJOR ADVANTAGE: What makes the proposal a favorable change? The proposal adds direct support for a common idiom in daily use by Java programmers worldwide, allowing them to express their intentions with greater clarity and ease. In comparison with some proposals, this is an attempt to make dealing with checked exceptions easier by increasing the expressiveness of exception handling code in general, rather than by attempting to deprecate checked exceptions in favour of unchecked exceptions. MAJOR BENEFIT: Why is the platform better if the proposal is adopted? There is a reduction in the amount of boilerplate Java programmers have to read and write for code dealing with checked exceptions. Declarations specifying both thrown and rethrown (wrapped) exceptions are kept together, aiding comprehension of the code. MAJOR DISADVANTAGE: There is always a cost. As with any syntax sugar which enables an alternative way of expressing an existing idiom, programmers may be tempted to use it even when the existing idiom would be more appropriate. 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. Before: void before() throws ConfigException { try { Class.forName("where.is.the.Code"); } catch (ClassNotFoundException e) { throw new ConfigException(e); } } After: void after() catch ClassNotFoundException throw ConfigException { Class.forName("here.is.the.Code"); } ADVANCED EXAMPLE: Show advanced usage(s) of the feature. Before: void suspendAccount() throws AuthorizationException, PersistenceException { try { checkMyAuthoritah(); db.update(/*...*/); log.recordInfo(/*...*/); } catch (InfernalDBException e) { throw new PersistenceException(e); } catch (InfernalLogException e) { throw new RuntimeException(e); } } After: void suspendAccount() throws AuthorizationException catch InfernalDBException throw PersistenceException, InfernalLogException throw RuntimeException { checkMyAuthoritah(); db.update(/*...*/); log.recordInfo(/*...*/); } 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. The syntactic grammar is modified to allow an optional rethrows clause immediately prior to a MethodBody: MethodDeclaratorRest: FormalParameters {[]} [throws QualifiedIdentifierList] ( ( [catch ExceptionTranslationList] MethodBody ) | ; ) ExceptionTranslationList: QualifiedIdentifier throw QualifiedIdentifier { , ExceptionTranslationList } JLSv3 ?8.4.6 : A rethrows clause lists one or more exception translations, each translation consisting of a caught type C and a translated type T for which all of the following must hold: * C <: java.lang.Exception * T < java.lang.Throwable * Neither C nor T is a type variable. * T has an accessible constructor suitable for rethrowing a value of type C (see below). * T is not the same type as C. Any exceptions thrown by the method body which are a subtype of a caught exception type in the rethrows clause, are rethrown as the corresponding translated exception type. For a given translated type T with corresponding caught type C, if T has an accessible constructor accepting a value of type C, then the translation is equivalent to the following: catch (C e) { throw new T(e); } Otherwise it must have an accessible no argument constructor, and the translation is equivalent to: catch (C e) { throw new T().initCause(e); } A rethrows clause does not restrict which types may appear in a throws clause for the same method. In particular, for a given caught type C in the rethrows clause, it is permitted for some type C1 :> C to also be listed in the throws clause. JLSv3 ?8.2 : The set of exception types declared to be thrown by a method is the union of: * the types in the throws clause * the translated types in the rethrow clause * the types thrown by the translated types' selected constructors JLSv3 ?11.2.2 : For the purposes of exception analysis, the set of checked exception types which may be thrown by the method's body is the union of: * the types in the throws clause * the caught types in the rethrows clause JLSv3 ?11.2.3 : It is a compile-time error if a rethrows clause contains a translation from a checked exception type C but there exists no checked exception type E such that all of the following hold: * E <: C * The method body can throw E * No preceding translation in the rethrow clause catches E or a supertype of E unless C is the class java.lang.Exception. JLSv3 ?13.4.21 : Changes to the rethrows clause of methods or constructors do not break compatibility with existing binaries; these clauses are checked only at compile time. 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! A simple desugaring could consist of enclosing the method body's statements in a try statement, with catch clauses for each translated exception type. For example, the following method: Method findMethod() catch ClassNotFoundException throw ConfigException, NoSuchMethodException throw ConfigException { Class c = Class.forName("some.Thing"); return c.getDeclaredMethod("execute", null); } would be desugared to: Method findMethod() throws ConfigException { try { Class c = Class.forName("some.Thing"); return c.getDeclaredMethod("execute", null); } catch (ClassNotFoundException e) { throw new ConfigException(e); } catch (MethodNotFoundException e) { throw new ConfigException(e); } } No changes to the classfile format are required. TESTING: How can the feature be tested? An initial set of jtreg tests is included in the prototype. LIBRARY SUPPORT: Are any supporting libraries needed for the feature? No 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. com.sun.source.tree.MethodTree would require updates to access the rethrows clause's caught and translated types. 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 MIGRATION: Sketch how a code base could be converted, manually or automatically, to use the new feature. Catch clauses which simply wrap and rethrow an exception as another exception type not caught in an enclosing scope, can be trivially replaced with a rethrows clause, either manually or automatically. It should be possible for tools to offer bidirectional conversions such that an exception translation may be moved back into the method body if it is subsequently decided that additional logic is required. COMPATIBILITY BREAKING CHANGES: Are any previously valid programs now invalid? If so, list one. No 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 semantics of existing class files and legal source files are unchanged by this feature. REFERENCES EXISTING BUGS: Please include a list of any existing Sun bug ids related to this proposal. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6534270 (similar, but emphasizes unchecked exceptions) URL FOR PROTOTYPE (optional): http://slm888.com/javac From scolebourne at joda.org Mon Mar 30 17:13:53 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 31 Mar 2009 01:13:53 +0100 Subject: PROPOSAL: abstract enums In-Reply-To: <49D04260.2010001@sun.com> References: <25275917.1238382825309.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D04260.2010001@sun.com> Message-ID: <49D16041.9080200@joda.org> Joseph D. Darcy wrote: > Of the extensible and non-extensible version of enum pattern, the JSR > 201 expert group chose the non-extensible variant and many other > decisions and details of the original enum design flow from that > fundamental decision. Revisiting that decision now is impractical. > > Additionally, some of the advantages of extensible enums can be had by > making different enum classes implement a common interface; for some > discussion of that general pattern see > > "Mixing-in an Enum" > http://blogs.sun.com/darcy/entry/enums_and_mixins > > as well as an item in the 2nd edition of "Effective Java." The lack of abstract enums (where the superclass merely contains code, not enum constants) has definitely had a negative impact on the usefulness of the feature. JSR-310 will be significantly worse as an implementation as a result of this omission. Further, the addition of abstract enums like this adds to the syntactic power of the language in a way few other Coin proposals do. This is because some of the use cases are simply impractical to do without the feature, due to the vast amount of repetitive boilerplate code that would be required. ('Abstract enums' are a request for implementation inheritence for enums, without which certain things are nigh on impossible now. The only alternative I can think of that is adding a language level 'delegation' concept, effectively allowing implementation by composition at the language level. And, given abstract enums likely interaction with annotations, delegation isn't a full answer) So, while I understand that this isn't a Coin feature (type change effectively), it really should not be dismissed so easily. This is something that can and should be open be revisited now we have experience with enums. The argument of "the original EG decided" is a poor one. By that argument, we should not make any changes to Java, and leave it as in v1.0. As such, I request that you consider merit, not an arbitrary 'it changed recently'. Stephen From scolebourne at joda.org Mon Mar 30 17:23:37 2009 From: scolebourne at joda.org (Stephen Colebourne) Date: Tue, 31 Mar 2009 01:23:37 +0100 Subject: For further consideration... In-Reply-To: <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> References: <49C95DB5.6020202@sun.com> <56df81890903301304ld1572cawf479c54f47421325@mail.gmail.com> Message-ID: <49D16289.4020001@joda.org> Martin Dobmeier wrote: > I'm sorta missing some kind of explanation why some of the other proposals > were not considered (e.g. enhanced string literals, enhanced for loop > iteration control, etc.). Something along the lines of: Do they entail too > big of a language change? Do they address no real pain points in the > language? Were they not specified thoroughly enough? In short: What's Sun's > opinion on those proposals? However, though I've read a lot of the mails > posted to this list, I might have just missed those things. Anyway, my first > impression when reading the short list was that it looks almost exactly like > the language changes that have been floating around on some Sun blogs for > some time now. I admit that it occured to me that it looks a bit "planned" > (no offense though). I'm pretty much happy with almost all of the stuff on > the short list. On the other hand I'd really like to hear some opinions on > why one proposal was chosen over the other. There are maybe to many to go > into too much detail, but just a few thoughts? One hint is the level of detail. The reality is that the total number of people in the world who can fully define the proposal form to the level of required detail is very small (and I don't exactly count myself in that group). This should be no surprise, as language change is a specialised art form. Further, it should be remembered that the Sun engineers already knew all of the requested ideas before the project started, simply by prior communication and the bug database. What is usefull here is discussion about the details of proposals, and the relative popularity. Unfortunately, the latter is misleading, as a highly deated proposal might well be more dubious, whereas a lihtly debated proposal probably means everyone simply likes it. And yes, there should be a detailed post-Coin summary reviewing how it went. After all, it migt be a good idea to rule some ideas out of Java for the next few years at least (so people can stop asking). Stephen From John.Rose at Sun.COM Mon Mar 30 17:39:58 2009 From: John.Rose at Sun.COM (John Rose) Date: Mon, 30 Mar 2009 17:39:58 -0700 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> Message-ID: <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> On Mar 20, 2009, at 1:50 PM, John Rose wrote: > I wrote the spec. draft and implementation (in antlr) for Groovy > gstring syntax; I did the work with the intention of helping the JSR > 241 Groovy standard. It could work in Java with adjustments, and the > Groovy spec. is detailed enough to be a starting point. I don't > really have time to work on it though. That's why I haven't done a > proposal. > > For Java, to extend the string syntax and emphasize that a new string > is being constructed, I recommend this: > > new "$foo, ${bar}s." I wrote up something more specific, for the sake of this go-around. It is generic and pluggable enough to provide some help with XML templating, and SQL construction. Enjoy! http://wikis.sun.com/display/mlvm/TemplatedConstructorExpressions (Although this document is hosted on mlvm at present, it has nothing to do with JSR 292.) -- John P.S. For the archive, here is the original wiki source. h3. AUTHOR(S): John Rose h3. OVERVIEW String templating syntaxes are found in shell-like languages. They allow a flexible and natural-looking mixture of constant templates with non-constant interpolation. Adapt such a notation to Java, in a way that provides natural-looking templating for unformatted and formatted text, XML, SQL, and other applications involving foreign notations andstructured text. h3. FEATURE SUMMARY: h4. *1.* simple templated strings The {{new}} keyword is currently used for creating objects and arrays. This specification introduces another syntax based on the {{new}} keyword, called the *templated construction expression*: {noformat} int zip = 95120, phone = 5551212; String s = new "zip=$(zip), phone=$(phone)."; String s2 = "zip=" + zip + ", phone=" + phone + "."; // same code {noformat} As with other languages, each unescaped dollar sign {{$}} introduces an *interpolation*, which is an arbitrary Java expression that contributes to the template. Everything else between the string quotes is treated as constant text; each non-empty span of string characters is called a *string segment*. The string segments also contribute to the template. As with the current plus {{+}} notation, each interpolation or string segment causes another item to be appended. Every interpolation ends with zero or more expressions, called the *interpolation arguments*. If there is exactly one interpolation argument, we speak unambiguously of the *interpolation expression*. (There are multi-argument examples below.) Such a syntax would be a merely marginal improvement over the current plus {{+}} notation for {{StringBuilder it includes two additional degree of freedom. They allow the programmer to specify templating mechanisms other than {{StringBuilder}}, and to more easily control the details of formatting for the interpolated items. h4. *2.* programmer-defined templating A templated construction expression may be qualified: {noformat} int zip = 95120, phone = 5551212; StringBuilder buf = new StringBuilder(); buf.new "zip=$(zip), phone=$(phone)."; String s = buf.toString(); // same result as previous example {noformat} In fact, if a templated construction expression is unqualified, it is exactly as if the compiler had supplied a default qualifier of {{new StringBuilder()}} and appended a call to {{toString}} at the end, to extract the resulting string. But, the programmer may provide a different object reference {{x}} as a qualifier to a templated construction expression; an object used this way is called a *template factory*. A qualified templated construction expression is equivalent to a chain of {{append}} method calls applied to the template factory, as detailed below. This allows new classes to be created which can define library- specific semantics for templated construction. The only requirement on template factories is that they supply the {{append}} calls implied by the interpolations within the templates. These {{append}} calls may be overloaded, and may take multiple arguments, or no arguments at all. {noformat} java.lang.Appendable app = ...; app.new "subseq: $(str, beg, end)"; // append(str, beg, end) {noformat} h4. *3.* generic format specifiers The dollar sign of an interpolation may be immediately followed by a *format specifier*, a sequence of string characters enclosed in angle brackets. These characters are collected into separate (presumably short) string literal which is passed as an additional leading argument to the method call for the interpolation; the method is named {{format}} instead of append, and may (again) take any number of arguments. Format specifiers may not contain unescaped right angle brackets; otherwise they are arbitrary, and interpreted only by the {{append}} call they are passed to. {noformat} String s = new Formatter().new "zip=$<%05d>(zip), phone=$< %d>(phone).".toString(); {noformat} h4. *4.* abbreviated interpolation expressions For certain simple interpolation expressions, the enclosing parentheses are optional. The expressions which can drop parentheses are a decimal numeral, a name (qualified or simple), a name followed by one parenthesized argument list, and a name followed by one bracketed array index. The name must not contain any dollar signs in its spelling. {noformat} int zip = 95120, phone = 5551212; String s = new "zip=$zip, phone=$phone."; // same code {noformat} As always, any ambiguity between the interpolation expression and a following interpolation or string segment can always be resolved by using explicit parentheses. (Note: This last feature of abbreviation is troublesome to specify and implement, but it appears to be a worthwhile creature comfort.) h3. MAJOR ADVANTAGE: The features specified here allow programmers a superior notation for creating templated textual items. Such notations are popular and well proven in other languages, including the shells, PHP, Perl, and Groovy. It will reduce pressure on programmers to move to those other languages. h3. MAJOR BENEFIT: Concise, natural templated expressions are easier to code and maintain than equivalent nests of method calls. h3. MAJOR DISADVANTAGE: The JLS gets more complicated. h3. ALTERNATIVES: Programmers may use explicitly coded nests method calls; they are of course more verbose. h3. EXAMPLES, BEFORE/AFTER: See above and below (in the specification) for one-line examples demonstrating each aspect of this specification. h4. SIMPLE EXAMPLE: {noformat} String whom = "world"; System.out.printlin(new "Hello, $whom!"); {noformat} h4. ADVANCED EXAMPLE: This syntax can easily support two-phase template creation, where a template is first compiled and checked, and then later applied one or more times. Let's suppose a hypothetical XML snippet compiler designed for templated construction expressions. It might be used this way to compile a snippet generator with optionally typed free variables mapped to an API featuring a {{make}} method with positional arguments: {noformat} XMLSnippetCompiler xmlc = ...; xmlc.new "$1$2"; XMLSnippet xmls = xmlc.compile(); System.out.println(xmls.make("raining", "walk inside", 5 /*medium pri*/)); System.out.println(xmls.make("fire", "run outside", 1 /*highest pri*/)); {noformat} h3. DETAILS The sequence of string segments and interpolations of a templated construction expression is called its body. Each string segment begins with either the opening quote of the body, or the end of a previous The templated construction expression is broken into zero or more interpolations and zero or more (non-empty) string segments. These are presented in order to the template factory object, as method calls to {{appendText}}, {{append}}, or {{format}}. {noformat} x.new "a"; // sugar for x.appendText("a") x.new "$(y)"; // sugar for x.append(y) x.new "$(y)"; // sugar for x.format("q",y) x.new "$(y)"; // sugar for x.format("q",y) x.new "a$(y)b"; // sugar for x.appendText("a").append(y).appendText("b") x.new "a$(y)b"; // sugar for x.appendText("a").format("q",y).appendText("b") x.new "a$(y)$(z)"; // sugar for x.appendText("a").append(y).format("q",z) x.new ""; // degenerate sugar for x {noformat} There is no particular restriction on the syntax of interpolation argument expressions. In particular, they can contain quoted strings and templated construction expressions. {noformat} new "Hello, $("world")."; new "Hello, $(new "wor$("")ld")."; {noformat} There is no particular restriction on the type or number of interpolation argument expressions. Since they are sugar for {{append}} or {{format}} method calls, they are simply required to participate successfully in the rules for method call resolution. {noformat} x.new "$()"; // sugar for x.append() x.new "$(y)"; // sugar for x.append(y) x.new "$(y,z)"; // sugar for x.append(y,z) x.new "$()"; // sugar for x.format("q") x.new "$(y)"; // sugar for x.format("q",y) x.new "$(y,z)"; // sugar for x.format("q",z) {noformat} If the templated construction expression is unqualified, it is provided with a new {{StringBuilder}} factory object, and the expression as a whole is closed with a {{toString}} call. For the sake of template factories which need to make the distinction, string segments are appended by {{appendText}} method call, if one exists on the factory object's static type; an error is reported if it is not applicable to a single {{String}}. Otherwise {{append}} is applied to the constant string segment, which will be a string literal. If the format specifier is completely empty, the leading argument to format is omitted, and it is up to the programmer to specify it explicitly in the interpolation arguments: {noformat} String fmt = (zip <= 99999) ? "%05d" : "%d"; String s = new Formatter().new "zip=$<>(fmt, zip), phone=$< %d>(phone).".toString(); //new Formatter().appendText {noformat} Here are examples of abbreviated interpolation expressions: {noformat} "$x" // same as "$(x)" "$1" // same as "$(1)" "$x.y" // same as "$(x.y)" "$x.y.z" // same as "$(x.y.z)" "$f(x)" // same as "$(f(x))" "$x.f(y)" // same as "$(x.f(y))" "$x[y]" // same as "$(x[y])" "$x.y[z]" // same as "$(x.y[z])" {noformat} Here are examples of abbreviated interpolation expression with interesting right contexts: {noformat} "$x." // same as "$(x)." "$1." // same as "$(1)." "$1.0" // same as "$(1).0" "$x.y." // same as "$(x.y)." "$f(x)[" // same as "$(f(x))[" "$x[y](" // same as "$(x[y])(" {noformat} Here are examples of illegal attempts at abbreviation: {noformat} "$$" // not same as "$($)"; must be rejected "$$x" // not same as "$($x)"; must be rejected "$x.$" // not same as "$(x.$)"; must be rejected "$x["... // same as "$(x["..., a likely syntax error "$[x]" // reserved; must be rejected "${x}" // reserved; must be rejected "$x{y}" // reserved; must be rejected "$x" // reserved; must be rejected {noformat} Within a string segment of a templated construction expression, the dollar character may be escaped with a backslash, to prevent it from introducing an interpolation. Within a format specifier of an interpolation, the close-angle-bracket may be escaped with a backslash, to prevent it from terminating the format specifier. An unescaped dollar sign must introduce a well-formed interpolation. {noformat} new "\$$x.priceInDollars()" new "$<<\>>("has strange format of \"<>\"")." new "$" // must be rejected; should be new "\$" {noformat} h3. SPECIFICATION: The specification is complete in the running text of this document. It will be distilled shortly. h3. COMPILATION: As this is syntactic sugar, no new mechanisms are needed. The hack of changing {{appendText}} to {{append}} when the former is missing requires an extra symbol table lookup. h3. TESTING: Testing will be done the usual way, via unit tests, and by early access customers experimenting with the new facilities. h3. LIBRARY SUPPORT: There should be some retrofitting of libraries that perform append- like operations. (This is similar retrofitting to that done when varargs was introduced.) Suitable methods for {{appendText}} are added to {{StringBuilder}}, {{StringBuffer}}, and {{Formatter}}. The class {{StringBuilder}}, which is privileged as the default template factory type, is augmented with one or more {{format}} methods that redirect to {{Formatter}}. {noformat} String s = new "zip=$<%05d>zip, phone=$phone.".toString(); {noformat} The class {{PrintStream}}, which already has {{format}} methods, is also given {{appendText}} and {{append}} methods, as synonyms for {{print}}. {noformat} System.out.new "zip=$<%05d>zip, phone=$phone.".toString(); {noformat} (*QUESTION:* What other classes could benefit from retrofitting?) h3. REFLECTIVE APIS: No changes. h3. OTHER CHANGES: None. h3. MIGRATION: The feature is for new code only. h3. COMPATIBILITY h4. BREAKING CHANGES: None. All changes are associated with previously unused syntaxes. h4. EXISTING PROGRAMS: No special interaction. h3. REFERENCES h4. EXISTING BUGS: None known. h4. URL FOR PROTOTYPE: None yet. From neal at gafter.com Mon Mar 30 17:40:31 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Mar 2009 17:40:31 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> Message-ID: <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> Josh- This approach precludes some designs for reifying generics in the future because it is defined by the implicit creation of non-reified interfaces (e.g. List, etc). It isn't clear if we'll ever add reification, but it would be a shame to restrict or remove our option to do so. You can avoid this by not implicitly tying language constructs to particular existing interfaces. Regards, Neal On Mon, Mar 30, 2009 at 4:30 PM, Joshua Bloch wrote: > Folks, > > Hi. ?I'd like to throw one more proposal into the Coin purse. ?This proposal > is intended to coexist with indexing access syntax for lists and maps. ?It > is similar to Shams Mahmood Imam's Concise Collection Initialization Syntax > proposal, but represents a different point in the design space. It is safer > (in that it only produces immutable collections) and more concise (in that > you need not specify the implementation type). It is likely to be higher in > space and time performance, in that the compiler can choose efficient > implementations for small collections (such as empty collections and > singletons). ?On the other hand, it is less flexible, in that you > cannot specify > the implementation type. > The proposal can be found here: > http://docs.google.com/Doc?id=ddv8ts74_4cbnn5mhj , and is reproduced below > as required by the submission guidelines. > > ? ? ? ? ?Regards, > > ? ? ? ? ?Josh > > Collection Literals > > *AUTHOR: *Joshua Bloch > > > *OVERVIEW* > > > FEATURE SUMMARY: Add support for immutable List, Set, and Map literals, with > a syntax similar to that of array initializers. > > > MAJOR ADVANTAGE: Reduces verbosity and adds clarity when creating small > lists, sets, and maps and whose contents are known at compile time. This > feature is well-liked in the many languages that support it (e.g., Perl, > Python). > > > MAJOR DISADVANTAGE: The facility can be abused to simulate named parameters, > resulting in loss of type safety. Hopefully people won't do this. > > > ALTERNATIVES: Typically programmers create an empty collection and insert > the initial elements or mappings. ?Sometimes they use Arrays.asList. It is > also possible to abuse anonymous classes to reduce verbosity ("crazybob's > contraption"). ?Arguably the current best practice for creating immutable > collections is to use the builder pattern, as demonstrated by the immutable > collections in the Google > Collections > ?project. > > > *EXAMPLES* > > > SIMPLE EXAMPLES: Here is a code fragment to create an immutable list as it > would be done today: > > > ? ?final List piDigits = > Collections.unmodifiableList(Arrays.asList( > > ? ? ? ?3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9 )); > > > The method invocations (Collections.unmodifiableList(Arrays.asList) are just > noise. With list literals, it would look like this: > > ? ?final List piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9]; > > > By substituting curly braces for the square brackets, you get a set literal > in place of a list: > > > ? ?final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; > > > Here is the empty set literal: > > > ? ?Set honestSenators = {}; > > > Here is a code fragment to create an immutable map as it would be done > today: > > > ? ?final Map platonicSolids; > > ? ?static { > > ? ? ? ?solids = new LinkedHashMap; > > ? ? ? ?solids.put(4, ?"tetrahedron"); > > ? ? ? ?solids.put(6, ?"cube"); > > ? ? ? ?solids.put(8, ?"octahedron"); > > ? ? ? ?solids.put(12, "dodecahedron"); > > ? ? ? ?solids.put(20, "icosahedron"); > > ? ? ? ?platonicSolids = Collections.immutableMap(solids); > > ? ?} > > > Here?s how it would look with map literals: > > > ? ?final Map platonicSolids = { 4 : "tetrahedron", > > ? ? ?6 : "cube", 8 : "octahedron", 12 : "dodecahedron", 20 : "icosahedron" > }; > > > Here is the empty map literal, which has a slightly irregular syntax to make > it differ from the empty set: > > > ? ?Map noJokeHere = { : }; > > > In all cases, the iteration order of collection literal corresponds to the > order in which the elements or keys appear in the code. ?Collections > literals are serializable (assuming their elements, keys or values are > serializable). List literals implement java.util.RandomAccess ?(dynamically, > but not statically). > > > COMPLEX EXAMPLES: Here is a nested list literal: > > > ? ?List> pascalsTriangle = > > ? ? ? ?[[1], > > ? ? ? ? [1, 1], > > ? ? ? ? [1, 2, 1], > > ? ? ? ? [1, 3, 3, 1], > > ? ? ? ? [1, 4, 6, 4, 1]]; > > > Note that the element type of the list literal (and the key and value types > of the map literal) are inferred by the compiler. ?As is the case when > invoking parameterized methods, the compiler cannot always infer the desired > type. ?For example this list literal will not compile, as the compiler will > infer the wrong element type: > > > ? ?final List numbers = [ 2, 2.718281828 ]; > > > > (Instead of Number, the compiler will infer Number & Comparable Number & Comparable>.) Therefore, we provide a similar "escape hatch" > that lets you specify the element (or key and value) types manually. ?Like > its method invocation analogue, it isn't pretty, and programmers will rarely > have to use it in practice: > > > ? ?final List numbers = ** [ 2, 2.718281828 ]; > > > *DETAILS* > > * * > > SPECIFICATION: What follows is not intended to be a formal JLS-quality > specification. It emphasizes brevity and clarity over thoroughness. > > > > SYNTAX: Two new expression types would be defined in JLS 15, *List Literals* > , *Set Literals*, and *Map Literals*: > > > > *ListLiteral*: > > ? ?*NonWildTypeArgument**opt** [* *List**ElementInitializers**opt ] * > > *ListElementInitializers*: > > ? ?*Expression* > > ? ?*List**ElementInitializers ,* *Expression* > > *NonWildTypeArgument:* > > * ? ?*< *ReferenceType *> > > > *SetLiteral*: > > ? ?*NonWildTypeArgument**opt** *{ *SetElementInitializers**opt } * > > *SetElementInitializers*: > > ? ?*AugmentedConstant**Expression* > > ? ?*SetE**lementInitializers ,* *AugmentedConstant**Expression* > > *NonWildTypeArgument:* > > * ? ?*< *ReferenceType *> > > > > *MapLiteral*: > > ? ?*NonWildTypeArgumentPair**opt** *{ *Entry**Initializers** } * > > ? ? ?* NonWildTypeArgumentPairopt EmptyMapLiteral* > > *EntryInitializers*: > > ? ?*AugmentedConstant**Expression* : *Expression* > > ? ?Entry*Initializers ,* *EntryInitializer* > > *NonWildTypeArgumentPair:* > > * ? ?*<* ReferenceType , ReferenceType *> > > *EmptyMapLiteral* > > * ? ?*{ : } > > > The following expression type would be added to (or immediately following) > JLS ??15.28, which currently defines the term constant expression, and the > corresponding nonterminal symbol *ConstantExpression*: > > > *AugmentedConstant**Expression:* > > > An *augmented constant expression* is a generalization of a constant > expression that allows several additional kinds of expressions: > > > > ? - enum constants (JLS ?8.9) > ? - class literals (JLS ?8.9) > ? - set literals (JLS 15.8.2) > ? - lists literals all of whose element initializers are themselves > ? augmented constant expressions > ? - map literals all of whose value initializers are themselves augmented > ? constant expressions > > > > SEMANTICS and COMPILATION: A list literal behaves roughly as if replaced by > the following "desugaring": > > > > ? ?Arrays. *NonWildTypeArguments**opt* asUnmodifiableList( * > ElementInitializers* ) > > > > This desugaring assumes the existence of a new library method, > asUnmodifiableList, described below under Library Support. Note that type > inference of the element type for the list literal is exactly as if the > following method were invoked with *ElementInitializers *as as actual > parameters: > > > ? void foo(E... args) { } > > > > > A set literal b*ehaves roughly as if replaced by the following desugaring:* > > > ? ?Collections.unmodifiableSet(Arrays. *NonWildTypeArguments**opt* asList( > *ElementInitializers* )) > > > *It is a compile time error for a set literal to contain multiple equal > element values.* ?Therefore, the size of the set (as reported by the > size method) > is the number of element initializers. > > > In both desugarings above, the wiggle word "roughly" is used in that there > is no guarantee that the indicated methods (Arrays.asUnmodifiableList, > Collections.unmodifiableSet, Arrays.asList) methods are actually called. > > > Moreover,* there **are no guarantees as to the implementation types of the > collections produced by collection literals.* The compiler can call any > public Java SE APIs to construct any List, Set, or Map implementations with > the correct semantics (immutability, iteration order, serializability and, > in the case of lists, RandomAccess). ?So, for example, if a list literal has > no elements, the compiler can emit a call to Collections.emptyList. Similarly, > if a list literal has a single element, the compiler can emit a call to > Collections.singletonList. ?Many other such optimizations are possible, and > new ones may become available in subsequent releases. > > A map literal behaves as if replaced by the following desugaring: > > > > ? ?Arrays. *NonWildTypeArguments**opt* #unmodifiableMap( > > * ? ? ? ?#gather( k0, k1, ... kn-1 ),* > > * ? ? ? ?#gather( v0, v1, ... vn-1 ))* > > > where ki and vi are the keys and value expressions in the ith > EntryInitializer in EntryInitializers, and #gather and #unmodifiableMap are the > following hypothetical methods: > > > ? ?private static T[] #gather(T... args) { > > ? ? ? ?return args; > > ? ?} > > > ? ?private static Map #unmodifiableMap(K[] keys, V[] vals) { > ? ? ? ?Map m = new LinkedHashMap(2 * keys.length); > ? ? ? ?for (int i = 0; i < keys.length; i++) > ? ? ? ? ? ?m.put(keys[i], vals[i]); > ? ? ? ?return Collections.unmodifiableMap(m); > ? ?} > > The compiler does not actually emit calls to the methods #unmodifiableMap > ?and #gather (which don't exist), but emulates their behavior. ?These methods > are merely an artifice to describe the semantics of the construct, including > type inference. > > > *It is a compile time error for a map literal to contain multiple equal key > values.* ?Therefore, the size of the map (as reported by the size method) is > the number of entry initializers. > > > TYPE SYSTEM: The proposal has no effect on the type system. > > > > TESTING: The proposed construct can be tested by writing list and map > literals to generate lists and maps of various lengths (say 0 through 100) > and types, and ensuring that these collections have the correct behavior by > using preexisting tests for immutable collections, which are part of the Google > Collections project. ?(These > tests will have to be modified slightly, but it will be straightforward.) > > > > LIBRARY SUPPORT: The following method (which is trivial to implement) will > be added to java.util.arrays: > > > ? ?/** > ? ? * Returns a fixed-size, unmodifiable list backed by the specified > array. > ? ? * (Any changes to the array "write through" to the list.) ?Attempting > to > ? ? * modify the list will result in an {@link > UnsupportedOperationException}. > ? ? * > ? ? *

The returned list is serializable and implements {@link > RandomAccess}. > ? ? * > ? ? * @param a the array by which the list will be backed > ? ? * @return an unmodifiable list view of the specified array > ? ? */ > ? ?public static List asUnmodifiableList(T... a); > > > The compiler may (but is not required to) emit calls to this method in the > implementation of list literals. ?It may also be desirable to add some > library support for immutable sets or lists (akin to that provided by the > Google Collections project), but this isn't necessary for the proposal to go > forward, and the compiler can take advantage of such support in whatever > release it happens to be added. > > REFLECTIVE APIS: This proposal has no effect on core reflective APIs. The tree > API inside javac > ?would require a minor extension. > > > > OTHER CHANGES: No other parts of the platform need be to be updated. > > > > MIGRATION: Existing manual list, set, and map construction code could be > replaced by more concise list and map literals, but this is not necessary. > > > > *COMPATIBILITY* > > * * > > BREAKING CHANGES: All previously valid programs remain valid, and their > semantics is unaffected. > > * * > > EXISTING PROGRAMS: Source and class files of earlier versions are unaffected > by the feature. ?No new overloadings or overridings can occur. > > > *REFERENCES* > > * * > > EXISTING BUGS: 4632701 , > 6237556 . > > > *FUTURE DIRECTIONS* > > > Assuming we make sure that no syntactic ambiguity would result, a future > release could allow certain collection literals as annotation values. ?This > is *not *proposed for Project Coin, but should inform the work. > > From jjb at google.com Mon Mar 30 17:45:03 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 30 Mar 2009 17:45:03 -0700 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> Message-ID: <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> Hi Neal, Could you please be a be a bit more specific? In particular, could you provide an example of something that this proposal precludes but the for-each construct (which is already in the language) does not? Once we have such an example, we'll be able to weigh the pros and cons intelligently. Thanks, Josh On Mon, Mar 30, 2009 at 5:40 PM, Neal Gafter wrote: > Josh- > > This approach precludes some designs for reifying generics in the > future because it is defined by the implicit creation of non-reified > interfaces (e.g. List, etc). It isn't clear if we'll ever add > reification, but it would be a shame to restrict or remove our option > to do so. You can avoid this by not implicitly tying language > constructs to particular existing interfaces. > > Regards, > Neal > > From neal at gafter.com Mon Mar 30 17:58:10 2009 From: neal at gafter.com (Neal Gafter) Date: Mon, 30 Mar 2009 17:58:10 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> Message-ID: <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> On Mon, Mar 30, 2009 at 5:45 PM, Joshua Bloch wrote: > Could you please be a be a bit more specific?? In particular, could you > provide an example of? something that this proposal precludes but the > for-each construct (which is already in the language) does not?? Once we > have such an example, we'll be able to weigh the pros and cons > intelligently. Sure. As the proposed construct is defined to create non-reified collection types, and that distinction may be highly visible to programmers, programs using the proposed syntax would have to continue creating non-reified collections. With the for-each loop, on the other hand, the only object created by the construct is an iterator. The iterator is constructed by a library method that is completely under control of the Iterable that comes in, and hidden from code containing the for-each loop. While non-reified types might continue to produce non-reified iterators, reified classes may well produce reified iterators. From belingueres at gmail.com Mon Mar 30 18:06:38 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Mon, 30 Mar 2009 22:06:38 -0300 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> Message-ID: 2009/3/30 Marek Kozie? : > W dniu 31 marca 2009 00:45 u?ytkownik Gabriel Belingueres > napisa?: >> Hi Marek: >> >> - VariableInitializer type is neither primitive nor Object. >> ?--> primitive : they should not be mixed with Object-s to easy. >> ?--> Object : when object type is Object, we mostly deal with >> situation 'Unknown type', so this should not be hidden. >> >> I still don't get why it is so bad to do something like this: >> final a = 1; // static type is int >> or >> final o = new Object(); // static type is Object, no doubt >> >> I still don't see the point on not making this feature more orthogonal >> (unless some convincing argument is presented against it.) >> >> > > For primitives I would prefer: > primitive a = 1; // a is int / short / byte > rather than: > final a = 1; // static type is int > > > Primitives represent other level of abstraction and mixing them will > make people to be confused (more or less). Why? final a = 1; // static type is int final b = new Integer(6); // static type is Integer If this is confusing for someone: final c = 1 + new Integer(7); then declare it as usual. > final o = new Object(); // in this form it's ok > > here I see problem: > final o = some.getBoo().getLocalization(); // o is Object > > For some reason we did not ensured valid type to be returned, so we > should care about it while declaring 'o', or say that we do not care: > final o = (Localization) some.getBoo().getLocalization(); > final Object o = some.getBoo().getLocalization(); Assuming that getLocalization() returns a Localization, then the whole point is that you don't need the cast; otherwise this feature is of doubtful utility. The variable type is known at compile type to be a Localization. OTOH, if the getLocalization() returns an Object, then final o = (Localization) some.getBoo().getLocalization(); might throw a ClassCastException at runtime, which is a pity because this is a new feature. If you want to risk to receive a ClassCastException, then declare it as usual: final Localization o = (Localization) some.getBoo().getLocalization(); IMHO, type casts should be forbidden, or at least discouraged. > If we allow final to be ANY type, then backing to declaration will be > required just to make correction, this will piss off programmers. > > So primitives and Object-s are special types and should be handled in this way. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > From per at bothner.com Mon Mar 30 19:20:25 2009 From: per at bothner.com (Per Bothner) Date: Mon, 30 Mar 2009 19:20:25 -0700 Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> Message-ID: <49D17DE9.1090007@bothner.com> On 03/30/2009 05:39 PM, John Rose wrote: >> For Java, to extend the string syntax and emphasize that a new string >> is being constructed, I recommend this: >> >> new "$foo, ${bar}s." A big advantage of templated strings is that they lend themselves nicely to Localization. That is a big advantage over using + between strings. We did this for JavaFX: http://openjfx.java.sun.com/current-build/doc/reference/ch02s03.html http://jfx.wikia.com/wiki/Proposal_for_the_string_literal_translation http://learnjavafx.typepad.com/weblog/2008/01/string-literal.html If you allow templated strings it is temping to also allow multi-line templated strings, because then you have a nice template engine for free. If we allow multi-line strings it seems a good idea to have distinct open and closing string delimiters, to catch errors and help IDEs. For example (wild off-the-top-of-my-head idea) <" and "> String x = <"Name: $(name) Address: $(address)">; (The proposal to use """ for both open and closing delimiters is very IDE-unfriendly. Imagine trying to do syntax highlighting and checking as the user is entering a program or makes a typo ...) You'd mark a localized string with some extra marker, for example: String x = <~"Name: $(name) Address: $(address)"~>; -- --Per Bothner per at bothner.com http://per.bothner.com/ From jjb at google.com Mon Mar 30 19:29:57 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 30 Mar 2009 19:29:57 -0700 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> Message-ID: <17b2302a0903301929n1aeb8af6k8f1b575b55e4de9f@mail.gmail.com> Neal, Sorry, I'm still confused. Can you tell me what client code would cause trouble, or at least give me a few examples? Thanks, Josh On Mon, Mar 30, 2009 at 5:58 PM, Neal Gafter wrote: > On Mon, Mar 30, 2009 at 5:45 PM, Joshua Bloch wrote: > > Could you please be a be a bit more specific? In particular, could you > > provide an example of something that this proposal precludes but the > > for-each construct (which is already in the language) does not? Once we > > have such an example, we'll be able to weigh the pros and cons > > intelligently. > > Sure. As the proposed construct is defined to create non-reified > collection types, and that distinction may be highly visible to > programmers, programs using the proposed syntax would have to continue > creating non-reified collections. > > With the for-each loop, on the other hand, the only object created by > the construct is an iterator. The iterator is constructed by a > library method that is completely under control of the Iterable that > comes in, and hidden from code containing the for-each loop. While > non-reified types might continue to produce non-reified iterators, > reified classes may well produce reified iterators. > From vapor1 at teleport.com Mon Mar 30 20:07:12 2009 From: vapor1 at teleport.com (Derek Foster) Date: Mon, 30 Mar 2009 23:07:12 -0400 (EDT) Subject: PROPOSAL: Underscores in numbers Message-ID: <11482659.1238468832504.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> 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 mre at m79.net Mon Mar 30 20:32:02 2009 From: mre at m79.net (Mike Elliott) Date: Mon, 30 Mar 2009 20:32:02 -0700 Subject: Proposal: Elided type specification for initialized final value declarations. Message-ID: <93e07d590903302032x4b00ba08m290239036762f2df@mail.gmail.com> See attached PDF for a prettier version, but here's the text: Title: Elided type specification for initialized final value declarations. Author: Mike Elliott ? The Boeing Company Overview: The use of the final keyword in declaring an initialized value (since it's final it's not really a ?variable?) is superfluous as all necessary type information is available from the right hand side of the declaration. Eliminating the type declaration will increase expressive power as well as reduce visual clutter. This feature exists to some degree in other languages ? the with construct in Modula 3 for example and the untyped constant declarations and (somewhat exotic) use of renames clauses in Ada ? where it has been shown to be useful in the building of complex expressions Examples: private final HashMap map = new HashMap(); would become private final map = new HashMap(); Since the type is completely determined by the expression on the right side of the equals sign, the type declaration on the left side of the equals sign is unnecessary and only adds visual clutter, making it more difficult to pick out the important thing, the name of the value being expressed. And since the value can never be changed the runtime determination of type, subtype, etc., is not an issue. A visually long value building process such as final BufferedInputStream in = new BufferedInputStream( new FileInputStream( filename )); is sometimes broken up into multiple declarations in order to keep the line lengths manageable, especially if there are coding conventions prohibiting physical lines which exceed 80 columns in order to encourage greater readability. final FileInputStream fis = new FileInputStream( filename ); final BufferedInputStream inStream = new BufferedInputStream( fis ); While this is semantically equivalent to the previous code, it avoids unsightly line wraps. However, this would be cleaner still if the type declaration could be elided: final fileInput = new FileInputStream( filename ); final bufferedIn = new BufferedInputStream( fileInput ); Note that locality of type expression is maintained. The programmer could still determine the type of the constant at the point of declaration. Details: This proposal makes optional the use of the type declaration when declaring final values with an initiailzer expression. The grammar would simply make this declaration optional which would break no existing code and still leave the deliberate declaration of type in this situation available if, for example, the programmer wished to use it as a sort of inline documentation. It can free up a substantial amount of screen real estate in the case of long type declarations which could be better used with a more expressive name for the constant than would otherwise fit on the line. Additionally it would encourage a greater use of the final keyword which can only help the compiler in code optimization efforts and provide greater clarity for the maintainer. The type system itself would not be impacted. The only change in compilation would be the necessity to look ahead to the value declaration in order to determine the constant's type from the value declartion rather than have it literally expressed immediately before that value declaration. No new byte codes would be necessary. Since this feature introduces no new functionality, no testing changes would be introduced other than to confirm that eliding the type declaration produces no changes in generated byte code. No library support is needed, nor would there be any changes to the reflection APIs. There is no effect on JNI or serialization. There would be an impact on JavaDoc as the type of the constant would not be immediately obvious to a post-process tool if this feature is allowed (as it probably should be) for named value declarations outside of method declarations; that is, for other than ?auto class? declarations. Compatability: No previously existing valid programs would become invalid. No overloadings can occur other than those which already occur, such as when a class variable in a superclass is ?overloaded? by creating the same class variable in a subclass (which should never have been allowed anyway, but that's another story). References: No known bugs related to this proposal. -- ============================ Mike Elliott mre at m79.net ============================ From Joe.Darcy at Sun.COM Mon Mar 30 20:53:13 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 30 Mar 2009 20:53:13 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> Message-ID: <49D193A9.4030104@sun.com> Hi Josh. A quick comment... Joshua Bloch wrote: > > *AUTHOR: *Joshua Bloch > > > *OVERVIEW* > > > FEATURE SUMMARY: Add support for immutable List, Set, and Map literals, with > a syntax similar to that of array initializers. [snip] > SEMANTICS and COMPILATION: A list literal behaves roughly as if replaced by > the following "desugaring": > > > > Arrays. *NonWildTypeArguments**opt* asUnmodifiableList( * > ElementInitializers* ) > > > > This desugaring assumes the existence of a new library method, > asUnmodifiableList, described below under Library Support. Note that type > inference of the element type for the list literal is exactly as if the > following method were invoked with *ElementInitializers *as as actual > parameters: > > > void foo(E... args) { } So the type of the list is computed as if using var-args, including when the args are themselves augmented constants. One possible wrinkle here is the bad interaction between var-args and generics. This would be removed if only "top level" literals were allowed (i.e. no nested Lists and Set, etc.), at the cost of reducing the utility of the feature. -Joe From Joe.Darcy at Sun.COM Mon Mar 30 21:05:44 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 30 Mar 2009 21:05:44 -0700 Subject: PROPOSAL: abstract enums In-Reply-To: <49D16041.9080200@joda.org> References: <25275917.1238382825309.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D04260.2010001@sun.com> <49D16041.9080200@joda.org> Message-ID: <49D19698.2000909@sun.com> Stephen Colebourne wrote: > Joseph D. Darcy wrote: >> Of the extensible and non-extensible version of enum pattern, the JSR >> 201 expert group chose the non-extensible variant and many other >> decisions and details of the original enum design flow from that >> fundamental decision. Revisiting that decision now is impractical. >> >> Additionally, some of the advantages of extensible enums can be had by >> making different enum classes implement a common interface; for some >> discussion of that general pattern see >> >> "Mixing-in an Enum" >> http://blogs.sun.com/darcy/entry/enums_and_mixins >> >> as well as an item in the 2nd edition of "Effective Java." > > The lack of abstract enums (where the superclass merely contains code, > not enum constants) has definitely had a negative impact on the > usefulness of the feature. JSR-310 will be significantly worse as an > implementation as a result of this omission. Even though lack of this feature admittedly makes writing certain APIs more difficult, that certainly does not necessarily imply a language change is an appropriate remedy. [snip] > The argument of "the original EG decided" is a poor one. By that The argument of "we can simply ignore the past" is a poor one as well. However, I assume you are not putting forward such a naive justification for this change. > argument, we should not make any changes to Java, and leave it as in > v1.0. As such, I request that you consider merit, not an arbitrary 'it > changed recently'. All the language changes occur in the context of what has gone before and what might come in the future. Some changes have been deliberately deferred until more research could occur. For example, some kind of generics were deliberately left out of Java 1.0 because it was determined an adequate version could not be designed and implemented in time. Other changes have been decided against explicitly or implicitly; Java explicitly decided against multiple inheritance of classes. IMO the level of discourse on the list would be improved if more time was taken to research and understand why the previous language decisions were made and the many trade offs involved. For example, some of the rationale for enums is contained in the early draft documents of JSR 201: http://www.jcp.org/en/jsr/detail?id=201 A quote I came across doing background reading for Project Coin frequently comes to mind: "If this book [Principles of Programming Languages] has convinced the reader that a programming language designer needs the expertise of a scientist, the precision of a mathematician, and the taste of an artist as well as the pragmatism of an engineer, then it has achieved one of its objectives." --R. D. Tennent -Joe From jjb at google.com Mon Mar 30 21:06:55 2009 From: jjb at google.com (Joshua Bloch) Date: Mon, 30 Mar 2009 21:06:55 -0700 Subject: Proposal: Collection Literals In-Reply-To: <49D193A9.4030104@sun.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D193A9.4030104@sun.com> Message-ID: <17b2302a0903302106x6c634037g81408c0fc940cb3b@mail.gmail.com> Joe, Thanks for looking at the proposal. On Mon, Mar 30, 2009 at 8:53 PM, Joe Darcy wrote: > >> This desugaring assumes the existence of a new library method, >> asUnmodifiableList, described below under Library Support. Note that type >> inference of the element type for the list literal is exactly as if the >> following method were invoked with *ElementInitializers *as as actual >> parameters: >> >> >> void foo(E... args) { } >> > > So the type of the list is computed as if using var-args, including when > the args are themselves augmented constants. > > One possible wrinkle here is the bad interaction between var-args and > generics. This would be removed if only "top level" literals were allowed > (i.e. no nested Lists and Set, etc.), at the cost of reducing the utility of > the feature. > Good point! Currently, the desugaring of the Pascal's triangle example would work, but it would generate an unchecked generic array creation (of type List[] for varargs parameter). But, if we end up implementing Bob Lee's proposal ("Simplified Varargs Method Invocation"), the problem goes away:) I consider it a good sign when a group of language changes work well together. Josh P.S. To be fair, I haven't thought through this in gory detail, especially when it comes to map literals. But I'm hopeful. From Joe.Darcy at Sun.COM Mon Mar 30 21:43:22 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Mon, 30 Mar 2009 21:43:22 -0700 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CF5AF2.8020408@entreact.com> References: <49CF5AF2.8020408@entreact.com> Message-ID: <49D19F6A.90006@sun.com> Jeroen van Maanen wrote: > I'd like to coin a switch (...) instanceof statement as a new feature of > the Java language. Please accept the attached proposal for review. > > Regards, Jeroen Hello. I largely concur with the feedback on this proposal already sent to the list; for examples, questions on fall-though semantics, ordering of type checks and subtypting, etc. I suggesting looking over my strings in switch proposal for other potential issues with modifying the switch statement: http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html However, I general don't favor this vein of modification to the switch statement. On a related note, I'm at most lukewarm toward switching on class literals. Class literals are constants of a sort, loadable by the "load constant" JVM instruction, and from that standpoint are a reasonable value to switch on, just like other kinds of constants. However, off hand I only know of one section of code in the JDK that would benefit from this capability so there doesn't seem to be a strong case for adding it. -Joe From rssh at gradsoft.com.ua Mon Mar 30 22:12:30 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 31 Mar 2009 08:12:30 +0300 (EEST) Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: <49D17DE9.1090007@bothner.com> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> <49D17DE9.1090007@bothner.com> Message-ID: <2b03cbabf59b28634b53f0ca16e85215.squirrel@wmail.gradsoft.ua> > > (The proposal to use """ for both open and closing delimiters > is very IDE-unfriendly. Imagine trying to do syntax highlighting > and checking as the user is entering a program or makes a typo ...) > But IDE-s ara adopted to groovy and scala now. (I.e. netbeans correctly parse and highlight groovy long strings). And all major IDE-s will be adopted to new . So, this argument is not counted. // And of course, I does not see prinicipal difference in number of delimiters. If multiline strings such anticipated -- may be syntax of some form of HERE document can be used instead ? P.S. Sorry, I know that multiline strings debate is closed ;) > You'd mark a localized string with some extra marker, for example: > > String x = > <~"Name: $(name) > Address: $(address)"~>; > -- > --Per Bothner > per at bothner.com http://per.bothner.com/ > > From rssh at gradsoft.com.ua Mon Mar 30 22:37:16 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 31 Mar 2009 08:37:16 +0300 (EEST) Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> 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 20, 2009, at 1:50 PM, John Rose wrote: > >> I wrote the spec. draft and implementation (in antlr) for Groovy >> gstring syntax; I did the work with the intention of helping the JSR >> 241 Groovy standard. It could work in Java with adjustments, and the >> Groovy spec. is detailed enough to be a starting point. I don't >> really have time to work on it though. That's why I haven't done a >> proposal. >> >> For Java, to extend the string syntax and emphasize that a new string >> is being constructed, I recommend this: >> >> new "$foo, ${bar}s." > > I wrote up something more specific, for the sake of this go-around. > It is generic and pluggable enough to provide some help with XML > templating, and SQL construction. > 1. Whith SQL constructions exists a problem: existence of such template string parameters provoke programmers to use it instead host variables in queries, which cause performance problems and SQL injection problems. So, for example, in many PHP guidelines exists rule do not use "-strings for SQL. 2. Also, I can't understand, how this construction will be useful without multiline strings. 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 '@' ?) 4. Why just not call this parser from some method ? I. e. what arguments for including string templates in language itself, instead library call ? > Enjoy! > > http://wikis.sun.com/display/mlvm/TemplatedConstructorExpressions > > (Although this document is hosted on mlvm at present, it has nothing > to do with JSR 292.) > > -- John > > P.S. For the archive, here is the original wiki source. > > h3. AUTHOR(S): > > John Rose > > h3. OVERVIEW > > String templating syntaxes are found in shell-like languages. They > allow a flexible and natural-looking mixture of constant templates > with non-constant interpolation. Adapt such a notation to Java, in a > way that provides natural-looking templating for unformatted and > formatted text, XML, SQL, and other applications involving foreign > notations andstructured text. > > h3. FEATURE SUMMARY: > > h4. *1.* simple templated strings > > The {{new}} keyword is currently used for creating objects and > arrays. This specification introduces another syntax based on the > {{new}} keyword, called the *templated construction expression*: > > {noformat} > int zip = 95120, phone = 5551212; > String s = new "zip=$(zip), phone=$(phone)."; > String s2 = "zip=" + zip + ", phone=" + phone + "."; // same code > {noformat} > > As with other languages, each unescaped dollar sign {{$}} > introduces an *interpolation*, which is an arbitrary Java expression > that contributes to the template. Everything else between the string > quotes is treated as constant text; each non-empty span of string > characters is called a *string segment*. The string segments also > contribute to the template. As with the current plus {{+}} > notation, each interpolation or string segment causes another item to > be appended. > > Every interpolation ends with zero or more expressions, called the > *interpolation arguments*. If there is exactly one interpolation > argument, we speak unambiguously of the *interpolation expression*. > (There are multi-argument examples below.) > > Such a syntax would be a merely marginal improvement over the current > plus {{+}} notation for {{StringBuilder it includes two additional > degree of freedom. They allow the programmer to specify templating > mechanisms other than {{StringBuilder}}, and to more easily control > the details of formatting for the interpolated items. > > h4. *2.* programmer-defined templating > > A templated construction expression may be qualified: > > {noformat} > int zip = 95120, phone = 5551212; > StringBuilder buf = new StringBuilder(); > buf.new "zip=$(zip), phone=$(phone)."; > String s = buf.toString(); // same result as previous example > {noformat} > > In fact, if a templated construction expression is unqualified, it is > exactly as if the compiler had supplied a default qualifier of {{new > StringBuilder()}} and appended a call to {{toString}} at the end, to > extract the resulting string. > > But, the programmer may provide a different object reference {{x}} as > a qualifier to a templated construction expression; an object used > this way is called a *template factory*. A qualified templated > construction expression is equivalent to a chain of {{append}} method > calls applied to the template factory, as detailed below. > > This allows new classes to be created which can define library- > specific semantics for templated construction. The only requirement > on template factories is that they supply the {{append}} calls implied > by the interpolations within the templates. These {{append}} calls > may be overloaded, and may take multiple arguments, or no arguments at > all. > > {noformat} > java.lang.Appendable app = ...; > app.new "subseq: $(str, beg, end)"; // append(str, beg, end) > {noformat} > > h4. *3.* generic format specifiers > > The dollar sign of an interpolation may be immediately followed by a > *format specifier*, a sequence of string characters enclosed in angle > brackets. These characters are collected into separate (presumably > short) string literal which is passed as an additional leading > argument to the method call for the interpolation; the method is named > {{format}} instead of append, and may (again) take any number of > arguments. Format specifiers may not contain unescaped right angle > brackets; otherwise they are arbitrary, and interpreted only by the > {{append}} call they are passed to. > > {noformat} > String s = new Formatter().new "zip=$<%05d>(zip), phone=$< > %d>(phone).".toString(); > {noformat} > > h4. *4.* abbreviated interpolation expressions > > For certain simple interpolation expressions, the enclosing > parentheses are optional. The expressions which can drop parentheses > are a decimal numeral, a name (qualified or simple), a name followed > by one parenthesized argument list, and a name followed by one > bracketed array index. The name must not contain any dollar signs in > its spelling. > > {noformat} > int zip = 95120, phone = 5551212; > String s = new "zip=$zip, phone=$phone."; // same code > {noformat} > > As always, any ambiguity between the interpolation expression and a > following interpolation or string segment can always be resolved by > using explicit parentheses. > > (Note: This last feature of abbreviation is troublesome to specify and > implement, but it appears to be a worthwhile creature comfort.) > > h3. MAJOR ADVANTAGE: > > The features specified here allow programmers a superior notation for > creating templated textual items. Such notations are popular and well > proven in other languages, including the shells, PHP, Perl, and > Groovy. It will reduce pressure on programmers to move to those other > languages. > > h3. MAJOR BENEFIT: > > Concise, natural templated expressions are easier to code and maintain > than equivalent nests of method calls. > > h3. MAJOR DISADVANTAGE: > > The JLS gets more complicated. > > h3. ALTERNATIVES: > > Programmers may use explicitly coded nests method calls; they are of > course more verbose. > > h3. EXAMPLES, BEFORE/AFTER: > > See above and below (in the specification) for one-line examples > demonstrating each aspect of this specification. > > h4. SIMPLE EXAMPLE: > > {noformat} > String whom = "world"; > System.out.printlin(new "Hello, $whom!"); > {noformat} > > h4. ADVANCED EXAMPLE: > > This syntax can easily support two-phase template creation, where a > template is first compiled and checked, and then later applied one or > more times. > > Let's suppose a hypothetical XML snippet compiler designed for > templated construction expressions. It might be used this way to > compile a snippet generator with optionally typed free variables > mapped to an API featuring a {{make}} method with positional arguments: > > {noformat} > XMLSnippetCompiler xmlc = ...; > xmlc.new "$1 pattern>$2"; > XMLSnippet xmls = xmlc.compile(); > System.out.println(xmls.make("raining", "walk inside", 5 /*medium > pri*/)); > System.out.println(xmls.make("fire", "run outside", 1 /*highest pri*/)); > {noformat} > > h3. DETAILS > > The sequence of string segments and interpolations of a templated > construction expression is called its body. Each string segment > begins with either the opening quote of the body, or the end of a > previous > > The templated construction expression is broken into zero or more > interpolations and zero or more (non-empty) string segments. These > are presented in order to the template factory object, as method calls > to {{appendText}}, {{append}}, or {{format}}. > > {noformat} > x.new "a"; // sugar for x.appendText("a") > x.new "$(y)"; // sugar for x.append(y) > x.new "$(y)"; // sugar for x.format("q",y) > x.new "$(y)"; // sugar for x.format("q",y) > x.new "a$(y)b"; // sugar for > x.appendText("a").append(y).appendText("b") > x.new "a$(y)b"; // sugar for > x.appendText("a").format("q",y).appendText("b") > x.new "a$(y)$(z)"; // sugar for > x.appendText("a").append(y).format("q",z) > x.new ""; // degenerate sugar for x > {noformat} > > There is no particular restriction on the syntax of interpolation > argument expressions. In particular, they can contain quoted strings > and templated construction expressions. > > {noformat} > new "Hello, $("world")."; > new "Hello, $(new "wor$("")ld")."; > {noformat} > > There is no particular restriction on the type or number of > interpolation argument expressions. Since they are sugar for > {{append}} or {{format}} method calls, they are simply required to > participate successfully in the rules for method call resolution. > > {noformat} > x.new "$()"; // sugar for x.append() > x.new "$(y)"; // sugar for x.append(y) > x.new "$(y,z)"; // sugar for x.append(y,z) > x.new "$()"; // sugar for x.format("q") > x.new "$(y)"; // sugar for x.format("q",y) > x.new "$(y,z)"; // sugar for x.format("q",z) > {noformat} > > If the templated construction expression is unqualified, it is > provided with a new {{StringBuilder}} factory object, and the > expression as a whole is closed with a {{toString}} call. > > For the sake of template factories which need to make the distinction, > string segments are appended by {{appendText}} method call, if one > exists on the factory object's static type; an error is reported if it > is not applicable to a single {{String}}. Otherwise {{append}} is > applied to the constant string segment, which will be a string literal. > > If the format specifier is completely empty, the leading argument to > format is omitted, and it is up to the programmer to specify it > explicitly in the interpolation arguments: > > {noformat} > String fmt = (zip <= 99999) ? "%05d" : "%d"; > String s = new Formatter().new "zip=$<>(fmt, zip), phone=$< > %d>(phone).".toString(); > //new Formatter().appendText > {noformat} > > Here are examples of abbreviated interpolation expressions: > > {noformat} > "$x" // same as "$(x)" > "$1" // same as "$(1)" > "$x.y" // same as "$(x.y)" > "$x.y.z" // same as "$(x.y.z)" > "$f(x)" // same as "$(f(x))" > "$x.f(y)" // same as "$(x.f(y))" > "$x[y]" // same as "$(x[y])" > "$x.y[z]" // same as "$(x.y[z])" > {noformat} > > Here are examples of abbreviated interpolation expression with > interesting right contexts: > > {noformat} > "$x." // same as "$(x)." > "$1." // same as "$(1)." > "$1.0" // same as "$(1).0" > "$x.y." // same as "$(x.y)." > "$f(x)[" // same as "$(f(x))[" > "$x[y](" // same as "$(x[y])(" > {noformat} > > Here are examples of illegal attempts at abbreviation: > {noformat} > "$$" // not same as "$($)"; must be rejected > "$$x" // not same as "$($x)"; must be rejected > "$x.$" // not same as "$(x.$)"; must be rejected > "$x["... // same as "$(x["..., a likely syntax error > "$[x]" // reserved; must be rejected > "${x}" // reserved; must be rejected > "$x{y}" // reserved; must be rejected > "$x" // reserved; must be rejected > {noformat} > > Within a string segment of a templated construction expression, the > dollar character may be escaped with a backslash, to prevent it from > introducing an interpolation. Within a format specifier of an > interpolation, the close-angle-bracket may be escaped with a > backslash, to prevent it from terminating the format specifier. An > unescaped dollar sign must introduce a well-formed interpolation. > > {noformat} > new "\$$x.priceInDollars()" > new "$<<\>>("has strange format of \"<>\"")." > new "$" // must be rejected; should be new "\$" > {noformat} > > h3. SPECIFICATION: > > The specification is complete in the running text of this document. > It will be distilled shortly. > > h3. COMPILATION: > > As this is syntactic sugar, no new mechanisms are needed. The hack of > changing {{appendText}} to {{append}} when the former is missing > requires an extra symbol table lookup. > > h3. TESTING: > > Testing will be done the usual way, via unit tests, and by early > access customers experimenting with the new facilities. > > h3. LIBRARY SUPPORT: > > There should be some retrofitting of libraries that perform append- > like operations. (This is similar retrofitting to that done when > varargs was introduced.) > > Suitable methods for {{appendText}} are added to {{StringBuilder}}, > {{StringBuffer}}, and {{Formatter}}. > > The class {{StringBuilder}}, which is privileged as the default > template factory type, is augmented with one or more {{format}} > methods that redirect to {{Formatter}}. > > {noformat} > String s = new "zip=$<%05d>zip, phone=$phone.".toString(); > {noformat} > > The class {{PrintStream}}, which already has {{format}} methods, is > also given {{appendText}} and {{append}} methods, as synonyms for > {{print}}. > > {noformat} > System.out.new "zip=$<%05d>zip, phone=$phone.".toString(); > {noformat} > > (*QUESTION:* What other classes could benefit from retrofitting?) > > h3. REFLECTIVE APIS: > > No changes. > > h3. OTHER CHANGES: > > None. > > h3. MIGRATION: > > The feature is for new code only. > > h3. COMPATIBILITY > > h4. BREAKING CHANGES: > > None. All changes are associated with previously unused syntaxes. > > h4. EXISTING PROGRAMS: > > No special interaction. > > h3. REFERENCES > > h4. EXISTING BUGS: > > None known. > > h4. URL FOR PROTOTYPE: > > None yet. > > > From vapor1 at teleport.com Mon Mar 30 22:51:38 2009 From: vapor1 at teleport.com (Derek Foster) Date: Tue, 31 Mar 2009 01:51:38 -0400 (EDT) Subject: Proposal: Sameness operators Message-ID: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> AUTHOR: Derek Foster OVERVIEW Many Java objects implement the Comparable interface, and/or override the Object.equals() method, to provide a way of ordering their instances or detecting whether two instances are equivalent . However, the syntax for using these methods has historically been fairly ugly: // We want to write "if a >= b", but we have to write... if (a.compareTo(B) >= 0) { whatever(); } // We want to write "if a == b", but we have to write... if (a.equals(b)) { whatever(); } The ugliness of these methods has often motivated the creation of special-purpose APIs to simplify the use of classes which implement them, such as the 'Date.before(Date)' and 'Date.after(Date)' methods in java.util.Date. However, these methods are inconsistent from class to class, and often not present. Furthermore, the existing language == and != operators exhibit a strange assymetry between the behavior of objects and that of primitive types that often catches new users of Java by surprise: int i; if (i == 5) { // gets here if the VALUE of i is 5 } String j = new String("abc"); if (j == "abc") { // probably never gets here! Comparing the values of the references, not the values of the strings. } String k = new String("abc"); if (k.equals("abc")) { // gets here if the VALUE of k is "abc". } This behavior often confuses newcomers to Java, and is a common source of bugs even for experienced programmers. This proposal suggests that a new set of relational operators be added to Java which would simplify ordering classes by their declared orderings (as specified by the Comparable class and Object.equals()), while still yielding syntax that is as simple as using the existing >=, <=, ==, and != operators. FEATURE SUMMARY: Adds four new operators to Java: a $$ b "same as": a==null ? b==null : a.equals(b), or a == b for primitive types. 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. and adds additional overloadings to existing operators: a < b a.compareTo(b) < 0, or a < b for primitive types. a > b a.compareTo(b) > 0, or a > b for primitive types. MAJOR ADVANTAGE: Use of new operators for these relational tests would simplify code and make it more clear what relational tests are being made, as well as reducing the opportunity for mistakes (such as accidentally typing a.compareTo(b) >=0 when <=0 was intended). MAJOR BENEFIT: Clearer code due to the use of infix operators instead of using method calls and an extra pair of parentheses, plus possible extra tests (often accidentally omitted) for nullness around calls to Object.equals(Object). Future proposals involving limited uses of operator overloading for code clarity (for BigInteger, etc. classes) would no longer run into the iceberg of "but you can't change the behavior of == in a backwards-compatible fashion!" MAJOR DISADVANTAGE: Modifications to the compiler would be required. These do not appear particularly difficult, but would take some effort. The !$ operator would not be available for Perl-style pattern matching, if that were ever added to Java. ALTERNATIVES: Keep using the Comparable.compareTo and Object.equals methods as they are. It would have been better to define == and != this way in the first place, and use some other operator (perhaps === as in some other languages?) to indicate comparison by object identity. This would have made Java simpler and easier for newcomers to understand. However, that's not how the language is currently defined, and to change the behavior of == now would be a backwards incompatible change. EXAMPLES SIMPLE EXAMPLE: String getOrdering(String first, String second) { if (first $$ second) { System.out.println("They are equal"); } else if (first !$ second) { System.out.println("They are not equal"); } else if (first > second) { System.out.println("The first is after the second"); } else if (first >$ second) { System.out.println("The first is same as or after the second"); } else if (first < second) { System.out.println("The first is before the second"); } else if (first <$ second) { System.out.println("The first is before or the same as the second"); } } ADVANCED EXAMPLE: Really, the simple example pretty much illustrates the feature. DETAILS SPECIFICATION: The following new tokens $$ !$ >$ <$ shall be added to section 3.12 of the JLS3. The expression grammar in section 15.20 shall be modified like so: RelationalExpression: ShiftExpression RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression >$ ShiftExpression RelationalExpression <$ ShiftExpression RelationalExpression instanceof ReferenceType The expression grammar in section 15.21 shall be modified like so: EqualityExpression: RelationalExpression EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression $$ RelationalExpression EqualityExpression !$ RelationalExpression Semantically, the behavior of these new operators is as follows: $$ and !$ operators: Evaluation of these operators shall occur exactly as they do for the == and != operators, as specified in section 15.21 of the JLS3 ("Equality Operators"), with the exception that for the purposes of these operators, section 15.21.3 ("Reference equality operators == and !=") shall be disregarded and replaced with: If the operands of a sameness operator are both of either reference type or the null type, then the operation is object equivalence. The behavior described below is for the $$ operator. The !$ operator shall behave identically except that it shall return false when the $$ operator would return true, and vice versa. The procedure for evaluating the $$ operator is as follows: If both operands are null, then the result shall be 'true'. Otherwise, if the left operand is null and the right operand is not null, then the result shall be 'false'. Otherwise, the return value shall be the value of the expression "left.equals(right)", evaluated using the java.lang.Object.equals(Object) method. >, >$, <, and <$ operators: Evaluation of these operators shall occur exactly as it does for corresponding >, >=, <, and <= operators, in section 15.20.1 of the JLS3 ("Numerical Comparison Operators <, <=, >, and >=") with the exception of the following. The text "The type of each of the operands of a numerical comparison operator must be a type that is convertible (?5.1.8) to a primitive numeric type, or a compile-time error occurs." shall be replaced with the text "If the type of both of the operands of a numerical comparison operator is a type that is convertible (?5.1.8) to a primitive numeric type, the following algorithm is used to evaluate the operator. Otherwise, the operation is object ordering (See ?15.20.1.1)" A new section 15.20.1.1 shall be added consisting of the folowing text: If one or both operands of a relational operator cannot be converted to primitive numeric types, then boxing conversions shall be used to convert both operands to object types. After this conversion, if the type of the left operand does not extend the raw type java.lang.Comparable, and also does not extend java.lang.Comparable for some type T which is equal to or a supertype of the type of the right operand, then a compiler error shall be reported. Otherwise, the result of the comparison shall be evaluated at runtime as follows: If the left operand is null, a NullPointerException shall be thrown. Otherwise, the method left.compareTo(right) shall be called. The following table shall be used to determine the result of the operator evaluation, based on the value returned from this method: left.compareTo(right) <0 ==0 >0 > false false true < true false false >$ false true true <$ true true false COMPILATION: Compilation of the example given above would be desugared as follows: if (first==null ? second==null : first.equals(second)) { System.out.println("They are equal"); } else if (first==null ? second != null : !first.equals(second)) { System.out.println("They are not equal"); } else if (first.compareTo(second) > 0) { System.out.println("The first is after the second"); } else if (first.compareTo(second) >= 0) { System.out.println("The first is same as or after the second"); } else if (first.compareTo(second) < 0) { System.out.println("The first is before the second"); } else if (first.compareTo(second) <= 0) { System.out.println("The first is before or the same as the second"); } TESTING: The feature can be tested by ensuring, first of all that the new operators return the same results as existing operators when invoked on operands which are both convertible to numeric primitive types. Secondly, that the new operators return the same results as their desugaring equivalents when invoked in circumstances where one or both operands are not convertible to numeric primitive types. Thirdly, that the relational operators throw NullPointerExceptions when the leftmost operation is null. Fourthly, that compiler errors are reported exactly in the cases when the desugared equivalents of the operators would not compile. LIBRARY SUPPORT: No library changes are needed for this feature. REFLECTIVE APIS: No changes to reflective APIs are needed for this feature. OTHER CHANGES: No other parts of the platform need to be updated. MIGRATION: A tool such as Eclipe or IntelliJ Idea might identify for the users existing calls to .compareTo or .equals which could be converted to use the new operators, and could offer to perform the change automatically at the user's request. Or a user could simply refactor code to use the new operators as desired. COMPATIBILITY BREAKING CHANGES: These operators should not cause any existing valid programs A program which, in source code, used the $ character at the start of an identifier might be affected, if it contained code such as: if (a<$something) { } meaning "if ( a < $something )" rather than "if ( a <$ something )" which is how it would be parsed according to this proposal. This would almost certainly result in a compiler error about a missing variable "something", particularly if the body of generated code was large, so the odds of this resulting in correctly compiling but silently misinterpreted code is small. This would only happen in generated code (the only place a $ character is supposed to be used, according to the JLS), and is expected to be an extremely rare phenomenon, since generated code rarely starts identifiers with dollar signs, and also usually generates code with spaces around operators for readability. This problem can be easily fixed when upgrading to Java 7 by altering the code generator to put a space in front of any such identifiers, either globally or only when they follow a < or > character. Note that internal synthetic variables generated by a compiler would be immune from this problem since they would never appear in source code form. Alternately, this proposal could be altered to use another character instead of $ for its tokens. One good candidate for this would be "$" which lends itself to being read as "is equivalent to" (rather than "$" for "is the same as"). There are, however, rare cases that this could break as well ( if (a<~b) { ... } ) and although relational tests against negated values are quite rare (since combining bitwise operations and relationals is usually a nonsensical operation), unfortunately this breakage could occur in non-generated code, which is much more common. Yet another option would be "#", which somewhat resembles an equals sign. Thus, instead of the $$, !$, <$, and >$ operators, this proposal could be implemented to use the ~~, !~, <~, and >~ operators, or the ##, !#, <#, and ># operators. The # operator has the advantage of being unused in Java, and so is guaranteed not to break code. However, it is highly sought after by writers of language change proposals, and so is under heavy competition as to its future meaning. EXISTING PROGRAMS: Except for the minor, rare, breaking change listed above, this change should not create incompatibilities with existing source or class files. REFERENCES EXISTING BUGS: There are a variety of proposals in the Bug Database related to various people's desires to support operator overloading for certain built-in mathematical classes such as BigInteger. A couple of such proposals are listed below. "Add [], -, +, *, / operators to core classes as appropriate" (related) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5099780 "BigInteger should support autoboxing" http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6407464 Also, see discussion on the Project Coin mailing list regarding the proposal "Draft proposal: allow the use of relational operators on Comparable classes," particularly with regards to why that proposal was withdrawn (namely, inability to make the == and != operators work properly on Comparable classes). http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000361.html URL FOR PROTOTYPE (optional): None. From schulz at e-Spirit.de Mon Mar 30 23:03:59 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Tue, 31 Mar 2009 08:03:59 +0200 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <49D15864.9000009@gmail.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com><49D0794C.7090400@sun.com> <49D15864.9000009@gmail.com> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC10887F35@osiris2.e-spirit.de> Stephen Colebourne wrote: > I'm surprised annotation solutions are being considered given the > general approach taken to annotations affecting the language. I actually had the same question in mind. In various places (and reactions on proposals on this list), annotations are doomed for influencing the outcome of the compilation process (e.g., ARM). Why should index access be different? > IndexedGet > IndexedSet > MappedGet > MappedPut I much prefer this approach, especially as one can only implement them once (annotations would require additional checks on multiple use). It might require some strategy, though, when a class implements both, indexed and mapped get. > It might be a good time to retrofit a Sized interface too, > defining the > size() method. Hm. Would it make sense to have something like Contains and ContainsKey, too? > Finally, arrays must "implement" the new indexed interfaces. This is > critical to allow code like this to work: This is interesting and fits into the development of unifying access to collections and arrays very well. Stefan From schulz at e-Spirit.de Mon Mar 30 23:20:59 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Tue, 31 Mar 2009 08:20:59 +0200 Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com><977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua><7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC10887F36@osiris2.e-spirit.de> I sent a proposal on embedded expressions to this list before, and it seemed to have been dismissed. I found the newly posted proposal even more complex and difficult to read, so it makes me wonder about the reasoning behind it. (Although, I am still in favor of Java supporting embedded expressions). And I agree with Per in that such a solution should support multi-line Strings as well. Especially, as Joe did not consider embedded expressions for Coin, I dropped on writing a combined proposal on these issues and remain confused. Stefan > -----Original Message----- > From: coin-dev-bounces at openjdk.java.net > [mailto:coin-dev-bounces at openjdk.java.net] On Behalf Of John Rose > Sent: Tuesday, March 31, 2009 2:40 AM > To: coin-dev > Subject: PROPOSAL: Templated Construction Expressions > (i.e.,Expressions Embedded in Strings) > > On Mar 20, 2009, at 1:50 PM, John Rose wrote: > > > I wrote the spec. draft and implementation (in antlr) for Groovy > > gstring syntax; I did the work with the intention of helping the JSR > > 241 Groovy standard. It could work in Java with > adjustments, and the > > Groovy spec. is detailed enough to be a starting point. I don't > > really have time to work on it though. That's why I haven't done a > > proposal. > > > > For Java, to extend the string syntax and emphasize that a > new string > > is being constructed, I recommend this: > > > > new "$foo, ${bar}s." > > I wrote up something more specific, for the sake of this go-around. > It is generic and pluggable enough to provide some help with XML > templating, and SQL construction. > > Enjoy! > > http://wikis.sun.com/display/mlvm/TemplatedConstructorExpressions > > (Although this document is hosted on mlvm at present, it has nothing > to do with JSR 292.) > > -- John > > P.S. For the archive, here is the original wiki source. > > h3. AUTHOR(S): > > John Rose > > h3. OVERVIEW > > String templating syntaxes are found in shell-like languages. They > allow a flexible and natural-looking mixture of constant templates > with non-constant interpolation. Adapt such a notation to > Java, in a > way that provides natural-looking templating for unformatted and > formatted text, XML, SQL, and other applications involving foreign > notations andstructured text. > > h3. FEATURE SUMMARY: > > h4. *1.* simple templated strings > > The {{new}} keyword is currently used for creating objects and > arrays. This specification introduces another syntax based on the > {{new}} keyword, called the *templated construction expression*: > > {noformat} > int zip = 95120, phone = 5551212; > String s = new "zip=$(zip), phone=$(phone)."; > String s2 = "zip=" + zip + ", phone=" + phone + "."; // same code > {noformat} > > As with other languages, each unescaped dollar sign {{$}} > introduces an *interpolation*, which is an arbitrary Java expression > that contributes to the template. Everything else between > the string > quotes is treated as constant text; each non-empty span of string > characters is called a *string segment*. The string segments also > contribute to the template. As with the current plus {{+}} > notation, each interpolation or string segment causes another > item to > be appended. > > Every interpolation ends with zero or more expressions, called the > *interpolation arguments*. If there is exactly one interpolation > argument, we speak unambiguously of the *interpolation expression*. > (There are multi-argument examples below.) > > Such a syntax would be a merely marginal improvement over the > current > plus {{+}} notation for {{StringBuilder it includes two > additional > degree of freedom. They allow the programmer to specify templating > mechanisms other than {{StringBuilder}}, and to more easily control > the details of formatting for the interpolated items. > > h4. *2.* programmer-defined templating > > A templated construction expression may be qualified: > > {noformat} > int zip = 95120, phone = 5551212; > StringBuilder buf = new StringBuilder(); > buf.new "zip=$(zip), phone=$(phone)."; > String s = buf.toString(); // same result as previous example > {noformat} > > In fact, if a templated construction expression is > unqualified, it is > exactly as if the compiler had supplied a default qualifier of {{new > StringBuilder()}} and appended a call to {{toString}} at the end, to > extract the resulting string. > > But, the programmer may provide a different object reference > {{x}} as > a qualifier to a templated construction expression; an object used > this way is called a *template factory*. A qualified templated > construction expression is equivalent to a chain of > {{append}} method > calls applied to the template factory, as detailed below. > > This allows new classes to be created which can define library- > specific semantics for templated construction. The only requirement > on template factories is that they supply the {{append}} > calls implied > by the interpolations within the templates. These {{append}} calls > may be overloaded, and may take multiple arguments, or no > arguments at > all. > > {noformat} > java.lang.Appendable app = ...; > app.new "subseq: $(str, beg, end)"; // append(str, beg, end) > {noformat} > > h4. *3.* generic format specifiers > > The dollar sign of an interpolation may be immediately followed by a > *format specifier*, a sequence of string characters enclosed > in angle > brackets. These characters are collected into separate (presumably > short) string literal which is passed as an additional leading > argument to the method call for the interpolation; the method > is named > {{format}} instead of append, and may (again) take any number of > arguments. Format specifiers may not contain unescaped right angle > brackets; otherwise they are arbitrary, and interpreted only by the > {{append}} call they are passed to. > > {noformat} > String s = new Formatter().new "zip=$<%05d>(zip), phone=$< > %d>(phone).".toString(); > {noformat} > > h4. *4.* abbreviated interpolation expressions > > For certain simple interpolation expressions, the enclosing > parentheses are optional. The expressions which can drop > parentheses > are a decimal numeral, a name (qualified or simple), a name followed > by one parenthesized argument list, and a name followed by one > bracketed array index. The name must not contain any dollar > signs in > its spelling. > > {noformat} > int zip = 95120, phone = 5551212; > String s = new "zip=$zip, phone=$phone."; // same code > {noformat} > > As always, any ambiguity between the interpolation expression and a > following interpolation or string segment can always be resolved by > using explicit parentheses. > > (Note: This last feature of abbreviation is troublesome to > specify and > implement, but it appears to be a worthwhile creature comfort.) > > h3. MAJOR ADVANTAGE: > > The features specified here allow programmers a superior > notation for > creating templated textual items. Such notations are popular > and well > proven in other languages, including the shells, PHP, Perl, and > Groovy. It will reduce pressure on programmers to move to > those other > languages. > > h3. MAJOR BENEFIT: > > Concise, natural templated expressions are easier to code and > maintain > than equivalent nests of method calls. > > h3. MAJOR DISADVANTAGE: > > The JLS gets more complicated. > > h3. ALTERNATIVES: > > Programmers may use explicitly coded nests method calls; they are of > course more verbose. > > h3. EXAMPLES, BEFORE/AFTER: > > See above and below (in the specification) for one-line examples > demonstrating each aspect of this specification. > > h4. SIMPLE EXAMPLE: > > {noformat} > String whom = "world"; > System.out.printlin(new "Hello, $whom!"); > {noformat} > > h4. ADVANCED EXAMPLE: > > This syntax can easily support two-phase template creation, where a > template is first compiled and checked, and then later > applied one or > more times. > > Let's suppose a hypothetical XML snippet compiler designed for > templated construction expressions. It might be used this way to > compile a snippet generator with optionally typed free variables > mapped to an API featuring a {{make}} method with positional > arguments: > > {noformat} > XMLSnippetCompiler xmlc = ...; > xmlc.new "$1 pattern>$2"; > XMLSnippet xmls = xmlc.compile(); > System.out.println(xmls.make("raining", "walk inside", 5 /*medium > pri*/)); > System.out.println(xmls.make("fire", "run outside", 1 > /*highest pri*/)); > {noformat} > > h3. DETAILS > > The sequence of string segments and interpolations of a templated > construction expression is called its body. Each string segment > begins with either the opening quote of the body, or the end of a > previous > > The templated construction expression is broken into zero or more > interpolations and zero or more (non-empty) string segments. These > are presented in order to the template factory object, as > method calls > to {{appendText}}, {{append}}, or {{format}}. > > {noformat} > x.new "a"; // sugar for x.appendText("a") > x.new "$(y)"; // sugar for x.append(y) > x.new "$(y)"; // sugar for x.format("q",y) > x.new "$(y)"; // sugar for x.format("q",y) > x.new "a$(y)b"; // sugar for > x.appendText("a").append(y).appendText("b") > x.new "a$(y)b"; // sugar for > x.appendText("a").format("q",y).appendText("b") > x.new "a$(y)$(z)"; // sugar for > x.appendText("a").append(y).format("q",z) > x.new ""; // degenerate sugar for x > {noformat} > > There is no particular restriction on the syntax of interpolation > argument expressions. In particular, they can contain quoted > strings > and templated construction expressions. > > {noformat} > new "Hello, $("world")."; > new "Hello, $(new "wor$("")ld")."; > {noformat} > > There is no particular restriction on the type or number of > interpolation argument expressions. Since they are sugar for > {{append}} or {{format}} method calls, they are simply required to > participate successfully in the rules for method call resolution. > > {noformat} > x.new "$()"; // sugar for x.append() > x.new "$(y)"; // sugar for x.append(y) > x.new "$(y,z)"; // sugar for x.append(y,z) > x.new "$()"; // sugar for x.format("q") > x.new "$(y)"; // sugar for x.format("q",y) > x.new "$(y,z)"; // sugar for x.format("q",z) > {noformat} > > If the templated construction expression is unqualified, it is > provided with a new {{StringBuilder}} factory object, and the > expression as a whole is closed with a {{toString}} call. > > For the sake of template factories which need to make the > distinction, > string segments are appended by {{appendText}} method call, if one > exists on the factory object's static type; an error is > reported if it > is not applicable to a single {{String}}. Otherwise {{append}} is > applied to the constant string segment, which will be a > string literal. > > If the format specifier is completely empty, the leading argument to > format is omitted, and it is up to the programmer to specify it > explicitly in the interpolation arguments: > > {noformat} > String fmt = (zip <= 99999) ? "%05d" : "%d"; > String s = new Formatter().new "zip=$<>(fmt, zip), phone=$< > %d>(phone).".toString(); > //new Formatter().appendText > {noformat} > > Here are examples of abbreviated interpolation expressions: > > {noformat} > "$x" // same as "$(x)" > "$1" // same as "$(1)" > "$x.y" // same as "$(x.y)" > "$x.y.z" // same as "$(x.y.z)" > "$f(x)" // same as "$(f(x))" > "$x.f(y)" // same as "$(x.f(y))" > "$x[y]" // same as "$(x[y])" > "$x.y[z]" // same as "$(x.y[z])" > {noformat} > > Here are examples of abbreviated interpolation expression with > interesting right contexts: > > {noformat} > "$x." // same as "$(x)." > "$1." // same as "$(1)." > "$1.0" // same as "$(1).0" > "$x.y." // same as "$(x.y)." > "$f(x)[" // same as "$(f(x))[" > "$x[y](" // same as "$(x[y])(" > {noformat} > > Here are examples of illegal attempts at abbreviation: > {noformat} > "$$" // not same as "$($)"; must be rejected > "$$x" // not same as "$($x)"; must be rejected > "$x.$" // not same as "$(x.$)"; must be rejected > "$x["... // same as "$(x["..., a likely syntax error > "$[x]" // reserved; must be rejected > "${x}" // reserved; must be rejected > "$x{y}" // reserved; must be rejected > "$x" // reserved; must be rejected > {noformat} > > Within a string segment of a templated construction expression, the > dollar character may be escaped with a backslash, to prevent it from > introducing an interpolation. Within a format specifier of an > interpolation, the close-angle-bracket may be escaped with a > backslash, to prevent it from terminating the format specifier. An > unescaped dollar sign must introduce a well-formed interpolation. > > {noformat} > new "\$$x.priceInDollars()" > new "$<<\>>("has strange format of \"<>\"")." > new "$" // must be rejected; should be new "\$" > {noformat} > > h3. SPECIFICATION: > > The specification is complete in the running text of this document. > It will be distilled shortly. > > h3. COMPILATION: > > As this is syntactic sugar, no new mechanisms are needed. > The hack of > changing {{appendText}} to {{append}} when the former is missing > requires an extra symbol table lookup. > > h3. TESTING: > > Testing will be done the usual way, via unit tests, and by early > access customers experimenting with the new facilities. > > h3. LIBRARY SUPPORT: > > There should be some retrofitting of libraries that perform append- > like operations. (This is similar retrofitting to that done when > varargs was introduced.) > > Suitable methods for {{appendText}} are added to {{StringBuilder}}, > {{StringBuffer}}, and {{Formatter}}. > > The class {{StringBuilder}}, which is privileged as the default > template factory type, is augmented with one or more {{format}} > methods that redirect to {{Formatter}}. > > {noformat} > String s = new "zip=$<%05d>zip, phone=$phone.".toString(); > {noformat} > > The class {{PrintStream}}, which already has {{format}} methods, is > also given {{appendText}} and {{append}} methods, as synonyms for > {{print}}. > > {noformat} > System.out.new "zip=$<%05d>zip, phone=$phone.".toString(); > {noformat} > > (*QUESTION:* What other classes could benefit from retrofitting?) > > h3. REFLECTIVE APIS: > > No changes. > > h3. OTHER CHANGES: > > None. > > h3. MIGRATION: > > The feature is for new code only. > > h3. COMPATIBILITY > > h4. BREAKING CHANGES: > > None. All changes are associated with previously unused syntaxes. > > h4. EXISTING PROGRAMS: > > No special interaction. > > h3. REFERENCES > > h4. EXISTING BUGS: > > None known. > > h4. URL FOR PROTOTYPE: > > None yet. > > > > From develop4lasu at gmail.com Mon Mar 30 23:27:46 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 08:27:46 +0200 Subject: PROPOSAL: Glue classes based on Extension Methods Message-ID: <28bca0ff0903302327m39c0eacdv53ae94306945a111@mail.gmail.com> GENESIS I simplified glue classes and described it basing on Extension Methods, but it still can be extended to support static / static methods "ArrayList..create();" and static variables. The main difference rely on the way glue method is executed (almost no names conflicts). I hope that this version will be easier to understood, especially the way TypeParameters are split. AUTHOR: Lasu aka Marek Kozie? OVERVIEW FEATURE SUMMARY: Glue classes allow to execute static methods on objects using double dot notation. MAJOR ADVANTAGE: Simplification of localizing additional functionality MAJOR BENEFIT(s): + New functions can be easy localized (critically important during introduction new people into project). + Security: glue class does not see anything protected. + Light binding new functionality with existing classes. + Reduction of a number of used classes. + It allows to assign methods and functions (static methods) to arrays, classes, interfaces, ? + It's proof against the situation that the same method occurs in class and delegator as well as in two delegators. + It allows to link gained(.jar) logic with a new one, what is impossible before final developer implements his classes. + It allows to project compact interfaces and does not worry about additional logic. MAJOR DISADVANTAGE: - ALTERNATIVES: Utils classes, more work on project, duplicated code... EXAMPLES SIMPLE / ADVANCED EXAMPLE: See below. DETAILS SPECIFICATION: Extension Methods: public class Extensions{ public static int countWords(this String str){ return str.Split(...)...; } public static String[] split(this String str, boolean trim){ return str.Split(...)...; } } To make it Glue class we extract type linked with 'this' to class header, remove parameter name occurring after 'this', remove static word, and use 'this' as simple parameter: public class base glue (String ){ public int countWords(this){ return this.split(...)...; } public String[] split(this, boolean trim){ return this.split(...)...; } } How do we execute methods: Extension Methods: int count = ?Extension Methods?.countWords(); Glue classes: base is in import and no other glue method exists with same name for this object: int count = ?Extension Methods?..countWords(); or base is in import: int count = ?Extension Methods?..base.countWords(); or int count = ?Extension Methods?..com.some.base.countWords(); GENERICS: Extension Methods: public class Extensions{ public static T getLast(this ArrayList list){ return list.get(list.size()-1); } public static T getFirstValid(this ArrayList list, Validator validator){ for (T t : list){ if (validator.isValid(t)) return t; } return null; } } Glue classes: public class base glue ( ArrayList ){ public T getLast( this ){ return list.get(list.size()-1); } public T getFirstValid( this , Validator validator){ for (T t : list){ if (validator.isValid(t)) return t; } return null; } } How do we execute methods (glue): void test(ArrayList list){ System.out.print(?Last:? + list..getLast() ); } Advanced: public class base glue ( ArrayList ){ public T getFirstValid( this , Validator validator, S condition){ for (T t : list){ if (validator.isValid( t, condition )) return t; } return null; } } Execution: void test(ArrayList list, Condition condition){ System.out.print(?First:? + list..getFirstValid(Condition.validator, condition ) ); } Notice that T cannot be directly specified while it's always determined by object used as 'this' COMPILATION All methods are compiled to simple static form (like this visible in extension methods:) , so they can be executed in normal way. The extracted method header (like: glue (ArrayList)) to class header is used for grouping methods properly. Method: $glue (ArrayList nothing){}; is created basing on: ? glue (ArrayList)? and used for matching control and determining which class is glue type. TESTING: Like simple static methods. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: No. MIGRATION: None. COMPATIBILITY New jars are fully compatible. Code is only backward compatible. REFERENCES: http://msdn.microsoft.com/en-us/library/bb383977.aspx http://bugs.sun.com/view_bug.do?bug_id=4093687 http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000680.html From per at bothner.com Mon Mar 30 23:34:02 2009 From: per at bothner.com (Per Bothner) Date: Mon, 30 Mar 2009 23:34:02 -0700 Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: <2b03cbabf59b28634b53f0ca16e85215.squirrel@wmail.gradsoft.ua> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> <49D17DE9.1090007@bothner.com> <2b03cbabf59b28634b53f0ca16e85215.squirrel@wmail.gradsoft.ua> Message-ID: <49D1B95A.6030906@bothner.com> On 03/30/2009 10:12 PM, rssh at gradsoft.com.ua wrote: >> (The proposal to use """ for both open and closing delimiters >> is very IDE-unfriendly. Imagine trying to do syntax highlighting >> and checking as the user is entering a program or makes a typo ...) >> > > But IDE-s ara adopted to groovy and scala now. (I.e. netbeans correctly > parse and highlight groovy long strings). The problem is parsing and highlighting programs as they're being edited and that may at any given time be syntactically invalid. Of course a compiler and an IDE *can* work with "unfriendly" syntax, but some language syntax is going to be easier than others in terms of error recovery and dealing with partial programs. What should the IDE do when the uses types: String x = """| (where | means the insertion point). Should the IDE color the rest of the program with the color for strings? That is clearly bad. Should it automatically add the closing terminator, so you get: String x = """|""" That's probably the test bet, though perhaps weird. But what if the user points the cursor at the first " and types 6 times? What should the IDE do in between each ? There are all kinds of pragmatic questions when you have delimited forms, and multi-line strings using """ as both the start and ending delimiter makes it pretty nasty. Through in template expressions that may contain nested string literals and it becomes really nasty. > And all major IDE-s will be > adopted to new . So, this argument is not counted. I'm afraid not. I have talked with the NetBeans implementors specifically about the syntax of templated and multiline strings in JavaFX. We made changes to the JavaFX syntax at their suggestion/request. -- --Per Bothner per at bothner.com http://per.bothner.com/ From schulz at e-Spirit.de Mon Mar 30 23:35:25 2009 From: schulz at e-Spirit.de (Schulz, Stefan) Date: Tue, 31 Mar 2009 08:35:25 +0200 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49D159BC.6070804@joda.org> References: <49C56020.2070207@joda.org> <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com><49D141B2.1050808@e-spirit.de> <49D159BC.6070804@joda.org> Message-ID: <7D2077BFF677D2429DDDEE095D9A48AC10887F39@osiris2.e-spirit.de> Stephen Colebourne wrote: > Stefan Schulz wrote: > > Frankly, I cannot see a great advantage of: > > for (Foo foo : fooList : it) { > > ... > > } > > saving two lines of code over: > > Iterator it = fooList.iterator(); > > while (it.hasNext()) { > > Foo foo = it.next(); > > ... > > } > > The former captures the *intent* of the loop. The latter is all about > plumbing. I know that, Stephen. I don't mind adding some convenience syntax at all. My comment included the overhead being produced. > > by adding two wrappers and stuff to the code in the background. > > The proposal discusses possible optimisations, however I suspect that > hohtspot can probably cope with two additional objects being created. > > Remember, the extra overhead only happens if you add the optional > iterator reference. Well, if you give developers a tool, they use it. I am thinking of nested loops using this feature and the implications on instance creations the developer does not recognize when applying iteration control. One could as well assign the constructed iterator directly to "it", only the compiler loses some control on the iteration. And that's not worth the overhead, IMHO. Uniforming array access on the iteration control seems nice, though. Stefan From develop4lasu at gmail.com Mon Mar 30 23:40:49 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 08:40:49 +0200 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> Message-ID: <28bca0ff0903302340s3aa480a4h3f675ca5e1a00741@mail.gmail.com> W dniu 31 marca 2009 03:06 u?ytkownik Gabriel Belingueres napisa?: > > Why? > final a = 1; // static type is int > final b = new Integer(6); // static type is Integer > > If this is confusing for someone: > final c = 1 + new Integer(7); > > then declare it as usual. > I just think that in this form solution will be easier to use. > Assuming that getLocalization() returns a Localization, then the whole > point is that you don't need the cast; otherwise this feature is of > doubtful utility. The variable type is known at compile type to be a > Localization. "o is Object" for any reason, if it would be Localization then problem would not exists. > OTOH, if the getLocalization() returns an Object, then > final o = (Localization) some.getBoo().getLocalization(); > might throw a ClassCastException at runtime, which is a pity because > this is a new feature. > If you want to risk to receive a ClassCastException, then declare it as usual: > final Localization o = ?(Localization) some.getBoo().getLocalization(); What for if we already casted it ? > > IMHO, type casts should be forbidden, or at least discouraged. I can agree a little. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From rssh at gradsoft.com.ua Mon Mar 30 23:47:45 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 31 Mar 2009 09:47:45 +0300 (EEST) Subject: PROPOSAL: Templated Construction Expressions (i.e., Expressions Embedded in Strings) In-Reply-To: <49D1B95A.6030906@bothner.com> References: <3dd3f56a0903181505m517125a0w30f0aa540d1d038b@mail.gmail.com> <977c14e250a47d19b21f818f9aceb1aa.squirrel@wmail.gradsoft.ua> <7D2077BFF677D2429DDDEE095D9A48AC105DFB8D@osiris2.e-spirit.de> <9EA33E4A-C6EB-4F54-93E5-0E06FBD1876F@sun.com> <49D17DE9.1090007@bothner.com> <2b03cbabf59b28634b53f0ca16e85215.squirrel@wmail.gradsoft.ua> <49D1B95A.6030906@bothner.com> Message-ID: <00538bc9f1da5f0ab60313fb217028b7.squirrel@wmail.gradsoft.ua> >> And all major IDE-s will be >> adopted to new . So, this argument is not counted. > > I'm afraid not. > Hmm, I still believe that difference in ergonomics between '"""' and '<" strings in most IDE will be small. Difference is in implementation effort for IDE: Yes, such difference exists. > I have talked with the NetBeans implementors specifically about the > syntax of templated and multiline strings in JavaFX. We made > changes to the JavaFX syntax at their suggestion/request. > -- Interesting, thanks for information. > --Per Bothner > per at bothner.com http://per.bothner.com/ > From markmahieu at googlemail.com Mon Mar 30 23:49:20 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 31 Mar 2009 07:49:20 +0100 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> Message-ID: Neal, Are you referring to the idea that a reified collections API may have to be separate from (and not directly compatible with) the current one? Mark 2009/3/31 Neal Gafter > On Mon, Mar 30, 2009 at 5:45 PM, Joshua Bloch wrote: > > Could you please be a be a bit more specific? In particular, could you > > provide an example of something that this proposal precludes but the > > for-each construct (which is already in the language) does not? Once we > > have such an example, we'll be able to weigh the pros and cons > > intelligently. > > Sure. As the proposed construct is defined to create non-reified > collection types, and that distinction may be highly visible to > programmers, programs using the proposed syntax would have to continue > creating non-reified collections. > > With the for-each loop, on the other hand, the only object created by > the construct is an iterator. The iterator is constructed by a > library method that is completely under control of the Iterable that > comes in, and hidden from code containing the for-each loop. While > non-reified types might continue to produce non-reified iterators, > reified classes may well produce reified iterators. > > From neal at gafter.com Tue Mar 31 00:03:08 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 00:03:08 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903301929n1aeb8af6k8f1b575b55e4de9f@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> <17b2302a0903301929n1aeb8af6k8f1b575b55e4de9f@mail.gmail.com> Message-ID: <15e8b9d20903310003k697d7a12k4a298840dfd235c7@mail.gmail.com> On Mon, Mar 30, 2009 at 7:29 PM, Joshua Bloch wrote: > Sorry, I'm still confused. ?Can you tell me what client code would cause > trouble, or at least give me a few examples? The form of the trouble would depend on precisely how reification is done. I don't really want to explore that design space here. I'd rather not constrain it either, though. The basic point is that we may want to allow programmers to write "collection" literals for the reified types, but this proposal is written to return particular existing interface types that are not reified. From develop4lasu at gmail.com Tue Mar 31 00:15:04 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 09:15:04 +0200 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> Message-ID: <28bca0ff0903310015g664c4351u896e09336d8f819a@mail.gmail.com> 2009/3/31 Neal Gafter : > On Mon, Mar 30, 2009 at 5:45 PM, Joshua Bloch wrote: >> Could you please be a be a bit more specific?? In particular, could you >> provide an example of? something that this proposal precludes but the >> for-each construct (which is already in the language) does not?? Once we >> have such an example, we'll be able to weigh the pros and cons >> intelligently. > > Sure. ?As the proposed construct is defined to create non-reified > collection types, and that distinction may be highly visible to > programmers, programs using the proposed syntax would have to continue > creating non-reified collections. > > With the for-each loop, on the other hand, the only object created by > the construct is an iterator. ?The iterator is constructed by a > library method that is completely under control of the Iterable that > comes in, and hidden from code containing the for-each loop. ?While > non-reified types might continue to produce non-reified iterators, > reified classes may well produce reified iterators. > > Don't you think that "non-reified types" should be able to produce both types of iterators? -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Tue Mar 31 00:14:37 2009 From: brucechapman at paradise.net.nz (Bruce Chapman) Date: Tue, 31 Mar 2009 20:14:37 +1300 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: <49D1C2DD.6080506@paradise.net.nz> Derek, thanks for writing this up, it saved me doing it. (and it would complement my integer literal proposals nicely) 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. 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 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. 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? 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 neal at gafter.com Tue Mar 31 00:23:08 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 00:23:08 -0700 Subject: Proposal: Collection Literals In-Reply-To: <28bca0ff0903310015g664c4351u896e09336d8f819a@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903301740v5a388faeu743fd64f81ba2388@mail.gmail.com> <17b2302a0903301745w298bdf42k4c42f8ecd63a3b8a@mail.gmail.com> <15e8b9d20903301758w659a5fc3k897c4dd16bd7263d@mail.gmail.com> <28bca0ff0903310015g664c4351u896e09336d8f819a@mail.gmail.com> Message-ID: <15e8b9d20903310023o1469f81era1800319355afd1a@mail.gmail.com> On Tue, Mar 31, 2009 at 12:15 AM, Marek Kozie? wrote: > Don't you think that "non-reified types" should be able to produce > both types of iterators? I don't see how they can, given that they don't have the type parameter at runtime. From mthornton at optrak.co.uk Tue Mar 31 00:47:04 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 08:47:04 +0100 Subject: Proposal: Indexing access syntax for Lists and Maps In-Reply-To: <49D15864.9000009@gmail.com> References: <350193.71588.qm@web36708.mail.mud.yahoo.com> <49D0794C.7090400@sun.com> <49D15864.9000009@gmail.com> Message-ID: <49D1CA78.3010901@optrak.co.uk> Stephen Colebourne wrote: > I'm surprised annotation solutions are being considered given the > general approach taken to annotations affecting the language. > > For this feature, if it went ahead, I would strongly request having four > new interfaces > > IndexedGet > IndexedSet > MappedGet > MappedPut > > Each with one method. > There are two disadvantages to this approach: 1. The type of the index is restricted, presumably to int. This would prevent this mechanism being used to provide huge 'arrays' with long indexes. If regular arrays are subsequently extended to support long indexes this would then be a mismatch. 2. Can't readily be extended to higher dimensions should that later be considered desireable. Mark Thornton From mthornton at optrak.co.uk Tue Mar 31 00:56:10 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 08:56:10 +0100 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> Message-ID: <49D1CC9A.8050001@optrak.co.uk> Joshua Bloch wrote: > The method invocations (Collections.unmodifiableList(Arrays.asList) are just > noise. With list literals, it would look like this: > > final List piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9]; > > > By substituting curly braces for the square brackets, you get a set literal > in place of a list: > > > final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; > Would it be possible to infer the type of the RHS from the left (and thus also avoid Neal's issue with generics). You could then use {} for both lists and sets, and not need the odd syntax for an empty map. Thus: List emptyList = {}; Set emptySet = {}; Map emptyMap = {}; Regards, Mark Thornton From vilya.harvey at gmail.com Tue Mar 31 00:56:19 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 31 Mar 2009 08:56:19 +0100 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> Message-ID: <6aef848f0903310056n4c3fe700sd6cdbdebb855fbdd@mail.gmail.com> Hi Josh, This would be a very nice feature to have. One small nit: By substituting curly braces for the square brackets, you get a set literal > in place of a list: > > > final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; > The literal syntax is the same as for an array initialisation, which could cause a bit of confusion. In the example - for example :-) - it looks like an array of ints is being autoboxed into a set., but I presume that won't actually be what happens (i.e. the assignment wouldn't compile if the literal was replaced by a variable with type int[])? Vil From j16sdiz at gmail.com Tue Mar 31 01:07:49 2009 From: j16sdiz at gmail.com (Daniel Cheng) Date: Tue, 31 Mar 2009 16:07:49 +0800 Subject: PROPOSAL: Underscores in numbers In-Reply-To: <49D1C2DD.6080506@paradise.net.nz> References: <11482659.1238468832504.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49D1C2DD.6080506@paradise.net.nz> Message-ID: On Tue, Mar 31, 2009 at 3:14 PM, Bruce Chapman wrote: > Derek, > thanks for writing this up, it saved me doing it. (and it would > complement my integer literal proposals nicely) > > 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. > > 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 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. I am in favour of consecutive underscore -- I can use them to align digits over lines and this make parsing a bit easier > 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. > > 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? > > Bruce From jjb at google.com Tue Mar 31 01:13:42 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 01:13:42 -0700 Subject: Proposal: Collection Literals In-Reply-To: <49D1CC9A.8050001@optrak.co.uk> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> Message-ID: <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> Mark, Thanks for reading the proposal. Inferring the right side from the left is called "target typing," and with one small exception, Java doesn't do it. My proposal uses existing type inference rules, and allows you to use collection literals in in any reasonable context. Besides the right hand side of assignments, this includes use as a method or constructor parameter (e.g., new HashSet({"Larry", "Moe", "Curly"}), before a dot (e.g., [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9].size()), and elsewhere. We don't have to further complicate Java's already complicated type inference logic to make this work; instead, we take advantage of the rules that are already there. Josh On Tue, Mar 31, 2009 at 12:56 AM, Mark Thornton wrote: > Joshua Bloch wrote: > >> The method invocations (Collections.unmodifiableList(Arrays.asList) are >> just >> noise. With list literals, it would look like this: >> >> final List piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9]; >> >> >> By substituting curly braces for the square brackets, you get a set >> literal >> in place of a list: >> >> >> final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; >> >> > Would it be possible to infer the type of the RHS from the left (and thus > also avoid Neal's issue with generics). You could then use {} for both lists > and sets, and not need the odd syntax for an empty map. > > Thus: > > List emptyList = {}; > Set emptySet = {}; > Map emptyMap = {}; > > Regards, > Mark Thornton > > From neal at gafter.com Tue Mar 31 01:16:26 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 01:16:26 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> Message-ID: <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> How does the syntax distinguish between an initializer for an array of sets, and an initializer for an array of arrays? On Tue, Mar 31, 2009 at 1:13 AM, Joshua Bloch wrote: > Mark, > Thanks for reading the proposal. Inferring the right side from the left is > called "target typing," and with one small exception, Java doesn't do it. > ?My proposal uses existing type inference rules, and allows you to use > collection literals in in any reasonable context. ?Besides the right hand > side of assignments, this includes use as a method or constructor parameter > (e.g., new HashSet({"Larry", "Moe", "Curly"}), before a dot (e.g., [3, 1, 4, > 1, 5, 9, 2, 6, 5, 3, 5, 9].size()), and elsewhere. ?We don't have to further > complicate Java's already complicated type inference logic to make this > work; instead, we take advantage of the rules that are already there. > > ? ? ? ? ? ? ? ? ? Josh > > On Tue, Mar 31, 2009 at 12:56 AM, Mark Thornton wrote: > >> Joshua Bloch wrote: >> >>> The method invocations (Collections.unmodifiableList(Arrays.asList) are >>> just >>> noise. With list literals, it would look like this: >>> >>> ? ?final List piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9]; >>> >>> >>> By substituting curly braces for the square brackets, you get a set >>> literal >>> in place of a list: >>> >>> >>> ? ?final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; >>> >>> >> Would it be possible to infer the type of the RHS from the left (and thus >> also avoid Neal's issue with generics). You could then use {} for both lists >> and sets, and not need the odd syntax for an empty map. >> >> Thus: >> >> List emptyList = {}; >> Set emptySet = {}; >> Map emptyMap = {}; >> >> Regards, >> Mark Thornton >> >> > > From jjb at google.com Tue Mar 31 01:19:38 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 01:19:38 -0700 Subject: Proposal: Collection Literals In-Reply-To: <6aef848f0903310056n4c3fe700sd6cdbdebb855fbdd@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <6aef848f0903310056n4c3fe700sd6cdbdebb855fbdd@mail.gmail.com> Message-ID: <17b2302a0903310119h72085490uf56fb9386b8c83dc@mail.gmail.com> Vilya, Hi. I originally felt the same way, and so drafted the proposal with curly braces for list literals (which are almost like arrays) and square brackets for maps. But this was the opposite of what people are used to from other languages such as Python, Perl, JavaScript, and Ruby. On balance, it was even more confusing so I opted for the proposed syntax. There's no actual ambiguity, as a bare array initializer (without the new Foo[]) is only legal on the right side of an array declaration. Regards, Josh On Tue, Mar 31, 2009 at 12:56 AM, Vilya Harvey wrote: > Hi Josh, > > This would be a very nice feature to have. One small nit: > > By substituting curly braces for the square brackets, you get a set literal >> in place of a list: >> >> >> final Set primes = { 2, 7, 31, 127, 8191, 131071, 524287 }; >> > > The literal syntax is the same as for an array initialisation, which could > cause a bit of confusion. In the example - for example :-) - it looks like > an array of ints is being autoboxed into a set., but I presume that won't > actually be what happens (i.e. the assignment wouldn't compile if the > literal was replaced by a variable with type int[])? > > Vil > From jjb at google.com Tue Mar 31 01:34:28 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 01:34:28 -0700 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> Message-ID: <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> Neal, On Tue, Mar 31, 2009 at 1:16 AM, Neal Gafter wrote: > How does the syntax distinguish between an initializer for an array of > sets, and an initializer for an array of arrays? > Good catch! Of course this is currently legal and must remain so: Integer[][] aa = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}; It wouldn't bother me if this were a compiler error: Set[] aa = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; In other words, we could prohibit set literals in array initializers. Arrays of sets are an awful idea anyway, so it's no great loss. Presumably that would take care of the problem? Thanks, Josh From david.goodenough at linkchoose.co.uk Tue Mar 31 01:35:39 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 31 Mar 2009 09:35:39 +0100 Subject: For further consideration... In-Reply-To: <49D13A52.1020709@optrak.co.uk> References: <49C95DB5.6020202@sun.com> <200903302151.24925.david.goodenough@linkchoose.co.uk> <49D13A52.1020709@optrak.co.uk> Message-ID: <200903310935.41623.david.goodenough@linkchoose.co.uk> On Monday 30 March 2009, Mark Thornton wrote: > David Goodenough wrote: > > 5 years as near to indefinitely as matters). I need compiler > > checkability for field references now. > > Define an annotation > > @interface @fieldReference { > String name(); > } > > class MyClass { > @fieldReference("myField") static FieldRef FIELD_REF; > > static { > // use reflection to set initialise static fields with > @fieldReference annotations > } > } > > You could use an annotation processor to verify that the @fieldReference > named valid fields and was attached to a suitable reference field. There > are probably other ways of doing this, but it does give you the compile > time check you want without requiring a language change. > > Regards > Mark Thornton My first instinct when I read this was that this was another example of moving the problem to a better place (the place where the field originates rather than the place where you use it) but that it was still uncheckable. But then you suggest using the annotation processor to do the verification process, and that does seem to answer the question. Its odd that none of the potential users of this (Binding frameworks, Criteria like APIs, and PropertyChangeSupport) have used this approach which makes me a little suspicious. The only niggle that strikes me immediately is that existing beans will not be suitably annotated, and this includes all the Swing screen widgets (subclassing or a helper class can solve that as it is a well defined set) and classes built by schema scrapers from places like existing SQL databases, or from XML schemas. These would have to have these added manually, or the tools that do the extraction would have to be modified. But that is not a show stopper, its just a little extra work to be done. I will have to try this and see if it solves the problem. If it does then I will happly withdraw my proposal, and stop getting in everyone's hair. David From mthornton at optrak.co.uk Tue Mar 31 01:47:52 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 09:47:52 +0100 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> Message-ID: <49D1D8B8.9030206@optrak.co.uk> Joshua Bloch wrote: > Neal, > > In other words, we could prohibit set literals in array initializers. > Arrays of sets are an awful idea anyway, so it's no great loss. Ouch, I have a few of those. Invariably where the universe of unique sets is very small and the array contains all of them. Regards, Mark Thornton From rssh at gradsoft.com.ua Tue Mar 31 01:48:29 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 31 Mar 2009 11:48:29 +0300 (EEST) Subject: [typesafe properties access](was Re: For further consideration... In-Reply-To: <200903310935.41623.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903302151.24925.david.goodenough@linkchoose.co.uk> <49D13A52.1020709@optrak.co.uk> <200903310935.41623.david.goodenough@linkchoose.co.uk> Message-ID: <6132fe9b3c54434ae8250d9023f08228.squirrel@wmail.gradsoft.ua> Just note, that similar problem was quite elegant resolved in JPA-2.0 API http://in.relation.to/Bloggers/ATypesafeCriteriaQueryAPIForJPA > On Monday 30 March 2009, Mark Thornton wrote: >> David Goodenough wrote: >> > 5 years as near to indefinitely as matters). I need compiler >> > checkability for field references now. >> >> Define an annotation >> >> @interface @fieldReference { >> String name(); >> } >> >> class MyClass { >> @fieldReference("myField") static FieldRef FIELD_REF; >> >> static { >> // use reflection to set initialise static fields with >> @fieldReference annotations >> } >> } >> >> You could use an annotation processor to verify that the @fieldReference >> named valid fields and was attached to a suitable reference field. There >> are probably other ways of doing this, but it does give you the compile >> time check you want without requiring a language change. >> >> Regards >> Mark Thornton > > My first instinct when I read this was that this was another example of > moving the problem to a better place (the place where the field originates > rather than the place where you use it) but that it was still uncheckable. > > But then you suggest using the annotation processor to do the verification > process, and that does seem to answer the question. Its odd that none > of the potential users of this (Binding frameworks, Criteria like APIs, > and > PropertyChangeSupport) have used this approach which makes me a > little suspicious. > > The only niggle that strikes me immediately is that existing beans will > not be suitably annotated, and this includes all the Swing screen widgets > (subclassing or a helper class can solve that as it is a well defined set) > and classes built by schema scrapers from places like existing SQL > databases, or from XML schemas. These would have to have these added > manually, or the tools that do the extraction would have to be modified. > But that is not a show stopper, its just a little extra work to be done. > > I will have to try this and see if it solves the problem. If it does then > I > will happly withdraw my proposal, and stop getting in everyone's hair. > > David > > From jjb at google.com Tue Mar 31 01:51:57 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 01:51:57 -0700 Subject: Proposal: Collection Literals In-Reply-To: <49D1D8B8.9030206@optrak.co.uk> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> Message-ID: <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> Mark, Presumably you'd be happy to replace them with lists of sets, and then you could use (nested) collection literals? Josh On Tue, Mar 31, 2009 at 1:47 AM, Mark Thornton wrote: > Joshua Bloch wrote: > >> Neal, >> >> In other words, we could prohibit set literals in array initializers. >> Arrays of sets are an awful idea anyway, so it's no great loss. >> > Ouch, I have a few of those. Invariably where the universe of unique sets > is very small and the array contains all of them. > > Regards, > Mark Thornton > From mthornton at optrak.co.uk Tue Mar 31 02:08:32 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 10:08:32 +0100 Subject: For further consideration... In-Reply-To: <200903310935.41623.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903302151.24925.david.goodenough@linkchoose.co.uk> <49D13A52.1020709@optrak.co.uk> <200903310935.41623.david.goodenough@linkchoose.co.uk> Message-ID: <49D1DD90.7010002@optrak.co.uk> David Goodenough wrote: > On Monday 30 March 2009, Mark Thornton wrote: > >> David Goodenough wrote: >> >>> 5 years as near to indefinitely as matters). I need compiler >>> checkability for field references now. >>> >> Define an annotation >> >> @interface @fieldReference { >> String name(); >> } >> >> class MyClass { >> @fieldReference("myField") static FieldRef FIELD_REF; >> >> static { >> // use reflection to set initialise static fields with >> @fieldReference annotations >> } >> } >> >> You could use an annotation processor to verify that the @fieldReference >> named valid fields and was attached to a suitable reference field. There >> are probably other ways of doing this, but it does give you the compile >> time check you want without requiring a language change. >> >> Regards >> Mark Thornton >> > > My first instinct when I read this was that this was another example of > moving the problem to a better place (the place where the field originates > rather than the place where you use it) but that it was still uncheckable. > > ... > The only niggle that strikes me immediately is that existing beans will > not be suitably annotated, and this includes all the Swing screen widgets > (subclassing or a helper class can solve that as it is a well defined set) > and classes built by schema scrapers from places like existing SQL > You could add an optional field to the annotation which specifies the class defining the field. This would default to null, meaning the current class if not specified. Now you can declare them anywhere and don't need to modify existing classes. Someone with more experience with annotation processors than I have could probably come up with a much neater scheme. > I will have to try this and see if it solves the problem. If it does then I > will happly withdraw my proposal, and stop getting in everyone's hair. > Although your proposal isn't large in itself, it intersects with many other proposals in the same area which are clearly large (and outside the scope of Coin). This makes it difficult to consider without also evaluating those other proposals. Anyway I hope my suggestion allows you to get the compile time validation you want without waiting another month let alone a year or even 5 years. Mark Thornton From vapor1 at teleport.com Tue Mar 31 02:19:26 2009 From: vapor1 at teleport.com (Derek Foster) Date: Tue, 31 Mar 2009 05:19:26 -0400 (EDT) Subject: PROPOSAL: abstract enums Message-ID: <3426774.1238491166326.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Joe Darcy wrote: >IMO the level of discourse on the list would be improved if more time >was taken to research and understand why the previous language decisions > were made and the many trade offs involved. For example, some of the >rationale for enums is contained in the early draft documents of JSR 201: > > http://www.jcp.org/en/jsr/detail?id=201 Joe, I am not sure you realize that I actually HAVE done serious research as to why enums were designed the way they were. I've read those documents already, and a lot of other ones besides. I just read them again now just to be sure I hadn't missed anything. Nonetheless, my research has so far not come up with evidence that the approach I have outlined in my proposal was seriously considered (or considered at all!) by the working group, and has produced zero instances of a technical argument as to why it wouldn't work or why it would be significantly difficult to implement, or would cause significant problems. Basically, the documents you have pointed me towards so far have not discussed my approach at all. The link above is no exception to this. It discusses the (lack of) merits of the extensible enums approach but is entirely silent on the approach suggested by my proposal. If you have specific technical reasons why you think MY approach (as opposed to the extendable enums approach that is the only one discussed by all of the links you have sent out so far) won't work or would be difficult to implement, then please present them, so I can address them. My research so far has failed to turn up any such reasons. I have seen nobody claiming that lack of the ability to have abstract supertypes of enums is a GOOD thing, just that having concrete subtypes of them (as per the extendable enums approach) is clearly a BAD things. I can speak from personal experience when I say that the lack of this feature in Java is both mysterious (since there seems no specific technical reason to forbid it, and it seems unnecessarily different from how classes work) and quite frustrating and time-consuming to work around. I mentioned some of those experiences in the overview of my proposal. Apparently Stephen has had similar experiences. Obviously, I was annoyed enough by them that I spent five hours researching the topic and writing up a proposal to fix the problem. I think that those two testimonials should count for something when considering what impact this problem has on developers. Perhaps (although I have seen no documented evidence of this) the original working group DID carefully consider this exact feature and decided that lack of it wasn't likely to cause enough problems to justify the small effort required to implement it. Well, if that is true, then perhaps the real-world evidence of Stephen and I should be considered as evidence that that initial hypothesis was possibly incorrect and should be reevaluated in light of the new evidence. Derek -----Original Message----- >From: Joe Darcy >Sent: Mar 31, 2009 12:05 AM >To: Stephen Colebourne >Cc: coin-dev at openjdk.java.net >Subject: Re: PROPOSAL: abstract enums > >Stephen Colebourne wrote: >> Joseph D. Darcy wrote: >>> Of the extensible and non-extensible version of enum pattern, the JSR >>> 201 expert group chose the non-extensible variant and many other >>> decisions and details of the original enum design flow from that >>> fundamental decision. Revisiting that decision now is impractical. >>> >>> Additionally, some of the advantages of extensible enums can be had by >>> making different enum classes implement a common interface; for some >>> discussion of that general pattern see >>> >>> "Mixing-in an Enum" >>> http://blogs.sun.com/darcy/entry/enums_and_mixins >>> >>> as well as an item in the 2nd edition of "Effective Java." >> >> The lack of abstract enums (where the superclass merely contains code, >> not enum constants) has definitely had a negative impact on the >> usefulness of the feature. JSR-310 will be significantly worse as an >> implementation as a result of this omission. > > >Even though lack of this feature admittedly makes writing certain APIs >more difficult, that certainly does not necessarily imply a language >change is an appropriate remedy. > >[snip] > >> The argument of "the original EG decided" is a poor one. By that > >The argument of "we can simply ignore the past" is a poor one as well. > >However, I assume you are not putting forward such a naive justification >for this change. > >> argument, we should not make any changes to Java, and leave it as in >> v1.0. As such, I request that you consider merit, not an arbitrary 'it >> changed recently'. > >All the language changes occur in the context of what has gone before >and what might come in the future. Some changes have been deliberately >deferred until more research could occur. For example, some kind of >generics were deliberately left out of Java 1.0 because it was >determined an adequate version could not be designed and implemented in >time. Other changes have been decided against explicitly or implicitly; > Java explicitly decided against multiple inheritance of classes. > >IMO the level of discourse on the list would be improved if more time >was taken to research and understand why the previous language decisions > were made and the many trade offs involved. For example, some of the >rationale for enums is contained in the early draft documents of JSR 201: > > http://www.jcp.org/en/jsr/detail?id=201 > >A quote I came across doing background reading for Project Coin >frequently comes to mind: > >"If this book [Principles of Programming Languages] has convinced the >reader that a programming language designer needs the expertise of a >scientist, the precision of a mathematician, and the taste of an artist >as well as the pragmatism of an engineer, then it has achieved one of >its objectives." >--R. D. Tennent > > >-Joe > From david.goodenough at linkchoose.co.uk Tue Mar 31 02:19:56 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 31 Mar 2009 10:19:56 +0100 Subject: [typesafe properties access](was Re: For further consideration... In-Reply-To: <6132fe9b3c54434ae8250d9023f08228.squirrel@wmail.gradsoft.ua> References: <49C95DB5.6020202@sun.com> <200903310935.41623.david.goodenough@linkchoose.co.uk> <6132fe9b3c54434ae8250d9023f08228.squirrel@wmail.gradsoft.ua> Message-ID: <200903311019.57665.david.goodenough@linkchoose.co.uk> On Tuesday 31 March 2009, rssh at gradsoft.com.ua wrote: > Just note, that similar problem was quite elegant resolved in JPA-2.0 API > http://in.relation.to/Bloggers/ATypesafeCriteriaQueryAPIForJPA But that proposal still requires the use of uncheckable field names as strings. The second code block contains all those strings, and the comment above it says exactly that you have to use string based names. David > > > On Monday 30 March 2009, Mark Thornton wrote: > >> David Goodenough wrote: > >> > 5 years as near to indefinitely as matters). I need compiler > >> > checkability for field references now. > >> > >> Define an annotation > >> > >> @interface @fieldReference { > >> String name(); > >> } > >> > >> class MyClass { > >> @fieldReference("myField") static FieldRef FIELD_REF; > >> > >> static { > >> // use reflection to set initialise static fields with > >> @fieldReference annotations > >> } > >> } > >> > >> You could use an annotation processor to verify that the @fieldReference > >> named valid fields and was attached to a suitable reference field. There > >> are probably other ways of doing this, but it does give you the compile > >> time check you want without requiring a language change. > >> > >> Regards > >> Mark Thornton > > > > My first instinct when I read this was that this was another example of > > moving the problem to a better place (the place where the field > > originates rather than the place where you use it) but that it was still > > uncheckable. > > > > But then you suggest using the annotation processor to do the > > verification process, and that does seem to answer the question. Its odd > > that none of the potential users of this (Binding frameworks, Criteria > > like APIs, and > > PropertyChangeSupport) have used this approach which makes me a > > little suspicious. > > > > The only niggle that strikes me immediately is that existing beans will > > not be suitably annotated, and this includes all the Swing screen widgets > > (subclassing or a helper class can solve that as it is a well defined > > set) and classes built by schema scrapers from places like existing SQL > > databases, or from XML schemas. These would have to have these added > > manually, or the tools that do the extraction would have to be modified. > > But that is not a show stopper, its just a little extra work to be done. > > > > I will have to try this and see if it solves the problem. If it does > > then I > > will happly withdraw my proposal, and stop getting in everyone's hair. > > > > David From jeroen at lexau.org Tue Mar 31 02:20:57 2009 From: jeroen at lexau.org (Jeroen van Maanen) Date: Tue, 31 Mar 2009 11:20:57 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: References: <49CF5AF2.8020408@entreact.com> Message-ID: <49D1E079.2020207@lexau.org> Gabriel Belingueres schreef: > IMO I'm against this. > > First, it is against current best practices for the design of > object-oriented software to make easier to code something with a case > statement on types/classes. I read this as: the 'current best practices [of] design' say that if I want to write code that is easy to reuse because it doesn't make any a priori assumptions about the types of the objects it deal with, then the code *should* be hard to read. If that is a correct translation of the directive, then I would like to know the resulting benefits of following the directive before accepting it. Please provide a reference to an article that discusses the pro's and con's of this. This proposal is attempting to deal with a real every day problem with writing reusable code and that is: how do you deal with a lack of compile time knowledge and uncooperative objects. (The logging API doesn't know the type of the object logged and the object logged doesn't know that is being logged, so it doesn't provide logging assistance methods). Somebody said that I would be easy and neat to code this kind of thing using a continuations API. What would that look like? > Second: > void log(Object object) { > switch (object) instanceof { > case String: > logger.debug("'" + object + "'"); > case Date: > logger.debug(object.getTime()); > case void: > logger.debug("null"); > default: > logger.debug("<" + object.toString() + ">"); > } > } > > It think it is clearer (when possible) writing it with several > overloaded methods and double dispatching. I never found a way to get my code that shows me the contents of collections and arrays and that distinguishes between strings and object representations to work without instanceof or isInstance. > Third: > } catch (Exception exception) { > switch (exception.getCause()) instanceof { > case ParseException: > log.warn("Could not get status for '" + id + ": " + > exception.getCause()); > default: > log.warn("Could not get status for '" + id + ", exception); > } > } > > in the case you intentionally left out the break statement, then the > switch statement is not any clearer than doing an if. > in the case that you wanted the break statement on the ParseException > case, it is even clearer to use two catch blocks (one for > ParseException and other for Throwable. Two catch bocks won't work. The distinction is on the *cause* of the exception, not the exception itself. > [...] From rssh at gradsoft.com.ua Tue Mar 31 02:27:20 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 31 Mar 2009 12:27:20 +0300 (EEST) Subject: [typesafe properties access](was Re: For further consideration... In-Reply-To: <200903311019.57665.david.goodenough@linkchoose.co.uk> References: <49C95DB5.6020202@sun.com> <200903310935.41623.david.goodenough@linkchoose.co.uk> <6132fe9b3c54434ae8250d9023f08228.squirrel@wmail.gradsoft.ua> <200903311019.57665.david.goodenough@linkchoose.co.uk> Message-ID: > On Tuesday 31 March 2009, rssh at gradsoft.com.ua wrote: >> Just note, that similar problem was quite elegant resolved in JPA-2.0 >> API >> http://in.relation.to/Bloggers/ATypesafeCriteriaQueryAPIForJPA > But that proposal still requires the use of uncheckable field names as > strings. The second code block contains all those strings, and the > comment > above it says exactly that you have to use string based names. > Generated persistent scheme class contains all information. Extend one to define all properties as constants in generated class is easy. Generation can be done with annotation processor. > David >> >> > On Monday 30 March 2009, Mark Thornton wrote: >> >> David Goodenough wrote: >> >> > 5 years as near to indefinitely as matters). I need compiler >> >> > checkability for field references now. >> >> >> >> Define an annotation >> >> >> >> @interface @fieldReference { >> >> String name(); >> >> } >> >> >> >> class MyClass { >> >> @fieldReference("myField") static FieldRef FIELD_REF; >> >> >> >> static { >> >> // use reflection to set initialise static fields with >> >> @fieldReference annotations >> >> } >> >> } >> >> >> >> You could use an annotation processor to verify that the >> @fieldReference >> >> named valid fields and was attached to a suitable reference field. >> There >> >> are probably other ways of doing this, but it does give you the >> compile >> >> time check you want without requiring a language change. >> >> >> >> Regards >> >> Mark Thornton >> > >> > My first instinct when I read this was that this was another example >> of >> > moving the problem to a better place (the place where the field >> > originates rather than the place where you use it) but that it was >> still >> > uncheckable. >> > >> > But then you suggest using the annotation processor to do the >> > verification process, and that does seem to answer the question. Its >> odd >> > that none of the potential users of this (Binding frameworks, Criteria >> > like APIs, and >> > PropertyChangeSupport) have used this approach which makes me a >> > little suspicious. >> > >> > The only niggle that strikes me immediately is that existing beans >> will >> > not be suitably annotated, and this includes all the Swing screen >> widgets >> > (subclassing or a helper class can solve that as it is a well defined >> > set) and classes built by schema scrapers from places like existing >> SQL >> > databases, or from XML schemas. These would have to have these added >> > manually, or the tools that do the extraction would have to be >> modified. >> > But that is not a show stopper, its just a little extra work to be >> done. >> > >> > I will have to try this and see if it solves the problem. If it does >> > then I >> > will happly withdraw my proposal, and stop getting in everyone's hair. >> > >> > David > > > > From david.goodenough at linkchoose.co.uk Tue Mar 31 02:35:37 2009 From: david.goodenough at linkchoose.co.uk (David Goodenough) Date: Tue, 31 Mar 2009 10:35:37 +0100 Subject: For further consideration... In-Reply-To: <49D1DD90.7010002@optrak.co.uk> References: <49C95DB5.6020202@sun.com> <200903310935.41623.david.goodenough@linkchoose.co.uk> <49D1DD90.7010002@optrak.co.uk> Message-ID: <200903311035.37297.david.goodenough@linkchoose.co.uk> On Tuesday 31 March 2009, Mark Thornton wrote: > David Goodenough wrote: > > On Monday 30 March 2009, Mark Thornton wrote: > >> David Goodenough wrote: > >>> 5 years as near to indefinitely as matters). I need compiler > >>> checkability for field references now. > >> > >> Define an annotation > >> > >> @interface @fieldReference { > >> String name(); > >> } > >> > >> class MyClass { > >> @fieldReference("myField") static FieldRef FIELD_REF; > >> > >> static { > >> // use reflection to set initialise static fields with > >> @fieldReference annotations > >> } > >> } > >> > >> You could use an annotation processor to verify that the @fieldReference > >> named valid fields and was attached to a suitable reference field. There > >> are probably other ways of doing this, but it does give you the compile > >> time check you want without requiring a language change. > >> > >> Regards > >> Mark Thornton > > > > My first instinct when I read this was that this was another example of > > moving the problem to a better place (the place where the field > > originates rather than the place where you use it) but that it was still > > uncheckable. > > ... > > > The only niggle that strikes me immediately is that existing beans will > > not be suitably annotated, and this includes all the Swing screen widgets > > (subclassing or a helper class can solve that as it is a well defined > > set) and classes built by schema scrapers from places like existing SQL > > You could add an optional field to the annotation which specifies the > class defining the field. This would default to null, meaning the > current class if not specified. Now you can declare them anywhere and > don't need to modify existing classes. Someone with more experience with > annotation processors than I have could probably come up with a much > neater scheme. > > > I will have to try this and see if it solves the problem. If it does > > then I will happly withdraw my proposal, and stop getting in everyone's > > hair. > > Although your proposal isn't large in itself, it intersects with many > other proposals in the same area which are clearly large (and outside > the scope of Coin). This makes it difficult to consider without also > evaluating those other proposals. Actually I have been thinking about this, and I do not believe that my proposal would preclude those other bits of the full properties proposals when (if) they eventually get considered for inclusion into Java. The full properties discussion breaks down into two bits. The first, and this seems actually to be where most of the problems lie, is stuff that Java can do today. it just does it in a way that is not as simple and easy to read and write as it might be. In my book that makes is desirable to fix (I am all for ease of use) but not necessary to fix (its not a show stopper). And one can see in the list of Coin proposals that are being progressed several fall into this same category. For example the switch on string can be expressed as an if tree, its messy and the new proposal is much nicer, but it is only desirable not necessary. The problem that I was having all along was not the bits of the property proposals that can be done already, it was the bit that I could not find a compiler checkable way to do today (but which you may have solved). That (as a show stopper) I class as necessary and desirable. I have spent too much time fixing code that got the string form of field names wrong (both in my own code and in that of others) for comfort, and in a language that generally catches such things up front and won't compile wrong code this is a big problem. Having the primitive hat gets me a FieldRef (I like that name) is exactly what I need, and it can then be used under the covers in the implementation of the full properties solutions later. I see nothing that they need that my proposal actually precludes or even makes it difficult. Actually you do need a little more than a Field object. Firstly it can be a Field array (if you have compound names - Foo#bar#ali or foo#bar#ali) and secondly having checked that bar and ali are valid in this context it does seem silly to loose the reference to the class Foo or the instance foo and then put them back again and have to check all over again when you come to use it the Field object. In addition getting a FieldRef object is a simple matter of calling a constructor or factory method, so it is very easy to de-sugar in javac. Getting a Field object is more complicated because it would either require looping up the superclass chain (java.lang.Class.getDefinedField only looks in the current class) or (and this would rule it out of Coin immediately) it requires a change to java.lang.Class to add a new method which does the climbing up the super class chain for you. David > > Anyway I hope my suggestion allows you to get the compile time > validation you want without waiting another month let alone a year or > even 5 years. > > Mark Thornton From roy.van.rijn at gmail.com Tue Mar 31 03:56:03 2009 From: roy.van.rijn at gmail.com (Roy van Rijn) Date: Tue, 31 Mar 2009 12:56:03 +0200 Subject: Addition to Comparable interface Message-ID: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> AUTHOR(S): Roy van Rijn OVERVIEW Currently the interface Comparable only has one method: int compareTo(Object o); This is perfect and enough to work with. But the 'int' you have to return is a bit messy and unclear. FEATURE SUMMARY: The return value of the Comparable interfae could be made a lot clearer if it would have the following static variables: public static int BEFORE = -1; public static int EQUAL = 0; public static int AFTER = 1; MAJOR ADVANTAGE: Its much more clear what you need to return when you are implementing the Comparable interface. The addition won't affect any previously written code and won't break backwards compatibility.. MAJOR BENEFIT: Readability of the code where the interface is used. MAJOR DISADVANTAGE: The interface becomes a little bit larger. ALTERNATIVES: Another alternative would be to use an enum. This would be even clearer but would break backwards compatibility. EXAMPLE: Comparing humans by age and name (in case the age is equal): public int compareTo(Object otherHuman) { if(this == otherHuman) { //Same object? Then we are equal return EQUAL; } else if(otherHuman==null || otherHuman.getName() == null) { //Other human has null values, we need to go after return AFTER; } else if(this.getName() == null) { //We have null values, we go before other human return BEFORE; } else if(this.getAge != otherHuman.getAge()) { //If the age isn't the same, compare by age: return this.getAge() - otherHuman.getAge(); } else { //Finally compare by name return this.getName().compareTo(otherHuman.getName()); } } This is clearer then: .... if(this == otherHuman) { //Same object? Then we are equal return 0; } else if(otherHuman==null || otherHuman.getName() == null) { //Other human has null values, we need to go after return 1; } else if(this.getName() == null) { //We have null values, we go before other human return -1; .... DETAILS: SPECIFICATION: Specification and details are clear, just add this to Comparable: public static int BEFORE = -1; public static int EQUAL = 0; public static int AFTER = 1; COMPILATION: Trivial. TESTING: Trivial. LIBRARY SUPPORT: No. REFLECTIVE APIS: No. OTHER CHANGES: Maybe implementing classes can be refactored to use this feature, optional. MIGRATION: No. COMPATIBILITY: No issues. BREAKING CHANGES: No. EXISTING PROGRAMS: Same, no changes. From Thomas.Hawtin at Sun.COM Tue Mar 31 04:09:00 2009 From: Thomas.Hawtin at Sun.COM (Tom Hawtin) Date: Tue, 31 Mar 2009 12:09:00 +0100 Subject: Proposal: Sameness operators In-Reply-To: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <2729451.1238478698193.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <49D1F9CC.6000809@sun.com> 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 > 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). Tom From howard.lovatt at iee.org Tue Mar 31 04:14:38 2009 From: howard.lovatt at iee.org (Howard Lovatt) Date: Tue, 31 Mar 2009 22:14:38 +1100 Subject: Proposal idea - generators Message-ID: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> 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. From mthornton at optrak.co.uk Tue Mar 31 04:29:00 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 12:29:00 +0100 Subject: Addition to Comparable interface In-Reply-To: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> Message-ID: <49D1FE7C.7070008@optrak.co.uk> Roy van Rijn wrote: > AUTHOR(S): Roy van Rijn > > OVERVIEW > > Currently the interface Comparable only has one method: > int compareTo(Object o); > > This is perfect and enough to work with. But the 'int' you have to > return is a bit messy and unclear. > > FEATURE SUMMARY: > > The return value of the Comparable interfae could be made a lot > clearer if it would have the following static variables: > public static int BEFORE = -1; > public static int EQUAL = 0; > public static int AFTER = 1; > > MAJOR ADVANTAGE: > > Its much more clear what you need to return when you are implementing > the Comparable interface. The addition won't affect any previously > written code and won't break backwards compatibility.. > This might give the impression that the only values returned by compareTo are -1, 0, 1 which is certainly not true. The interface only requires that the sign of the returned value reflect the ordering. Mark Thornton From roy.van.rijn at gmail.com Tue Mar 31 05:16:14 2009 From: roy.van.rijn at gmail.com (Roy van Rijn) Date: Tue, 31 Mar 2009 14:16:14 +0200 Subject: Addition to Comparable interface In-Reply-To: <49D1FE7C.7070008@optrak.co.uk> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> <49D1FE7C.7070008@optrak.co.uk> Message-ID: <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> >> FEATURE SUMMARY: >> >> The return value of the Comparable interfae could be made a lot >> clearer if it would have the following static variables: >> ? ?public static int BEFORE = -1; >> ? ?public static int EQUAL = 0; >> ? ?public static int AFTER = 1; > > This might give the impression that the only values returned by compareTo > are -1, 0, 1 which is certainly not true. The interface only requires that > the sign of the returned value reflect the ordering. > That might be a problem indeed, but the javadoc should still indicate its possible to use any positive and negative integer value. The problem I've seen a lot is the following, even in large corporate programs, when people compare integers like this: import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Compare implements Comparable { int number; public Compare(int nr) { this.number = nr; } public static void main(String args[]) { System.out.println("Testing order:"); List compareList = new ArrayList(); compareList.add(new Compare(Integer.MIN_VALUE)); compareList.add(new Compare(Integer.MAX_VALUE)); compareList.add(new Compare(-100000)); compareList.add(new Compare(100000)); compareList.add(new Compare(300000)); compareList.add(new Compare(200000)); compareList.add(new Compare(2147473647)); //Some large value compareList.add(new Compare(-2147473648)); //Some other large negative number Collections.sort(compareList); for(Compare sorted:compareList) { System.out.println(sorted.getNumber()); } } public int getNumber() { return number; } public int compareTo(Object o) { if(o instanceof Compare && o != null) { return this.getNumber() - ((Compare)o).getNumber(); //compareTo with minus, used too much...! } return 0; } } Returns something like: 2147483647 -2147483648 -100000 100000 200000 300000 2147473647 -2147473648 Not really ordered because people forget the boundaries of the integer! So having an enum instead, forcing a triple return value would be much better. And this comes pretty close without breaking any code. The only reason I know this method returns an integer is because of simplicity and not wanting to make a triple-value return value (correct me if I'm wrong!). Roy van Rijn From glenn.a.marshall at gmail.com Tue Mar 31 05:22:48 2009 From: glenn.a.marshall at gmail.com (Glenn A. Marshall) Date: Tue, 31 Mar 2009 08:22:48 -0400 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <49D0C82D.1000208@sun.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> Message-ID: <980366fa0903310522u31ac7641r6a1554c188122175@mail.gmail.com> On Mon, Mar 30, 2009 at 9:25 AM, Tom Hawtin wrote: > Glenn A. Marshall wrote: > >> 1. This example is syntactically invalid since the first try does not >> have >> a catch nor finally clause; it is not ambiguous. Good example tho. >> > > Neal's example: > > >> try > >> try stmt; > >> catch(...) stmt; > >> catch(...) stmt; > >> finally stmt; > > Under the proposal "try stmt; catch(...) stmt;" is a statement. So the > above is equivalent to: > > try > stmt2; > catch(...) stmt; > finally stmt; > > But "try stmt; catch(...) stmt; catch(...) stmt;" is also a statement. So > the example is also equivalent to: > > try > stmt2; > finally stmt; > > Which is different. Which is it? > > This is similar to the dangling-else ambiguity. > http://en.wikipedia.org/wiki/Dangling_else It is, indeed, a precise parallel to the dangling-else ambiguity, when viewed from a grammar perspective. >From JLS 14.5: "The Java programming language ... arbitrarily decree that an else clause belongs to the innermost if to which it might possibly belong" Under this proposal, a catch and a finally belongs to the innermost try to which they might possibly belong. > > 2. The optional omission of the braces is only applicable to simple, >> single >> statement try, catch, finally (and method declaration). Braces are still >> allowed, and are required for disambiguation, as well as for multiple >> statement try, catch finally (and method declaration). They are are >> needed >> in this example. >> > > That reads as if you think of a block statement (in for example the typical > while usage) as not a type of statement. A block is a statement. You could > ammend the grammar so the proposal uses non-block statement, but this is not > how the rest of the language works. 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? > > > > > BTW: Does anyone have a good suggestion for tool and basic Java grammar to > check that syntax modifications are still parseable? > > Tom > From mthornton at optrak.co.uk Tue Mar 31 05:31:44 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 13:31:44 +0100 Subject: Addition to Comparable interface In-Reply-To: <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> <49D1FE7C.7070008@optrak.co.uk> <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> Message-ID: <49D20D30.2090207@optrak.co.uk> Roy van Rijn wrote: >>> FEATURE SUMMARY: >>> >>> The return value of the Comparable interfae could be made a lot >>> clearer if it would have the following static variables: >>> public static int BEFORE = -1; >>> public static int EQUAL = 0; >>> public static int AFTER = 1; >>> >> This might give the impression that the only values returned by compareTo >> are -1, 0, 1 which is certainly not true. The interface only requires that >> the sign of the returned value reflect the ordering. >> >> > > That might be a problem indeed, but the javadoc should still indicate > its possible to use any positive and negative integer value. > > The problem I've seen a lot is the following, even in large corporate > programs, when people compare integers like this: > > It is valid for reduced ranges of integers, notably when the values are known to be positive. Mark Thornton From reinier at zwitserloot.com Tue Mar 31 05:50:58 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 14:50:58 +0200 Subject: Submission: switch (...) instanceof feature In-Reply-To: <49CFDD56.8070802@lexau.org> References: <49CF5AF2.8020408@entreact.com> <49CFCE4C.10808@adres.pl> <49CFDD56.8070802@lexau.org> Message-ID: Nice proposal, Jeroen. I would make the case (heh) for using 'case null' instead. null's type is not 'void' - it's every type. Technically, the first case FOO: should match an input null, so you're looking at an exceptional situation already. This exceptionality is also built into the 'instanceof' keyword, eventhough technically 'null instanceof FOO' is true for all FOO, instanceof specifically defines: If the LHS is null, then instanceof will evaluate to false, eventhough null is technically an instance of all types. Such a special rule seems inevitable in a switch() instanceof construct as well, so roll with it. If the switch statement matches stictly top-down first-match, then you should add that it is a compiler error to relist any type, or to relist any subtype of any other type. Thus: switch (foo) instanceof { case List: case ArrayList: } should be a compile-time error, because the second case block couldn't possibly ever be matched (any qualifiying object would already match 'List' first!) fallthrough sucks and was a clear mistake in the original java, but defining switch()instanceof to not fall through, but switch() to yes fall through, is an even greater mistake. If avoiding fall through is that important, then the syntax should change to require braces: switch (foo) instanceof { case (String) { /* code */ } case (Number) { /* code */ } } and then you still have an inconsistency in the JLS which is unfortunate, though at least it would no longer be as confusing. I agree that fallthrough precludes automatic casting. 'break' should therefore either be mandatory, or only mandatory if a future block will be using the variable name, -or- the type of the variable name inside any case construct is the intersection type of all cases (including itself) above it that do not have a definite exit, up to the nearest case statement that does have a definite exit. Something like this could be both useful and easily made legal: Object foo = foo(); switch (foo) instanceof { case Double: case Float: //foo, as an expression, is now a Number. break; case ArrayList: case LinkedList: //foo, as an expression, is now: //AbstractList & Serializable & Cloneable default: case String: //foo is still just Object due to the 'default'. } regarding unchecked warnings: Major point of this proposal. One way around it is to notice that if the variable name is never actually used inside / the intersection type doesn't include any generics, raw or otherwise, no warning is needed. This is one of the main reasons why I would push for lub on the various involved types for any case block. The feel would then be: The type is the type of the expression, with some magic voodoo applied to make that type more specific, but only with added specific types for things where the compiler is 100% certain it'll work out that way. In this view, adding Map: to the case list would actually not be legal, because the compiler can't ensure those generics. You'd only get the raw types (which is a compiler certainty - the uncertainty starts when getting or putting stuff in that). --Reinier Zwitserloot On Mar 29, 2009, at 22:43, Jeroen van Maanen wrote: > Artur Biesiadowski wrote: >> 1) Why case void: instead of case null: ? > > Yes, I agree that it is potentially confusing. At the other hand, > null is an instance not a type. It would also be possible to add a > type or even a keyword to describe the type of null, but that would > increase the impact of the change and it would mean another type > with no instances. I thought that void would pretty much fit the > descrition of what I would like: a keyword that indicates a type > that would not have any actual instances. I suppose that if we are > stretching the exact meaning of the terms anyway, then 'case null:' > would probably just be as well and easier to remember. > >> 2) What is a expected behavior in case of multiple matches ? For >> example > > I propose to do strict top-down first-match-only evaluation, because > if the given variable matches many of the labels and the types of > the labes belong to a complicated hierarchy of interfaces, then > reordering the cases according to inheritance could lead to > unpredictable results. I don't think that executing all matching > blocks would be a good idea, because I think that many code readers > would not expect this from a switch statement. Although it would be > possible to allow a fallthrough from a specific type to a super > type, I am afraid that allowing such highly constrained > constructions would lead to code that is hard to read and easy to > misunderstand. > >> switch(collection) instanceof { >> case RandomAccess: >> ... >> case List: >> ... >> case Collection: >> ... >> } >> Do I need to put switch cases in correct order because of top-to- >> down evaluation or most specific one will be used? Or maybe all >> matching ones ? >> 3) I think you have forgotten to put 'break' in your examples, >> unless you plan to disallow fall-through. > > Ah, I should have made that explicit. No breaks necessary and no > lists of labels before a statement block. I could not think of a way > to get the casts right in a fallthrough situation. Maybe it would > be less confusing to make break a compulsory statement at the end of > each statement block. That is: > > TypeSwitchBlockStatementGroup: > TypeSwitchLabel BlockStatements break ; > > What do you think? > >> Regards, >> Artur Biesiadowski > > I just thought about another situation that needs to be clarified: > > 4) How does the switch instanceof statement handle generics? > > I would like to see > > switch (model) instanceof { > FreeMarkerModel: > template.process(..., model); > Map: > template.process(..., toFMM(model)) > } > > translated as > > if (model instanceof FreeMarkerModel) { > FreeMarkerModel model$1 = (FreeMarkerModel) model; > template.process(..., model$1); > } > else if (model instanceof Map) { > Map model$2 = (Map) model; > template.process(..., toFMM(model$2)); > } > > So each type parameter that we cannot guess would be specified as ?. > > The following would be illegal, because the specification allows no > type parameters after the type name in a label. > > switch (model) instanceof { > ... > Map: > ... > } > > This is fine, because I can't think of a way where the desugared > code would be free of "unchecked" warnings. > > Regards, Jeroen > > From reinier at zwitserloot.com Tue Mar 31 05:52:24 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 14:52:24 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <87fxgwzfew.fsf@mid.deneb.enyo.de> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> Message-ID: <51DE64F8-7D84-4368-8A52-F37A1FAD06DB@zwitserloot.com> Yes, the type of the RHS of: final list = foo ? new LinkedList() : new ArrayList(); is indeed AbstractList & Cloneable & Serializable. The question is: Is that what you make the type of 'list'? That would be a novel idea: Now we have type variables that can have intersection types, not just expressions. There's nothing inherent in java stopping you from doing this for local method variables as you said, but one should consider the future impact of this: There is absolutely no way to specify intersection types in either java or in any sort of reflection tool. Any attempt to add introspection of any sort to types of method locals is thus going to be a major issue in the future if we allow intersection types for them. I don't think this proposal suggests you're allowed to infer the type on fields, regardless of the issue of intersection types, but what if that seems useful later on? Then either we overhaul java.lang.reflect, -or-, we all of a sudden exclude it for fields but allow it (to be backwards compatible) for method locals. Ugh. Feels hacky. I would -strongly- suggest at least for project coin to just not allow intersection types at all, period. A future version of java can add this support later if it is deemed important. This is analogous to how java gained intersection types in the fist place, which wasn't in the earlier versions of java. Until intersection types, the following expression wasn't even legal: foo ? new LinkedList() : new Arraylist(); because the type of the expression (and thence also must be the type of the third arugment to the ?: operator) is decided by the type of the second argument (in the above example, 'LinkedList', and ArrayList is not a LinkedList. this was added without any backwards compatibility issues. The same can be done for making method local variables support intersection types. Note that according to Neal, the complete lub of Collections.emptyList() and new ArrayList() is JUST 'List' and nothing else, because one of the intersections is a strict subtype of the other. This is nice, because that would mean that even if we don't allow intersection types for method-locals, the following: String foo = someCall(); final list = foo == null ? Collections.emptyList() : Arrays.asList(foo); would be legal, and would make 'list' be type "List". A casual glance at large swathes of code finds almost no instances where I want to shorten my final method-local declaration by excluding the LHS type, but where I would not be able to because the expression on the RHS has an intersection type. The slight penalty of being long- winded in those situations is not as big as the potential for future pain, IMO. Marek: I got it right. expressions in java routinely have intersection types. Just try to ascertain what the type is of: 'foo ? new LinkedList() : new ArrayList()'. It's Serializable & Cloneable & AbstractList. Expressions have had such types since java 1.4 (1.5? - whichever one relaxed the ternary operator typing). The entire point of discussion here is: Do we extend this intersection concept to the type of *variables*? Currently only expressions and the bounds on generics parameters can be intersections. Remi: Which problems do you see? Muchos gracias for a link to the proposal. --Reinier Zwitserloot On Mar 29, 2009, at 14:23, Florian Weimer wrote: > * Reinier Zwitserloot: > >> final list = foo ? new LinkedList() : new ArrayList(); >> >> the type of 'list' is what, exactly? > > It's the type specified in section 15.25 of the JLS. I can't find a > definition of lub(T1, T2) in the spec, but "lub" probably stands for > "least upper bound", and lub(LinkedList, ArrayList) would be > AbstractList & Serializable & Cloneable (if I got the types right). > >> Serializable? Cloneable? List? They're all valid, so that wouldn't >> work. > > Intersection types are already part of the language, so I don't see > any problem. The following compiles: > > interface I1 {} > interface I2 {} > > static class C1 implements I1, I2 {} > static class C2 implements I1, I2 {} > > static void foo1(T foo) { > } > > static void foo1(boolean foo) { > foo1(foo ? new C1() : new C2()); > } > > Existence of intersection types also leaks to the surface during > overload resolution. > > It's just that you can't write down the type of some expressions using > Java type notation. For local variables, this isn't a problem; only > debugging information needs to be updated slightly. The effect for > fields would be more pronounced, and I guess to stay within COIN's > scope, a proposal would have to exclude inference for fields. From jlardoint at ilog.fr Tue Mar 31 05:55:45 2009 From: jlardoint at ilog.fr (Jean-Louis Ardoint) Date: Tue, 31 Mar 2009 14:55:45 +0200 Subject: Proposal: Accepting a subclass as an element type in a for loop Message-ID: 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 reinier at zwitserloot.com Tue Mar 31 05:59:33 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 14:59:33 +0200 Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax In-Reply-To: <49CE8541.7050009@optrak.co.uk> References: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49CE8541.7050009@optrak.co.uk> Message-ID: <39971D1E-05CB-4384-9D43-5BEFEB182B4C@zwitserloot.com> + being overloaded to also mean string concatenation was a mistake in java 1.0*. Let's not enshrine it by making more of them. 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 :/ } 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. 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. *) 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. --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 reinier at zwitserloot.com Tue Mar 31 06:03:19 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 15:03:19 +0200 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <11840193.1238294525158.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <11840193.1238294525158.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <17188EC0-2C56-4AE1-8B4E-11F4B3843341@zwitserloot.com> '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. 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. 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 say: No. The community has done a fine job of addressing these issues by creating code checkers. 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. --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 reinier at zwitserloot.com Tue Mar 31 06:05:23 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 15:05:23 +0200 Subject: PROPOSAL: Auto-assignment Parameters In-Reply-To: <1502806.1238275891268.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <1502806.1238275891268.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <5D89E486-351A-49EB-A7FE-4AD54959CB62@zwitserloot.com> 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. 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. 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! 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. --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 evildeathmath at yahoo.com Tue Mar 31 06:05:52 2009 From: evildeathmath at yahoo.com (Gene Ray) Date: Tue, 31 Mar 2009 06:05:52 -0700 (PDT) Subject: PROPOSAL: checked exception handling enhancement Message-ID: <311816.88072.qm@web112214.mail.gq1.yahoo.com> I suggest then replacing "wtf" with "wtf!?", which should be safe as it would currently generate a compiler error in all suggested contexts and is not a valid identifier name. --- On Mon, 3/30/09, Joseph D. Darcy wrote: From: Joseph D. Darcy Subject: Re: PROPOSAL: checked exception handling enhancement To: evildeathmath at yahoo.com Cc: coin-dev at openjdk.java.net Date: Monday, March 30, 2009, 7:08 PM evildeathmath at yahoo.com wrote: > AUTHOR(S): > > Eugene Ray > > OVERVIEW > > FEATURE SUMMARY: > > A new class-level modifier keyword, "wtf", is added to the language, eliminating the need to explicitly handle every checked exception in the class. >??? I think the wide possible use of the name in question must disqualify the proposal from consideration. -Joe From mthornton at optrak.co.uk Tue Mar 31 06:09:27 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 14:09:27 +0100 Subject: PROPOSAL: Simplified StringBuffer/StringBuilder syntax In-Reply-To: <39971D1E-05CB-4384-9D43-5BEFEB182B4C@zwitserloot.com> References: <15886363.1238270778184.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <49CE8541.7050009@optrak.co.uk> <39971D1E-05CB-4384-9D43-5BEFEB182B4C@zwitserloot.com> Message-ID: <49D21607.4010309@optrak.co.uk> Reinier Zwitserloot wrote: > + being overloaded to also mean string concatenation was a mistake in > java 1.0*. Let's not enshrine it by making more of them. > > 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 :/ > } > and most people who see it will immediately tell him that he is a clown. So I think peer pressure will ensure that we see very little of this use. I agree that using + for string concatenation was unfortunate, but we can't change it now. Mark From Ulf.Zibis at gmx.de Tue Mar 31 06:10:25 2009 From: Ulf.Zibis at gmx.de (Ulf Zibis) Date: Tue, 31 Mar 2009 15:10:25 +0200 Subject: Proposal: Accepting a subclass as an element type in a for loop In-Reply-To: References: Message-ID: <49D21641.4030901@gmx.de> +1 -Ulf Am 31.03.2009 14:55, Jean-Louis Ardoint schrieb: > 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 develop4lasu at gmail.com Tue Mar 31 06:13:46 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 15:13:46 +0200 Subject: PROPOSAL: 'final' without explicit type In-Reply-To: <51DE64F8-7D84-4368-8A52-F37A1FAD06DB@zwitserloot.com> References: <28bca0ff0903261305x2de00436r5ca8183fe01578d4@mail.gmail.com> <87fxgwzfew.fsf@mid.deneb.enyo.de> <51DE64F8-7D84-4368-8A52-F37A1FAD06DB@zwitserloot.com> Message-ID: <28bca0ff0903310613o41ed1e49q8f94063ffb2c1b28@mail.gmail.com> 2009/3/31 Reinier Zwitserloot : > Yes, the type of the RHS of: > > final list = foo ? new LinkedList() : new ArrayList(); > > ?is indeed AbstractList & Cloneable & Serializable. > > The question is: Is that what you make the type of 'list'? That would > be a novel idea: Now we have type variables that can have intersection > types, not just expressions. There's nothing inherent in java stopping > you from doing this for local method variables as you said, but one > should consider the future impact of this: There is absolutely no way > to specify intersection types in either java or in any sort of > reflection tool. Any attempt to add introspection of any sort to types > of method locals is thus going to be a major issue in the future if we > allow intersection types for them. I don't think this proposal > suggests you're allowed to infer the type on fields, regardless of the > issue of intersection types, but what if that seems useful later on? > Then either we overhaul java.lang.reflect, -or-, we all of a sudden > exclude it for fields but allow it (to be backwards compatible) for > method locals. Ugh. Feels hacky. > > I would -strongly- suggest at least for project coin to just not allow > intersection types at all, period. I have same opinion, just added most logic way to handle it, while people want it a lot. Of course if we say about effect of intersection, not intersection at expression; > A future version of java can add > this support later if it is deemed important. This is analogous to how > java gained intersection types in the fist place, which wasn't in the > earlier versions of java. Until intersection types, the following > expression wasn't even legal: > > foo ? new LinkedList() : new Arraylist(); > > because the type of the expression (and thence also must be the type > of the third arugment to the ?: operator) is decided by the type of > the second argument (in the above example, 'LinkedList', and ArrayList > is not a LinkedList. > > this was added without any backwards compatibility issues. The same > can be done for making method local variables support intersection > types. > Totally agree. > Note that according to Neal, the complete lub of > Collections.emptyList() and new ArrayList() is JUST 'List' and > nothing else, because one of the intersections is a strict subtype of > the other. This is nice, because that would mean that even if we don't > allow intersection types for method-locals, the following: > > String foo = someCall(); > final list = foo == null ? Collections.emptyList() : Arrays.asList(foo); > > would be legal, and would make 'list' be type "List". > I'm not sure about that. I mostly use my own collection so I do not have much problems with such situations. Warning may be solution here. > > A casual glance at large swathes of code finds almost no instances > where I want to shorten my final method-local declaration by excluding > the LHS type, but where I would not be able to because the expression > on the RHS has an intersection type. The slight penalty of being long- > winded in those situations is not as big as the potential for future > pain, IMO. > > Marek: I got it right. expressions in java routinely have intersection > types. Just try to ascertain what the type is of: > Then we agree here as well. > > 'foo ? new LinkedList() : new ArrayList()'. It's Serializable & > Cloneable & AbstractList. Expressions have had such types since > java 1.4 (1.5? - whichever one relaxed the ternary operator typing). > The entire point of discussion here is: Do we extend this intersection > concept to the type of *variables*? Currently only expressions and the > bounds on generics parameters can be intersections. > > Remi: Which problems do you see? Muchos gracias for a link to the > proposal. > > ?--Reinier Zwitserloot > -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From reinier at zwitserloot.com Tue Mar 31 06:29:55 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 15:29:55 +0200 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <49D159BC.6070804@joda.org> References: <49C56020.2070207@joda.org> <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> <49D141B2.1050808@e-spirit.de> <49D159BC.6070804@joda.org> Message-ID: <7CA05CC2-2D49-4929-B0D1-9C35843F473F@zwitserloot.com> I very much like the enhanced for each loop iteration control. The advantages are numerous, in my opinion: 1. intent - if you're looping across an essentially pre-defined set of items (which iterators generally give you), the associated keyword is 'for' and not 'while'. 2. Fixes some serious annoyances in java such as a lack of a join operator, by giving utility methods that you currently don't even get on iterators (first() and index() and company). and a non-issue, again, IMO: 3. Speed isn't inherent in the foreach construct in the first place. That seems to make 'Slow because it requires creating a bunch of objects' a very strange argument. The for-each construct is already slow in the following myriad, high-impact ways: 3a: Index looping is just an array lookup, but especially for Collections, every interaction with your iterator causes a check for throwing ConcurrentModificationException. Slow. 3b: You cannot for-each over an iterator, you must have an iterable. The iterable has to create an object to fulfill its contract, so we're already creating objects here. Another one in the mix really doesn't make a difference then. In practice, hotspot makes most of these points moot anyway. In my experience, the JVM can optimize many things that seem slow, but sometimes cannot optimize a trivial thing that you'd think wouldn't be a problem. Without a few PhD degrees in hotspot's internals, profiling is always a good idea. Is there a profile that shows the JVM would have serious issues with creating a wrapper object? If not, I think it would be a bad idea to continue this conversation on the presumption that extended foreach would somehow be much slower than plain foreach. I doubt that is true. NB: Yes, labels are an entirely separate namespace. --Reinier Zwitserloot On Mar 31, 2009, at 01:46, Stephen Colebourne wrote: > Stefan Schulz wrote: >> Frankly, I cannot see a great advantage of: >> for (Foo foo : fooList : it) { >> ... >> } >> saving two lines of code over: >> Iterator it = fooList.iterator(); >> while (it.hasNext()) { >> Foo foo = it.next(); >> ... >> } > > The former captures the *intent* of the loop. The latter is all about > plumbing. > >> by adding two wrappers and stuff to the code in the background. > > The proposal discusses possible optimisations, however I suspect that > hohtspot can probably cope with two additional objects being created. > > Remember, the extra overhead only happens if you add the optional > iterator reference. > > Stephen > From develop4lasu at gmail.com Tue Mar 31 06:31:13 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 15:31:13 +0200 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <11840193.1238294525158.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> References: <11840193.1238294525158.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> Message-ID: <28bca0ff0903310631o2cb0b4dey19e857514cece0e8@mail.gmail.com> 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 tim.lebedkov at googlemail.com Tue Mar 31 06:43:21 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Tue, 31 Mar 2009 15:43:21 +0200 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: <28bca0ff0903302340s3aa480a4h3f675ca5e1a00741@mail.gmail.com> References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> <28bca0ff0903302340s3aa480a4h3f675ca5e1a00741@mail.gmail.com> Message-ID: 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 On Tue, Mar 31, 2009 at 8:40 AM, Marek Kozie? wrote: > W dniu 31 marca 2009 03:06 u?ytkownik Gabriel Belingueres > napisa?: >> >> Why? >> final a = 1; // static type is int >> final b = new Integer(6); // static type is Integer >> >> If this is confusing for someone: >> final c = 1 + new Integer(7); >> >> then declare it as usual. >> > > I just think that in this form solution will be easier to use. > > >> Assuming that getLocalization() returns a Localization, then the whole >> point is that you don't need the cast; otherwise this feature is of >> doubtful utility. The variable type is known at compile type to be a >> Localization. > > "o is Object" for any reason, if it would be Localization then problem > would not exists. > >> OTOH, if the getLocalization() returns an Object, then >> final o = (Localization) some.getBoo().getLocalization(); >> might throw a ClassCastException at runtime, which is a pity because >> this is a new feature. >> If you want to risk to receive a ClassCastException, then declare it as usual: >> final Localization o = ?(Localization) some.getBoo().getLocalization(); > > What for if we already casted it ? > >> >> IMHO, type casts should be forbidden, or at least discouraged. > > I can agree a little. > > -- > Pozdrowionka. / Regards. > Lasu aka Marek Kozie? > > http://lasu2string.blogspot.com/ > > From mthornton at optrak.co.uk Tue Mar 31 06:43:53 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 14:43:53 +0100 Subject: PROPOSAL: checked exception handling enhancement In-Reply-To: <311816.88072.qm@web112214.mail.gq1.yahoo.com> References: <311816.88072.qm@web112214.mail.gq1.yahoo.com> Message-ID: <49D21E19.9080703@optrak.co.uk> Gene Ray wrote: > I suggest then replacing "wtf" with "wtf!?", which should be safe as it would currently generate a compiler error in all suggested contexts and is not a valid identifier name. > > Was this proposal submitted a few days earlier than intended? In any case I don't think even abbreviated obscenities have any place in a programming language intended for serious use. Mark Thornton From tim.lebedkov at googlemail.com Tue Mar 31 06:44:15 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Tue, 31 Mar 2009 15:44:15 +0200 Subject: Fwd: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: References: <91dd9a4f0903280314o2f0253c9ub08e8f459e6e3ae5@mail.gmail.com> Message-ID: ---------- Forwarded message ---------- From: Tim Lebedkov Date: 2009/3/30 Subject: Re: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. To: ???? Hello, as far as I understand, you propose to drop the "auto" keyword from the statements. This would lead to many bugs if you mistype an identifier. Example: String sample = "1"; for (simple: list) { // it should be *sample* // } use sample here... --Tim 2009/3/28 ???? : > Hi, > A variable declaration has 3 kind of style: > 1, field: class Case1{ fieldType fieldName;} > 2, local: method or si, type varName; > 3, statement, for(type var...) > then do assignment, > switch(case) > 1: the "fieldName" field type determinated, so assignment value must > acceptable by the field type. so the generic type argument is no need > at all. > 2: split 2 child case, 2.1assign a given argument, which type > determinated, same as 1. > 2.2 new local var, Yes, the new instance and generic type argument > is just my want. in this case, the type of local variable is no need > at all. > 3: same as 2.2 > So I would hope this: > class Test{ > List list1 = new ArrayList(); > List list2; > Test(){ > list2 = new ArrayList(); > } > void test(List list){ > list = new ArrayList(); > list2 = new ArrayList(); > for(s: list) handleString(s); > for(i: list2) handleInteger(i); > } > } > > What do you think? > > 2009/3/28 Tim Lebedkov : >> 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 tim.lebedkov at googlemail.com Tue Mar 31 06:44:32 2009 From: tim.lebedkov at googlemail.com (Tim Lebedkov) Date: Tue, 31 Mar 2009 15:44:32 +0200 Subject: Fwd: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. In-Reply-To: References: <91dd9a4f0903280314o2f0253c9ub08e8f459e6e3ae5@mail.gmail.com> <91dd9a4f0903300734p311abcc0m7c7df982e56b6efa@mail.gmail.com> Message-ID: ---------- Forwarded message ---------- From: Tim Lebedkov Date: 2009/3/31 Subject: Re: Proposal: Type inference for variable definition/initialization using the 'auto' keyword. To: ???? Hello, yes, this syntax is possible, but I don't like it because of an implicit variable definition (without the "auto" keyword). Regards Tim 2009/3/30 ???? : > Hi, > Seems should have no problem > String sample="1" > for(simple: list){ > //at here the coder should reference the simple var > //2 case: simple type same as sample, or not same > //case 1, not same, the simple is new variable, not problem > //case 1, same, > //in the loop, or after loop, the coder reference sample, but indeed > simple handed, sample not. > //so maybe bugs, but the case not problem too in unit test sight > } > > 2009/3/30 Tim Lebedkov : >> Hello, >> >> as far as I understand, you propose to drop the "auto" keyword from >> the statements. >> This would lead to many bugs if you mistype an identifier. >> Example: >> >> String sample = "1"; >> >> for (simple: list) { // it should be *sample* >> // >> } >> >> use sample here... >> >> --Tim >> >> 2009/3/28 ???? : >>> Hi, >>> A variable declaration has 3 kind of style: >>> 1, field: class Case1{ fieldType fieldName;} >>> 2, local: method or si, type varName; >>> 3, statement, for(type var...) >>> then do assignment, >>> switch(case) >>> 1: the "fieldName" field type determinated, so assignment value must >>> acceptable by the field type. so the generic type argument is no need >>> at all. >>> 2: split 2 child case, 2.1assign a given argument, which type >>> determinated, same as 1. >>> 2.2 new local var, Yes, the new instance and generic type argument >>> is just my want. in this case, the type of local variable is no need >>> at all. >>> 3: same as 2.2 >>> So I would hope this: >>> class Test{ >>> List list1 = new ArrayList(); >>> List list2; >>> Test(){ >>> list2 = new ArrayList(); >>> } >>> void test(List list){ >>> list = new ArrayList(); >>> list2 = new ArrayList(); >>> for(s: list) handleString(s); >>> for(i: list2) handleInteger(i); >>> } >>> } >>> >>> What do you think? >>> >>> 2009/3/28 Tim Lebedkov : >>>> 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 develop4lasu at gmail.com Tue Mar 31 06:49:05 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 15:49:05 +0200 Subject: PROPOSAL: Enhanced for each loop iteration control In-Reply-To: <7CA05CC2-2D49-4929-B0D1-9C35843F473F@zwitserloot.com> References: <49C56020.2070207@joda.org> <28bca0ff0903300117h532acd65i42c0cbe674126c7d@mail.gmail.com> <49D141B2.1050808@e-spirit.de> <49D159BC.6070804@joda.org> <7CA05CC2-2D49-4929-B0D1-9C35843F473F@zwitserloot.com> Message-ID: <28bca0ff0903310649l22ae907dw348f43ce15c4c135@mail.gmail.com> 2009/3/31 Stephen Colebourne : > While I understand that this may seem appealing, it really isn't. Labels > are in a different namespace IIRC, and using that for psuedo method > calls is really an abuse. 2009/3/31 Reinier Zwitserloot : [snip] > > > NB: Yes, labels are an entirely separate namespace. > > ?--Reinier Zwitserloot > I didn't noticed that ;P Thanks! 2009/3/31 Stephen Colebourne : > > I accept that my proposal doesn't allow custom iterators, but I don't > believe that to be a major problem. In my opinion it is. Interfaces and needs evolve. Enumeration -> Iterator -> ArrayIterationControlIterator, IterableIterationControlIterator -> ??? So there is no point to limit language here, and change Iterator type every 4 Java versions, while obtain actual iterator type is no problem. > Consider it that my proposal tackles > 80%+ of the problem (which was part of the 20% of the original looping > problem, and still a good number of LOC in a reasonable system). > > Stephen > If iterator cannot be assigned to variable and .next() cannot be called (compile time error) then this proposal can be really nice one. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From belingueres at gmail.com Tue Mar 31 06:49:20 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 31 Mar 2009 10:49:20 -0300 Subject: PROPOSAL: @OverrideAll annotation Message-ID: Hi, I've written a new feature that might be comfortable to use for someone. All input is welcomed. 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 develop4lasu at gmail.com Tue Mar 31 06:58:30 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 15:58:30 +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: <28bca0ff0903310658k15b0c9abk45270080ab7cf7af@mail.gmail.com> 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 rssh at gradsoft.com.ua Tue Mar 31 07:02:55 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Tue, 31 Mar 2009 17:02:55 +0300 (EEST) Subject: PROPOSAL: @OverrideAll annotation In-Reply-To: References: Message-ID: <740b03271540fda5faf1315980a7ff60.squirrel@wmail.gradsoft.ua> > 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 Tue Mar 31 07:15:01 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 31 Mar 2009 11:15:01 -0300 Subject: PROPOSAL: @OverrideAll annotation In-Reply-To: <740b03271540fda5faf1315980a7ff60.squirrel@wmail.gradsoft.ua> References: <740b03271540fda5faf1315980a7ff60.squirrel@wmail.gradsoft.ua> Message-ID: Yes. I thought this for easily implementing Null objects, because it has such a direct relationship with inheritance, and because they usually don't do much. I suppose the idea could be extended to support delegation too (as is the case with the Proxy pattern.) That would be nice. 2009/3/31, rssh at gradsoft.com.ua : > > 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 evildeathmath at yahoo.com Tue Mar 31 07:30:58 2009 From: evildeathmath at yahoo.com (Gene Ray) Date: Tue, 31 Mar 2009 07:30:58 -0700 (PDT) Subject: PROPOSAL: checked exception handling enhancement Message-ID: <388308.39767.qm@web112210.mail.gq1.yahoo.com> Sadly, the ideal submission date was (will be?) after the Project Coin deadline, so I had to make do. --- On Tue, 3/31/09, Mark Thornton wrote: From: Mark Thornton Subject: Re: PROPOSAL: checked exception handling enhancement To: "Gene Ray" Cc: coin-dev at openjdk.java.net Date: Tuesday, March 31, 2009, 1:43 PM Gene Ray wrote: > I suggest then replacing "wtf" with "wtf!?", which should be safe as it would currently generate a compiler error in all suggested contexts and is not a valid identifier name. > >??? Was this proposal submitted a few days earlier than intended? In any case I don't think even abbreviated obscenities have any place in a programming language intended for serious use. Mark Thornton From reinier at zwitserloot.com Tue Mar 31 07:34:11 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 16:34:11 +0200 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> Message-ID: First off: WANT! Second: Whichever form Reified Lists/Sets/Maps eventually take, won't they neccessarily extend List and friends? I imagine that any attempt to create: public interface ReifiedList {} involves making that type implement List, eventhough treating your reified list as a List would no longer give you the benefit of reification, possibly. Therefore, what we seem to be talking about, if I'm right so far (and I'm just taking a stab at this here, please correct me if I'm wrong!), is that we specify that the collection literals return some implementation of List, Set, and Map, with listed behaviours (specifically, 'linked' behaviour for maps and sets, otherwise nothing special), but that in a future version, we may change this to: They will return ReifiedList, ReifiedSet, and ReifiedMap, all of which extend List, Set, and Map. How is that not backwards compatible? --Reinier Zwitserloot On Mar 31, 2009, at 10:51, Joshua Bloch wrote: > Mark, > Presumably you'd be happy to replace them with lists of sets, and > then you > could use (nested) collection literals? > > Josh > > On Tue, Mar 31, 2009 at 1:47 AM, Mark Thornton > wrote: > >> Joshua Bloch wrote: >> >>> Neal, >>> >>> In other words, we could prohibit set literals in array >>> initializers. >>> Arrays of sets are an awful idea anyway, so it's no great loss. >>> >> Ouch, I have a few of those. Invariably where the universe of >> unique sets >> is very small and the array contains all of them. >> >> Regards, >> Mark Thornton >> > From neal at gafter.com Tue Mar 31 07:37:47 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 07:37:47 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> Message-ID: <15e8b9d20903310737u73bea11dgeced4504631b1df1@mail.gmail.com> On Tue, Mar 31, 2009 at 1:34 AM, Joshua Bloch wrote: > Arrays > of sets?are an awful idea anyway, so it's no great loss. It might not remain such an awful idea if we have reified generics in the future. I don't think forbidding this combination is a great idea. From neal at gafter.com Tue Mar 31 07:42:16 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 07:42:16 -0700 Subject: Proposal: Collection Literals In-Reply-To: References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> Message-ID: <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> Your guesses are about future design decisions. We shouldn't make assumptions about future design decisions without doing the future design now, and I don't believe we are in a position to do so. In any case, some contexts will have the type parameters reified and some will not, so the future spec for this feature cannot uniformly require the creation of reified collections, even if doing so were compatible with its previous non-reified-only behavior. On Tue, Mar 31, 2009 at 7:34 AM, Reinier Zwitserloot wrote: > First off: WANT! > > Second: > > Whichever form Reified Lists/Sets/Maps eventually take, won't they > neccessarily extend List and friends? I imagine that any attempt to > create: > > public interface ReifiedList {} > > involves making that type implement List, eventhough treating your > reified list as a List would no longer give you the benefit of > reification, possibly. > > Therefore, what we seem to be talking about, if I'm right so far (and I'm > just taking a stab at this here, please correct me if I'm wrong!), is that > we specify that the collection literals return some implementation of > List, Set, and Map, with listed behaviours (specifically, > 'linked' behaviour for maps and sets, otherwise nothing special), but that > in a future version, we may change this to: They will return ReifiedList, > ReifiedSet, and ReifiedMap, all of which extend List, Set, and Map. > > > How is that not backwards compatible? > > > ?--Reinier Zwitserloot > > > > On Mar 31, 2009, at 10:51, Joshua Bloch wrote: > >> Mark, >> Presumably you'd be happy to replace them with lists of sets, and then you >> could use (nested) collection literals? >> >> ? ? ? Josh >> >> On Tue, Mar 31, 2009 at 1:47 AM, Mark Thornton >> wrote: >> >>> Joshua Bloch wrote: >>> >>>> Neal, >>>> >>>> In other words, we could prohibit set literals in array initializers. >>>> Arrays of sets are an awful idea anyway, so it's no great loss. >>>> >>> Ouch, I have a few of those. Invariably where the universe of unique sets >>> is very small and the array contains all of them. >>> >>> Regards, >>> Mark Thornton >>> >> > > From neal at gafter.com Tue Mar 31 07:49:33 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 07:49:33 -0700 Subject: Proposal idea - generators In-Reply-To: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> References: <3dd3f56a0903310414w4c579d63xbc8f31ff0ff82021@mail.gmail.com> Message-ID: <15e8b9d20903310749n4bb99322ldd92a96e3aa965c0@mail.gmail.com> 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 From neal at gafter.com Tue Mar 31 07:51:50 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 07:51:50 -0700 Subject: PROPOSAL: open and close brace optional for single statement try, catch, finally, method declaration In-Reply-To: <980366fa0903310522u31ac7641r6a1554c188122175@mail.gmail.com> References: <49d02e12.18038e0a.6c4e.ffffa859@mx.google.com> <980366fa0903300445y6727dfaehc885c184d0dbe2c6@mail.gmail.com> <49D0C82D.1000208@sun.com> <980366fa0903310522u31ac7641r6a1554c188122175@mail.gmail.com> Message-ID: <15e8b9d20903310751m2da11e10q97ea59c4ffed1bd2@mail.gmail.com> 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 kris.nuttycombe at gmail.com Tue Mar 31 07:56:01 2009 From: kris.nuttycombe at gmail.com (Kris Nuttycombe) Date: Tue, 31 Mar 2009 08:56:01 -0600 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> Message-ID: <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> Given the possibility of confusion between set literals and array initializers, how much worse would it be simply to provide vararg constructors, in the various collection classes? Similarly, why not just some additional vararg factory methods in Collections that can be used to produce the immutable versions? I realize that the syntax isn't quite as terse as what this proposal suggests, but I think it avoids the issues with reified types and would not represent a substantial deviation from the current state of the libraries. The only place where this wouldn't work is for map literals; however, if a Pair literal were introduced as has been suggested elsewhere then this problem could be easily resolved. Kris From reinier at zwitserloot.com Tue Mar 31 08:03:20 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:03:20 +0200 Subject: Addition to Comparable interface In-Reply-To: <49D20D30.2090207@optrak.co.uk> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> <49D1FE7C.7070008@optrak.co.uk> <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> <49D20D30.2090207@optrak.co.uk> Message-ID: <862A21A2-8ECE-4F29-B40E-E49A0BA8617D@zwitserloot.com> This is an API change, not a language change, so by definition you're on the wrong list for this proposal. Also, I think it's a bad idea in general. For -writing- the result of a compare operation, they're great. But for reading, it's an instant bug. Any code this form: if ( a.compareTo(b) == Comparator.BEFORE) is an instant bug, but unless you suggest the novel idea of having javac actually attempt to find such things and warn on it, which is very difficult, this is going to cause more pain that it'll solve. (very difficult because: what if you pass the result of the compare job to another method, and that method decides to switch on the result, using the BEFORE/EQUAL/AFTER constants? How do you detect this happened?) --Reinier Zwitserloot On Mar 31, 2009, at 14:31, Mark Thornton wrote: > Roy van Rijn wrote: >>>> FEATURE SUMMARY: >>>> >>>> The return value of the Comparable interfae could be made a lot >>>> clearer if it would have the following static variables: >>>> public static int BEFORE = -1; >>>> public static int EQUAL = 0; >>>> public static int AFTER = 1; >>>> >>> This might give the impression that the only values returned by >>> compareTo >>> are -1, 0, 1 which is certainly not true. The interface only >>> requires that >>> the sign of the returned value reflect the ordering. >>> >>> >> >> That might be a problem indeed, but the javadoc should still indicate >> its possible to use any positive and negative integer value. >> >> The problem I've seen a lot is the following, even in large corporate >> programs, when people compare integers like this: >> >> > It is valid for reduced ranges of integers, notably when the values > are > known to be positive. > > Mark Thornton > > From mthornton at optrak.co.uk Tue Mar 31 08:13:14 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 16:13:14 +0100 Subject: Addition to Comparable interface In-Reply-To: <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> <49D1FE7C.7070008@optrak.co.uk> <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> Message-ID: <49D2330A.9010809@optrak.co.uk> Roy van Rijn wrote: >>> FEATURE SUMMARY: >>> >>> The return value of the Comparable interfae could be made a lot >>> clearer if it would have the following static variables: >>> public static int BEFORE = -1; >>> public static int EQUAL = 0; >>> public static int AFTER = 1; >>> >> This might give the impression that the only values returned by compareTo >> are -1, 0, 1 which is certainly not true. The interface only requires that >> the sign of the returned value reflect the ordering. >> >> > > That might be a problem indeed, but the javadoc should still indicate > its possible to use any positive and negative integer value. > > The problem I've seen a lot is the following, even in large corporate > programs, when people compare integers like this: > As Reinier points out this is the wrong list for this proposal. However a better solution might be to add Integer.compare(int,int) and Long.compare(int, int) methods, and encourage people to use tham inside of writing the comparison themselves. Mark Thornton From jjb at google.com Tue Mar 31 08:14:38 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 08:14:38 -0700 Subject: Proposal: Collection Literals In-Reply-To: <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> Message-ID: <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> Kris, I think the confusion between set literals and array literals is overblown. So far as I know, the only context in which it can occur is a nested array initializer on the right hand side of an array declaration. If you want arrays, you typically want them "all the way down." So the proposed solution of banning collection literals in array initializers on the right hand side of array declarations seems like a perfect solution to this corner case. Of course it is possible to directly use collection factories with varargs (such as Arrays.toList), but you lose the conciseness, especially for maps. Similarly, we don't need array-like access to collections: we can continue using set, get, and put. But it people want the succinctness of array-like access to collections, then they probably want the succinctness of collection literals too. As for reified generics, I'm still waiting for a code example where the proposed approach will cause trouble. Regards, Josh On Tue, Mar 31, 2009 at 7:56 AM, Kris Nuttycombe wrote: > Given the possibility of confusion between set literals and array > initializers, how much worse would it be simply to provide vararg > constructors, in the various collection classes? Similarly, why not > just some additional vararg factory methods in Collections that can be > used to produce the immutable versions? > > I realize that the syntax isn't quite as terse as what this proposal > suggests, but I think it avoids the issues with reified types and > would not represent a substantial deviation from the current state of > the libraries. > > The only place where this wouldn't work is for map literals; however, > if a Pair literal were introduced as has been suggested elsewhere then > this problem could be easily resolved. > > Kris > > From reinier at zwitserloot.com Tue Mar 31 08:16:01 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:16:01 +0200 Subject: Proposal: Accepting a subclass as an element type in a for loop In-Reply-To: References: Message-ID: <7E2F23A9-6F80-4932-80C4-8D2D9C6F3348@zwitserloot.com> 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 reinier at zwitserloot.com Tue Mar 31 08:19:42 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:19:42 +0200 Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <28bca0ff0903310631o2cb0b4dey19e857514cece0e8@mail.gmail.com> References: <11840193.1238294525158.JavaMail.root@mswamui-andean.atl.sa.earthlink.net> <28bca0ff0903310631o2cb0b4dey19e857514cece0e8@mail.gmail.com> Message-ID: <29FD1AA7-ABC1-4C3D-82E2-032E885C5C3D@zwitserloot.com> On Mar 31, 2009, at 15:31, Marek Kozie? wrote: > public Root(Bar right, Bar left) { > this.left = left// left is set here > .right = right; > } > > } > Heh. Nice find. You're absolutely right. naked dot is not practical, for any proposal. (At least, if naked dot is used a an expression. It might be okay in the paramlist or return type of a method declaration). -- Reinier Zwitserloot From reinier at zwitserloot.com Tue Mar 31 08:28:12 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:28:12 +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: 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: List list = new ArrayList(); The LHS type is not the same as the RHS type. Virtually all java programmers would agree the above is superior to: ArrayList list = new ArrayList(); for two reasons: 1. You will not be able to assign another type of list to this thing later. 2. You will not be calling arraylist-specific methods (which there are none, but let's argue for a moment that there are), eventhough the intent is for 'list' to perhaps hold some other non-ArrayList list, and And yet, with type inference, you'll get ArrayList on the LHS, and not List. Both of those reasons become moot, or almost moot, if the variable is final: 1. It's final. You can't assign anything to it, so no problem here, and 2. Because you can't assign anything else, calling arraylist- specific stuff is less of an issue. The issue doesn't go away entirely (and this is in fact the only reasonable complaint against the final- without-explicit-type proposal that I can think of) but it becomes much less important. It is further mediated by the idea that java allows you to operate on expressions and not just variables, and expression do quite auto-infer (and are in essence final, you can't re- assign the value of an expression, of course!), so there's precedent, which is always a good thing for language changes. In other words: (new LinkedList()).push("Hello!"); is perfectly legal, and yet it has the exact same problem that, supposedly, a (final!) implicit variable type would have: If you were intending to change that linkedlist for an arraylist later, than 'push' was not a method you were supposed to call on it. As the above example clearly shows: It's a problem, but not exactly a backbreaking one. We've been dealing with it for years. 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; --Reinier Zwitserloot On Mar 31, 2009, at 15:43, Tim Lebedkov wrote: > 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 > > On Tue, Mar 31, 2009 at 8:40 AM, Marek Kozie? > wrote: >> W dniu 31 marca 2009 03:06 u?ytkownik Gabriel Belingueres >> napisa?: >>> >>> Why? >>> final a = 1; // static type is int >>> final b = new Integer(6); // static type is Integer >>> >>> If this is confusing for someone: >>> final c = 1 + new Integer(7); >>> >>> then declare it as usual. >>> >> >> I just think that in this form solution will be easier to use. >> >> >>> Assuming that getLocalization() returns a Localization, then the >>> whole >>> point is that you don't need the cast; otherwise this feature is of >>> doubtful utility. The variable type is known at compile type to be a >>> Localization. >> >> "o is Object" for any reason, if it would be Localization then >> problem >> would not exists. >> >>> OTOH, if the getLocalization() returns an Object, then >>> final o = (Localization) some.getBoo().getLocalization(); >>> might throw a ClassCastException at runtime, which is a pity because >>> this is a new feature. >>> If you want to risk to receive a ClassCastException, then declare >>> it as usual: >>> final Localization o = (Localization) >>> some.getBoo().getLocalization(); >> >> What for if we already casted it ? >> >>> >>> IMHO, type casts should be forbidden, or at least discouraged. >> >> I can agree a little. >> >> -- >> Pozdrowionka. / Regards. >> Lasu aka Marek Kozie? >> >> http://lasu2string.blogspot.com/ >> >> > From Joe.Darcy at Sun.COM Tue Mar 31 08:27:52 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 31 Mar 2009 08:27:52 -0700 Subject: Call for proposals is over! Message-ID: <49D23678.8070708@sun.com> Greetings. Now that it is at least March 30, 2009 in every time zone, with over 60 proposals submitted and over 1000 email messages sent to the list, the call for proposals phase of Project Coin is hereby concluded! -Joe From mthornton at optrak.co.uk Tue Mar 31 08:33:05 2009 From: mthornton at optrak.co.uk (Mark Thornton) Date: Tue, 31 Mar 2009 16:33:05 +0100 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: <49D237B1.6040908@optrak.co.uk> Reinier Zwitserloot wrote: > 2. You will not be calling arraylist-specific methods (which there > are none, but let's argue for a moment that there are), eventhough the > intent is for 'list' to perhaps hold some other non-ArrayList list, and > ArrayList.ensureCapacity ArrayList.trimToSize Mark Thornton From alexdmiller at yahoo.com Tue Mar 31 08:37:35 2009 From: alexdmiller at yahoo.com (Alex Miller) Date: Tue, 31 Mar 2009 08:37:35 -0700 (PDT) Subject: PROPOSAL: abstract enums In-Reply-To: References: Message-ID: <239717.41781.qm@web32201.mail.mud.yahoo.com> Derek Foster wrote: > I can speak from personal experience when I say that the lack of this feature in Java is both mysterious (since there > seems no specific technical reason to forbid it, and it seems unnecessarily different from how classes work) and > quite frustrating and time-consuming to work around. I mentioned some of those experiences in the overview of my > proposal. Apparently Stephen has had similar experiences. Just wanted to throw my two cents in that I also have run into circumstances where I really needed an abstract enum and was forced to go with some very awkward delegation choices instead. And I know Fred Simon has been advocating them for quite some time and even created a branch in kijaro for it I think. http://tech.puredanger.com/2008/01/10/property-enum/ Alex Miller From reinier at zwitserloot.com Tue Mar 31 08:38:55 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:38:55 +0200 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> Message-ID: <0AF02B4E-E47E-4CD3-B025-3F0618DFB312@zwitserloot.com> Many reasons for not just having varargs constructors on collections API classes: 1. constructors don't infer generics. 2. constructors don't make immutables. Even Arrays.asList doesn't. This is how you make an immutable list of constants today: Collections.unmodifiableList(Arrays.asList("foo", "bar")); that, is, in a word, ridiculous. Even with constructor help, it woud become: Collections.unmodifiableList(new ArrayList("foo", "bar")); not much help, and arguably even worse. It would become, with Joshes proposal: ["foo", "bar"] which makes me smile. 3. import statements. Okay, that's a small one, but nevertheless. 4. Implementation is often irrelevant, when the list is immutable anyway. Why force people to type ArrayList. For that matter, why force people to -read- ArrayList? It's just 'A list with no surprises, which is immutable'. That's easy enough to remember. 5. varargs are fundamentally broken, though fortunately the proposal to address this issue is on the project coin shortlist. --Reinier Zwitserloot On Mar 31, 2009, at 17:14, Joshua Bloch wrote: > Kris, > I think the confusion between set literals and array literals is > overblown. > So far as I know, the only context in which it can occur is a nested > array > initializer on the right hand side of an array declaration. If you > want > arrays, you typically want them "all the way down." So the proposed > solution of banning collection literals in array initializers on the > right > hand side of array declarations seems like a perfect solution to > this corner > case. > > Of course it is possible to directly use collection factories with > varargs > (such as Arrays.toList), but you lose the conciseness, especially > for maps. > Similarly, we don't need array-like access to collections: we can > continue > using set, get, and put. But it people want the succinctness of > array-like > access to collections, then they probably want the succinctness of > collection literals too. > > As for reified generics, I'm still waiting for a code example where > the > proposed approach will cause trouble. > > Regards, > > Josh > > On Tue, Mar 31, 2009 at 7:56 AM, Kris Nuttycombe > wrote: > >> Given the possibility of confusion between set literals and array >> initializers, how much worse would it be simply to provide vararg >> constructors, in the various collection classes? Similarly, why not >> just some additional vararg factory methods in Collections that can >> be >> used to produce the immutable versions? >> >> I realize that the syntax isn't quite as terse as what this proposal >> suggests, but I think it avoids the issues with reified types and >> would not represent a substantial deviation from the current state of >> the libraries. >> >> The only place where this wouldn't work is for map literals; however, >> if a Pair literal were introduced as has been suggested elsewhere >> then >> this problem could be easily resolved. >> >> Kris >> >> > From jjb at google.com Tue Mar 31 08:33:16 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 08:33:16 -0700 Subject: Proposal: Collection Literals In-Reply-To: <15e8b9d20903310737u73bea11dgeced4504631b1df1@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <15e8b9d20903310737u73bea11dgeced4504631b1df1@mail.gmail.com> Message-ID: <17b2302a0903310833i18b18a2eh23a7fee48c94d84b@mail.gmail.com> Neal, Even if we were to reify generics in a future release, arrays of sets would remain a bad idea. Arrays are covariant and sets are non-variant. The combination of the two is problematic. Currently it isn't even typesafe (hence the ban on generic array creation). With reification of generics, arrays of sets could be made typesafe, but would still admit the possibility of runtime errors that would be caught at compile time if you used List> in place of Set[]. Josh On Tue, Mar 31, 2009 at 7:37 AM, Neal Gafter wrote: > On Tue, Mar 31, 2009 at 1:34 AM, Joshua Bloch wrote: > > Arrays > > of sets are an awful idea anyway, so it's no great loss. > > It might not remain such an awful idea if we have reified generics in > the future. I don't think forbidding this combination is a great > idea. > From reinier at zwitserloot.com Tue Mar 31 08:39:40 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:39:40 +0200 Subject: PROPOSAL: 'final' without explicit type (update) In-Reply-To: <49D237B1.6040908@optrak.co.uk> References: <28bca0ff0903301426o7449e309t9de2e43743593ea6@mail.gmail.com> <28bca0ff0903301609y10c30815ice919d750f523745@mail.gmail.com> <28bca0ff0903302340s3aa480a4h3f675ca5e1a00741@mail.gmail.com> <49D237B1.6040908@optrak.co.uk> Message-ID: <124E11B6-2AC9-4D2E-A216-91391E0CC725@zwitserloot.com> I stand corrected. --Reinier Zwitserloot On Mar 31, 2009, at 17:33, Mark Thornton wrote: > Reinier Zwitserloot wrote: >> 2. You will not be calling arraylist-specific methods (which >> there are none, but let's argue for a moment that there are), >> eventhough the intent is for 'list' to perhaps hold some other non- >> ArrayList list, and >> > ArrayList.ensureCapacity > ArrayList.trimToSize > > Mark Thornton > From jlardoint at ilog.fr Tue Mar 31 08:41:20 2009 From: jlardoint at ilog.fr (Jean-Louis Ardoint) Date: Tue, 31 Mar 2009 17:41:20 +0200 Subject: Proposal: Accepting a subclass as an element type in a for loop In-Reply-To: <7E2F23A9-6F80-4932-80C4-8D2D9C6F3348@zwitserloot.com> References: <7E2F23A9-6F80-4932-80C4-8D2D9C6F3348@zwitserloot.com> Message-ID: You might say that all proposals are very niche, and almost all of them can be solved by writing some code (you may save some time by writing a generic comment ?). About List> foo = someMethodCall(); for ( Set set : foo ) { // You can't do this in java. } I don't understand your point. A List> should not contain a Set if you use generics without tweaks. So what would you expect? Anyway, thank you for your comments. --Jean-Louis Ardoint ________________________________________ From: Reinier Zwitserloot [mailto:reinierz at gmail.com] On Behalf Of Reinier Zwitserloot Sent: Tuesday, March 31, 2009 5:16 PM 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 Joe.Darcy at Sun.COM Tue Mar 31 08:40:57 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 31 Mar 2009 08:40:57 -0700 Subject: Addition to Comparable interface In-Reply-To: <49D2330A.9010809@optrak.co.uk> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> <49D1FE7C.7070008@optrak.co.uk> <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> <49D2330A.9010809@optrak.co.uk> Message-ID: <49D23989.60501@sun.com> Mark Thornton wrote: > Roy van Rijn wrote: > >>>> FEATURE SUMMARY: >>>> >>>> The return value of the Comparable interfae could be made a lot >>>> clearer if it would have the following static variables: >>>> public static int BEFORE = -1; >>>> public static int EQUAL = 0; >>>> public static int AFTER = 1; >>>> >>>> >>> This might give the impression that the only values returned by compareTo >>> are -1, 0, 1 which is certainly not true. The interface only requires that >>> the sign of the returned value reflect the ordering. >>> >>> >>> >> That might be a problem indeed, but the javadoc should still indicate >> its possible to use any positive and negative integer value. >> >> The problem I've seen a lot is the following, even in large corporate >> programs, when people compare integers like this: >> >> > As Reinier points out this is the wrong list for this proposal. > However a better solution might be to add Integer.compare(int,int) and > Long.compare(int, int) methods, and encourage people to use tham inside > of writing the comparison themselves. > > Mark Thornton > > Yes; as noted the request is off-topic for Project Coin since it is a pure libraries change. I agree a set of two-argument int and long (and float and double ...) compare methods on primitive types would be a fine addition to the platform libraries in JDK 7: 6582946 Add suite of compare(T, T) methods for ints, longs etc http://bugs.sun.com/view_bug.do?bug_id=6582946 -Joe From reinier at zwitserloot.com Tue Mar 31 08:45:58 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 17:45:58 +0200 Subject: Proposal: Accepting a subclass as an element type in a for loop In-Reply-To: References: <7E2F23A9-6F80-4932-80C4-8D2D9C6F3348@zwitserloot.com> Message-ID: Mistake in my sample. try List> as an input source. I'll qualify my 'this is too niche' with: I've never, ever, needed that. I can think of many things that follow the same general line of thought that I'd also never need. Why is yours so special? Can you show some relevant use cases? Why is null included in this one? Only because it technically can be cast? If you consider the 'instanceof' syntax sugar on its face value, you should NOT include it. Why is inclusion preferred? Will there be an alternative syntax if I want to exclude null? If not, why is that not a valid use case, but yours is? Some proposals have obvious use cases. Others dont. I would venture a guess that it would be quite useful to prove the merit of the use cases you're trying to solve if you're not absolutely certain you fall into the former category. --Reinier Zwitserloot On Mar 31, 2009, at 17:41, Jean-Louis Ardoint wrote: > You might say that all proposals are very niche, and almost all of > them can be solved by writing some code (you may save some time by > writing a generic comment ?). > > About > List> foo = someMethodCall(); > for ( Set set : foo ) { > // You can't do this in java. > } > > I don't understand your point. A List> should not > contain a Set if you use generics without tweaks. So what > would you expect? > > Anyway, thank you for your comments. > > --Jean-Louis Ardoint > > > > ________________________________________ > From: Reinier Zwitserloot [mailto:reinierz at gmail.com] On Behalf Of > Reinier Zwitserloot > Sent: Tuesday, March 31, 2009 5:16 PM > 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 roy.van.rijn at gmail.com Tue Mar 31 08:46:08 2009 From: roy.van.rijn at gmail.com (Roy van Rijn) Date: Tue, 31 Mar 2009 17:46:08 +0200 Subject: Addition to Comparable interface In-Reply-To: <49D23989.60501@sun.com> References: <573ca1690903310356y24fcb4cdt8a907bff7e2354@mail.gmail.com> <49D1FE7C.7070008@optrak.co.uk> <573ca1690903310516p1997068xe10a5139d9f01af7@mail.gmail.com> <49D2330A.9010809@optrak.co.uk> <49D23989.60501@sun.com> Message-ID: <573ca1690903310846w5cf2507ex752826f39ae06bcc@mail.gmail.com> Ah yes, much better, thanks! On Tue, Mar 31, 2009 at 5:40 PM, Joseph D. Darcy wrote: > Mark Thornton wrote: >> >> Roy van Rijn wrote: >> >>>>> >>>>> FEATURE SUMMARY: >>>>> >>>>> The return value of the Comparable interfae could be made a lot >>>>> clearer if it would have the following static variables: >>>>> ? public static int BEFORE = -1; >>>>> ? public static int EQUAL = 0; >>>>> ? public static int AFTER = 1; >>>>> >>>> >>>> This might give the impression that the only values returned by >>>> compareTo >>>> are -1, 0, 1 which is certainly not true. The interface only requires >>>> that >>>> the sign of the returned value reflect the ordering. >>>> >>>> >>> >>> That might be a problem indeed, but the javadoc should still indicate >>> its possible to use any positive and negative integer value. >>> >>> The problem I've seen a lot is the following, even in large corporate >>> programs, when people compare integers like this: >>> >> >> As Reinier points out this is the wrong list for this proposal. >> However a better solution might be to add Integer.compare(int,int) and >> Long.compare(int, int) methods, and encourage people to use tham inside of >> writing the comparison themselves. >> >> Mark Thornton >> >> > > Yes; as noted the request is off-topic for Project Coin since it is a pure > libraries change. > > I agree a set of two-argument int and long (and float and double ...) > compare methods on primitive types would be a fine addition to the platform > libraries in JDK 7: > > 6582946 Add suite of compare(T, T) methods for ints, longs etc > http://bugs.sun.com/view_bug.do?bug_id=6582946 > > -Joe > > From kris.nuttycombe at gmail.com Tue Mar 31 08:57:03 2009 From: kris.nuttycombe at gmail.com (Kris Nuttycombe) Date: Tue, 31 Mar 2009 09:57:03 -0600 Subject: Proposal: Collection Literals In-Reply-To: <0AF02B4E-E47E-4CD3-B025-3F0618DFB312@zwitserloot.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> <0AF02B4E-E47E-4CD3-B025-3F0618DFB312@zwitserloot.com> Message-ID: <2771e600903310857rdfe1443tc869486dafaa130@mail.gmail.com> On Tue, Mar 31, 2009 at 9:38 AM, Reinier Zwitserloot wrote: > Many reasons for not just having varargs constructors on collections > API classes: > > 1. constructors don't infer generics. > > 2. constructors don't make immutables. Even Arrays.asList doesn't. > This is how you make an immutable list of constants today: > > Collections.unmodifiableList(Arrays.asList("foo", "bar")); > > that, is, in a word, ridiculous. Even with constructor help, it woud > become: > > Collections.unmodifiableList(new ArrayList("foo", "bar")); > > not much help, and arguably even worse. > I was imagining something more along the lines of: Collections.immutableList("foo", "bar"). Of course, this is currently possible to do as a third-party library, so if one is content with such syntax there's already a solution. > It would become, with Joshes proposal: > > ["foo", "bar"] > > which makes me smile. > Yes, however his proposal does not address the issue of simplifying the construction of mutable collections with initial contents. Of course, as the original proposal mentions one can always use anonymous inner classes (Crazybob's contraption) for this. Kris > 3. import statements. Okay, that's a small one, but nevertheless. > > 4. Implementation is often irrelevant, when the list is immutable > anyway. Why force people to type ArrayList. For that matter, why force > people to -read- ArrayList? It's just 'A list with no surprises, which > is immutable'. That's easy enough to remember. > > 5. varargs are fundamentally broken, though fortunately the proposal > to address this issue is on the project coin shortlist. > > ?--Reinier Zwitserloot From reinier at zwitserloot.com Tue Mar 31 09:07:25 2009 From: reinier at zwitserloot.com (Reinier Zwitserloot) Date: Tue, 31 Mar 2009 18:07:25 +0200 Subject: Proposal: Collection Literals In-Reply-To: <2771e600903310857rdfe1443tc869486dafaa130@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> <0AF02B4E-E47E-4CD3-B025-3F0618DFB312@zwitserloot.com> <2771e600903310857rdfe1443tc869486dafaa130@mail.gmail.com> Message-ID: Actually, it would help creating mutable collections classes with initial values quite well. If the proposal is accepted: List list = new SuperExtraMegaList(["foo", "bar"]); I am assuming there will be an 'addAll' constructor, which is what ArrayList, LinkedList, and just about every other list, set, and map in java.util has. Even if it doesn't: List list = new CrazyList(); list.addAll(["foo", "bar"]); not as nice, but still nicer than what we have now, especially if your initial set contains 20, and not 2, items. --Reinier Zwitserloot On Mar 31, 2009, at 17:57, Kris Nuttycombe wrote: > On Tue, Mar 31, 2009 at 9:38 AM, Reinier Zwitserloot > wrote: >> Many reasons for not just having varargs constructors on collections >> API classes: >> >> 1. constructors don't infer generics. >> >> 2. constructors don't make immutables. Even Arrays.asList doesn't. >> This is how you make an immutable list of constants today: >> >> Collections.unmodifiableList(Arrays.asList("foo", "bar")); >> >> that, is, in a word, ridiculous. Even with constructor help, it woud >> become: >> >> Collections.unmodifiableList(new ArrayList("foo", "bar")); >> >> not much help, and arguably even worse. >> > > I was imagining something more along the lines of: > > Collections.immutableList("foo", "bar"). Of course, this is > currently possible to do as a third-party library, so if one is > content with such syntax there's already a solution. > >> It would become, with Joshes proposal: >> >> ["foo", "bar"] >> >> which makes me smile. >> > > Yes, however his proposal does not address the issue of simplifying > the construction of mutable collections with initial contents. Of > course, as the original proposal mentions one can always use anonymous > inner classes (Crazybob's contraption) for this. > > Kris > >> 3. import statements. Okay, that's a small one, but nevertheless. >> >> 4. Implementation is often irrelevant, when the list is immutable >> anyway. Why force people to type ArrayList. For that matter, why >> force >> people to -read- ArrayList? It's just 'A list with no surprises, >> which >> is immutable'. That's easy enough to remember. >> >> 5. varargs are fundamentally broken, though fortunately the proposal >> to address this issue is on the project coin shortlist. >> >> --Reinier Zwitserloot From neal at gafter.com Tue Mar 31 09:22:57 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 09:22:57 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310833i18b18a2eh23a7fee48c94d84b@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1CC9A.8050001@optrak.co.uk> <17b2302a0903310113i321bd7e5r97567a9c8cfbd570@mail.gmail.com> <15e8b9d20903310116j41ea01f7w49957c788a35fe5@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <15e8b9d20903310737u73bea11dgeced4504631b1df1@mail.gmail.com> <17b2302a0903310833i18b18a2eh23a7fee48c94d84b@mail.gmail.com> Message-ID: <15e8b9d20903310922p55605238ia902504cac8a9b7e@mail.gmail.com> On Tue, Mar 31, 2009 at 8:33 AM, Joshua Bloch wrote: > Even if we were to reify generics in a future release, arrays of sets would > remain a bad idea. Arrays are covariant and sets are non-variant. ?The > combination of the two is problematic. ?Currently it isn't even typesafe > (hence the ban on generic array creation). ?With reification of generics, > arrays of sets could be made typesafe, but would still admit the possibility > of runtime errors that would be caught at compile time if you used > List> in place of Set[]. Your comments about arrays interactions with reified types applies to arrays today with ordinary, non-generic types. I understand your desire to provide arrays with less than first-class treatment even with reification and recommend List instead, but I don't think we should be constraining the design space at this time. From jjb at google.com Tue Mar 31 09:55:50 2009 From: jjb at google.com (Joshua Bloch) Date: Tue, 31 Mar 2009 09:55:50 -0700 Subject: Proposal: Collection Literals In-Reply-To: <2771e600903310857rdfe1443tc869486dafaa130@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <17b2302a0903310134p4c1bcb1dredf700c79f9999a4@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> <0AF02B4E-E47E-4CD3-B025-3F0618DFB312@zwitserloot.com> <2771e600903310857rdfe1443tc869486dafaa130@mail.gmail.com> Message-ID: <17b2302a0903310955m3eaace3dwe8e11cd0e8ff50f1@mail.gmail.com> Kris, Actually my proposal was intended to address creation of mutable collections. I should have mentioned this explicitly in the proposal, and will do so. Here's the idiom I recommend. Suppose you want a LinkedHashSet initialized to contain Santa's eight reindeer. This will do the trick: Set team = new LinkedHashSet<>( ["Dasher", "Dancer", "Prancer", "Vixen","Comet", "Cupid", "Donner", "Blitzen"]); I think it looks pretty good! The same idea works for all other standard collection implementations, including maps. Josh On Tue, Mar 31, 2009 at 8:57 AM, Kris Nuttycombe wrote: > On Tue, Mar 31, 2009 at 9:38 AM, Reinier Zwitserloot > wrote: > > Many reasons for not just having varargs constructors on collections > > API classes: > > > > 1. constructors don't infer generics. > > > > 2. constructors don't make immutables. Even Arrays.asList doesn't. > > This is how you make an immutable list of constants today: > > > > Collections.unmodifiableList(Arrays.asList("foo", "bar")); > > > > that, is, in a word, ridiculous. Even with constructor help, it woud > > become: > > > > Collections.unmodifiableList(new ArrayList("foo", "bar")); > > > > not much help, and arguably even worse. > > > > I was imagining something more along the lines of: > > Collections.immutableList("foo", "bar"). Of course, this is > currently possible to do as a third-party library, so if one is > content with such syntax there's already a solution. > > > It would become, with Joshes proposal: > > > > ["foo", "bar"] > > > > which makes me smile. > > > > Yes, however his proposal does not address the issue of simplifying > the construction of mutable collections with initial contents. Of > course, as the original proposal mentions one can always use anonymous > inner classes (Crazybob's contraption) for this. > > Kris > > > 3. import statements. Okay, that's a small one, but nevertheless. > > > > 4. Implementation is often irrelevant, when the list is immutable > > anyway. Why force people to type ArrayList. For that matter, why force > > people to -read- ArrayList? It's just 'A list with no surprises, which > > is immutable'. That's easy enough to remember. > > > > 5. varargs are fundamentally broken, though fortunately the proposal > > to address this issue is on the project coin shortlist. > > > > --Reinier Zwitserloot > > From jlardoint at ilog.fr Tue Mar 31 10:20:09 2009 From: jlardoint at ilog.fr (Jean-Louis Ardoint) Date: Tue, 31 Mar 2009 19:20:09 +0200 Subject: Proposal: Accepting a subclass as an element type in a for loop In-Reply-To: References: <7E2F23A9-6F80-4932-80C4-8D2D9C6F3348@zwitserloot.com> Message-ID: Ok I understand your point about generics. If you have List> foo = someMethodCall(); for ( Set set : foo ) { // You can't do this in java. } I would say you would get a nice error, like what you get if you write O instanceof Set (it's only a proposal for a small feature, not for generics reification) About nulls, there is a good reason to keep nulls. For example if you write Collection foo = new ArrayList; foo.add(null); for (Integer i : foo) m(i); you expect m to be called once with null. If you write Collection foo = new ArrayList; foo.add(null); for (Integer i : foo) m(i); If m doesn't get call with null, it would mean that the behavior of the loop depends on the kind of Iterable that is used. I don't think it makes sense. So, the behavior I propose is that references to null are accepted, so the behavior of the for is independent of the kind of Iterable that is used. I agree that it could be nice to have a syntax to exclude nulls, but this is not related to my proposal. It could be used with regular enhanced for loops. A typical use case for the proposed loop is for analyzing lists of things. For example, if you have a list of statements, and you want to build a symbol table, you can do List statements = ... Map symbolTable = ... For (VariableDeclaration decl : statements) symbolTable.put(decl.getName, decl); // assuming I know there is no null Of course, when you are really doing such things, you'll probably need some other exploration tools, like visitors. Yet when you need just to do some stuff on one kind of objects, it would be handy to have such a loop. --Jean-Louis Ardoint -----Original Message----- From: Reinier Zwitserloot [mailto:reinierz at gmail.com] On Behalf Of Reinier Zwitserloot Sent: Tuesday, March 31, 2009 5:46 PM 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 Mistake in my sample. try List> as an input source. I'll qualify my 'this is too niche' with: I've never, ever, needed that. I can think of many things that follow the same general line of thought that I'd also never need. Why is yours so special? Can you show some relevant use cases? Why is null included in this one? Only because it technically can be cast? If you consider the 'instanceof' syntax sugar on its face value, you should NOT include it. Why is inclusion preferred? Will there be an alternative syntax if I want to exclude null? If not, why is that not a valid use case, but yours is? Some proposals have obvious use cases. Others dont. I would venture a guess that it would be quite useful to prove the merit of the use cases you're trying to solve if you're not absolutely certain you fall into the former category. --Reinier Zwitserloot On Mar 31, 2009, at 17:41, Jean-Louis Ardoint wrote: > You might say that all proposals are very niche, and almost all of > them can be solved by writing some code (you may save some time by > writing a generic comment ?). > > About > List> foo = someMethodCall(); > for ( Set set : foo ) { > // You can't do this in java. > } > > I don't understand your point. A List> should not > contain a Set if you use generics without tweaks. So what > would you expect? > > Anyway, thank you for your comments. > > --Jean-Louis Ardoint > > > > ________________________________________ > From: Reinier Zwitserloot [mailto:reinierz at gmail.com] On Behalf Of > Reinier Zwitserloot > Sent: Tuesday, March 31, 2009 5:16 PM > 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 markmahieu at googlemail.com Tue Mar 31 12:52:54 2009 From: markmahieu at googlemail.com (Mark Mahieu) Date: Tue, 31 Mar 2009 20:52:54 +0100 Subject: Call for proposals is over! In-Reply-To: <49D23678.8070708@sun.com> References: <49D23678.8070708@sun.com> Message-ID: 2009/3/31 Joseph D. Darcy > Greetings. > > Now that it is at least March 30, 2009 in every time zone, with over 60 > proposals submitted and over 1000 email messages sent to the list, the > call for proposals phase of Project Coin is hereby concluded! > > -Joe > > That was fun! When's the next one? ;) Mark From pdoubleya at gmail.com Tue Mar 31 12:55:09 2009 From: pdoubleya at gmail.com (Patrick Wright) Date: Tue, 31 Mar 2009 21:55:09 +0200 Subject: Call for proposals is over! In-Reply-To: References: <49D23678.8070708@sun.com> Message-ID: <64efa1ba0903311255y3e767cdan7d4976540577d58a@mail.gmail.com> > That was fun! ?When's the next one? ;) Agreed. Also, next time, can you all aim at accepting more proposals and call it Project Change? :D Patrick From Joe.Darcy at Sun.COM Tue Mar 31 13:33:36 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 31 Mar 2009 13:33:36 -0700 Subject: Call for proposals is over! In-Reply-To: References: <49D23678.8070708@sun.com> Message-ID: <49D27E20.9010407@sun.com> Mark Mahieu wrote: > 2009/3/31 Joseph D. Darcy > > > Greetings. > > Now that it is at least March 30, 2009 in every time zone, with over 60 > proposals submitted and over 1000 email messages sent to the list, the > call for proposals phase of Project Coin is hereby concluded! > > -Joe > > > That was fun! When's the next one? ;) Have to recover from the first one first ;-) -Joe From develop4lasu at gmail.com Tue Mar 31 13:47:39 2009 From: develop4lasu at gmail.com (=?UTF-8?Q?Marek_Kozie=C5=82?=) Date: Tue, 31 Mar 2009 22:47:39 +0200 Subject: Call for proposals is over! In-Reply-To: <49D27E20.9010407@sun.com> References: <49D23678.8070708@sun.com> <49D27E20.9010407@sun.com> Message-ID: <28bca0ff0903311347q272342cbnb9aa57c88d357e0e@mail.gmail.com> 2009/3/31 Joe Darcy : > > Have to recover from the first one first ;-) > > -Joe > > I feel the same, but while for first time I worked on proposals I'm not satisfied with my results. -- Pozdrowionka. / Regards. Lasu aka Marek Kozie? http://lasu2string.blogspot.com/ From brucechapman at paradise.net.nz Tue Mar 31 13:57:22 2009 From: brucechapman at paradise.net.nz (brucechapman at paradise.net.nz) Date: Wed, 01 Apr 2009 09:57:22 +1300 (NZDT) Subject: Call for proposals is over! In-Reply-To: References: <49D23678.8070708@sun.com> Message-ID: <1238533042.49d283b2ee50f@www.paradise.net.nz> Quoting Mark Mahieu : > 2009/3/31 Joseph D. Darcy > > > Greetings. > > > > Now that it is at least March 30, 2009 in every time zone, with over > 60 > > proposals submitted and over 1000 email messages sent to the list, > the > > call for proposals phase of Project Coin is hereby concluded! > > > > -Joe > > > > > That was fun! When's the next one? ;) > Mark > Joe's email does not mark the end, merely the end of the beginning. The actual hard work is probably just about to start - and not just for Joe!! Bruce From rssh at gradsoft.com.ua Tue Mar 31 14:14:31 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 1 Apr 2009 00:14:31 +0300 (EEST) Subject: late Proposal: Add C-like preprocessing ability for java language. Message-ID: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> Sorry for late, but I was waiting for stars be in correct location for sending this. OVERVIEW: FEATURE SUMMARY: Add C-like preproceeding ability to Java language. MAJOR ADVANTAGE: Possibility implements language extensions, such as sugaring/desugaring, koffein/dekoffein outside of Sun, fix bugs 4411102, 6439965, 4649007 and many others from sun bugs database and increase team building importance for Java programmers by providing ability to any engineer tune life of all team in night ware. Of course, this possibility exists in current version of JAVA, but it's too rare used. Often rewriting of software system from scratch will speed-up economics, which is important for faster recovery from crisis. MAJOR DISADVANTAGE Inaccurate usage of this feature can cause producing of unmaintainable code. ALTERNATIVES: Use external preprocessing tool. EXAMPLES SIMPLE EXAMPLE: System.out.println("file is %s, line is %d\n ",__FILE__,__LINE__); ADVANCED EXAMPLE: ARM Proposal can be implemented on user level without language changes. #define TRY(xt,x,y,z) xt x=null; try{ \ x=y ; \ z ; \ } finally { \ x.close() \ } \ TRY(sqlConnection, cn, dataSource.getConnection(), \ RecordSet rs = \ cn.evaluateQuery("select * from customers where id=:x"\,2); \ while(rs.next()) { printRow(rs); } ) will be desugared as sqlConnection cn=null; try{ cn = dataSource.getConnection(); RecordSet rs = cn.evaluateQuery("select * from customers where id=:x",2); while(rs.next()) { printRow(rs); } }finally{ cn.close(); } DETAILS: No details required. COMPILATION: No changes to compiler required, all is do on preprocessor level. TESTING: We can reuse tested implelementation of C preporcessor. LIBRARY SUPPORT: It would be good add gcc distribution to java. REFLECTIVE APIS: None OTHER CHANGES: None MIGRATION: None COMPABILITY None REFERENCES http://bugs.sun.com/view_bug.do?bug_id=4165111 http://bugs.sun.com/view_bug.do?bug_id=4087771 http://bugs.sun.com/view_bug.do?bug_id=4615070 http://bugs.sun.com/view_bug.do?bug_id=4215781 IMPLEMENTATION PROTOTYPE URL See http://gcc.gnu.org Also exists java-only solutions for embedding http://www.duo-creative.com/chrisb/jpp/ From alexandre.makarenko at free.fr Tue Mar 31 14:37:32 2009 From: alexandre.makarenko at free.fr (alexandre.makarenko at free.fr) Date: Tue, 31 Mar 2009 23:37:32 +0200 (CEST) Subject: Naked dot - accessing object fields through unqualified "." [C1] In-Reply-To: <27255153.4372621238535398832.JavaMail.root@spooler2-g27.priv.proxad.net> Message-ID: <29449897.4372661238535452359.JavaMail.root@spooler2-g27.priv.proxad.net> First, this story is not about IDEs, this story is about Java!!! Second, this is not about fat-finger bugs and not about how tomorrow tools will replace developer's brain ... If you look at all possible troubles one can in with Java today, you will never ever write a single line of code. Now, what is the true reason of this proposal. WHAT FOLLOWS HERE BELOW IS STRICTLY MY PERSONAL OPINION I DO NOT use 'this.' since it completely destroys the nicest notion of scope and context (a part of the object oriented paradigm). By putting 'this.' one makes the compiler's job and a Java code looks like using an old style pointer to C structure all over the program (like Python's self?). It does not prevent developers from bugs neither... Ask a Java developer who uses 'this.' why he/she does so... There will be 3 answers (fix me if I'm wrong) - it is less error-prone (a developer with 6-month experience) - Eclipse puts it automatically (somebody who does not like his job, who types all the day 'this.' followed by Ctrl+Space to see what is on the menu...) - it makes the code more readable Now about the last point. Actually it makes the line you are looking at more readable and not the entire program. This is the point. Today people (not all) start to believe that a code is to be looked at. I think a computer program is to be read like a book (since it is written by humans for humans). With this regard 'this.' is not a friend. >From this point of view using 'Naked Dot' is not much different from 'this.' (unless in the 'Strict mode' as mentioned in the proposal). My hope was to save my eyes from that heavy looking programs making my brain to parse the code and not to read it fluently. Sincerely yours @lex ----- 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 vilya.harvey at gmail.com Tue Mar 31 14:48:09 2009 From: vilya.harvey at gmail.com (Vilya Harvey) Date: Tue, 31 Mar 2009 22:48:09 +0100 Subject: Call for proposals is over! In-Reply-To: <49D23678.8070708@sun.com> References: <49D23678.8070708@sun.com> Message-ID: <6aef848f0903311448m73f700bfo3fe94a1fd162c1cf@mail.gmail.com> Thanks for doing this Joe! I've learnt a lot from this process. It also finally got me to start hacking on the java compiler, something I'd been meaning to do ever since it got open sourced. Vil. 2009/3/31 Joseph D. Darcy > Greetings. > > Now that it is at least March 30, 2009 in every time zone, with over 60 > proposals submitted and over 1000 email messages sent to the list, the > call for proposals phase of Project Coin is hereby concluded! > > -Joe > > From kevinb at google.com Tue Mar 31 15:21:54 2009 From: kevinb at google.com (Kevin Bourrillion) Date: Tue, 31 Mar 2009 15:21:54 -0700 Subject: Proposal: Collection Literals In-Reply-To: <17b2302a0903310955m3eaace3dwe8e11cd0e8ff50f1@mail.gmail.com> References: <17b2302a0903301630w70b9283at4e8f54d1db9c6d57@mail.gmail.com> <49D1D8B8.9030206@optrak.co.uk> <17b2302a0903310151l2980e7c6m75080e3efb01710b@mail.gmail.com> <15e8b9d20903310742p6c04fb67qdc8d9c034cedc436@mail.gmail.com> <2771e600903310756t710e736am9a28e95e337dc703@mail.gmail.com> <17b2302a0903310814y5b6a9addt7a1341e1d105a6f6@mail.gmail.com> <0AF02B4E-E47E-4CD3-B025-3F0618DFB312@zwitserloot.com> <2771e600903310857rdfe1443tc869486dafaa130@mail.gmail.com> <17b2302a0903310955m3eaace3dwe8e11cd0e8ff50f1@mail.gmail.com> Message-ID: <108fcdeb0903311521w2770a903j572008ed364147@mail.gmail.com> On Tue, Mar 31, 2009 at 9:55 AM, Joshua Bloch wrote: > Kris, > > Actually my proposal was intended to address creation of mutable > collections. I should have mentioned this explicitly in the proposal, and > will do so. Here's the idiom I recommend. Suppose you want a > LinkedHashSet > initialized to contain Santa's eight reindeer. This will do the trick: > > Set team = new LinkedHashSet<>( > ["Dasher", "Dancer", "Prancer", "Vixen","Comet", "Cupid", "Donner", > "Blitzen"]); This is 100% the right idea! I'll also note that use cases for prepopulating collections that need to be mutable are very rare compared to the cases for immutable collections and the cases where you don't care (and so immutability is the sensible default choice.) I'd like everyone to consider importing the Immutable collections from our Google Collections Library. Example: http://code.google.com/p/google-collections/source/browse/trunk/src/com/google/common/collect/ImmutableSet.java On top of the advantages cited by Jesse (a few of which are admittedly shared by other alternatives), consider that the memory consumption of ImmutableSet is (size + tablesize), compared to (8 * size + tablesize) for its mutable equivalent (LinkedHashSet)! We wrote these collections with the specific goal in mind that they should be the ideal runtime type for a collection literal. Last point: Josh's proposed feature would allow me to stop using varargs in APIs completely, and avoid the ugly problems involved with them (overload confusion, forcing to the last argument position, having to deal with an array instead of a list (or worse, the 'first, second, rest' problem!) in my implementation, etc. -- Kevin Bourrillion @ Google internal: http://go/javalibraries google-collections.googlecode.com google-guice.googlecode.com From andrejnavodnik at yahoo.com Tue Mar 31 02:04:03 2009 From: andrejnavodnik at yahoo.com (Andrej Navodnik) Date: Tue, 31 Mar 2009 02:04:03 -0700 (PDT) Subject: Proposal: Improved declaration using final keyword of internal method variables and for-loop statement Message-ID: <795553.78251.qm@web50611.mail.re2.yahoo.com> Hi Project Coin members, here is my little proposal for improved declaration using final keyword of internal method variables and for-loop statement. Is it too late? Maybe not. At the time I'm sending this e-mail, in Honolulu, Hawaii, it is still Monday, 30 March 2009. Kind regards, Andrei ----------------------------------------------------------------------- PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0 TITLE: Improved declaration using final keyword of internal method variables and for-loop statement AUTHOR(S): Andrei Navodnik (andrejnavodnik at yahoo.com) OVERVIEW ======== FEATURE SUMMARY: Allow declaration of mixed final and non-final internal method variables in one statement and enable final keyword in for-loop declaration for variables other than index variable. MAJOR ADVANTAGE: Suppose that the developer wants to have as much variables defined as final then if this feature were accepted in the language one major advantage would be to allow shorter syntax of internal method variables. Mixing of final and non-final variables in one declaration statement would be allowed which is prohibited with the current state of the compiler. The compiler either allows all variables to be final or all variables to be non-final. As far as for-loop declaration is concerned, this feature would allow syntax that is more compact (no pollution of scope outside of the for-loop) and "safer" (the size of the list would be assigned to final variable and this value can not be changed inside of the loop). MAJOR BENEFIT: Suppose that the majority of code is written as for (int i = 0; i < values.size(); i++ ) { // ... } then this feature would allow easier refactoring to the optimized style of for-loops for (int i = 0, final n = values.size(); i < n; i++) { // ... } because variable n can not be already defined in the scope either outside or inside of the for-loop. Any such violation would make program uncompilable. According to my benchmarks the later style of for-loops is also slightly faster in client VM. MAJOR DISADVANTAGE: If the feature were accepted then the major disadvantage in my opinion would be slightly more complex grammar which would have to take care of the compatibility with the existing programs. ALTERNATIVES: One of the alternatives to the proposed syntax (see simple example bellow) would be to declare internal method variables in separate statements, for example one statement for all non-final variables and one statement for all final variables. Someone might even argue that syntax where each variable is defined on separate statements is better comparing to the syntax where all variables are defined in one statement. int a, c = 1; final b, d = 4; But, if developer's strategy is to define all read-only variables as final then the alternatives to the proposed syntax for the for-loop are not very nice. One is to declare variable of the size of the list outside of the for-loop declaration, for example final n = values.size(); for (int i = 0; i < n; i++) { // ... } or to declare index variable outside of the for-loop. int i = 0; for (final int n = values.size(); i < n; i++ ) { // ... } EXAMPLES ======== SIMPLE EXAMPLE: If the proposal were accepted then the code below should be valid. Please, compare the proposed syntax with the alternatives presented above. int a, final b, c = 1, final d = 4; for (int i = 0, final n = values.size(); i < n; i++) { // ... } ADVANCED EXAMPLE: No advanced example. DETAILS ======= SPECIFICATION: To support mixed final and non-final internal method variables the grammar should be changed as follows: LocalVariableDeclarationStatement: AllVariablesFinalDeclarationStatement SomeVariablesFinalDeclarationStatement AllVariablesFinalDeclarationStatement: final Type VariableDeclarators ; SomeVariablesFinalDeclarationStatement: Type SomeVariablesFinalDeclarators ; SomeVariablesFinalDeclarators: VariableDeclarator { , VariableMaybeFinalDeclarator } VariableMaybeFinalDeclarator: [final] Identifier SomeVariablesFinalDeclaratorsRest SomeVariablesFinalDeclaratorsRest: SomeVariablesFinalDeclaratorsRest { , VariableMaybeFinalDeclarator } To better support final keyword in the for-loop declaration the grammar should be changed as follows: ForVarControl: AllVariablesFinalForVarControl SomeVariablesFinalForVarControl AllVariablesFinalForVarControl: final [Annotations] Type Identifier ForVarControlRest SomeVariablesFinalForVarControl: [Annotations] Type Identifier SomeVariablesFinalForVarControlRest SomeVariablesFinalForVarControlRest: SomeVariablesFinalDeclaratorsRest; [Expression] ; [ForUpdate] : Expression TESTING: No specific testing is needed to test this feature. LIBRARY SUPPORT: The proposed language feature needs no additional library support. REFLECTIVE APIS: The feature does not affect reflective API's. OTHER CHANGES: The feature does not need other changes. MIGRATION: Existing programs should work without any change. COMPATIBILITY: All existing programs are compatible. BREAKING CHANGES: None. EXISTING PROGRAMS: There should be no impact on existing programs. REFERENCES ========== EXISTING BUGS: RFE has been already filed for this feature, please check internal review ID 1200191. URL FOR PROTOTYPE: There is no prototype for this feature. From Joe.Darcy at Sun.COM Tue Mar 31 15:36:37 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 31 Mar 2009 15:36:37 -0700 Subject: late Proposal: Add C-like preprocessing ability for java language. In-Reply-To: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> References: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> Message-ID: <49D29AF5.80502@sun.com> rssh at gradsoft.com.ua wrote: > Sorry for late, but I was waiting for stars be in correct location for > sending this. > > OVERVIEW: > > FEATURE SUMMARY: > > Add C-like preproceeding ability to Java language. By Pacific time, this proposal is either a day late or a day early ;-) -Joe PS Shouldn't the TRY #define should have "()" around all the uses its parameters, hazards of textual substitution and all. From John.Rose at Sun.COM Tue Mar 31 16:01:43 2009 From: John.Rose at Sun.COM (John Rose) Date: Tue, 31 Mar 2009 16:01:43 -0700 Subject: PROPOSAL: language support for JSR 292 In-Reply-To: <49D013A3.60505@univ-mlv.fr> References: <80FFB064-577D-4CEA-A93A-73C424AAE21B@sun.com> <15e8b9d20903290055p399a724al786f34b8188a62d2@mail.gmail.com> <49D013A3.60505@univ-mlv.fr> Message-ID: <8D7F16CE-69EB-4742-97E4-2B1E88A222BF@Sun.COM> On Mar 29, 2009, at 5:34 PM, R?mi Forax wrote: > John, your proposal doesn't cleanly separate the four parts of the > proposal > thus this is really hard to read (at 2 am :) Hi, R?mi! Everything is numbered #1 to #4, and I tried to keep the strands separate. Are there places where points about #n leak into section #m, m!=n? (Does it look better by daylight? :-) > Correct me if i'm wrong, > the purpose of Dynamic as a type is to > 1) be able to do an invokedynamic wich is receiverless using a dot. > Dynamic x=... > x.m() // is translated to invokedynamic m(Dynamic) Three purposes, which are loosely coupled, hence proposed together: #1 marker for static-syntax sites Dynamic.foo(...). #2 bare reference type with sugar d.foo(...) == Dynamic.foo(d, ...). #4 bare reference type with extra conversions, to make #2 easier to work with. (#3 is for exotic ids.) > 2) to have more conversions from/to Dynamic than from/to Object. That's #4. > Else, I would prefer null not being infered as Void instead > the compiler should raise an error and let the user cast it > to Object, Dynamic etc. I went back and forth on this point while I was working with the code. At first (a) null was implicitly Object, then (b) it caused an error (as you suggest), then (c) it uses a marker type Void. The most correct thing would be (d) to use Neal's marker type Null, but this doesn't exist yet. I settled on (c) as an approximation to (d), because I considered the use case of simulating Java call sites, and null is fundamentally different from any other type; therefore it need to be reified somehow. There is no real downside to using the hack type Void even if (d) becomes available, since the only consumers of those type references are bootstrap methods (MOP machinery), and they will always need some sort of special case for null types anyway; the special casing can be extended to Null and Void deprecated when the time comes. Also, this use of the type Void has no impact on statically typed Java code. Does that help explain? I'll add this to a FAQ on the wiki page. -- John From John.Rose at Sun.COM Tue Mar 31 16:58:19 2009 From: John.Rose at Sun.COM (John Rose) Date: Tue, 31 Mar 2009 16:58:19 -0700 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: >> >> I wrote up something more specific, for the sake of this go-around. >> It is generic and pluggable enough to provide some help with XML >> templating, and SQL construction. >> > > 1. Whith SQL constructions exists a problem: existence of such > template > string parameters provoke programmers to use it instead host variables > in queries, which cause performance problems and SQL injection > problems. Because this is a general template mechanism, and *not* merely a string constructor, it is *not* vulnerable to SQL injection. The string segments and interpolations are processed by different factory methods (appendText vs. append), so an SQL query factory is free to restrict and check the interpolated arguments. See the XML example in the proposal; it shows how a two-phase factory API can first compile and check a template, and then apply it. > So, for example, in many PHP guidelines exists rule do not use "- > strings > for SQL. > > 2. Also, I can't understand, how this construction will be useful > without > multiline strings. You are right; thanks. There is a need at least for C's "foo\n\bar" or "foo\n" "bar". If triple-quote (or some equivalent) happens, it would have to be applied to templated constructors as well as literals, giving the equivalent of here-files. > 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". > 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. -- John From belingueres at gmail.com Tue Mar 31 17:44:29 2009 From: belingueres at gmail.com (Gabriel Belingueres) Date: Tue, 31 Mar 2009 21:44:29 -0300 Subject: late Proposal: Add C-like preprocessing ability for java language. In-Reply-To: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> References: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> Message-ID: Hmm the preprocessor is a very powerful tool. But IIRC (back in the '90s) wasn't one of the initial design goals (strength?) of Java to never have a C like preprocessor? Can it be changed now? 2009/3/31 : > Sorry for late, but I was waiting for stars be in correct location for > sending this. > > OVERVIEW: > > ?FEATURE SUMMARY: > > Add C-like preproceeding ability to Java language. > > ?MAJOR ADVANTAGE: > > ? Possibility implements language extensions, such as sugaring/desugaring, > koffein/dekoffein outside of Sun, fix bugs 4411102, 6439965, 4649007 and many > others from sun bugs database and increase team building importance for Java > programmers by providing ability to any engineer tune life of all team in > night ware. Of course, this possibility exists in current version of JAVA, > but it's too rare used. > Often rewriting of software system from scratch will speed-up economics, > which is important for faster recovery from crisis. > > ?MAJOR DISADVANTAGE > ? Inaccurate usage of this feature can cause producing of unmaintainable > code. > > ?ALTERNATIVES: > > ? Use external preprocessing tool. > > EXAMPLES > > SIMPLE EXAMPLE: > > ?System.out.println("file is %s, line is %d\n ",__FILE__,__LINE__); > > ADVANCED EXAMPLE: > > ARM Proposal can be implemented on user level without language changes. > > #define TRY(xt,x,y,z) xt x=null; try{ ? ? ?\ > ? ? ? ? ? ? ? ? ? ? ?x=y ; ? \ > ? ? ? ? ? ? ? ? ? ? ?z ; ? ? \ > ? ? ? ? ? ? ? ? ? ?} finally { \ > ? ? ? ? ? ? ? ? ? ? ?x.close() \ > ? ? ? ? ? ? ? ? ? ?} \ > > > > TRY(sqlConnection, cn, dataSource.getConnection(), \ > ? ? ?RecordSet rs = \ > ? ? ? cn.evaluateQuery("select * from customers where id=:x"\,2); \ > ? ? ?while(rs.next()) { printRow(rs); } ) > > will be desugared as > sqlConnection cn=null; try{ > ?cn = dataSource.getConnection(); > ?RecordSet rs = > ? ? ? cn.evaluateQuery("select * from customers where id=:x",2); > ? ? ?while(rs.next()) { printRow(rs); } > ?}finally{ > ? ?cn.close(); > ?} > > > DETAILS: > > ?No details required. > > > COMPILATION: > > ?No changes to compiler required, all is do on preprocessor level. > > TESTING: > > ?We can reuse tested implelementation of C preporcessor. > > LIBRARY SUPPORT: > > ?It would be good add gcc distribution to java. > > REFLECTIVE APIS: None > > OTHER CHANGES: None > > MIGRATION: None > > COMPABILITY > ?None > > > REFERENCES > > ?http://bugs.sun.com/view_bug.do?bug_id=4165111 > ?http://bugs.sun.com/view_bug.do?bug_id=4087771 > ?http://bugs.sun.com/view_bug.do?bug_id=4615070 > ?http://bugs.sun.com/view_bug.do?bug_id=4215781 > > IMPLEMENTATION PROTOTYPE URL > > See http://gcc.gnu.org > Also exists java-only solutions for embedding > http://www.duo-creative.com/chrisb/jpp/ > > > > > > > > From Joe.Darcy at Sun.COM Tue Mar 31 18:07:37 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 31 Mar 2009 18:07:37 -0700 Subject: Mgmt query re Integer Literals In-Reply-To: <1238367476.49cffcf4e340f@www.paradise.net.nz> References: <1238367476.49cffcf4e340f@www.paradise.net.nz> Message-ID: <49D2BE59.1090004@sun.com> Hello. brucechapman at paradise.net.nz wrote: > Joe, > > from talking to various people it seems that using underscore as a meaningless > separator (as proposed in the binary literals proposal) inside all integer > literals would be of great value. > > Is the coin management sufficiently flexible to say accept all the integer > literal proposals for further work then produce a blended proposal, or should I > incorporate that feature in my two alternate proposals, or write up another > proposal just for the underscore separator? > > Bruce Since Derek sent in a proposals for underscores, we'll just evaluate that proposal now. -Joe From Joe.Darcy at Sun.COM Tue Mar 31 18:58:07 2009 From: Joe.Darcy at Sun.COM (Joe Darcy) Date: Tue, 31 Mar 2009 18:58:07 -0700 Subject: Opportunity Cost and Proposal Selection Message-ID: <49D2CA2F.1040401@sun.com> 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 neal at gafter.com Tue Mar 31 19:04:28 2009 From: neal at gafter.com (Neal Gafter) Date: Tue, 31 Mar 2009 19:04:28 -0700 Subject: Opportunity Cost and Proposal Selection In-Reply-To: <49D2CA2F.1040401@sun.com> References: <49D2CA2F.1040401@sun.com> Message-ID: <15e8b9d20903311904y15167ecdn60ccaeb95216a41f@mail.gmail.com> Joe- What is your schedule for the selection process? Regards, Neal On Tue, Mar 31, 2009 at 6:58 PM, Joe Darcy wrote: > 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 i30817 at gmail.com Tue Mar 31 19:38:14 2009 From: i30817 at gmail.com (Paulo Levi) Date: Wed, 1 Apr 2009 03:38:14 +0100 Subject: Proposal: Large arrays (take two) Message-ID: <212322090903311938g302a30d9x62643ee98c3df7ff@mail.gmail.com> I like this. I Like it very much. No discussion? From Joe.Darcy at Sun.COM Tue Mar 31 23:46:53 2009 From: Joe.Darcy at Sun.COM (Joseph D. Darcy) Date: Tue, 31 Mar 2009 23:46:53 -0700 Subject: Opportunity Cost and Proposal Selection In-Reply-To: <15e8b9d20903311904y15167ecdn60ccaeb95216a41f@mail.gmail.com> References: <49D2CA2F.1040401@sun.com> <15e8b9d20903311904y15167ecdn60ccaeb95216a41f@mail.gmail.com> Message-ID: <49D30DDD.3000009@sun.com> Hello. Neal Gafter wrote: > Joe- > > What is your schedule for the selection process? > I'd like to have the initial "for further consideration" cut of the proposals sent in after week three to be done in the next several weeks (many proposals to review!). -Joe From rssh at gradsoft.com.ua Tue Mar 31 23:47:07 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 1 Apr 2009 09:47:07 +0300 (EEST) Subject: late Proposal: Add C-like preprocessing ability for java language. In-Reply-To: References: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> Message-ID: > Hmm the preprocessor is a very powerful tool. > But IIRC (back in the '90s) wasn't one of the initial design goals > (strength?) of Java to never have a C like preprocessor? Can it be > changed now? > As I remeber, the initial design goal of Java was be language for writing applets (embeddable client-side dynamic content on web pages). Is this changed now ? > 2009/3/31 : >> Sorry for late, but I was waiting for stars be in correct location for >> sending this. >> >> OVERVIEW: >> >> ?FEATURE SUMMARY: >> >> Add C-like preproceeding ability to Java language. >> >> ?MAJOR ADVANTAGE: >> >> ? Possibility implements language extensions, such as >> sugaring/desugaring, >> koffein/dekoffein outside of Sun, fix bugs 4411102, 6439965, 4649007 and >> many >> others from sun bugs database and increase team building importance for >> Java >> programmers by providing ability to any engineer tune life of all team >> in >> night ware. Of course, this possibility exists in current version of >> JAVA, >> but it's too rare used. >> Often rewriting of software system from scratch will speed-up economics, >> which is important for faster recovery from crisis. >> >> ?MAJOR DISADVANTAGE >> ? Inaccurate usage of this feature can cause producing of unmaintainable >> code. >> >> ?ALTERNATIVES: >> >> ? Use external preprocessing tool. >> >> EXAMPLES >> >> SIMPLE EXAMPLE: >> >> ?System.out.println("file is %s, line is %d\n ",__FILE__,__LINE__); >> >> ADVANCED EXAMPLE: >> >> ARM Proposal can be implemented on user level without language changes. >> >> #define TRY(xt,x,y,z) xt x=null; try{ ? ? ?\ >> ? ? ? ? ? ? ? ? ? ? ?x=y ; ? \ >> ? ? ? ? ? ? ? ? ? ? ?z ; ? ? \ >> ? ? ? ? ? ? ? ? ? ?} finally { \ >> ? ? ? ? ? ? ? ? ? ? ?x.close() \ >> ? ? ? ? ? ? ? ? ? ?} \ >> >> >> >> TRY(sqlConnection, cn, dataSource.getConnection(), \ >> ? ? ?RecordSet rs = \ >> ? ? ? cn.evaluateQuery("select * from customers where id=:x"\,2); \ >> ? ? ?while(rs.next()) { printRow(rs); } ) >> >> will be desugared as >> sqlConnection cn=null; try{ >> ?cn = dataSource.getConnection(); >> ?RecordSet rs = >> ? ? ? cn.evaluateQuery("select * from customers where id=:x",2); >> ? ? ?while(rs.next()) { printRow(rs); } >> ?}finally{ >> ? ?cn.close(); >> ?} >> >> >> DETAILS: >> >> ?No details required. >> >> >> COMPILATION: >> >> ?No changes to compiler required, all is do on preprocessor level. >> >> TESTING: >> >> ?We can reuse tested implelementation of C preporcessor. >> >> LIBRARY SUPPORT: >> >> ?It would be good add gcc distribution to java. >> >> REFLECTIVE APIS: None >> >> OTHER CHANGES: None >> >> MIGRATION: None >> >> COMPABILITY >> ?None >> >> >> REFERENCES >> >> ?http://bugs.sun.com/view_bug.do?bug_id=4165111 >> ?http://bugs.sun.com/view_bug.do?bug_id=4087771 >> ?http://bugs.sun.com/view_bug.do?bug_id=4615070 >> ?http://bugs.sun.com/view_bug.do?bug_id=4215781 >> >> IMPLEMENTATION PROTOTYPE URL >> >> See http://gcc.gnu.org >> Also exists java-only solutions for embedding >> http://www.duo-creative.com/chrisb/jpp/ >> >> >> >> >> >> >> >> > From rssh at gradsoft.com.ua Tue Mar 31 23:53:27 2009 From: rssh at gradsoft.com.ua (rssh at gradsoft.com.ua) Date: Wed, 1 Apr 2009 09:53:27 +0300 (EEST) Subject: late Proposal: Add C-like preprocessing ability for java language. In-Reply-To: <49D29AF5.80502@sun.com> References: <83b707f6ee6db32f14cd0f4258b60655.squirrel@wmail.gradsoft.ua> <49D29AF5.80502@sun.com> Message-ID: <2929ed333562d65dc9102a262b9a2227.squirrel@wmail.gradsoft.ua> > rssh at gradsoft.com.ua wrote: >> Sorry for late, but I was waiting for stars be in correct location for >> sending this. >> >> OVERVIEW: >> >> FEATURE SUMMARY: >> >> Add C-like preproceeding ability to Java language. > > By Pacific time, this proposal is either a day late or a day early ;-) > > -Joe > > PS Shouldn't the TRY #define should have "()" around all the uses its > parameters, hazards of textual substitution and all. > Yes, you are right ;)