有没有没有 "null" 的语言?
Are there languages without "null"?
很多人认为特殊值null
的概念(因为它被用在C、Java、C#、Perl、Javascript等语言中, SQL 等)是个坏主意。 SO和P.SE上有几个关于这个的问题,比如Best explanation for languages without null and Are null references really a bad thing? .
但是,我找不到任何没有它们的语言。我熟悉的所有语言都有 null
或类似的东西(例如 Perl 中的“undefined”)。
我意识到可能每种语言都需要某种方式来表达“没有价值”。但是,除了使用“null”或“undefined”之外,还可以通过使用 Maybe
(Haskell) or Optional
(Guava) 之类的内容来明确表示。具有“null”或“undefined”的主要区别在于,如果对象具有特定类型(可能,可选...),则该对象只能具有“无值”。相反,“null”/“undefined”通常是 every 类型可能的有效值。
是否有任何语言没有null
或这个意义上的类似概念?
您已经提到 Haskell 作为没有 "null" 的语言的例子。还有 ML 家族中的语言,如标准 ML、OCaml 或 F#。许多动态类型语言也不支持空指针,scheme 就是一个很好的例子。
Tcl 没有任何 null 的概念。一切都是一个值,所有值都有一个字符串表示(通常总结为 "Everything is a String")。
最接近 null 的是空字符串。
传达"no value"的概念需要一些创意。
当然,如前所述,有些人使用空字符串来表示没有值。为此,空字符串在您正在处理的数据集中不能有效。令人惊讶的是,很多现实世界的数据都属于这一类。
另一种表示值缺失的方法是简单地抛出一个错误。在某些情况下,这正是应该做的,而不是 return 一些空值或错误值(从 C 中学到的反模式和难以摆脱的习惯)。
另一种方法是 return 一个空列表(列表在 Tcl 中等同于其他语言中的数组)。空列表的字符串表示是空字符串。但幸运的是,包含空字符串的列表的字符串表示是两个双引号:"\"\""
。这种差异使人们能够区分包含 "nothing" 的列表和包含没有字符的字符串的列表。
最后,有些人通过简单地不声明变量(或取消声明它,这是 tcl 中的事情)来简单地指示缺少值。这听起来可能很奇怪,因为变量似乎是一个编译时构造(而值是 运行-time 构造)但在 tcl 中一切都是 运行-time。因此,代码可以使用变量不存在作为信号。尝试读取未声明的变量会导致错误,您可以捕获该错误。此外,Tcl 还允许您使用内省来检查解释器的状态。因此,您可以使用 [info exist x]
来检查是否存在名为 x
的变量。
这是 null-safe 语言的不完整列表,因为它们没有任何 non-nonnullable 类型:
- Dart (2021):具有可选类型,语法为
?
。
- C# 8 (2019):具有 opt-in“可空引用类型”。
- Kotlin (2015): 具有可选类型,语法为
?
。
- Pony (2015)。使用其中一种类型为
None
. 的联合类型
- Swift (2014): 具有可选类型,语法为
?
。
- Crystal (2014):确实有
nil
,但在 compile-time. 处阻止了所有空指针异常
- Hack (2014):具有可选类型,语法为
?
。
- TypeScript (2012):联合类型可以有
undefined
或 null
作为变体。
- Elm (2012): 联合类型
Maybe
.
- Ceylon (2011):具有可选类型,语法为
?
。
- Rust (2010): 有可选类型
Option
.
- Fantom (2005): 有可选的类型
?
语法。
- F# (2005): 联合类型
Option
.
- Nice (2003): 具有可选类型,语法为
?
。
- Netlogo (1999) 没有类型
null
- OCaml (1996):联合类型
option
.
- Haskell (1990): 联合类型
Maybe
.
- Standard ML (1990):联合类型
option
.
- Tcl (1988)
- Erlang (1986)
- Prolog (1972):逻辑变量代表“任何东西”。没有“null”或“undefined”的概念。
随时补充列表。这些年份代表第一个 public 版本。
V 是一种较新的语言,具有类似 Golang 的语法,没有空值。
很多人认为特殊值null
的概念(因为它被用在C、Java、C#、Perl、Javascript等语言中, SQL 等)是个坏主意。 SO和P.SE上有几个关于这个的问题,比如Best explanation for languages without null and Are null references really a bad thing? .
但是,我找不到任何没有它们的语言。我熟悉的所有语言都有 null
或类似的东西(例如 Perl 中的“undefined”)。
我意识到可能每种语言都需要某种方式来表达“没有价值”。但是,除了使用“null”或“undefined”之外,还可以通过使用 Maybe
(Haskell) or Optional
(Guava) 之类的内容来明确表示。具有“null”或“undefined”的主要区别在于,如果对象具有特定类型(可能,可选...),则该对象只能具有“无值”。相反,“null”/“undefined”通常是 every 类型可能的有效值。
是否有任何语言没有null
或这个意义上的类似概念?
您已经提到 Haskell 作为没有 "null" 的语言的例子。还有 ML 家族中的语言,如标准 ML、OCaml 或 F#。许多动态类型语言也不支持空指针,scheme 就是一个很好的例子。
Tcl 没有任何 null 的概念。一切都是一个值,所有值都有一个字符串表示(通常总结为 "Everything is a String")。
最接近 null 的是空字符串。
传达"no value"的概念需要一些创意。
当然,如前所述,有些人使用空字符串来表示没有值。为此,空字符串在您正在处理的数据集中不能有效。令人惊讶的是,很多现实世界的数据都属于这一类。
另一种表示值缺失的方法是简单地抛出一个错误。在某些情况下,这正是应该做的,而不是 return 一些空值或错误值(从 C 中学到的反模式和难以摆脱的习惯)。
另一种方法是 return 一个空列表(列表在 Tcl 中等同于其他语言中的数组)。空列表的字符串表示是空字符串。但幸运的是,包含空字符串的列表的字符串表示是两个双引号:"\"\""
。这种差异使人们能够区分包含 "nothing" 的列表和包含没有字符的字符串的列表。
最后,有些人通过简单地不声明变量(或取消声明它,这是 tcl 中的事情)来简单地指示缺少值。这听起来可能很奇怪,因为变量似乎是一个编译时构造(而值是 运行-time 构造)但在 tcl 中一切都是 运行-time。因此,代码可以使用变量不存在作为信号。尝试读取未声明的变量会导致错误,您可以捕获该错误。此外,Tcl 还允许您使用内省来检查解释器的状态。因此,您可以使用 [info exist x]
来检查是否存在名为 x
的变量。
这是 null-safe 语言的不完整列表,因为它们没有任何 non-nonnullable 类型:
- Dart (2021):具有可选类型,语法为
?
。 - C# 8 (2019):具有 opt-in“可空引用类型”。
- Kotlin (2015): 具有可选类型,语法为
?
。 - Pony (2015)。使用其中一种类型为
None
. 的联合类型
- Swift (2014): 具有可选类型,语法为
?
。 - Crystal (2014):确实有
nil
,但在 compile-time. 处阻止了所有空指针异常
- Hack (2014):具有可选类型,语法为
?
。 - TypeScript (2012):联合类型可以有
undefined
或null
作为变体。 - Elm (2012): 联合类型
Maybe
. - Ceylon (2011):具有可选类型,语法为
?
。 - Rust (2010): 有可选类型
Option
. - Fantom (2005): 有可选的类型
?
语法。 - F# (2005): 联合类型
Option
. - Nice (2003): 具有可选类型,语法为
?
。 - Netlogo (1999) 没有类型
null
- OCaml (1996):联合类型
option
. - Haskell (1990): 联合类型
Maybe
. - Standard ML (1990):联合类型
option
. - Tcl (1988)
- Erlang (1986)
- Prolog (1972):逻辑变量代表“任何东西”。没有“null”或“undefined”的概念。
随时补充列表。这些年份代表第一个 public 版本。
V 是一种较新的语言,具有类似 Golang 的语法,没有空值。