从语句内部的函数返回

时间:2015-04-29 03:54:51

标签: scheme lisp racket

我要做的就是使用when语句返回一个值:( 我想要的功能:

if(x)
    return y

我正在尝试使用:

(when (x) y)

但是when语句没有以退出函数并返回y的方式进行评估。它很高兴继续下一行。有没有办法做到这一点,而不是一个非常难看的if-else块? mzscheme / racket不允许单臂ifs。

4 个答案:

答案 0 :(得分:7)

好的,我将成为"那个家伙&#34 ;;使用"极其丑陋的"把剩下的功能放在" else"有条件的;它使代码更易于阅读和理解。当我试图理解函数的作用时,我不想扫描所有代码搜索隐藏的return和奇怪的控制流。一个直截了当的“如果'或者' cond'非常清楚在什么情况下将使用每一段代码。

如果你认真思考为什么你喜欢"当+返回"解决方案,我怀疑在某种程度上,你想要抓住那个后卫并且#34;让它脱离困境"你的认知过程,让其余的功能成为焦点。这(我声称)是一个微妙的错误的配方。

搜索你的感受;你知道这是真的!

编辑:一只蚂蚁爬过我的笔记本电脑。这是我说出真相的标志。

答案 1 :(得分:5)

Racket中的一个简单方法:

(define (foo x)
  (let/ec return
    (when (= x 0)
       (return 'zero))
    'not-zero))

这里ec代表逃避延续,它比完全延续便宜。

答案 2 :(得分:2)

您将此标记为Common Lisp和Racket,它们是两种完全不同的语言。如果您正在使用Racket或Scheme并希望尽早从函数返回,则可以使用延续来执行此操作:

(define (my-function x y)
  (call-with-current-continuation
    (lambda (return)
      (when x (return y))
      ;; Rest of code not evaluated if X is true
      )))

在包括Racket在内的一些Scheme实现中,call-with-current-continuation也绑定到call/cc,但call-with-current-continuation是唯一可以使用continuation的可移植方式。

上述内容甚至比使用cond语句更加丑陋。如果你想摆脱所有额外的废话,你可以定义一个宏来创建define的替代版本,自动创建延续并将其绑定到return

(define-syntax define/return
   (syntax-rules ()
      ((_ (name . args) . body)
       (define (name . args)
         (capture-vars (return)
            (call/cc (lambda (return) . body)))))))

这需要您拥有我的capture-vars宏,您可以在this answer找到它。

编辑:Leppie提供了define/return的以下实施,这更简单,因为它不需要我的capture-vars宏:

(define-syntax define/return
  (lambda (x)
    (syntax-case x ()
      [(_ (name . args) . body)
        (with-syntax
          ([return (datum->syntax #'name 'return)])
         #'(define (name . args)
             (call/cc (lambda (return) . body))))])))

编辑2:但是,如果您将return合并到另一个宏中,则很容易意外地取消define/return这样做的定义。

然后return会按照您的预期行事,而不会在语法上令人反感:

(define/return (my-function x y)
    (when x (return y))
    ;;; more code...
)

但是,如果您使用Common Lisp,情况会有所不同。在Common Lisp中,(return y)只会在定义名为block的{​​{1}}时进行编译。某些表单隐式定义名为nil的块,例如nil宏。如果没有名为loop的块,您仍然可以使用nil从命名块返回。如果您在使用return-from定义的函数中,该函数的名称也是包装该函数的块的名称,因此这将起作用:

defun

答案 3 :(得分:0)

简单:

(and (x) y)

问题是“何时”不返回值。 “和”可以。