常见的lisp和clojure
(defn function-name (arg1 arg2) (body))
球拍/计划呢
(defn (function-name arg1 arg2) (body))
后者对我更有意义,因为函数定义和调用的语法类似.前者的理由是什么?
TL; DR它并不像你说的那么简单.语法略有不同,每当有人创建语言时,他们就会决定新的语法,通常是为了使之更简洁,以前的语言或语言都有需要它的设计.当然,"更好"的是一个意见问题.
在Scheme(和后代Racket)中,您有一个名称空间用于变量和函数.因此,你define
用于一切.
(define variable 10) (define function (lambda (arg1 arg2) body ...))
现在define
有最后一个的捷径,即:
(define (function arg1 arg2) body ...)
所以规则是如果第一部分是a,pair?
它应该被扩展到更长的形式lambda
.我认为它类似于应用程序只是一个讽刺.这个额外的功能只是为了节省一些击键,并且经常在诸如The Little Schemer之类的书籍中被省略,因为它有两种方式和学习者的混淆,他们可能认为定义一个函数的绑定比定义更特殊10
,这是荒谬的.其余的争论通常会引起混淆.例如.这些都是一样的:
(define (test . x) x) (define test (lambda x x))
在Common Lisp中,您有两个名称空间,因此defun
仅用于全局作用域,并且有函数等效的变量形式.在defun
你在Common Lisp的列表中第一个参数太多,但它确实完全不同的东西:
(defun (setf name) (new-value) body ...)
这提供了一种与CL中的其他访问器具有相同对称性的方法.例如.如果(car x)
从利弊获得汽车价值(setf (car x) 10)
将改变它.在我的例子name
中可以使用相同的方式car
.这很方便.
Clojure使用def
和fn
使用数组作为参数:
(def function (fn [arg1 agr2] body ...))
defn
只是一个速记版本,就像define
从一对开始.它最终与Scheme类似的结果可能是参数数据是一个数组,或者它们保持语法尽可能接近原始数据.如果我没记错的话,你可以有一个函数的名字作为第二个参数fn
,以及制作fn
和defn
外观几乎一样.
后者对我更有意义,因为函数定义和调用的语法类似.
在Common Lisp中,函数定义通常与调用不相似,因此假装它们没有意义.
这是一个有效的函数定义:
(defun foo (arg1 arg2 &optional (ovar 10) &rest args &key (ak 11 a-p) &allow-other-keys &aux (aux1 12)) (list arg1 arg2 ovar args ak a-p aux1))
这些是上面的有效要求:
(foo 1 2) (foo 1 2 3) (foo 1 2 3 :ak 4) (foo 1 2 3 :foo 10 :ak 4)
因此,调用参数看起来与定义参数列表不同.
在DEFMETHOD
定义的情况下可能看起来像:
(defmethod (setf foobar) :around ((value integer) (object foo)) (setf (slot-value object 'a) value))
并打电话
(setf (foobar object) 10)
摘要
在Common Lisp中,函数定义看起来不像调用
短途旅行
为简单的CL函数定义类似Scheme的语法很简单:
(defmacro define ((name &rest args) &body body) `(defun ,name ,args ,@body)) CL-USER 36 > (macroexpand-1 `(define (foo a b c) (baz) (bar))) (DEFUN FOO (A B C) (BAZ) (BAR)) T
有些程序甚至使用类似的东西......