2013-05-21 32 views
3

R5RS说匹配值例子...如何实现呼叫与值在R5RS

值可能被定义如下:

(define (values . things) 
    (call-with-current-continuation 
    (lambda (cont) (apply cont things)))) 

没有,不过,请说明如果通过这种方式实现值,可以如何实现与值调用。所以,如果以这种方式实现值,那么如何实现值调用? (这是因为我试图获得一些使用call-with-value来处理TinyScheme的代码,它不支持它,我通过伪造值和使用列表调用值进行管理,但是, - 当我看到这个在R5RS,我想知道这可能是一个更好的解决方法)

回答

1

简短的回答是:你可以用” t

值的漂亮实现并没有改变这样一个事实,即如果你没有任何方法来戳这些值,就无法实现其他过程。如果你有办法窥视,那么你可以用其他方式来实现其他方法。

(+ (values 4 5)) 
(apply + (values 4 5)) 

不起作用,这就是为什么您需要这些其他原语。

当时说。返回更多值和返回列表与值之间没有区别,因为差异是优化。你可以制作一个把它们当作绑定的宏,然后你使用它们的方式也是一样的。性能的差异是一些指针跳跃和一些consing,对于任何lisp实现来说都是合理的。继承人,将工作给你的代码简约实施是正确的:

(define values list) 
(define (call-with-values producer consumer) 
    (apply consumer (producer))) 
+0

您提供的基于列表的版本正是我使用的版本。应该注意的是,除了优化差异之外,还可以将值的“真实”实现用作身份识别功能,该解决方法可以解决此问题。 (而且我实际上碰到了我正在使用的代码。) –

+0

所以,现在我想知道为什么R5RS甚至包含这个例子。 –

+1

@RobertFisher通过使用Kent Dybvig的神奇令牌技巧,您可以将其作为身份使用。 RnRS规范是(也)在那里的实施者,所以这是我脑海中的实施提示。我想象(有趣的)=> b就在申请之前,在申请之前有一个有趣的堆栈,并且在完全CPS版本的计划之后继续。 – Sylwester

3

肯特Dybvig定义call/ccvaluescall-with-valuesthusly

(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)))))) 
+0

这是因为它回答了需要执行值并调用与 - 值缺少他们实现一个很好的答案。我真的希望有一个与值来自R5RS的示例兼容的值调用实现或解释为什么它不能完成。 –

+0

为什么包含call/cc?如果没有这个调用/ cc,这些版本的值和调用值将会工作吗? –

+0

阅读Dybvig原创的链接(关于“如此”一词);我所做的只是复制它。但我很肯定答案是“不”。 – user448810