构建一台 LISP 机器需要多少个原语?十个、七个还是五个?

发布于 2024-09-14 04:22:58 字数 659 浏览 9 评论 0原文

在这个网站上,他们说有 10 个 LISP 原语。 原语为:atom、quote、eq、car、cdr、cons、cond、lambda、label、apply。

http://hyperpolyglot.wikidot.com/lisp#ten-primitives

Stevey 认为有七(或五):

这是 LISP 思想的纯粹性的一部分:你只需要七个(或者是 它有五个?)构建完整机器的原语。 http://steve-yegge.blogspot.com /2006/04/lisp-is-not-acceptable-lisp.html

构建 LISP 机器(即可以在 LISP 代码上运行 eval/value 函数的机器)的最小原语数量是多少? (它们是哪些?)

(我可以理解你可以没有 atom、label 和 apply 生活)

On this site they say there are 10 LISP primitives.
The primitives are: atom, quote, eq, car, cdr, cons, cond, lambda, label, apply.

http://hyperpolyglot.wikidot.com/lisp#ten-primitives

Stevey reckons there are seven (or five):

Its part of the purity of the idea of LISP: you only need the seven (or is
it five?) primitives to build the full machine.
http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html

What is the minimum number of primitives to build a LISP machine (ie something that can run an eval/value function on LISP code)? (And which ones are they?)

(I can understand you could live without atom, label and apply)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

司马昭之心 2024-09-21 04:22:58

基本谓词/F 函数

McCarthy基本 S 函数和谓词为:

  1. atom

    这是必要的,因为 car 和 cdr 仅为列表定义,这意味着如果您给 car 一个原子,您就不能指望任何类型的答案来指示发生了什么。

  2. eq

    用于测试原子之间的相等性。

  3. 汽车

    用于返回 cons 单元的前半部分(地址)。 (地址寄存器的内容)。

  4. cdr

    用于返回 cons 单元的后半部分(递减)。 (减量寄存器的内容)。

  5. 缺点

    用于创建一个新的 cons 单元,地址一半包含 cons 的第一个参数,减量一半包含第二个参数。

将其结合在一起:S-Functions

然后他继续添加到他的基本符号中,以便能够编写他所谓的 S-functions:

  1. quote

    表示一个表达式而不求值。

  2. 条件

    与前面描述的谓词一起使用的基本条件。

  3. lambda

    表示一个函数。

  4. 标签

    虽然他不需要递归,但他可能不知道 Y -Combinator根据 Paul Graham),他补充道这是为了方便并能够轻松递归。


所以你可以看到他实际上为他的 Lisp 机器定义了 9 个基本“操作符”。在之前对另一个问题的回答中,我解释了如何使用此系统表示数字并对其进行操作

但这个问题的答案实际上取决于你想从你的 Lisp 机器中得到什么。您可以在没有 label 函数的情况下实现一个函数,因为您可以简单地在功能上组合所有内容,并通过应用 Y-Combinator 获得递归。

如果您在原子上定义了 car 操作以返回 NIL,则 atom 可能会被丢弃。

您本质上可以拥有包含这 9 个已定义原语中的 7 个的 McCarthy 的 LISP 机器,但您表面上可以定义一个更简洁的版本,具体取决于您希望给自己带来多少不便。我非常喜欢他的机器,或者像 Clojure 这样的新语言中的许多原语。

Basic Predicates/F-functions

McCarthy's Elementary S-functions and Predicates were:

  1. atom

    Which was necessary because car and cdr are defined for lists only, which means you cannot count on any sort of answer to indicate what was happening if you gave car an atom.

  2. eq

    For testing equality between atoms.

  3. car

    For returning the first half (address) of the cons cell. (Contents of address register).

  4. cdr

    For returning the second half (decrement) of the cons cell. (Contents of decrement register).

  5. cons

    For making a new cons cell, with the address half containing the first argument to cons, and the decrement half containing the second argument.

Tying it together: S-Functions

He then went on to add to his basic notation, to enable writing what he called S-functions:

  1. quote

    To represent an expression without evaluating it.

  2. cond

    The basic conditional to be used with the previously described predicates.

  3. lambda

    To denote a function.

  4. label

    Though he didn't need this for recursion, he might not have known about the Y-Combinator (according to Paul Graham), he added this for convenience and to enable easy recursion.


So you can see he actually defined 9 basic "operators" for his Lisp machine. In a previous answer to another one of your questions, I explained how you could represent and operate on numbers with this system.

But the answer to this question really depends on what you want out of your Lisp machine. You could implement one without the label function, as you could simply functionally compose everything, and obtain recursion through applying the Y-Combinator.

atom could be discarded if you defined the car operation on atoms to return NIL.

You could essentially have McCarthy's LISP machine with 7 of these 9 defined primitives, but you could ostensibly define a more concise version depending on how much inconvenience you'd want to inflict on yourself. I like his machine quite fine, or the many primitives in the newer languages like Clojure.

长梦不多时 2024-09-21 04:22:58

真正了解这一点的最佳方法是实施它。我用了 3 个夏天的时间创建了 Zozotez,它是一个运行在 Brainfuck

我试图找出我需要的东西,在论坛上你会发现一个线程,上面写着 你只需要 lambda。 因此,你可以用 lambda 演算创建一个完整的 LISP。我发现它很有趣,但如果你想要一些最终会产生副作用并且在现实世界中有效的东西,那么这几乎不是一个可行的方法。

对于图灵完备的 LISP,我使用了 Paul Grahams 对 McCarthy 论文的解释,你真正需要的是:

  • 符号-evaluation
  • 特殊形式 quote
  • 特殊形式 if (或 cond)
  • 特殊形式 lambda (类似于 quote)
  • function eq
  • functionatom
  • function cons
  • function car
  • function cdr
  • function-dispatch (list-lambda)

Thats 10. 除此之外,还有一个实现您可以测试而不仅仅是在绘图板上:

  • function read
  • function write

那就是 12。在我的 Zozotez 中,我实现了set 和 flambda(匿名宏,如 lambda)也是如此。我可以给它提供一个实现任何动态绑定 Lisp(Elisp、picoLisp)的库,但文件 I/O 除外(因为底层 BF 除了 stdin/stdout 之外不支持它)。

我建议任何人都在 LISP 和(不是 LISP)中实现 LISP1 解释器,以充分理解语言是如何实现的。 LISP 具有非常简单的语法,因此它是解析器的良好起点。我目前正在开发一个以具有不同目标的方案编写的方案编译器(例如斯大林针对目标 C),希望 BF 能够成为其中之一。

The best way to actually know this for sure is if you implement it. I used 3 summers to create Zozotez which is a McCarty-ish LISP running on Brainfuck.

I tried to find out what I needed and on a forum you'll find a thread that says You only need lambda. Thus, you can make a whole LISP in lambda calculus I you'd like. I found it interesting, but it's hardly the way to go if you want something that eventually has side effects and works in the real world.

For a Turing complete LISP I used Paul Grahams explanation of McCarthy's paper and all you really need is:

  • symbol-evaluation
  • special form quote
  • special form if (or cond)
  • special form lambda (similar to quote)
  • function eq
  • function atom
  • function cons
  • function car
  • function cdr
  • function-dispatch (list-lambda)

Thats 10. In addition to this, to have a implementation that you can test and not just on a drawing board:

  • function read
  • function write

Thats 12. In my Zozotez I implemeted set and flambda (anonymous macroes, like lambda) as well. I could feed it a library implementing any dynamic bound lisp (Elisp, picoLisp) with the exception of file I/O (because the underlying BF does not support it other than stdin/stdout).

I recommend anyone to implement a LISP1-interpreter in both LISP and (not LISP) to fully understand how a language is implemented. LISP has a very simple syntax so it's a good starting point for a parser. I'm currently working on a scheme compiler written in scheme with different targets (like Stalin is for target C), hopefully BF as one of them.

屌丝范 2024-09-21 04:22:58

McCarthy 使用七个运算符来定义原始 Lisp:quoteatomeqcarcdrconscond这篇文章回顾了他的足迹。

McCarthy used seven operators to define the original Lisp: quote, atom, eq, car, cdr, cons and cond. This article retraces his steps.

过去的过去 2024-09-21 04:22:58

常见问题解答指出:

没有单一的“最佳”最小基元集;这一切都取决于
实施。例如,即使是像数字这样基本的东西
不必是原始的,并且可以表示为列表。一种可能
原语集可能包括 CAR、CDR 和 CONS,用于操作
S 表达式,用于 S 表达式的输入/输出的 READ 和 PRINT
并针对口译员的胆量进行应用和评估。但那时你可能
想要为函数添加 LAMBDA,为相等添加 EQ,为
条件语句、赋值语句 SET、定义语句 DEFUN。引用
可能也会派上用场。

这来自卡内基梅隆大学计算机科学学院网站。

This faq states:

There is no single "best" minimal set of primitives; it all depends on
the implementation. For example, even something as basic as numbers
need not be primitive, and can be represented as lists. One possible
set of primitives might include CAR, CDR, and CONS for manipulation of
S-expressions, READ and PRINT for the input/output of S-expressions
and APPLY and EVAL for the guts of an interpreter. But then you might
want to add LAMBDA for functions, EQ for equality, COND for
conditionals, SET for assignment, and DEFUN for definitions. QUOTE
might come in handy as well.

That comes from the School of Computer Science, Carnegie Melon website.

爱她像谁 2024-09-21 04:22:58

只需要一条 x86 MOV 指令

“M/o/Vfuscator(短‘o’,听起来像“mobfuscator”)将程序编译为“mov”指令,并且仅编译为“mov”指令。算术、比较、跳转、函数调用以及其他所有内容都由程序需求全部通过mov操作来完成;没有自修改代码,没有传输触发计算,也没有其他形式的非mov作弊。”

但说真的,这些原语不会实现 Lisp 机器。机器需要 I/O 和垃圾收集等设施。更不用说函数调用机制了!好的,您有七个原语,它们是函数。机器如何调用函数?

对这些原语的正确理解是,它们公开通用图灵机的指令集。因为这些指令是“Lisp”,所以由于口误(用 Lisp 说话),我们偷偷地称其为“Lisp 机器”。 “通用”意味着机器是可编程的:通过一些应用于通用图灵机的组合指令,我们可以实例化任何图灵机。但到目前为止,所有这些都纯粹是数学构造。

为了实际模拟这个 UTM——以物理方式实现它,以便在计算机上探索它,我们需要一台机器,它为我们提供一种方法来实际输入那些形式,这些形式根据这七个 Lisp 指令的组合创建图灵机。我们还需要某种形式的输出;机器至少能够告诉我们“是”、“否”或“等等,我还在运行”。

换句话说,这七个指令实际上可以工作的唯一方法是将它们托管在提供环境的更大的机器中。

另请注意,格雷厄姆的七个基元没有对数字的明确支持,因此您必须用函数构建它们(“教堂数字”技术)。没有哪个 Lisp 生产实现会做出如此疯狂的事情。

You just need an x86 MOV instruction.

"The M/o/Vfuscator (short 'o', sounds like "mobfuscator") compiles programs into "mov" instructions, and only "mov" instructions. Arithmetic, comparisons, jumps, function calls, and everything else a program needs are all performed through mov operations; there is no self-modifying code, no transport-triggered calculation, and no other form of non-mov cheating."

Seriously though, these primitives will not implement a Lisp Machine. A machine needs facilities like I/O, and garbage collection. Not to mention a function calling mechanism! Okay, you have seven primitives which are functions. How does the machine call a function?

The proper understanding of what these primitives make possible is that they expose the instruction set of a Universal Turing Machine. Because those instructions are "Lispy", by a slip of the tongue (speaking with a Lisp) we sneakily call this a "Lisp Machine". "Universal" means that the machine is programmable: with some combination instructions applied to the Universal Turing Machine, we can instantiate any Turing Machine. But so far, all of that is purely a mathematical construct.

To actually simulate this UTM—realize it physically in order to explore it on a computer, we need a machine which provides for a way to us to actually input those forms which create Turing Machines from combinations of those seven Lisp instructions. And we also need some form of output; the machine as to at least be able to tell us "yes", "no", or "Wait, I'm still running".

In other words, the only way those seven instructions can practically work is if they are hosted in a larger machine which provides the environment.

Also note that Graham's seven primitives have no explicit support for numbers, so you would have to build them out of functions ("Church numerals" technique). No production Lisp implementation does such a crazy thing.

执手闯天涯 2024-09-21 04:22:58

Paul Graham 使用 7 实现 eval。

在 McCarthy's Micro Manual for LISP 中,他使用 ten 实现了 eval。

Paul Graham implements eval using seven.

In McCarthy's Micro Manual for LISP he implements eval using ten.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文