为什么Little Schemer中的所有lambdas?

And*_*dré 18 lambda scheme the-little-schemer

在从SICP学习了一点Scheme之后,我开始阅读The Little Schemer(我发现它非常有趣)并且大约完成了四分之一.我注意到我可以在不使用lambda的情况下编写许多(大多数?全部?)解决方案,而Little Schemer 总是使用它们.例如,第一个定义是

(define atom?
  (lambda (x)
    (and (not (pair? x)) (not (null? x)))))
Run Code Online (Sandbox Code Playgroud)

除非我弄错了,否则可以更简单地写成

(define (atom? x) 
   (and (not (pair? x)) (not (null? x))))
Run Code Online (Sandbox Code Playgroud)

如果我写无lambda的解决方案,我会遗漏一些基本的东西吗?

acf*_*zer 22

lambda杰伊说,我非常喜欢教学的重要风格,因为它使功能创作更加明确.

在学习时,您开始使用的简单功能atom?就是define在顶层.这意味着用你提到的defun样式创建函数是可能的,甚至更紧凑define.

但是,当你开始使用函数作为第一类值时,例如,作为参数map,你将lambda第一次看到它,它可能看起来更奇怪,更真实.

相反,如果你一直在定义你的函数lambda,那么看起来函数就像任何其他值一样,这不是一个飞跃.它们恰好位于define相当频繁的右侧,但与数字或引用的常数没有区别:

(define x 1)
(define l '(2 3 4 5))
(define s (cons x ls))
(define f (lambda (n) (+ n 2)))
Run Code Online (Sandbox Code Playgroud)

当然,该语言支持两种形式,因此最终归结为风格.对我而言,在使用define所有函数时,使用时有一个吸引人的一致性lambda:第一个参数始终是符号,第二个参数只是任何旧表达式.事实lambda就像任何旧表达式一样,是任何功能程序员学习的最重要的事情之一.

  • +1以与声明变量相同的方式考虑声明函数令人耳目一新:左边的名字,右边的值. (6认同)
  • "并且lambda就像任何旧表达式一样,这是任何功能程序员学习的最重要的事情之一" - 在我阅读你的解释之前,我不清楚这一点. (2认同)

Jav*_*ier 14

最初,define只有一个语法,将变量设置为一个值.这就是这些古老(和永恒)书籍中使用的风格.稍后,define获得了一个不同的语法作为快捷方式,这是你正在使用的.

只是为了好玩,搜索您的Scheme库,您可能会发现一个宏,它将非lambda表单扩展为旧的lambda表单.

  • 不是真的 - 自1978年第一次修订报告以来,"新"的"定义"形式一直是该语言.本书中使用明确的lambdas的选择是一种风格/教学方式. (9认同)

erj*_*ang 8

您可以看到您的Scheme将这些快捷方式(宏)扩展为使用expand(如果支持):

mzscheme 4.2.4(与DrScheme合作):

> (expand '(define (add1 x) (+ 1 x)))
#<syntax (define-values (add1) (lambda...>
(define-values
  (add1)
  (lambda (x) (apply + '1 x)))
Run Code Online (Sandbox Code Playgroud)

Chez Scheme 8.0:

> (expand '(define (add1 x) (+ 1 x)))
(begin
  (set! add1
    (lambda (x)
      (+ 1 x)))
  (void))
Run Code Online (Sandbox Code Playgroud)

lambda出现纯如白昼.

  • 只是去展示宏在Scheme中的重要性,甚至`define`也是一个宏! (3认同)