首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方案/“经验丰富的阴谋家”:关于"try“函数定义的语法问题

方案/“经验丰富的阴谋家”:关于"try“函数定义的语法问题
EN

Stack Overflow用户
提问于 2020-02-19 13:34:22
回答 2查看 169关注 0票数 1

在他们的书“经验丰富的阴谋家”中,费莱森和弗里德曼介绍了try函数。根据http://community.schemewiki.org/?seasoned-schemer,这个函数可以定义为

代码语言:javascript
复制
(define-syntax try
  (syntax-rules ()
    ((try var a . b)
     (letcc success 
       (letcc var (success a)) . b))))

其中letcc被定义为

代码语言:javascript
复制
(define-syntax letcc 
  (syntax-rules () 
    ((letcc var body ...) 
     (call-with-current-continuation 
       (lambda (var)  body ... ))))) 

现在,虽然我了解try做了什么以及如何使用它,但我很难遵循它的正式定义。letcc在行中的success(letcc var (success a)) . b的应用中点的确切含义是什么?

代码语言:javascript
复制
(letcc success 
       (letcc var (success a)) . b)

try的?或者可能被问到不同的问题:如果在try中调用var,那么在var的定义中哪一部分可以确定try被求值为b

编辑1:对不起,letcc的定义不完整。增加了缺失的第一行。

编辑2:下面的代码可以在球拍中运行。

代码语言:javascript
复制
(define-syntax letcc
   (syntax-rules ()
                 ((letcc var body ...)
                  (call-with-current-continuation
                    (lambda (var)  body ... )))))

 (define-syntax try
   (syntax-rules ()
                 ((try var a . b)
                  (letcc success
                         (letcc var (success a)) . b))))

(try var (+ 1 1) 4)
; output: 2

(try var (var '(2)) 4)
; output: 4
EN

回答 2

Stack Overflow用户

发布于 2020-02-19 17:44:52

我不是Scheme宏语法复杂性方面的专家,但我认为try的一个等价定义是:

代码语言:javascript
复制
(define-syntax try 
  (syntax-rules () 
    ((try var a b ...) 
     (letcc success 
       (letcc var (success a)) b ...))))

我觉得这很容易读懂。

(try e <a> <b> <c>) (任何一个版本,至少在球拍中)然后扩展到

代码语言:javascript
复制
(letcc success
  (letcc e
    (success <a>))
  <b> <c>)))

因此,当计算<a>时,e是一个延续,它从内部letcc表单返回参数,在那里它们被忽略。如果调用了e,那么就会以正常的方式对<b><c>进行评估(我只在那里放置了一个以上的东西,因为我可以,它处理整个. ... )。如果e<a>的计算过程中没有被调用,那么success就会被调用,并且它也是一个延续,然后返回整个表单中计算<a>的结果。

至少我认为这就是发生的事。

下面是一块球拍,我用它来测试我理解的东西。

代码语言:javascript
复制
(module+ test
  (require rackunit))

(define-syntax let/cc 
  (syntax-rules () 
    ((let/cc var body ...) 
     (call-with-current-continuation 
       (lambda (var) body ... ))))) 

(define-syntax try 
  (syntax-rules () 
    ((try var a b ...) 
     (let/cc success 
       (let/cc var (success a)) b ...))))

(module+ test
  (check-eqv?
   (try fail (+ 1 1) 4)
   2)

  (check-eqv?
   (try fail (fail '(2)) 4)
   4)

  (check-eqv?
   (try fail
        (begin 1 (fail) (error "failed to fail"))
        4 5 6)
   6))
票数 2
EN

Stack Overflow用户

发布于 2020-02-20 07:21:13

让我们试着看看会发生什么。我在用麻省理工学院的计划。

文件try.scm:

代码语言:javascript
复制
(define-syntax letcc
  (syntax-rules ()
     ((letcc var body ...)
      (call-with-current-continuation
          (lambda (var)  body ... )))))

(define-syntax try
  (syntax-rules ()
     ((try var a . b)
      (letcc success
        (letcc var (success a)) . b))))

(try var (+ 1 1) 4)

(try var (var '(2)) 4)

第一步:编译文件:

代码语言:javascript
复制
> (sf "try")

这将生成try.bin

第二步,打印desugared语法:

代码语言:javascript
复制
> (pp (unsyntax (fasload "try")))


;Loading "try.bin"... done
 ................
 (call-with-current-continuation
  (lambda (success)
    (call-with-current-continuation 
        (lambda (var) (success (+ 1 1))))
    4))
 (call-with-current-continuation
  (lambda (success)
    (call-with-current-continuation 
        (lambda (var) (success (var '(2)))))
    4)))

现在,您将显式地看到执行的内容,从而看到结果。

(try var (+ 1 1) 4)的情况下,您跳出2个嵌套的calcc,因为您使用值2调用success,而在(try var (var '(2)) 4)中,您跳出了1层,第一个连续序列中的4将被返回。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60301595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档