R5RS说......
值可能定义如下:
(define (values . things) (call-with-current-continuation (lambda (cont) (apply cont things))))
但是,它没有说明如果以这种方式实现值,如何实现call-with-values。那么,如果以这种方式实现值,那么如何实现call-with-values?
(这是因为我试图获得一些使用call-with-values来处理TinyScheme的代码,它不支持它。我通过伪造值和使用列表调用值来管理,但是 - 当我在R5RS中看到这个时 - 我想知道这是否是一个更好的解决方法。)
答案 0 :(得分:3)
Kent Dybvig定义call/cc
,values
和call-with-values
thusly:
(define call/cc call/cc)
(define values #f)
(define call-with-values #f)
(let ((magic (cons 'multiple 'values)))
(define magic?
(lambda (x)
(and (pair? x) (eq? (car x) magic))))
(set! call/cc
(let ((primitive-call/cc call/cc))
(lambda (p)
(primitive-call/cc
(lambda (k)
(p (lambda args
(k (apply values args)))))))))
(set! values
(lambda args
(if (and (not (null? args)) (null? (cdr args)))
(car args)
(cons magic args))))
(set! call-with-values
(lambda (producer consumer)
(let ((x (producer)))
(if (magic? x)
(apply consumer (cdr x))
(consumer x))))))
答案 1 :(得分:1)
简短的回答是:你不能
值的漂亮实现并没有改变这样一个事实,即如果你没有任何方法可以实现其他程序,那么它们就无法实现其他程序。如果你有一种方法可以窥视,那么你可以用其他方式实现其他方法。
(+ (values 4 5))
(apply + (values 4 5))
不起作用,这就是你需要那些其他原语的原因。
当说的时候。返回更多值和返回列表与值之间没有区别,因为区别在于优化。您可以创建一个将它们都视为绑定的宏,然后您使用它们的方式将是相同的。性能上的差异是一些指针跳跃和一些消耗,这对于任何lisp实现都是合理的。如果你的代码是正确的,那么这将是一个简单的实现:
(define values list)
(define (call-with-values producer consumer)
(apply consumer (producer)))