Existential operator (was: ||= is much needed?)

Jeremy Ashkenas jashkenas at gmail.com
Tue Jun 19 10:34:16 PDT 2012


Sorry -- an old inbox filter caused me to miss this...

There were a couple of questions asked in the thread, but I think it might
be helpful to summarize the overall rationale first.

The existential operator in CoffeeScript (?) is intended to make it easier
to ask questions about whether values exist. And to do so in different
circumstances where telling the difference might be useful: as a postfix,
as a binary operator, as a chained accessor, etc...

The existential operator conflates null and undefined because both are the
way to say "no value" in JavaScript. While it's entirely possible to define
a JS api that behaves differently when you pass it null instead of
undefined, doing so is almost certainly a bad idea. Long-time JavaScripters
will tell you that they mean two different things: undefined is a value
that has never been created whereas null is a value that has explicitly
been removed -- in practice, that distinction is only ever useful for
debugging ... you really don't want your code semantics to care about *how*
a value came to not exist -- just that it does exist or doesn't.

So, given that premise, the operator allows you to ask questions about
existence in the following ways:


Does the object exist?
object?

Does the property exist?
object.property?

Give me the object if it exists, otherwise give me the other value.
object ? other

Assign the property only if it doesn't already exist.
object.property ?= value

Call the method if it exists.
object.method?(value)

And finally, what we're discussing here: Continue accessing into the object
only if the property exists.
object.property?.other.properties.go.here

I'm afraid that I don't quite follow Allen's reasoning from the comments in
the previous tickets -- whether it's an object or a property is expected to
exist isn't quite the point ... you want to be able to handle either case,
or both at once, with equal ease.

"I was trying to illustrate a possible issue with your semantics when the
existence of a property is conditional but the object that would have the
property is expected to exist."


If the object may not exist: `obj?.property` If the property may not exist:
`obj.property?` If both may not exist: `obj?.property?`

If ES.Next just does `?.` and not `?()`, that'll work, but will make it
impossible to have method calls take part in chains of accesses.

Allen asks about when you would want to write `foo?.bar()`

... the only use case I can think of is when `foo` may or may not be
defined, and you know that if it *is* defined, it's going to have a `bar`
method on it, and if it *is* defined, you want to call `bar` for its side
effects. A bit far fetched. The far more common case is:

options.success?(response)

... if the user passed a "success" callback, call it.

I hope all that reasoning is first-principles-y enough. For what it's
worth, there is one aspect of the existential operator that I'm not
satisfied with and still want to change: How the check is stricter when
you're calling a function: `func?()`.

Everywhere else in the language, `?` means existence (not null or
undefined) -- but when used to call a function, the check ensures that the
value is callable as well. In a DWIM sense, this makes sense, because the
only things you'd ever want to try to call in JavaScript must be callable
... but I think it's strange that the meaning of "existence" alters itself
just for this use case. I opened a ticket talking about rolling it back to
"null or undefined" semantics here:

https://github.com/jashkenas/coffee-script/issues/2315

Cheers,
Jeremy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120619/9a7cc50a/attachment.html>


More information about the es-discuss mailing list