On the fly I can't think of a reason to return a List<Option<T>>, that's
just ridiculous.
On Friday, July 6, 2012 12:41:26 PM UTC+2, Reinier Zwitserloot wrote:
>
> I'd use annotations for this. If you give me an Option<T>, that's not TOO
> bad, but if you give me i.e. a List<Option<T>>, you're pretty much forcing
> me to jump through awkward hoops.
>
> On Tuesday, July 3, 2012 10:27:57 AM UTC+2, Dale Wijnand wrote:
>>
>> I've found it very useful to design my API, making the intent evident
>> from the type signature ("this method might not have a return value
>> for you").
>>
>> Unfortunately it's a bit verbose and of limited use in Java than in Scala
>> but it still beats ambiguity and having to resort to reading the Javadoc
>> (or, even worst, making assumptions)..
>>
>> Dale
>>
>> On 2 July 2012 23:34, Reinier Zwitserloot <reinierz AT gmail (dot) com>wrote:
>>
>>> On Tuesday, June 12, 2012 8:52:30 AM UTC+2, Dale Wijnand wrote:
>>>>
>>>> The class Tobias is talking about (which I can't believe no
>>>> one mentioned yet, thanks Tobias) is Optional: http://docs.guava-**
>>>> libraries.googlecode.com/git-**history/v12.0/javadoc/com/**
>>>> google/common/base/Optional.**html<http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/com/google/common/base/Optional.html>
>>>
>>>
>>>
>>> Nobody mentioned it, probably because it's frankly unusable in java. As
>>> has been covered before, if you use Option, you _NEED_ closures all over
>>> the place; there needs to be a way to map your type for ANY operation that
>>> runs on a collection of said type, such that you can easily pass a
>>> collection of Option<type> along with a mapping.
>>>
>>>
>>>>
>>>> I also like the use of JSR 305 annotations, which I think work well for
>>>> parameters, while using Optional for return types when not returning a
>>>> value is an expected result (as opposed to an exception case, in which
>>>> case
>>>> I prefer to design the API to throw an exception).
>>>>
>>>> Dale
>>>>
>>>> On Monday, June 11, 2012 10:12:18 PM UTC+2, Tobias Neef wrote:
>>>>>
>>>>> Some of you may be interested that Google Guava also contains a Type
>>>>> to represent optional values http://docs.guava-**
>>>>> libraries.googlecode.com/git-**history/v12.0/javadoc/index.**html<http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/index.html>.
>>>>>
>>>>> I use this approach a lot in the most recent java projects I have done.
>>>>> In
>>>>> my own code this is a nice thing, but in contrast to the scala word we
>>>>> have
>>>>> a lot of places in java which do not follow this pattern. As a result we
>>>>> still have issues with NPEs from time to time.
>>>>>
>>>>> In the most recent version it is also possible to apply a function on
>>>>> the Optional object using the transform function which is similar to the
>>>>> scala 'map' behavior which was described by Dick. Because the
>>>>> guava library is already used in a lot of places, some Java projects will
>>>>> maybe start using this way of dealing with optional values. Another
>>>>> advantage of guava is, that it uses the JSR 305 annotations for static
>>>>> type
>>>>> checking which also helps to avoid nulls. This is especially helpful for
>>>>> methods those methods of the Guava Collections or the Optional type which
>>>>> do not allow null parameters.
>>>>>
>>>>> On Tuesday, June 5, 2012 1:19:52 PM UTC+2, KWright wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 5 June 2012 11:05, Reinier Zwitserloot wrote:
>>>>>>
>>>>>>> On Monday, June 4, 2012 5:09:43 PM UTC+2, KWright wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> This now has alarm bells going off in my head. These (as
>>>>>>>> described) would only make sense if specified at both declaration AND
>>>>>>>> use
>>>>>>>> site, that's an awful lot of boilerplate and ceremony to be added! We
>>>>>>>> already tried the same thing with checked exceptions, and you know how
>>>>>>>> well
>>>>>>>> that succeeded...
>>>>>>>>
>>>>>>>
>>>>>>> Yes, you need to specify both at declaration and use. Like _ANY_
>>>>>>> type. Why does that have alarm bells going off in your head?
>>>>>>>
>>>>>>> String x = "Hello"; //site 1
>>>>>>> System.out.println(x);
>>>>>>>
>>>>>>> public void println(String in) { ... } //site 2
>>>>>>>
>>>>>>> That's perfectly normal, no need for alarm bells.
>>>>>>>
>>>>>>>
>>>>>> Not quite. In addition to the regular type system, we also have the
>>>>>> shadow type systems of annotations and checked exceptions. This would
>>>>>> be a
>>>>>> third shadow system and it *would* add complexity.
>>>>>>
>>>>>> I suspect that Nullity in this form could be internally implemented
>>>>>> through annotations to minimise the effort required, yet it would have
>>>>>> to
>>>>>> follow different rules in the presence of subtyping (more later). In
>>>>>> practice, it would feel a lot more like generics - optional, erased, yet
>>>>>> still part of the type system.
>>>>>>
>>>>>> Nullity is close to variance in this regard. With use-site (Java) or
>>>>>> declaration-site(C#, Scala) approaches both being possible. If I could
>>>>>> statically type Map<K!, V!> when *defining* the class, then using a
>>>>>> guava-esque factory we might have:
>>>>>>
>>>>>> public static final Map<String, Integer> example = Map.of("a", 1,
>>>>>> "c", 2)
>>>>>>
>>>>>>
>>>>>> declaration-site nullity. No extra ceremony or boilerplate in the
>>>>>> client code :)
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>> Then there's the issue of subtyping and the LSP to consider.
>>>>>>>>
>>>>>>>
>>>>>>> No, the 4-nulls thing actually solves this. Technically, you could
>>>>>>> treat [dunno-null] as "? extends String! super String?" if you really
>>>>>>> wanted to, but you can simplify matters considerably by taking nullity
>>>>>>> out
>>>>>>> of the type inheritance system. String is a type, and where inheritance
>>>>>>> is
>>>>>>> concerned, String is just String, and the nullity of it does not enter
>>>>>>> into
>>>>>>> the equation whatsoever; String, String!, String?, String[raw], it's
>>>>>>> all
>>>>>>> the same to the type system. As in, == equals - the exact same. If
>>>>>>> there's
>>>>>>> a mismatch between a type's nullity state and the operation you do on
>>>>>>> it,
>>>>>>> then the compiler will emit an error (you're treating a could-be-null
>>>>>>> as if
>>>>>>> it's never-null, or you're passing a could-be-null to something that
>>>>>>> wants
>>>>>>> a never-null) or a warning (you're doing null-checks on a never-null).
>>>>>>> This
>>>>>>> errors-and-warnings system is like a compiler plugin, it has no actual
>>>>>>> effect on the meaning of any of the code nor of how any of the code is
>>>>>>> compiled, the ONLY thing that it could possibly cause is errors and
>>>>>>> warnings. It's analogous to @Override in that sense. Just
>>>>>>> compiler-checked
>>>>>>> documentation is all.
>>>>>>>
>>>>>>> If you want to be technical about it, nullity is its own tiny little
>>>>>>> non-expandable strictly and statically defined hardcoded type system.
>>>>>>> The
>>>>>>> upshot is that it's all very easy to reason about and there's no risk
>>>>>>> of
>>>>>>> conflicting with existing specs. For example, you cannot write both:
>>>>>>>
>>>>>>> public static void test1(String? foo) {}
>>>>>>>
>>>>>>> public static void test1(String! foo) {}
>>>>>>>
>>>>>>> in the same file, but that would have been possible if these were
>>>>>>> actually different types.
>>>>>>>
>>>>>>
>>>>>> Here's a thought experiment, I have:
>>>>>>
>>>>>> public class Foo { ... }
>>>>>> public class Bar extends Foo { ... }
>>>>>> public void doSomething(List<? super Bar!> xs)
>>>>>>
>>>>>>
>>>>>> What would be a valid argument to doSomething?
>>>>>>
>>>>>> List<Bar!>
>>>>>> List<Bar>
>>>>>> List<Foo!>
>>>>>> List<Foo>
>>>>>>
>>>>>>
>>>>>> This is definitely something outside the current spec, so adding it
>>>>>> would be a mammoth task - possibly the same order of magnitude as both
>>>>>> generics and annotations.
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> It's easy enough to say that String is a subtype of both String!
>>>>>>>> and String?, but it massively changes the Java spec (which only allows
>>>>>>>> subtyping through inheritance). It looks like we'd be in a similar
>>>>>>>> position to having Array[Object] being a supertype of Array[T], and
>>>>>>>> the
>>>>>>>> problems that caused. Then you still have the midas problem if you
>>>>>>>> need to
>>>>>>>> pass a String where a String! is demanded. And how does it work
>>>>>>>> inside
>>>>>>>> collections and generics (especially wildcarded ones)? and through
>>>>>>>> reflection?
>>>>>>>>
>>>>>>>>
>>>>>>> See above - no changes needed whatsoever. There is also no midas
>>>>>>> problem here; just because I use this equivalent of Option somewhere
>>>>>>> does
>>>>>>> NOT mean my code is going to end up with every type in every parameter
>>>>>>> replaced with Option<T> everywhere! Generalized APIs such as List will
>>>>>>> most
>>>>>>> likely roll with dunno-Ts everywhere but this is completely transparent
>>>>>>> to
>>>>>>> ALL nullities: You can pass never-nulls, could-be-nulls, and
>>>>>>> dunno-nulls to
>>>>>>> such an API and it would all work. Maybe you don't understand the midas
>>>>>>> problem? With Option, then I start having List<Option<X>> everywhere,
>>>>>>> severely complicating my API documentation and requiring me to also
>>>>>>> start
>>>>>>> using option. The entire _point_ of the 4-nullity concept is that null
>>>>>>> safety is transparent yet compile-time checked. Contrast to Option,
>>>>>>> which
>>>>>>> is compile-time checked but not transparent, and java's system, which
>>>>>>> is
>>>>>>> transparent but not compile-time checked.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>> public String! turtleA() { return turtleB(); }
>>>>>> public String turtleB() { return turtleC(); }
>>>>>> public String turtleC() { return ...; }
>>>>>> ... continue until you run out of turtles ...
>>>>>>
>>>>>>
>>>>>> Every method below the top one now has to be changed to return a
>>>>>> String! (unless you provide some form of nullity cast). Is this not the
>>>>>> essence of the midas problem?
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> I have no solution for this dilemma, other than introducing an IDE
>>>>>>>>> which exceeds the ascii character set for symbols, and which
>>>>>>>>> introduces
>>>>>>>>> certain keyboard shortcuts to change nullity. But that's an entirely
>>>>>>>>> different can of worms.
>>>>>>>>>
>>>>>>>>>
>>>>>>>> Not just the IDE. You have javadoc, static analysis tools, code
>>>>>>>> coverage, etc. etc.
>>>>>>>>
>>>>>>>
>>>>>>> Nope, those can just use the long-form ASCII symbol that is in the
>>>>>>> actual source file. It's fine in all such tools, but where it gets real
>>>>>>> tedious is in day-to-day edit work, but if your IDE can let you enter
>>>>>>> the
>>>>>>> appropriate nullity state very easily, and render it in an unobtrusive
>>>>>>> manner, you've gotten your 90% in and it's fine then.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> It's a bold solution, to be sure. But the work and complexity
>>>>>>>> required to retrofit it look more complicated than Option[T] at this
>>>>>>>> stage.
>>>>>>>> That's before you even consider composability.
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Hah, just... no. It is not possible to retrofit java to Option<T>
>>>>>>> because that is not transparent; APIs are set in stone, you can't
>>>>>>> change
>>>>>>> them. 4-nullities is transparent which means that's actually an option,
>>>>>>> al
>>>>>>> though it is very complex.
>>>>>>>
>>>>>>> Sure. Retrofitting is *always* harder than getting a clean design
>>>>>> in the first place. This is why C# forked the collections when they
>>>>>> added
>>>>>> generics. I also consider Scala's collections to be a similar fork -
>>>>>> not
>>>>>> just adding option awareness, but also immutability at the root of the
>>>>>> hierarchy and all sorts of monadic goodness. Other such examples are
>>>>>> Google Guava and the totallylazy library. This can happen at the
>>>>>> library
>>>>>> level without requiring sweeping changes to the type system in the
>>>>>> language
>>>>>> spec.
>>>>>>
>>>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Java Posse" group.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msg/javaposse/-/NR37xDf42BgJ.
>>>
>>> To post to this group, send email to [email protected].
>>> 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.
>>>
>>
>>
--
You received this message because you are subscribed to the Google Groups "Java
Posse" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/javaposse/-/alKPZIyxOZUJ.
To post to this group, send email to [email protected].
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.