lisp - 同调性水平

标签 lisp machine-code self-modifying homoiconicity

关闭。这个问题是off-topic .它目前不接受答案。












想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。


9年前关闭。







Improve this question




这是我的 previous question 的后续行动.我不相信 Lisp 代码与 Von Neumann 架构上的机器代码一样具有同形性。在我看来,在这两种情况下,代码都表示为数据,但很明显,您可以在机器代码中比在 Lisp 中更自由地利用此属性。

当乱搞机器代码时,自我修改代码非常容易,它总是会发生,通常是偶然的,并且(根据我的经验)会产生有趣的结果。在编写一个简单的“打印数字 0-15”程序时,我的一个指针可能会出现“减一”错误。我最终会不小心将寄存器 1 中的任何内容转储到包含下一条指令的内存地址中,然后执行随机指令。 (当它是某种“goto”时总是很棒。上帝知道它会在哪里结束,以及在那之后它会做什么)

代码和数据之间确实没有分离。一切都同时是一条指令(即使它只是一个 NOP)、一个指针和一个普通的旧数字。代码可能会在您眼前发生变化。

请帮助我解决我一直在摸索的 Lisp 场景。假设我有以下程序:

(defun factorial (n)
   (if (<= n 1)
       1
       (* n (factorial (- n 1)))))
; -- Demonstrate the output of factorial --
; -- The part that does the Self modifying goes here –
; -- Demonstrate the changed output of factorial

现在我想要在这个程序中添加一些 Lisp 代码,这些代码会将 * 更改为 +,将 <= 更改为 >=,将 (+ 1 2 3) 粘贴到某个地方,并且通常会破坏函数向上。然后我希望程序执行导致的绝对困惑。

关键点:除非我在示例代码中犯了一些 fatal error ,否则您只能更改 -– More code goes here –-部分。你在上面看到的 是代码 .我不希望您引用整个列表并将其存储在变量中,以便可以将其作为具有相同名称的单独函数进行操作和吐出;我不希望将阶乘标准重新定义为完全不同的东西。我想要那个我可以在屏幕上看到的代码在我眼前改变,就像机器代码一样。

如果这是一个不可能/不合理的要求,那么它只会进一步巩固我的想法,即同音性不是一种语言具有或不具有的离散属性,它是一个频谱,而 Lisp 并不处于最前沿。 (或者,Lisp 就像它们来的一样,我正在寻找其他术语来描述机器代码式的自我修改)

最佳答案

这很容易。您只需要更改列表表示。您只需要一个 Lisp 翻译 .

Common Lisp 实现 LispWorks为我们提供了一个 Lisp 解释器:

CL-USER 137 > (defun factorial (n)
                (if (<= n 1)
                    1
                  (* n (factorial (- n 1)))))
FACTORIAL

CL-USER 138 > (fifth (function-lambda-expression #'factorial))
(IF (<= N 1) 1 (* N (FACTORIAL (- N 1))))

CL-USER 139 > (fourth (fifth (function-lambda-expression #'factorial)))
(* N (FACTORIAL (- N 1)))

CL-USER 140 > (setf (first (fourth (fifth (function-lambda-expression
                                             #'factorial))))
                    '+)
+

CL-USER 141 > (fourth (fifth (function-lambda-expression #'factorial)))
(+ N (FACTORIAL (- N 1)))

CL-USER 142 > (factorial 10)
55

CL-USER 143 > (setf (first (fourth (fifth (function-lambda-expression
                                             #'factorial))))
                    '*)
*

CL-USER 144 > (factorial 10)
3628800

这是一个函数修改自身的示例。为了让它更容易一些,我使用了 Common Lisp 的一个特性:它允许我编写代码,而不仅仅是一些嵌套列表,而是一个图形。在这种情况下,函数可以访问自己的代码:
CL-USER 180 > (defun factorial (n)
                (if (<= n 1)
                    1
                  (progn 
                    (setf (first '#1=(* n (factorial (- n 1))))
                          (case (first '#1#)
                            (+ '*)
                            (* '+)))
                    #1#)))
FACTORIAL

上述函数交替使用+*通过修改其代码。
#1=是表达式中的标签,#1#然后引用该标签。
CL-USER 181 > (factorial 10)
4555

在早期(70 年代/80 年代)的一些 Lisp 小组中,开发人员不是使用文本编辑器来编写 Lisp 代码,而是使用结构编辑器。编辑器命令直接改变了 Lisp 代码的结构。

关于lisp - 同调性水平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16914779/

相关文章:

c++ - 当一个线程正在编写另一个线程可能同时执行的代码时,如何在 ARM 上进行同步?

Python - 代码片段不适用于 Python 2.5.6,使用 IDLE

windows - 如何手动编写和执行 Windows .exe(使用十六进制编辑器的机器代码)?

assembly - 68k寄存器地址

c - 在Linux C程序中写入自己的可执行文件,错误 "Text file busy"

lisp - 制作midi实例:midifile

assembly - 将 PIC 汇编指令转换为机器码

scheme - SICP 练习 1.16 - 我的解决方案正确吗?

oop - 列出 Common Lisp (CLOS) 中的对象方法

lisp - SBCL 在 macOS、Linux、FreeBSD 上的路径名通配符约定是什么?