SICP 图片语言练习 Lambda 论证
SICP The Picture Language Exercise Lambda Argument
(define (segments->painter segment-list)
(lambda (frame)
(for-each
(lambda (segment)
(draw-line
((frame-coord-map frame)
(start-segment segment))
((frame-coord-map frame)
(end-segment segment))))
segment-list)))
有些人之前已经看过这个 sicp 示例,但对于初学者来说,有一个简短的解释:segments->painter 过程从段列表中获取参数,该列表的值是由向量组成的段。 for-each 过程就像 map 一样,但 returns 是一个值列表,它执行打印等操作,或者在这段代码中画线。 frame-coord-map 根据单位正方形框架缩放框架。我在这段代码中不明白的是第一个 lambda 函数从哪里获取它的参数(框架)。
让我们看一个更简单的例子:
(define (adder x)
(lambda (y)
(+ x y))
类似的问题是,“如果只用 x
就可以调用 adder
,y
从哪里来?”正如评论中所讨论的,它来自调用 lambda adder
returns 的人。你可以写:
(define plus5 (adder 5))
(plus5 8) ; 13
(plus5 1) ; 6
在你调用adder
的时候,没有y
。在接下来的调用中,y
是 8,之后是 1.
同样在您的实际代码中,没有 frame
直到有人调用返回的 lambda。
这里是currying
的案例。
在你的代码中
(define (segments->painter segment-list)
(lambda (frame)
...))
当你调用segments->painter
时,scheme会return一个类型的对象,让我们调用figure
。当您在此对象上应用图形框架时,scheme 将能够绘制您的对象。
(define obj1 (segments->painter seg1))
obj1
是类型为 figure
的对象,并且此对象能够接收帧。它在接收到一帧时只能执行一个操作,即在该帧中绘制:(obj1 frame1)
、(obj1 frame2)
等是您可以对该对象执行的操作。
在将图形数据应用于某个对象之前,谈论该对象确实有意义,但谈论该对象的真实表示是没有意义的。在您的情况下,该对象可以执行一个操作:绘制。
在为 figure
对象调用构造函数和绘制对象之间,您可以进行一些(静态)预处理,这样在您调用绘图方法的那一刻,您已经预先计算了一些东西。
这就是类型在编程语言中的实现方式。 Peter Henderson 的这种语言是对类型和组合器的首次介绍。这将在第 4 章中进一步发展,其中解释器使用一些预先计算的数据来执行(它将列表输入格式转换为内部格式)。
(define (segments->painter segment-list)
(lambda (frame)
(for-each
(lambda (segment)
(draw-line
((frame-coord-map frame)
(start-segment segment))
((frame-coord-map frame)
(end-segment segment))))
segment-list)))
有些人之前已经看过这个 sicp 示例,但对于初学者来说,有一个简短的解释:segments->painter 过程从段列表中获取参数,该列表的值是由向量组成的段。 for-each 过程就像 map 一样,但 returns 是一个值列表,它执行打印等操作,或者在这段代码中画线。 frame-coord-map 根据单位正方形框架缩放框架。我在这段代码中不明白的是第一个 lambda 函数从哪里获取它的参数(框架)。
让我们看一个更简单的例子:
(define (adder x)
(lambda (y)
(+ x y))
类似的问题是,“如果只用 x
就可以调用 adder
,y
从哪里来?”正如评论中所讨论的,它来自调用 lambda adder
returns 的人。你可以写:
(define plus5 (adder 5))
(plus5 8) ; 13
(plus5 1) ; 6
在你调用adder
的时候,没有y
。在接下来的调用中,y
是 8,之后是 1.
同样在您的实际代码中,没有 frame
直到有人调用返回的 lambda。
这里是currying
的案例。
在你的代码中
(define (segments->painter segment-list)
(lambda (frame)
...))
当你调用segments->painter
时,scheme会return一个类型的对象,让我们调用figure
。当您在此对象上应用图形框架时,scheme 将能够绘制您的对象。
(define obj1 (segments->painter seg1))
obj1
是类型为 figure
的对象,并且此对象能够接收帧。它在接收到一帧时只能执行一个操作,即在该帧中绘制:(obj1 frame1)
、(obj1 frame2)
等是您可以对该对象执行的操作。
在将图形数据应用于某个对象之前,谈论该对象确实有意义,但谈论该对象的真实表示是没有意义的。在您的情况下,该对象可以执行一个操作:绘制。
在为 figure
对象调用构造函数和绘制对象之间,您可以进行一些(静态)预处理,这样在您调用绘图方法的那一刻,您已经预先计算了一些东西。
这就是类型在编程语言中的实现方式。 Peter Henderson 的这种语言是对类型和组合器的首次介绍。这将在第 4 章中进一步发展,其中解释器使用一些预先计算的数据来执行(它将列表输入格式转换为内部格式)。