根据本文,以下Lisp代码行将“ Hello world”打印到标准输出。
(format t "hello, world")
Lisp是一种谐音语言,可以通过以下方式将代码视为数据:
现在假设我们编写了以下宏:
(defmacro backwards (expr) (reverse expr))
向后是宏的名称,该宏采用一个表达式(表示为列表)并将其反转。再次使用宏,这是“您好,世界”:
(backwards ("hello, world" t format))
当Lisp编译器看到该行代码时,它将查看列表(
backwards
)中的第一个原子,并注意到它为宏命名。它将未评估的列表传递("hello, world" t format)
给宏,该宏将列表重新排列为(format t "hello, world")
。结果列表将替换宏表达式,并且将在运行时对其进行评估。Lisp环境将看到它的第一个原子(format
)是一个函数,并对其进行评估,并将其余的参数传递给它。
在Lisp中,完成此任务很容易(如果我错了,请纠正我),因为代码是作为列表实现的(s-expressions?)。
现在看看这个OCaml(不是谐音语言)片段:
let print () =
let message = "Hello world" in
print_endline message
;;
想象一下,您想向OCaml添加谐音,与Lisp相比,它使用的语法要复杂得多。你会怎么做?语言是否必须具有特别简单的语法才能实现谐音?
编辑:从该主题中,我找到了另一种实现同音的方法,该方法不同于Lisp的方法:用io语言实现的方法。它可能会部分回答这个问题。
在这里,让我们从一个简单的块开始:
Io> plus := block(a, b, a + b) ==> method(a, b, a + b ) Io> plus call(2, 3) ==> 5
好的,所以该块起作用了。加号块将两个数字相加。
现在让我们对这个小家伙做一些自省。
Io> plus argumentNames ==> list("a", "b") Io> plus code ==> block(a, b, a +(b)) Io> plus message name ==> a Io> plus message next ==> +(b) Io> plus message next name ==> +
热圣冷模具。您不仅可以获取块参数的名称。而且,您不仅可以获得字符串的完整源代码字符串。您可以潜入代码并遍历其中的消息。最令人惊奇的是:它非常简单自然。忠于艾欧的追求。Ruby的镜子看不到任何东西。
但是,哇,嘿,现在,不要碰那个拨盘。
Io> plus message next setName("-") ==> -(b) Io> plus ==> method(a, b, a - b ) Io> plus call(2, 3) ==> -1