nil, nothing, and notset
One of the more nagging elements of Java programming (and programming in general) is that there is a coarseness to the representation of the conditions nil, nothing, and notset. In Java, one typically uses null
to represent all three of these conditions and the semantics for the actual meaning lies in the secret incantation of its usage. While playing around with my hobby language Jaka I felt that there could be a finer way to deal with these conditions using a set of objects known as object references.
nil
In Jaka, nil is used to represent an object that has no possible value. Since, Jaka is built around the Cons data structure, the really only idiomatic usage of nil is for its termination. However, there are conceivably other instances where “no possible value” could come into play. Of all of the object reference types, nil is the only that an object can be explicitly set.
notset
While nil represents the case where an object can have no possible value, notset describes an object whose value has never been defined. When an object is defined without a value it is implicitly marked as notset. Jaka is designed such that any defined objects are immutable, so it is useful to distinguish those that have not been set.
(def x)
x => gives notset
(def y x) => error condition, x was never set
But the real win is when you access a map with a key that was never set:
(def m {a 1 b 2})
(get m a) => 1
(get m c) => notset
nothing
Jaka distinguishes between an object having no possible value, an unknown value, and with nothing, the non-existence of an object. One of the driving goals of Jaka is to eliminate needless earth-shattering exceptions. Most languages will choke if an undefined variable is even referenced, but Jaka will happily assign it as nothing and move on. What this means to something like addition is TBD, but for something as fundamental as equality it’s a no-brainer.
(def x 2)
(is x z) => z was never defined, so it's "value" is nothing and the equality check is false
Of course, if you try to check the equality of two nothing objects a hole in the space-time continuum is ripped opened.
-m
7 Comments, Comment or Ping
Ola Bini
Nice thinking – I like it a lot and might steal it for my language Ioke. =)
Oct 15th, 2008
fogus
Thanks for commenting.
I have been following your Ioke project via your blog, twitter, and github activities, I look forward to a useable implementation. As for stealing; my ideas are open for theft and ridicule… usually it’s the latter, but it would be nice if the former happened from time to time also. ;)
-m
Oct 15th, 2008
Simon
Won’t the proposed semantics of nothing lead to very hard to find bugs stemming from something as simple as a typo (an annoyance in dynamic languages as it is)?
When is the best use-case for nothing assuming a correct program? The best I can come up with are shenanigans with (dynamic) code loading/importing.
I like notset though. Will functions such as hash look-up return notset on fail?
Oct 15th, 2008
fogus
I suppose with
nothing
more thought is required to specify a precise semantics. That being said, I still believe it to be a good idea to enumerate nothingness explicitly rather than through the normal ad-hoc measures. I see how class of bug you describe can be insidious, but is it any more so than the typo variable name? Maybe not… if I can implement it in a smart way.I hadn’t thought of how hashset use case, I was mainly considering the cases where things like -1, null, or MAXINT are used to indicate notset but fail horribly on the edge cases where those values actual occur.
The main goal is explicit meaning over ad-hoc.
Thanks for posting! -m
Oct 15th, 2008
Greg M
Surely you’re not implementing a functional language in this day and age without support for algebraic datatypes or near equivalent?
Assuming you have that basic feature, you don’t need (hence shouldn’t have!) a universal null value at all. Make libraries like Haskell’s Maybe and Either and roll your own type parameter for Either when you need to.
Oct 16th, 2008
Greg M
Rereading…
It looks like you’re nearly getting it right, but you’ve ended up with an undiscriminated union. I think it’s the confusion that causes that’s leading to the proliferation of new values.
Oct 16th, 2008
fogus
Greg M, Thanks for the comments. It’s interesting comments like yours that will get me motivated to solidify my thought processes. That being said, I am not sure that a tagged union is the way that I wish to go, I may opt for the untagged lot and leave it up to the program logic to deal with the implications (perhaps through multimethod support). It’s up in the air at the moment and I suspect the answer will fall out as I go. -m
Oct 16th, 2008