为什么Haskell没有符号(la ruby​​)/ atoms(la erlang)?

Anu*_*ain 16 ruby erlang language-features haskell language-design

我使用符号的两种语言是Ruby和Erlang,我总是发现它们非常有用.

Haskell确实有代数数据类型,但我仍然认为符号会非常方便.我想到的一个直接用途是,由于符号与整数同构,因此您可以在使用积分或字符串"主键"的地方使用它们.

原子的语法糖可能很小 - :某物或<某物>是原子.所有原子都是名为Atom的Type的实例,它派生Show和Eq.然后,您可以将其用于更多描述性错误代码

type ErrorCode = Atom
type Message = String
data Error = Error ErrorCode Message
loginError = Error :redirect "Please login first"
Run Code Online (Sandbox Code Playgroud)

在这种情况下:重定向比使用字符串("重定向")更有效,并且比整数更容易理解(404).

好处可能看似微不足道,但我说值得添加原子作为语言特征(或至少GHC扩展).

那么为什么没有将符号添加到语言中呢?或者我是否以错误的方式思考这个问题?

nom*_*olo 19

我同意camccann的答案,它可能缺失主要是因为它必须在实施中深入研究,并且它对于这种复杂程度的使用太少.在Erlang(和Prolog和Lisp)中,符号(或原子)通常用作特殊标记,并且与构造函数大致相同.在Lisp中,动态环境包括编译器,因此它部分也是一个(有用的)编译器概念泄漏到运行时.

问题如下,符号实习是不纯的(它修改了符号表).但是,因为我们永远不会修改现有对象,所以它在引用上是透明的,但是如果实现天真可能会导致运行时空间泄漏.实际上,正如目前在Erlang中实现的那样,你实际上可以通过实现太多的符号/原子来实现崩溃(我认为当前限制是2 ^ 20),因为它们永远不会被垃圾收集.如果没有围绕符号表的巨大锁定,在并发设置中实现也很困难.

然而,这两个问题都可以(并且已经)得到解决.例如,请参阅Erlang EEP 20.我在simple-atom包中使用这种技术.它unsafePerformIO在引擎盖下使用,但仅限于(希望)罕见的情况.它仍然可以使用GC的一些帮助来执行类似于间接缩短的优化.它IORef内部也使用了不少s,这对性能和内存使用来说并不算太大.

总而言之,可以做到这一点,但正确实施它并非易事.编译器编写者总是权衡一个功能的强大功能与其实现和维护工作,并且看起来像这样的一流符号会丢失.


C. *_*ann 14

我认为最简单的答案是,在Haskell中,Lisp风格的符号(这是Ruby和Erlang都得到了这个想法,我相信)的用途,大多数是:

  • 已经以其他方式完成 - 例如具有一堆nullary构造函数的数据类型,其也表现为"整数的方便名称".

  • 难以适应 - 存在于语言语法层面而不是常规数据的东西通常具有与它们相关联的更多类型信息,但符号必须是彼此不同的类型(如果没有某种轻量级广告,则几乎无用) -hoc sum类型)或所有相同的类型(在这种情况下,它们与仅使用字符串几乎没有区别).

另外,请记住,Haskell本身实际上是一种非常非常小的语言.很少被"烘焙",其中最多的东西只是其他原语的语法糖.如果你包含一堆GHC扩展,那就不那么真了,但是带-XAndTheKitchenSinkToo的GHC与Haskell本身的语言不同.

此外,Haskell非常适合伪语法和元编程,因此即使没有内置也可以做很多事情.特别是如果你进入TH和可怕的类型元编程和其他任何东西.

因此,它主要归结为符号的大多数实际效用已经可以从其他功能中获得,并且不可用的东西将比其值更难添加.

  • Erlang肯定是从Prolog和Lisp的Prolog获得的. (3认同)

scl*_*clv 9

原子不是由语言提供的,但可以作为库合理地实现:

http://hackage.haskell.org/package/simple-atom

还有其他一些关于hackage的库,但是这个库看起来是最新的并且维护得很好.

  • @Anupam -XOverloadedStrings (2认同)