我目前在大学攻读课程计划,在看一些练习时,我遇到了这个问题。 教授还没回答我以前的邮件,因此我有更多机会在这里更快地收到答案。
鉴于此代码
(define (list-iter-cc lst)
(call/cc
(lambda (return)
(for-each
(lambda (x)
(call/cc (lambda (next-step)
(return (cons x next-step)))))
lst)
'end)))
我必须用它来编写语法为
的iter
宏
(iter <a variable symbol> in <a list> <code>)
示例:
(iter x in '(1 2 3)
(display x)
(newline))
由于我无法理解list-iter-cc
我去了解解决方案,我也不了解。解决方案:
(define-syntax iter2
(syntax-rules (-> in)
((_ var in lst code ...)
(let loop ((head (list-iter-cc lst)))
(unless (eq? head 'end)
(let ((var (car head)))
code ...
(loop ((cdr head)))))))))
要解开宏我尝试编写以下内容
> (define head (list-iter-cc '(1 2 3 4)))
> head
'(1 . #<continuation>)
> (let ( (var (car head))) (display var))
1
> (define head2 (cdr head))
> (let ( (var2 (car head2)) ) (display var2))
Xxx X car: contract violation
expected: pair?
given: #<continuation>
>
这正是我认为会发生的事情。
list-iter-cc
在第一个lambda内的for-each的第一次迭代中调用return continuation,返回cons x next-step
。
x
是列表的第一个元素,next-step
是一个延续。
1)。 next-step
的内容是什么? for-each
的以下迭代?如何在最后一次迭代后评估'end
?
2)。假设在宏head (list-iter-cc lst)
中'(1 . #<continuation>)
为1
, car 为var (car head)
并显示,但在循环显示 cdr 之后,2
将是延续的汽车!它怎么可能评估为3
然后'end
然后java.lang.UnsupportedOperationException: Java Runtime Environment (JRE) version 1.8 is not supported by this driver.
Use the sqljdbc4.jar class library, which provides support for JDBC 4.0.
,以及为什么在我尝试编写以理解它的代码中不会发生这种情况?
任何帮助都会受到赞赏,特别是可以一步一步指导我的帮助。
答案 0 :(得分:4)
我们可以将其重新编写为
(define list-iter-cc
(lambda (lst)
(call/cc
(lambda (return)
(for-each
(lambda (x)
(call/cc (lambda (next-step)
(return (cons x next-step)))))
lst)
'end))))
所以它是一个lambda函数,参数名为lst
。调用此函数时,lst
设置为像往常一样保存函数调用的实际参数。然后,call/cc
设置名为return
的延续以保持当前的延续......这是什么?此时, next-to-do 只是将值返回给list-iter-cc
的来电者。
这意味着,调用(return a)
会立即将a
的值返回给list-iter-cc
的来电者,就好像函数list-iter-cc
完成了计算一样。
现在,
(for-each
(lambda (x)
(call/cc (lambda (next-step)
(return (cons x next-step)))))
lst)
输入。它为列表lst
中的每个元素调用其lambda参数,因此得到名称x
。
那么,对于x
中的第lst
个拳头,会发生什么?
(call/cc (lambda (next-step)
(return (cons x next-step))))
被调用。即它设置next-step
以立即保存当前延续,并从整个函数list-iter-cc
中返回!
它返回什么?对(x . <next-step>)
。并且什么打电话给(next-step)
是什么意思?这意味着要返回for-each
的正文,它会转到lst
中的下一个元素,(如果有的话)。如果没有,则退出for-each
的循环体,并且'end
> 返回<{1}}函数list-iter-cc
的最后一个表达式值完成计算!
那么,我们如何使用它呢?例如,像这样:
(define (qq lst)
(let ([a ;; <<= ; control returns here
(list-iter-cc lst)])
(unless (eq? a 'end) ; if it's not past-last-element
(let ([val (car a)]) ; take the actual value
(display val) ; use it
(newline)
((cdr a)))))) ; run the `next-step` continuation
当运行(cdr a)
中的延续时,控件会跳回list-iter-cc
的呼叫网站。请记住,&#34; 接下来要做的事情&#34;是&#34;只是为list-iter-cc
的来电者返回一个值&#34;?然后使用列表中的下一个值重新输入外部let
的正文。
然后需要将其转换为宏,这应该是直截了当的。
我注意到你的教授在那里使用命名循环,宏调用(loop ((cdr a)))
。但是,延续不会返回其值,因此,loop
的下一次迭代未输入,因为调用了loop
。控件跳转作为延续的一部分,如我的示例函数中所示(当我在DrRacket中测试它时它起作用了。)
更新:关于您的成绩单,head2
已经是#<continuation>
,它没有car
- 它不是pair?
1}}。相反,请参阅以下内容:
> (define head #| <<= |# (list-iter-cc '(1 2 3 4))) ; control returns here
> head
'(1 . #<continuation>)
> (let ( (var (car head))) (display var)) ; your code
1
> ((cdr head)) ; this is how we run it!
> head
'(2 . #<continuation>)
>
什么?你看到刚刚发生了什么吗? head
被重新定义了!再次,
> ((cdr head))
> head
'(3 . #<continuation>)
>
为什么呢?因为运行延续意味着控件返回其调用站点 - 这里,意味着&#34;定义变量head
以保存提供的值,并返回到REPL&#34;