29

There are many people who think that the concept of the special value null (as it is used in lanuages like C, Java, C#, Perl, Javascript, SQL etc.) is a bad idea. There are several questions about this on SO and P.SE, such as Best explanation for languages without null and Are null references really a bad thing? .

However, I could not find any language that does without them. All the languages I'm familiar with have null, or something similar (e.g. "undefined" in Perl).

I realize that proably every language needs some way to express "absence of a value". However, instead of having "null" or "undefined", this can also be made explicit by using something like Maybe (Haskell) or Optional (Guava). The principal difference to having "null" or "undefined" is that an object can only have "no value" if it has a specific type (Maybe, Optional...). In contrast, "null"/"undefined" is typically a valid value possible for every type.

Are there any languages that do not have nullor a similar concept in this sense?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
sleske
  • 81,358
  • 34
  • 189
  • 227
  • Pointers are a bad idea, not nulls. In Perl, it is impossible to create a null reference or a dangling pointer. In many modern languages, it is also impossible to create a null pointer or a dangling one. – shawnhcorey Jan 23 '15 at 14:33
  • Unless the language is scoped to handle finite states, I don't think "null" would be avoidable. The need of representing an absence or lack of information arise pretty quickly. You could always have an "empty" value for each type that you create but then it would be more practical to only have a null type common to all – Pedrom Jan 23 '15 at 14:34
  • 2
    Well, the usual recommendation is to make the "absence of data" explicit. Something like `Maybe` in Haskell, or `Optional` in Guava. I'll edit the question. – sleske Jan 23 '15 at 14:41
  • 1
    Empty should be a state of a variable, not a value it can have. You should not be able to pass it to a subroutine or get it back as a return value. The lack of valid data should be an exception. – shawnhcorey Jan 23 '15 at 16:41
  • Well the difference between other representation of absence and null is semantic and I believe there are several laguange that don't have nulls in the strictly sense of the word. Scheme comes to my mind since it uses an empty list '() to indicate void. – Pedrom Jan 23 '15 at 16:41
  • @shawnhcorey "The lack of valid data should be an exception." I think it depends. If you are modelling a contiguos data structure you definetly want to know which cells are empty which ones are not. So a getter for a specific index have to return some sort of empty value to indicate that – Pedrom Jan 23 '15 at 16:45
  • 4
    I'm confused, didn't you answer your own question by mentioning Haskell? – svick Jan 23 '15 at 17:32
  • @Pedron, it should provide a test for empty elements, similar to Perl's `exists`. See http://perldoc.perl.org/functions/exists.html – shawnhcorey Jan 23 '15 at 18:16
  • @svick: I don't know, I don't really know Haskell :-). Just heard about `Maybe`. Also, Haskell has [Bottom](https://www.haskell.org/haskellwiki/Bottom), which *seems* similar to `undefined` in other languages. – sleske Jan 23 '15 at 18:52
  • @sleske Bottom is very different from `undefined`, because you can't for example have a function that returns `True` if its parameter is bottom and `False` otherwise. It's basically a lazy exception: if a function tries to look at it, it also has to return bottom itself. (I *think*.) – svick Jan 23 '15 at 20:52
  • 3
    brainf*ck does not have `null` or much of anything really. – rossum Jan 31 '15 at 16:04
  • BASIC (Not VB but the original dialect that was invented for mainframes); FORTRAN IV and earlier; Cobol (early versions). – Klitos Kyriacou May 17 '17 at 13:03
  • @KlitosKyriacou: Care to add that to the top answer below, as an edit? Thanks! – sleske May 17 '17 at 13:09
  • 1
    There are several comments above which ignore the whole point of doing without nulls. It is not just about null pointers, but the fact that it is _impossible_ to have the program crash if something is null when you assumed it is not. Eg. in Perl, you can point to a dictionary value you _think_ should be present, or get a value from db thinking that a user has a surname. In Haskell, you cannot do such mistake. Also note that many languages with similar optional constructs still allow one to wrap a null there without compiler complaining. – EdvardM Nov 21 '17 at 16:40

4 Answers4

35

Here's an incomplete list of languages that are null-safe in the sense that they don't have any non-nonnullable types:

  • Dart (2021): Has optional types with ? syntax.
  • C# 8 (2019): Has opt-in "nullable reference types".
  • Kotlin (2015): Has optional types with ? syntax.
  • Pony (2015). Uses union type where one of the types is None.
  • Swift (2014): Has optional types with ? syntax.
  • Crystal (2014): Does have nil, but prevents all null pointer exceptions at compile-time.
  • Hack (2014): Has optional types with ? syntax.
  • TypeScript (2012): Has union types that can have undefined or null as a variant.
  • Elm (2012): Has union type Maybe.
  • Ceylon (2011): Has optional types with ? syntax.
  • Rust (2010): Has optional type Option.
  • Fantom (2005): Has optional types with ? syntax.
  • F# (2005): Has union type Option.
  • Nice (2003): Has optional types with ? syntax.
  • Netlogo (1999) has no type null
  • OCaml (1996): Has union type option.
  • Haskell (1990): Has union type Maybe.
  • Standard ML (1990): Has union type option.
  • Tcl (1988)
  • Erlang (1986)
  • Prolog (1972): A logical variable stands for "anything at all". There is no concept of "null" or "undefined".

Feel free to complement the list. The years represent the first public release.

Waqar
  • 45
  • 1
  • 7
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • PHP has nullable type hint since 7.1 (http://php.net/manual/en/migration71.new-features.php) – devsmt May 09 '18 at 09:39
  • 4
    Kotlin is a bit of a stretch. It supports null, but it differentiates between nullable types and non-null types. It does, however, have a concept of null – Zoe Aug 07 '19 at 09:56
  • 1
    If just wrapping null in an "optional" type is good enough to be on this list, why is the list so limited? Wouldn't even C++ be on it with `std::optional`, or java for that matter? – swalog Mar 08 '21 at 10:46
  • @swalog C++ and Java still have pointer and reference types which cannot be declared non-null (using just the type system). This list includes languages which don't have such types (or, as is the case with C#, allow opting out from such types using compiler options). – Emil Laine Mar 08 '21 at 13:54
  • 7
    Somehow I have the feeling that this answer misses the point of the question. It equates the concept of `null` with option types. Option types are necessary for representing certain situation. When thinking about `null`, I more think about languages where basically every variable might potentially be null. – ziggystar Mar 08 '21 at 14:15
  • 4
    That's my feeling as well. For example, dart has all along had `?`-operator to express nullable variables. But only after the more recent "null sound safety" support in `2.12` that it supports statically guaranteeing non-null values. I would consider that distinction more interesting, and possibly what the question was really after. – swalog Mar 08 '21 at 14:27
  • C# "non-nullable" still allows assignment of null. All you get is a compiler warning, it won't protect you from the null-referencing. – montonero Jan 23 '23 at 13:55
  • @montonero You can treat nullable-related warnings as errors: https://stackoverflow.com/a/62116924/3425536 – Emil Laine Jan 23 '23 at 15:28
  • @emlai it still doesn't make C# null-safe but just helps to mitigate some errors. – montonero Jan 24 '23 at 16:27
4

Tcl has no concept of null whatsoever. Everything is a value and all values have a string representation (typically summarized as "Everything is a String").

The closest thing to null is the empty string.

To convey the concept of "no value" requires some creativity.

Of course, as mentioned above, some people use the empty string to signify no value. For this to work, empty strings cannot be valid in the data set you're processing. Surprisingly, a lot of real world data falls into this category.

Another way to indicate absence of value is to simply throw an error. In some cases this is exactly what should have been done instead of returning some null or error value (an anti-pattern learned from C and a habit that's hard to get rid of).

Yet another way is to return an empty list (a list is Tcl's equivalent of arrays in other languages). The string representation of an empty list is the empty string. But fortunately the string representation of a list containing an empty string is two double quotes: "\"\"". This difference allows one to differentiate between a list that contains "nothing" and a list that contains a string that has no characters in it.

Finally some people simply indicate the absence of values by simply not declaring the variable (or undeclaring it, which is a thing in tcl). This may sound odd because variables seem to be a compile-time construct (while values are run-time construct) but in tcl everything is run-time. Thus it's possible for code to use non existence of the variable as a signal. Trying to read an undeclared variable results in an error which you can catch. In addition, Tcl also allows you to use introspection to check the state of the interpreter. So you can use [info exist x] to check if a variable called x exists.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • 2
    Deliberately "undeclaring" a variable is a feature of many dynamically typed languages. Perl has `undef`, Javascript has `delete`, Bash has `unset`. – sleske Jan 27 '15 at 12:41
  • Very interesting. Thanks for sharing TCL info – MegaTux Jan 04 '17 at 15:14
  • This misses the point. Semantically, an empty string is equally bad as null. A properly typed language -- according to many -- should not make it possible to even indirectly reference a value that is not present. By conventional semantics, an empty string is not a value that is "present". Of course, if everything is a string, it does avoid you from errors like trying to concatenate string ```"foo"``` with an empty string ```""```, but then you often need to check emptiness of the string in several places (say, validation, joining strings by comma etc) – EdvardM Nov 21 '17 at 16:44
2

V is a newer language with Golang-like syntax that has no nulls.

chikega
  • 135
  • 1
  • 6
  • 1
    At least as of today, V doesn’t hold up to its claim to have no null: [#10837](https://github.com/vlang/v/issues/10837), [#14911](https://github.com/vlang/v/issues/14911), [#14914](https://github.com/vlang/v/issues/14914). – Anders Kaseorg Jul 04 '22 at 04:30
1

You already mention Haskell as an example of a language without "null". There are also the languages in the ML family like Standard ML, OCaml or F#. Many dynamically typed languages also do not feature null pointers, scheme would be a good example.

svenningsson
  • 4,009
  • 1
  • 24
  • 32
  • 1
    I think the main point of the question was not just null pointers, but null values lacking restriction. So Scheme, Common Lisp, and Ruby have `nil`, which has all the same problems as Java's `null`. The only difference is that, if you're in a dynamically typed language, you're already expecting to deal with those kinds of problems and are probably already doing more runtime checks to avoid them. – Silvio Mayolo Jul 10 '17 at 01:02