HACKER Q&A
📣 sgbeal

Should scripting engines distinguish between "null" and "undefined"?


i'm working on porting/rewriting my language-agnostic scripting engine[^1] from C to C++ and i have a small conundrum:

Do scripting languages really need both "null" and "undefined" values?

i have long liked that JavaScript provides both "null" and "undefined", and have modeled my scripting languages after that since tinkering with them first became a hobby (right at 20 years ago). In the C++ rewrite, however, having both null and undefined would be slightly awkward, in exactly one of the two would require non-NULL (as in C++ nullptr) value, and that just feels odd.

The simplest solution to this is to consolidate undefined/null into the same conceptual non-value and leave it at that. The more complex solution is to make one or the other of them a full-fledged value, with its own memory address, which seems somewhat counter-intuitive. (In this project's C predecessor[^1], both null and undefined have distinct C addresses, and that works well within that framework. It works _less well_ within the rewrite's framework, where _one_ of them will fit quite nicely but the other will require some shoehorning and special-casing).

One of the inspirations for this rewrite is my recent first-time work with the Java Native Interface (JNI), which treats a Java null as a C NULL. That initially bugged me, but in practice it's more comfortable than having a distinct C value representing a Java null. In Java, however, null also fills the roll of "undefined," whereas JavaScript has both (and i rather _like_ that, as the distinction is occasionally relevant and/or interesting... but also doesn't seem game-breaking if they're combined into one concept).

What say you, dear internet, on the matter of having separate "null" and "undefined" values? Yes? No? It depends? (On what does it depend?)

PS: suggestions that it instead be rewritten in Rust will be tactfully ignored.

[^1]: the being-rewritten project is: https://fossil.wanderinghorse.net/r/cwal


  👤 aristofun Accepted Answer ✓
From hi level perspective in JS for me undefined means "this variable/property hasn't been assigned any value yet".

While null - "after variable/property update we explicitly got nothing (from network, file, db etc.)


👤 stephenr
As much as some will proclaim neither is required, I think `null` has genuine use when representing data. It's the data-model equivalent of "no preference"; "use the default"; "automatic"; or even "not applicable". That doesn't mean every field in every object/schema should allow null, but there's definitely a use-case for it.

`undefined` to me sounds like a language/engine internal state that ideally shouldn't be relied upon. Whether that means you treat it the same as `null`, I'm unsure of.

JS obviously has `undefined`, but I think it's rare to actually rely on it specifically as different than null; the biggest specific reliance that comes to mind is polyfilling e.g. `if (typeof window.foo === 'undefined'){...}`...; This pattern could just be inverted `typeof window.foo !== 'function'` but could also be just a simple boolean check, `if (!window.foo){...}`.

PHP has something similar with typed properties that have no initial value set - they start with a state of `uninitialized` (whereas untyped properties without an initial value start with a value of `null`). In this case it really is an internal representation that scripts can't really use - trying to fetch the value of an uninitialized property is an error in PHP.


👤 sgbeal
Update from OP: this conundrum has been resolved. The library in question will have native JSON support once it's ported over from its predecessor, and using JSON effectively from a high-level language requires some way of distinguishing between "property not set" and "property set to a non-value," which the undefined-vs-null distinction is a perfect fit for. It turns out that both null and undefined can coexist in the current model without either requiring a concrete value to distinguish it from the other, so the initial conundrum was not a genuine problem.

Thank you to who helped me work through this.


👤 tlb
It seems rare to make use of the distinction between null and undefined in real Javascript code. It mainly seems useful in debugging: seeing a crash with an undefined value tells you something different than a null value.

👤 wruza
Property existence: key in object, typing `key?: T`

Property no-value: undefined, typing `key: T | undefined`, a default for non-existent properties.

Null: a synthetic unnamed symbol-object-nonobject artifact, arbitrarily used for statuses like n/a, not-yet, multiple-values, #err, not-set, unknown, no-result, no-value.

JSON: got it completely wrong.


👤 throwaway019254
> Do scripting languages really need both "null" and "undefined" values?

Do programming languages really need any of these two?


👤 joshxyz
i would model it in compliance to typescript and sql.

undefined if property does not exist on an object.

null if property exists but value is unset.


👤 compressedgas
You can have any number of sentinel objects.