我目前正在通过great article on Y-combinator完成此Mike Vanier。根据解释,删除了以下行:
事实证明,任何let表达式都可以使用以下公式转换为等效的lambda表达式:
fragments
本文通过转换说明了这一陈述:
getstring
为:
(let ((x <expr1>)) <expr2>)
==> ((lambda (x) <expr2>) <expr1>)
现在,我了解上面的两个代码段是如何以及为何相同,但我无法理解将(define (part-factorial self)
(let ((f (self self)))
(lambda (n)
(if (= n 0)
1
(* n (f (- n 1)))))))
转换为(define (part-factorial self)
((lambda (f)
(lambda (n)
(if (= n 0)
1
(* n (f (- n 1))))))
(self self)))
的一般方程式:
let
我很欣赏精心解释。
答案 0 :(得分:4)
我最终弄清楚了自己=)。
我遗漏的一点是:
lambda
(let ((x <expr1>)) <expr2>)
==> ((lambda (x) <expr2>) <expr1>)
位于(let ((x <expr1>)) <expr2>)
==> ((lambda (x) <expr2>) <expr1>)
内的某处,所以它更像是:
x
话虽如此,如果我们将<expr2>
替换为(let ((x <expr1>)) <expr-containing-x>)
==> ((lambda (x) <expr-containing-x>) <expr1>)
:
x
以及:
f
并以不同的颜色突出显示(define (part-factorial self)
(let ((f (self self)))
(lambda (n)
(if (= n 0)
1
(* n (f (- n 1)))))))
,(define (part-factorial self)
((lambda (f)
(lambda (n)
(if (= n 0)
1
(* n (f (- n 1))))))
(self self)))
和x
,转换公式应该变得清晰:
答案 1 :(得分:4)
你应该想象一下,有一个非常小的lisp语言有lambda
但不是let
。你想做的事:
(let ((nsq (square n)))
(+ nsq nsq))
您知道nsq
是一个新变量,let
的主体可以成为一个函数:
(lambda (nsq) (+ nsq nsq))
然后你需要使用它来获得相同的值:
((lambda (nsq) (+ nsq nsq)) (square n))
想象一下,您的简单方案有宏,因此,您实现为let
:
(define-syntax let
(syntax-rules ()
[(let ((binding value) ...)
body ...)
((lambda (binding ...)
body ...)
value ...)]))
请注意,在许多实现中,这实际上就是这种方式。
答案 2 :(得分:2)
(let ((x 42)) <body>)
可让您打开一个可用变量的新环境。在编程语言术语中,我们称它“打开一个新的框架”。
当您撰写x
时,您会在<body>
内创建42
可用的框架,并为其指定值lambda
。
好吧,还有另一个工具可以让你打开新的框架。实际上,它通常是构建更抽象结构的基本块:它被称为lambda
。
(lambda (x) <body>)
打开一个新的框架,其框架可以使用其参数。
当您撰写x
时,您可以<body>
使用此功能的lambda
。
let
和let
之间的唯一区别是x
会立即为lambda
分配值,而<body>
会等待该值作为参数。< / p>
因此,如果您想使用lambda
打包带有直接指定值的((lambda (x) <body>) 42)
,则只需传递该值!
(let ((x 42)) <body>)
这使它完全等同于:
.arrowUp {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid black;
margin-left: -10px;
}