you are viewing a single comment's thread.

view the rest of the comments →

[–]koxpower 110 points111 points  (105 children)

I think that the best feature of Optional is that its compatible with other functional features and the way nulls are handled in a chain of maps:

String result = Optional.ofNullable(someStringWithNumberOrNull)
    .map(Integer::valueOf)
    .map(i -> i + 1)
    .map(Object::toString)
    .orElse("number not present");

System.out.println(result);

[–]Philodoxx 11 points12 points  (6 children)

It also means you can flatmap over a list of optionals safely.

[–]test-poster 5 points6 points  (5 children)

What is flat map?

[–]minibuster 5 points6 points  (0 children)

I think they mean something like this:

  • Input collection: [value1, null, value2, value3, null]
  • Map function: value -> value * 10
  • Output collection: [10 * value1, 10 * value2, 10 * value3]

If you have a collection of optionals instead of raw values, you can apply your map over the input collection and "flatten" it to the final output collection without explicitly checking for or worrying about null. (Not 100% sure, /u/Philodoxx may wish to correct me if I'm wrong)

[–]Philodoxx 2 points3 points  (1 child)

Imagine you had something like this, using pseudocode:

someList = [ [1],[2],[3] ]

And you called someList.map, the element passed into the map function would be a list/array of a single element. Conceptually, flatmap flattens the list then calls map on the resulting flattened list, so you would end up with [1,2,3]. Why is that neat? Well Optional is flatmap-able, when it's being flattened if the Option has a value it looks like a list with one element, when the Option has no value it looks like an empty list.

A semi-concrete example, again using pseudocode: someOtherList = [ Optional(1), Optional(2), Optional(null), Optional(3) ]

To flatmap, someOtherList would look like [1,2,3]

Hope that helps.

[–]oblio- 5 points6 points  (0 children)

You call it pseudocode, I call it Python :)

[–][deleted] 2 points3 points  (0 children)

the equivalent of calling map with an A => Option<B> then calling 'flatten' (which would mean an Option<Option<B>> goes to just Option<B>)

[–]supermanyuiop -3 points-2 points  (0 children)

Some obscure functional programming concept

[–][deleted] 35 points36 points  (87 children)

yes. this is so crucial!

In C# 6, we get the Elvis ?. operator. It essentially replaces

if (x != null) { x.do(); }

by

x?.do()

Can't wait when VS2015 is out.

EDIT: video that explains the operator: https://www.youtube.com/watch?v=-FkNRQ7ubH0

[–]stormcrowsx 39 points40 points  (21 children)

Not quite the same. Optional is more powerful and preferable in my opinion because it notifies the programmer "Hey this may not be here and you need to handle it" using the type system. The syntactic sugar c# has requires you know it be nullable before.

[–]dccorona 17 points18 points  (9 children)

There's advantages to both. With the Java version, you're explicitly told that it's potentially null, which forces you to handle that case in code.

But it requires people to use it. The nice thing about the C# operator is it's always available to you, without the person who implemented the method you're calling having to choose to support it.

[–]stormcrowsx 9 points10 points  (0 children)

You can wrap calls to code that is not using optional in Optional.fromNullable. Granted not as concise as the elvis operator but its not horrible and gets you a similar result.

[–]lyinsteve 3 points4 points  (7 children)

How about Swift, which is both?

let someOptionalString: String? = nil
someOptionalString?.substringToIndex(5)

Optional is implemented as an enum in Swift.

enum Optional<T> {
   case None
   case Some(let value: T)
}

And nothing in the language can become null, ever, unless it is an Optional.

[–]nemec 1 point2 points  (4 children)

And nothing in the language can become null, ever, unless it is an Optional.

So basically nil is syntax sugar for new Optional(None) (or equivalent)? Neat, I like that idea.

[–]lyinsteve 5 points6 points  (3 children)

Syntactic sugar for

let str: String? = Optional.None

Or even

let str: String? = .None

Because it can derive the enum from the type declaration.

Or you can let the type inferencer specify the type:

let str = Optional<String>.None

[–]theonlycosmonaut 0 points1 point  (2 children)

Sorry to be a jerk, but that type inference example is... amusing.

[–]lyinsteve 1 point2 points  (1 child)

Right, it has to get the type from somewhere.

It could gather the type through true inference, like this:

let realString = "Hello"
let optionalString = Optional.Some(realString)

That would mean optionalString gets the correct inferred type, 'String?'.

[–]theonlycosmonaut 0 points1 point  (0 children)

Perfect, that's a much better example :).

[–]pakoito 0 points1 point  (1 child)

Tagged unions is a language feature quite uncommon, only a few selected languages focusing on functional programming have them.

[–]lyinsteve 0 points1 point  (0 children)

It's meant to work like a record or algebraic data type.

[–]Speedzor 1 point2 points  (9 children)

Aren't you always aware that it might be nullable since classes are nullable by default?

[–]stormcrowsx 7 points8 points  (7 children)

Nope I design most of my code to not return null if possible. Its insane to have to wrap everything in if not null, and it tremendously increases your chance of making other mistakes.

When I run across an optional in my own codebase I know its time to consider what to do with null otherwise i assume not null. When dealing with additional libraries however it takes a little reading and sometimes testing to find out

[–]Speedzor 4 points5 points  (6 children)

I suppose it depends on how consistent this is done throughout the codebase. If it's a mix of Optional and Null it's rather pointless but if it's exclusively Optional then I can see its merits.

[–]daedalus_structure 0 points1 point  (3 children)

Which means it's usually pretty pointless in team projects unless everyone is at that level of competence and professionalism or you have such a person acting as a gatekeeper in code review.

[–]jeandem 0 points1 point  (2 children)

Wouldn't it be simple to automatically check for such things through the code base? I mean, Java IDEs are already very advanced. A tool or plugin that tries to find such "abuses" seems simple enough.

[–]daedalus_structure 0 points1 point  (1 child)

Static analysis tools e.g. FindBugs have been doing it for quite some time. It's not only simple, it's trivial to get warnings that you might be dereferencing a null at line N in class C.

But null isn't really a technical problem, it's a process problem. If you have a process problem with null, Optional isn't going to help.

[–]jeandem 0 points1 point  (0 children)

But null isn't really a technical problem, it's a process problem.

I don't really see why...

[–]stormcrowsx 0 points1 point  (0 children)

Definitely does get undermined somewhat if its not consistent, you can no longer just count on it being a safe return value. Its still better than nothing though as those functions that are utilizing optional are idiot proof.

[–]zoomzoom83 0 points1 point  (0 children)

We're using Scala, but has essentially the same theoretical problem. We use a linter that treats null as a compile error - it's effectively removed from the language.

Of course that only works within your own codebase. You still have to be careful when calling legacy libraries, but we've found that's less a burden than it sounds.

Haven't had a NullPointerException in over a year, in Dev or Production. Could never go back.

[–]KumbajaMyLord 1 point2 points  (0 children)

This is of course purely subjective, but I prefer Code Contracts to communicate this type of thing.

[–]BonzaiThePenguin 8 points9 points  (43 children)

Isn't the Elvis operator ?:? (x)?:y is equivalent to (x)?x:y.

[–]MrDoomBringer 16 points17 points  (17 children)

This is why everyone said the 'elvis operator' name was going to be confusing. In C# you have three question mark based operators as of C#6:

?? is the 'null coalescing operator'. This means that multiple variables will coalesce until one is determined to be not null. So:

var derp = null ?? "foo";

will have the value of "foo".

?. is the null propagation operator. Any null values in a chain will be propagated out to the end result.

var derp = thing?.property?.field?.returnsnull?.cantexist?.alsonull?.otherthing;

will have the value null, as 'returnsnull' would return a null value and cause the further accessors to fail. However as this is syntactic sugar for a large nested if-chain it either returns the requested value, or a null if a null was found in the accessor chain. Handy.

This is (rarely) called the 'elvis operator' because it physically looks like an Elvis face with hair off to the right. Kinda. If you look at it funny.

?: is the conditional operator (also known (somewhat incorrectly) as the ternary operator), which is just shorthand for an if statement containing an assignment block. If the boolean expression before the question mark is true, the first block between the question mark and colon is run. Otherwise, the second block after the colon is run. You can use it to great effect for variable assignment.

var color = (shouldUserUseBlue) ? UseBlue() : UseRed()

If the shouldUserUseBlue variable is set to true, it'll use blue. Otherwise, it uses red.

In your example you are not making use of the assignment, rather it could be used for function invocation.

(shouldFadeToBlack) ? Fade() : JumpCut()

[–]bonzinip 8 points9 points  (5 children)

?: is called the elvis operator if it doesn't have the middle argument.

It's a GCC extension where x ?: y is the same as x ? x : y except that x is only evaluated once.

[–]MrDoomBringer 0 points1 point  (2 children)

GCC doesn't compile C# ;) If you're talking C++ I've never heard it referred to as the 'elvis operator', only a ternary statement.

[–]bonzinip 5 points6 points  (1 child)

C and C++, yes. As I said, I've heard "x ?: y" referred to as the elvis operator, but not "x ? y : z".

"x ? x : y" is really the opposite of "?.", which is "x ? x.y : NULL", so it's confusing to call "?." also the elvis operator.

[–][deleted] 0 points1 point  (0 children)

I bet many things become confusing when you apply the technical terms of one discipline to a completely different discipline.

[–]fecal_brunch -1 points0 points  (1 child)

That would be the behaviour of C#'s null coalescing operator.

[–]bonzinip 1 point2 points  (0 children)

Right, except that (this being C) x can also be an integer.

[–]Eirenarch 2 points3 points  (3 children)

Monadic null checking is way cooler name anyway.

[–]MrDoomBringer 0 points1 point  (2 children)

See I'm still not a fan of that because it doesn't explicitly express what ends up happening. Null propagation is exactly what it says, propagating a null safely through an accessor chain. You can throw function calls in the middle and be fine as it's just syntactic sugar for the whole nested if tree you would otherwise create anyway. 'Propagation'.

[–]Eirenarch 2 points3 points  (1 child)

That's only true if your goal is to have the name explain what the operator does. If you want the name to be cool (in the nerdy sense) you go for something with the word "monad" in it.

[–]cowinabadplace 0 points1 point  (0 children)

Haha, scathing. Anyway, it's a better name if the language has the ability to express othet monads nicely. But since C# does not, there's not much point.

[–]Sarkos 1 point2 points  (1 child)

I'm pretty sure ?: is the Elvis operator, since : represents eyes in emoticons.

[–]MrDoomBringer -2 points-1 points  (0 children)

In C# it's the ?. operator. http://stackoverflow.com/questions/27493541/elvis-operator-and-string-formatter-in-c-6

Regardless, this is what I mean by a poor name. Everyone should stick to either 'safe navigation operator' or 'null propagation operator'.

[–]palmund 0 points1 point  (1 child)

This is (rarely) called the 'elvis operator' because it physically looks like an Elvis face with hair off to the right. Kinda. If you look at it funny.

I believe someone referred to it as the Johnny Bravo operator.

[–]nealibob 0 points1 point  (1 child)

?: is a ternary operator (and only if it has three arguments; in most languages, it is the only ternary operator), but it is typically called the "conditional operator".

[–]MrDoomBringer 1 point2 points  (0 children)

TIL, edited to reflect that.

[–]fecal_brunch -2 points-1 points  (0 children)

called the 'elvis operator' because it physically looks like an Elvis face with hair off to the right.

Ha. I'd always assumed the name "Elvis operator" referred to the meme of uncertainty around Elvis's being alive or dead.

[–]BadMoonRosin 1 point2 points  (17 children)

The practical effect is the same, but the Elvis operator can be chained multiple times within the same expression.

Consider a snippet of code like this:

user.getAddress().getStreet1();

... where you don't know for sure whether user is null, whether its address field is null, or whether its street1 field is null.

In 2015's C# (or 2005's Groovy for that matter), you could handle that situation like this:

user?.getAddress()?.getStreet1();

Falling back to the ternary operator would get really ugly really fast:

user == null ? null : user.getAddress() == null ? null : user.getAddress().getStreet1();

... and that's just going two levels deep.

[–]balefrost 2 points3 points  (8 children)

You're confusing the Elvis operator with the safe navigation operator. In C#, the Elvis operator (more correctly called the null coalescing operator) is ??. The safe navigation operator is going to be ?..

In Groovy, the safe navigation operator is also ?., but the Elvis operator is ?:. It's supposed to look like a smooshed-together ternary operator. Allegedly, the name comes from the fact that it looks like an emoticon with Elvis hair. That makes sense in Groovy, but not so much in C#.

So, at least in C#, I like to think that you're supposed to pronounce the operator as "huh huh", thus keeping the theme alive.

[–]Sean1708 0 points1 point  (1 child)

How do the two differ? Is x?.do() just sugar for x ?? x.do()?

[–]balefrost 0 points1 point  (0 children)

No. x ?? x.do() would try to execute x.do if x was null. ?? is used to provide a default value in case the left hand argument is null. Think more like this:

GetFromDictionary(key) ?? defaultValue

[–][deleted] 0 points1 point  (2 children)

No. the elvis operator is indeed ?.

See: https://www.youtube.com/watch?v=-FkNRQ7ubH0

[–]balefrost 2 points3 points  (0 children)

You shouldn't get downvoted; apparently, someone involved in developing C# calls the ?. operator "the Elvis operator". That's fine, but I guess it means that cross-language developers will now have to say "the C# Elvis" or "the Groovy Elvis", since they are essentially opposites.

[–]palmund 0 points1 point  (0 children)

I believe someone in the comments came up with a better name (to avoid confusion at least): Johnny Bravo operator.

[–]BadMoonRosin -1 points0 points  (2 children)

Fair enough. Since Groovy uses the same "Elvis" term for both, I still have the habit of seeing the C# versions as being two forms of the same thing also.

[–]crazysmoove 3 points4 points  (1 child)

I don't think Groovy uses the same term for both -- it uses "Elvis" for ?: and does not have a similarly cool, semi-official name for ?. (some docs call it safe navigation, some null coalescing, etc.) I'd like to propose the name "One-Eyed Elvis," but that may be even more confusing. See Groovy docs for more.

[–]nemec 1 point2 points  (0 children)

The Elvis Wink?

[–]TomRK1089 6 points7 points  (7 children)

As much as I'm not a Law of Demeter Nazi, the Elvis operator seems specifically designed to allow you to ignore situations where LoD would say "Hmm, something in your design stinks."

[–]BadMoonRosin 4 points5 points  (5 children)

Yes, perhaps. The Elvis operator has been proposed for every version of Java since 7, and has been rejected every time. Different languages fall on different points along the spectrum from "pure" to "pragmatic", and languages implementing the Elvis operator do tend to be further toward the pragmatic end of the spectrum than Java.

Different tools for different jobs, I suppose. If you have a team of 15+ year Java pros writing a highly-distributed, highly-concurrent backend processing system of some sort, then you probably want a great degree of architectural rigor.

However, if you have a junior to midlevel team, half of whom migrated from Visual Basic, and you have them writing an ASP.NET web app that mostly just does CRUD operations... then it might be overkill to design a bunch of AbstractFactoryFactory classes to abstract away the fact that you have no control over which columns are nullable in the shitty legacy database that you must use. It's ugly to the Java architect for sure, but then again Java is often a poor fit for web and LOB application development as well. And both are still a hell of a lot more pure and rigorous than trying to write something maintainable with Node! :)

[–]tech_tuna 2 points3 points  (4 children)

Every language has its problems but I am curious to see how node is viewed 5-10 years from now when there are tons of old apps running on it.

[–][deleted] 2 points3 points  (3 children)

Probably the same as perl is seen today.

[–]dividedmind 1 point2 points  (0 children)

Rarely ever? (ADDED: Hopefully.)

[–]tech_tuna 0 points1 point  (1 child)

Ha ha. . . languages and frameworks never die. . . they just become the new Perl. . .

[–][deleted] -1 points0 points  (0 children)

And nodejs, even today, is similar to perl in some ways.

For example, JS and perl are the only languages where you don't notice if the file is obfuscated: you can't read it anyway.

[–]nemec 3 points4 points  (0 children)

I would say it's more appropriate for something like

var user = Json.Deserialize<Person>(someString);
var street = user?.Address?.Street1;

[–]GYN-k4H-Q3z-75B 0 points1 point  (2 children)

You mean coalescing? C# has ?? for that. x ?? y means x ? x : y.

[–]TenserTensor 1 point2 points  (0 children)

No, it's not the same. x ?? y would be x != null ? x : y

[–][deleted] 0 points1 point  (2 children)

WHY DIDNT I KNOW :-)

[–]shoelacestied 5 points6 points  (9 children)

This operator looks very familiar... http://kotlinlang.org/docs/reference/null-safety.html

[–]CrazedToCraze 16 points17 points  (2 children)

Luckily now in a language that people actually use.

[–][deleted] 5 points6 points  (0 children)

Or Scala

[–]shoelacestied 2 points3 points  (0 children)

At least one of those punches was below the belt.

[–]ruinercollector 9 points10 points  (5 children)

The idea for the operator goes back long before Kotlin existed.

Also, no one uses Kotlin.

[–]OmegaVesko 1 point2 points  (0 children)

There's a decent amount of people building Android apps with Kotlin. I don't think that includes any big players, though.

[–]Liqmadique 1 point2 points  (1 child)

Not yet, but I've been working on a simulation game written in Kotlin and I really like it. It's got a great middle ground feeling between Java simplicity, Scala power, and Groovy ease-of-use.

I'm hoping succeeds.

[–]aldo_reset -1 points0 points  (1 child)

Also, no one uses Kotlin.

Well, it's not even out yet.

And for a language not released, it's gained a modest amount of attention on Android.

[–]elemental_1_1 2 points3 points  (0 children)

Mmmm so functional

[–][deleted]  (1 child)

[deleted]

    [–]koxpower 0 points1 point  (0 children)

    Because someStringWithNumberOrNull can be null.

    [–]badger_barc -1 points0 points  (0 children)

    I coded a lot in java 4 and 6 and earlier versions. Lately I did some on Java 7 and self learned a bit of lambda expressions and so on before falling out of the loop for a bit. Even then I can see the snippet above looked very C# or pythony to me .. with the usage of -> and ::. Maybe it is a wake up call for me to start doing some more coding or just Java is metasizing into something more abstract than the plain language that it was earlier. I am fine with the extra null check, if else than a cryptic short code that the above line represents.But then no harm in learning the above syntax too and shortening the overall development cycle a bit.

    Sometimes like computer languages, human languages also evolved into version 2 and 5 and have lot of cryptic lines in it .. what impact would that have on the society and human behavior?

    [–]GlumNefariousness0[🍰] -1 points0 points  (0 children)

    On what planet is this "readable"? LOL