TL;DR 这并不像你说的那么简单。语法略有不同,每次有人创建一种语言时,他们都会决定新的语法,通常是为了使以前的语言或语言具有需要它的设计更简洁。当然,什么是“更好”是见仁见智的问题。
在Scheme(和后代Racket)中,变量和函数都有一个命名空间。因此,您对所有内容都使用define。
(define variable 10)
(define function (lambda (arg1 arg2) body ...))
现在define 有最后一条捷径,即:
(define (function arg1 arg2) body ...)
所以规则是,如果第一部分是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 看起来几乎相同。