On Oct 15, 3:04 pm, "Viktor Klang" <[EMAIL PROTECTED]> wrote: > This expands to: > > List?<X?> list = someMethodThatReturnsAStringList(); > list.add("foo");
No; it doesn't. The above means that 'list.add(null);' should be legal. This is a meaningful property of a type, but it does come with caveats. Specifically, if the 'someMethodThatReturnsAStringList' method returns a list that does not allow nulls, this should be a compile-time error. There's really no way that I can see to get around the notion that you need 3 different properties in generics parameters: A. Definitely allows null, (benefit: Can write nulls in) B. Definitely does not allow null (benefit: No need to null-check when reading) C. Don't know / Don't care if its allowed (benefit: Accept anything) Because the whole point, in a sense, is to eliminate null checks as much as possible, it seems fundamentally bad to ADD situations where you need to perform null checks (which is what you'd do if you tried to e.g. combine B and C, for example). that's what I meant. Now, 3 types might be acceptable, but syntax is definitely an issue. ESPECIALLY if non-null becomes the default; there are two different more nully options, so you need 'nully' and 'even more nully'; using '?' and '??' seems kinda wrong, and the ? is used a lot more in java than the !, which makes it hard to use ? or even ??. I'd say it's pretty bad to let parser architecture dictate syntax, but its undeniable that suffix-! for non-null, suffix-? for most definitely allows null, and -nothing- to indicate 'don't know/care' is easiest on the parser and thus easiest for tools out in the wild to adapt this change, and easiest for the tutorials. It's not easiest on the eyes once everyone's used to it, which is a pretty big problem, but for now it's the front-runner for me. > > Whis is exactly (I don't care wether list is null or String, and if it > contains Xs or null) what you said. > > > > > in such a way that the method can return either a list of strings-or- > > nulls, or a list of definitely-not-null-strings. > > > Eventhough, given the only thing it does is add a non-null string, it > > doesn't matter. > > > I'm pretty much positive not being able to do that makes this feature > > very stupid. > > Reinier, that's an opinion, and not an argument. > > I'd like to continue this discussion, so it'd be nice if more people join in > with ideas, questions, etc. > > > > > On Oct 14, 4:49 pm, "Viktor Klang" <[EMAIL PROTECTED]> wrote: > > > I don't like the possibility to not specify nullness. > > > > Let's say that ? is implicit > > > > List<String> = List?<String?> = (a list with Strings or null) or null > > > > List!<String!> = a list with strings > > > > List<String!> = (a list with Strings) or null > > > > List!<? extends String> = a list with (subtypes of string or null) > > > List!<?! extends String> = a list with subtypes of string > > > List!<? super String> = a list with (supertypes of String or null) > > > List!<?! super String> = a list with supertypes of String > > > > List?<? extends String> a = ... > > > List!<? extends String> b = ... > > > > a = b is legal (since they have the same generics signature) > > > b = a is not legal since a can be null > > > > I haven't really thought this through, I'm just exploring the > > possibilities. > > > > /Viktor > > > > On Tue, Oct 14, 2008 at 2:54 PM, Reinier Zwitserloot <[EMAIL PROTECTED] > > >wrote: > > > > > Introducing ! as definitely never null, and ? as might be null, in an > > > > Either/Maybe kind of construct, doesn't really help, unless you are > > > > willing to throw out the ability to make a list/map/anything else with > > > > generics in it which will take arbitrary type input; it doesn't matter > > > > if the type you're passing in is of the 'never null' or of the 'maybe > > > > null' or of the 'I don't know' variety. Throwing that out seems like a > > > > death sentence for the entire feature; the point is ease of use, and > > > > getting rid of pointless null checks, not conflagrating the issue by > > > > adding a bunch of neccessary null checks just to satisfy the compiler. > > > > > In other words, you need to be able to say: > > > > > List< AAAAA > list; > > > > > where AAAA is something that says: "Strings, but the nullable or non- > > > > nullable nature of them is irrelevant; I'll only be reading from them, > > > > and I'll do explicit null checks when I do, so I just don't care, and/ > > > > or when I write to it, I'll definitely write non-null." > > > > > You also need: I do care; only one particular variant of null-allowed > > > > is okay here. > > > > > This is actually one less scenario than generics (which splits up the > > > > first scenario into: I'll only be writing into it, so I'll give an > > > > type range going from Object to the thing I'll be putting in, say, > > > > Integer, and you can then feed it a List of Object, Number, or > > > > Integer, it'll all be good, and into a second scenario: I'll only be > > > > reading from it, so I'll give a type range going from, say, Number, up > > > > to whatever, and I'll only be reading Numbers out, so if you give me a > > > > Number, or Integer, or Double, it'll be all good. In our case we can > > > > combine these two situations into stating that: When reading, you get > > > > possibly-null out, and when writing, you must never write nulls in. > > > > > I think your suggestion to use ? to indicate 'definitely allowed to be > > > > null' and use the lack of a marker as 'we don't know if null is > > > > allowed here or not' might make the concept a lot simpler to grok > > > > (though it would force you to add a marker to every type you state in > > > > your entire codebase to do it 'right', which I envision would get > > > > annoying fast). You'd then have: > > > > > ! = Definiitely not null. > > > > ? = Definitely allowed to be null. > > > > (nothing) = We don't know, so to be safe, when reading, you get ?, but > > > > when writing, you must write in ! - that can't go wrong. > > > > > So, you'd get: > > > > > List!<String> listA; // must only add non-nulls, but when reading > > > > elements out, must check for null. > > > > List!<String?> listB; //when reading, you must still check for null, > > > > but you're allowed to write null into it as well. > > > > List!<String!> listC; //must only add non-nulls, and when reading, you > > > > get String!s out, so no need for null checks. > > > > > listA = listB; //okay > > > > listA = listC; //also okay. Hey! That's nice! > > > > listB = listA; //not okay > > > > listC = listA; //also not okay > > > > listB = listC; //duh - not okay > > > > > Of course, if your generics type has an unnamed type with a bound, you > > > > still get the funky ?! and ?? syntax, and you also still get the extra > > > > leniency: > > > > > List!<? extends Number> listA; //can't add, but when reading, must > > > > check for null. > > > > List!<?? extends Number> listB; //can't add, but when reading, must > > > > check for null. Same as listA. > > > > List!<?! extends Number> listC; //can't add but when reading, no need > > > > for null-check. > > > > > listA = listB; //okay > > > > listB = listA; //okay - contrast to above, where it wasn't. > > > > listA = listC; //okay > > > > listB = listC; //okay - contrast to above, where it wasn't. > > > > listC = either; //not okay. > > > > > And the most complicated case, super: > > > > > List!<? super Integer> listA; //write Integer!, read Object? > > > > List!<?? super Integer> listB; //write Integer!/Integer/Integer?, read > > > > Object? > > > > List!<?! super Integer> listC; //write Integer!, read Object! > > > > > note that listA and listC aren't quite the same, due to the fact that > > > > you can read from ? super X bounds, whereas you can't write to ? > > > > extends Y bounds. > > > > > assignment compatibility: same as in the String! vs. String? vs. > > > > String case. > > > > > Grokking this might be easier, and being compatible with existing java > > > > code is way easier (no marker = dunno), but there is the issue of ! > > > > and ? showing up *EVERYWHERE*: > > > > > public Integer? combineHashes(List?<?!> list) { > > > > if ( list == null ) return null; > > > > Integer! hash = 0; > > > > for ( Object! x : list ) hash ^= x; > > > > return hash; > > > > } > > > > > Does that look okay to you? If it does, this might be worth the > > > > trouble. > > > > > On Oct 14, 9:52 am, "Viktor Klang" <[EMAIL PROTECTED]> wrote: > > > > > Actually, I think non-nullness could be simplified if you change the > > way > > > > you > > > > > view it. > > > > > > if ! indicates the type <a string value> > > > > > and ? indicates the type <Either<String!,null>> > > > > > > Clearly, > > > > > > 1) casting a ! to a ? is not possible, a type conversion needs to > > take > > > > place > > > > > 2) casting a ? to a ! is not possible, a checked unboxing needs to > > take > > > > > place (assuring that only the left path of the either is taken for > > the > > > > > assignment) > > > > > > Can this simplify the non-nullness problem? > > > > > > Translating all reference == to .equals is a good idea. (reference > > > > equality > > > > > is horrid) > > > > > > I agree that JVM changes are freaking people out, and Sun is being > > > > childish > > > > > in their efforts to slow JVM development down to a grinding halt. > > > > > > On Mon, Oct 13, 2008 at 11:13 AM, Reinier Zwitserloot < > > > > [EMAIL PROTECTED]>wrote: > > > > > > > Okay, most of those aren't low hanging fruit. I've spent the past > > week > > > > > > working out specifically how to translate from source to source and > > > > > > its just too difficult for many of the changes I had in mind. CICE, > > > > > > rewiring == to use .equals, and value classes are really the only > > big > > > > > > ones that 'work'. > > > > > > > I'll explain the insane complexity of non-nullness just as a single > > > > > > example to show how extraordinarily difficult being compatible with > > > > > > java (even on the class file level) is: > > > > > > > non-nullness seems like a simple thing to add. For arguments sake, > > > > > > lets say that a standard type is nullable, and a suffix ! indicates > > > > > > never null. (I know the prevailing attitude is that non-null should > > be > > > > > > the default, and I sort of agree with this, but its easier to > > explain > > > > > > the difficulty this way, so bear with me. Its easy to see that if > > you > > > > > > can make '!' work, then going the extra step and making that the > > > > > > default, and '?' as a marker to indicate nullity, is trivial, so it > > > > > > doesn't really matter which one of the two gets proved to be nearly > > > > > > impossible to implement). > > > > > > > So, here's the ! marker in action: > > > > > > > List!<String!> list = new ArrayList<String!>(); > > > > > > list.add(null); //compiler error; list contains 'String!', so null > > > > > > is not allowed. > > > > > > list = null; //compiler error; list is of type List!, so may not > > be > > > > > > null. > > > > > > String! foo = list.get(0); //okay > > > > > > String bar = list.get(0); //okay; returns a String! but that is > > > > > > assign-compatible with String. > > > > > > String x ="foo"; > > > > > > list.add(x); //not okay. x might be null. > > > > > > list.add((!)x); //okay. (!) is shorthand for 'throw NPE if > > > > > > expression is null'. > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to javaposse@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/javaposse?hl=en -~----------~----~----~----~------~----~------~--~---