Lisp 像Elixir和Julia这样的语言有什么意义?
Lisp中的同源性很容易看出:Lisp 像Elixir和Julia这样的语言有什么意义?,lisp,julia,homoiconicity,Lisp,Julia,Homoiconicity,Lisp中的同源性很容易看出: (+12) 既是以1、2作为参数的对+的函数调用,也是包含+、1和2的列表。它同时是代码和数据 不过,用茱莉亚这样的语言: 1+2 我知道我们可以在Julia中将其解析为Expr: :(1+2) 然后我们可以得到AST并操纵它: julia>Meta.show\u sexpr(:(1+2)) (:call,:+,1,2) 因此,我们可以在Julia(和Elixir)中操纵程序的AST。但是,它们是否与Lisp具有相同的含义?任何代码片段是否真的只是语言本身的数据结
(+12)
既是以1
、2
作为参数的对+
的函数调用,也是包含+
、1
和2
的列表。它同时是代码和数据
不过,用茱莉亚这样的语言:
1+2
我知道我们可以在Julia中将其解析为Expr
:
:(1+2)
然后我们可以得到AST并操纵它:
julia>Meta.show\u sexpr(:(1+2))
(:call,:+,1,2)
因此,我们可以在Julia(和Elixir)中操纵程序的AST。但是,它们是否与Lisp具有相同的含义?任何代码片段是否真的只是语言本身的数据结构
我看不出Julia中的
1+2
这样的代码是如何立即成为数据的——Lisp中的(+12)
只是一个列表。那么,这仍然是说教吗?用比尔·克林顿的话说,“这取决于‘是’这个词的含义。”。好吧,不是真的,但这取决于“同象性”这个词的含义。这一术语极具争议性,我们不再说朱莉娅是同性恋——所以你可以自己决定它是否合格。我将引用(谁知道Lisp的一两件事)在2001年的一篇回忆录中所说的话,而不是试图定义同象性:
我喜欢Lisp表现自己的意愿。人们经常把这解释为它表现自身的能力,但我认为这是错误的。大多数语言都能表达自己,但他们根本没有表达自己的意愿。Lisp程序由列表表示,程序员知道这一点。如果它是数组也没关系。重要的是它所表示的是程序结构,而不是字符语法,但除此之外,选择是相当随意的。表示是否正确并不重要。重要的是,这是一个共同的、一致同意的选择,这样就可以有一个丰富的程序操作程序社区,在这个共同的表示中“做交易”
他也没有定义同象性——他可能和我一样不想卷入定义的争论。但他切入了问题的核心:一种语言有多愿意表现自己?Lisp非常愿意——你甚至无法避免它:程序作为数据的表示就在那里,盯着你的脸。Julia不使用S-expression语法,因此代码作为数据的表示形式不太明显,但隐藏的不是很深:
julia> ex = :(2a + b + 1)
:(2a + b + 1)
julia> dump(ex)
Expr
head: Symbol call
args: Array(Any,(4,))
1: Symbol +
2: Expr
head: Symbol call
args: Array(Any,(3,))
1: Symbol *
2: Int64 2
3: Symbol a
typ: Any
3: Symbol b
4: Int64 1
typ: Any
julia> Meta.show_sexpr(ex)
(:call, :+, (:call, :*, 2, :a), :b, 1)
julia> ex.args[3]
:b
julia> ex.args[3] = :(3b)
:(3b)
julia> ex
:(2a + 3b + 1)
Julia代码由Expr
类型(以及符号和原子)表示,虽然表面语法和结构之间的对应关系不太明显,但它仍然存在。更重要的是,人们知道代码只是可以生成和操作的数据,所以正如KMP所说,有一个“丰富的程序操作程序社区”
这不仅仅是Julia代码作为数据结构的一种肤浅的表示——这就是Julia如何向自己表示其代码。在REPL中输入表达式时,它将被解析为Expr
对象。然后,这些Expr
对象被传递到eval
,这会将它们“降低”到更规则的Expr
对象,然后这些对象被传递到类型推断,所有这些都是实现的。关键的一点是,编译器使用与您看到的代码完全相同的表示形式。在Lisp中情况并没有那么不同。当您查看Lisp代码时,实际上并没有看到列表对象——它们只存在于计算机内存中。您看到的是列表文字的文本表示,Lisp解释器将其解析并转换为列表对象,然后对其求值,就像Julia一样。Julia的语法可以看作是Expr
文本的文本表示形式,Expr
恰好是一种比列表更不通用的数据结构
我不知道细节,但我怀疑长生不老药是类似的——也许何塞会插嘴
更新(2019)
在过去4年多的时间里,我一直在思考这个问题,我认为Lisp和Julia之间的关键区别在于:
- 在Lisp中,代码的语法与用于表示该代码的数据结构的语法相同
- 在Julia中,代码的语法与表示该代码的数据结构的语法完全不同
Meta.@dump
,将其视为数据结构quote。。。end
和:(…)
在Julia中构造,允许您使用代码语法构造数据结构,但这仍然不如让它们首先使用相同的语法直接
另请参见: