定制' +' (总和)在lisp中的功能

时间:2016-08-23 06:08:52

标签: lisp common-lisp

我正在阅读Paul Graham的Lisots of Rop,他声称任何lisp功能都可以通过这7个基本功能的组合来构建:quote,atom,eq,cond,cons,car,cdr。

问题:Lisp方言真的完全基于这些功能吗?我们如何定义一笔“总和”?或者'加上'使用上述7个原始函数的函数?例如我们自己的(+ 1 2)功能

注意:我是Lisp的全新手,但我也开始对这种语言感到非常兴奋。这个问题的目的纯粹是真正的兴趣

3 个答案:

答案 0 :(得分:12)

作者参考了图灵奖和Lisp发明人约翰麦卡锡“Recursive Functions of Symbolic Expressions and Their Computation by Machine”于1960年撰写的一篇非常着名的论文,其中他将Lisp的语义定义为一种新的计算形式,与图灵机相当。

在论文中(以及在Lisp 1.5 Manual中)麦卡锡描述了语言的解释器,这可以通过仅使用格雷厄姆提到的七个原始函数来完全编写。

该语言主要用于符号计算,而论文中提供的解释器仅涉及那些计算,而不依赖于与原子和对不同的数字或其他数据类型。

格雷厄姆在Lisp的第11页的一个注释中说,“有可能通过使用例如McCarthy 1960年的Lisp算术。一个 n 原子列表来表示数字 n “,因此执行求和只相当于附加两个列表。

当然,这种做法效率非常低:它仅用于表示与其他计算形​​式的等价性,而在真正的解释器/编译器中,整数表示为通常的,并且具有通常的运算符。

答案 1 :(得分:3)

据我记忆,还有一种方法可以使用列表嵌套级别来做到这一点(不记得,在哪里)。从()开始为零,(()) == 1,依此类推。然后,您只需将inc定义为list,将dec定义为car

CL-USER> (defun zero? (x) (eq () x))
ZERO?

CL-USER> (zero? nil)
T

CL-USER> (zero? 1)
NIL

CL-USER> (defparameter *zero* ())
*ZERO*

CL-USER> (defun inc (x) (list x))
INC

CL-USER> (defun dec (x) (car x))
DEC

CL-USER> (defun plus (x y)
           (if (zero? y) x (plus (inc x) (dec y))))
PLUS

CL-USER> (plus *zero* (inc (inc *zero*)))
((NIL))

CL-USER> (defparameter *one* (inc *zero*))
*ONE*

CL-USER> (defparameter *two* (inc *one*))
*TWO*

CL-USER> (defparameter *three* (inc *two*))
*THREE*

CL-USER> (plus *two* *three*)
(((((NIL)))))

CL-USER> (equal *two* (dec (dec (dec (plus *two* *three*)))))
T

答案 2 :(得分:3)

<强> TL; DR:否。现代lisp系统比第一个lisp有更多的原语,每个新的原始数据类型都需要一个新的原语。

第一个Lisp没有数字,但是它已经完成了。这意味着它可以进行任何其他语言可能的任何计算,但这并不意味着这样做是可行的。数字并不难模仿,但计算速度很慢。今天有些人认为Lisp 1.5之前的算术速度很慢。

当我成为第一个口译员时,我不太关心数字。它并不是翻译的一个有趣的方面。然而,我确实以fibonacci为例,这就是它的样子:

;; This is NOT Common Lisp code. It's Zozotez
(setq + (lambda (x y)
  (if x (cons (car x) 
              (+ (cdr x) y))
      y)))

(setq - (lambda (z w)
  (if w (- (cdr z) 
           (cdr w)) 
      z)))

(setq fibonacci
  (lambda (n a1 a2)
    (if n
        (fibonacci (- n '(1))
                   a2 
                   (+ a2 a1)) 
        a1)))

(fibonacci '(1 1 1 1 1 1 1 1 1) () '(1))
; ==> (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)

没有数字! (1在我的语言中是一个符号,因此需要引用它,否则它将像变量一样被评估)

作为替代数字系统,我已经实现了一个位置系统,就像我们用相同的规则来编写数字来进行添加/乘法等等。也许比长度为n的lits要快但是要复杂得多。

如果Lisp有封闭,你可以做教堂数字。使用与lambda演算相同的方法,您可以使用闭包计算任何东西。您只需要一个原语lambda。 (同样,不是最容易使用的)

相关问题