在 scheme 中定义 goto

Posted

技术标签:

【中文标题】在 scheme 中定义 goto【英文标题】:Define goto in scheme 【发布时间】:2020-02-16 11:36:07 【问题描述】:

作为学习 call/cc 和宏的练习,我尝试定义 goto。

(define-syntax label
  (syntax-rules ()
           ((_ name)
        (begin
          (define name)
          (call/cc (lambda (c) (set! name c)))))))

(define (goto label) (label))

(define i 0)
(label start)
(display i) (newline)
(set! i (+ i 1))
(if (< i 3) (goto start))
(display "done") (newline)

它在 guile-2.0 中工作,但在 chez 方案和球拍 (r6rs) 中它只是打印

0
done

哪个实现是正确的?

【问题讨论】:

【参考方案1】:

我认为顶层在不同的实现中是不同的。对于 Racket,call/cc 捕获到单个最顶层表达式的延续,而不是整个程序。我认为 Guile 可以捕捉到整个程序。因此有区别。

您可以通过在函数中编写代码来获取 Guile 的行为:

#lang r5rs

(define-syntax label
  (syntax-rules ()
    ((_ name)
     (begin
       (define name #f)
       (call-with-current-continuation (lambda (c) (set! name c)))))))

(define (goto label) (label))

(define (main)
  (define i 0)
  (label start)
  (display i) (newline)
  (set! i (+ i 1))
  (if (< i 3) (goto start) #f)
  (display "done") (newline))

(main)

这个输出:

0
1
2
done

请注意,如果您使用 Racket,您可以创建新语言并重新定义顶层(通过 #%module-begin)来获取 Guile 的行为,而无需对程序进行任何修改。

【讨论】:

以上是关于在 scheme 中定义 goto的主要内容,如果未能解决你的问题,请参考以下文章

在 Scheme / Racket 中 let 的 lambda 定义是啥? [复制]

Scheme - 嵌套定义混淆

第一次使用Url scheme时App中iOS自定义Url Scheme打不开

自定义URL Scheme启动应用

语句goto不能跨变量定义?

ios和android应用都可以注册自定义url scheme吗