我将继续承认我对Lisp的了解非常少.但是我对这门语言非常感兴趣,并计划在不久的将来开始认真学习它.我对这些问题的理解无疑是有缺陷的,所以如果我说出任何错误的内容,请评论并纠正我而不是贬低.
真正的同性恋和自我修改的语言
我正在寻找支持Homoiconicity(代码与数据表示相同)和不受限制的自我修改的编程语言示例(Unrestricted意味着您可以更改正在运行的代码的每个方面,而不仅仅是发出新代码或更改函数指针/代表).
到目前为止我发现的三个例子符合这个标准:
为什么Lisp不在此列表中
Lisp不在那个列表中,因为在我看来,Lisp 几乎只是Homoiconic,并且只支持受限制的自我修改.你可以做点什么
(+ 1 2 3)
Run Code Online (Sandbox Code Playgroud)
这将做同样的事情
(eval '(+ 1 2 3))
Run Code Online (Sandbox Code Playgroud)
第一个版本(+ 1 2 3)是原始代码,而第二个版本是数据.通过假设这个陈述的真实性,可以说Lisp甚至不是杀人的.代码与数据具有相同的表示形式,即它们都是列表/树/ S表达式.但事实上你必须明确地标记这些列表/树/ S表达式中的哪些是代码以及哪些是我的数据似乎说Lisp毕竟不是杀人的.这些表示非常相似,但它们的细节不同,您必须实际说明您是在处理代码还是数据.这绝不是一件坏事(实际上其他任何东西都会是疯狂的),但它强调了Lisp和机器代码之间的区别.在机器代码中,您不必明确标记哪些数字是指令,哪些是指针,哪些是数据.在实际需要解释之前,一切都只是一个数字,此时它可以是任何一个.
对于不受限制的自我修改,这是一个更强大的案例.当然,您可以获取代表某些代码并对其进行操作的列表.例如改变
'(+ 1 2 3)
Run Code Online (Sandbox Code Playgroud)
至
'(+ 1 4 3)
Run Code Online (Sandbox Code Playgroud)
然后你运行它eval.但是当你这样做时,你只是编译一些代码并运行它.您没有修改现有代码,只是发出并运行新代码.C#可以使用表达式树完全相同的事情,即使是一种不太方便的格式(由于C#代码对其AST具有不同的表示而产生,而不是Lisp,这是它自己的AST).您是否可以实际获取整个源文件并在运行时开始修改整个源文件,对源文件所做的更改会对程序行为产生实时影响?
除非有某种方法可以做到这一点,否则Lisp既不是讽刺也不是自我修改.(为了推断定义的争论,Lisp不是同源的,也不是自我修改到与机器代码相同的程度.)
如何制作Lisp Homoiconic/Unrestrictedly self-modifiable
我可以看到3种可能的方法使Lisp像机器代码一样可以单调/自我修改.
点1.结合2.将产生一个完全自我修改的Lisp.前提是可以生产所描述的神奇的Lisp机器.2.单独可以产生自我修改的Lisp,但是在冯·诺依曼架构上的实现可能非常低效.
问题
附录
语言具有不受限制的自我修改但不具有杀戮性
其他概念和语言可能在某种程度上相关/有趣:Lisp,Ruby,Snobol,Forth和它的编译时元编程,Smalltalk和它的反射,无类型的lambda演算,它的属性是一切都是函数(哪种意味着假设我们可以发明一台直接执行lambda演算的机器,lambda演算将是homoiconic而Von Neumann机器代码在所述机器上运行时不会.[并且Godels定理将是可执行的.哈哈,可怕的想法:P])