Scheme 什么是「;return";计划中?

Scheme 什么是「;return";计划中?,scheme,Scheme,我正在尝试将一些python代码翻译成scheme def test(x): if x > 1: do something if x > 10: return if x == 4: do something test(11) 我没有在计划中找到“回报”。当x>10时,我想退出测试函数。 如何在方案中模拟“回报”? (我在用诡计) 感谢在Scheme中没有显式的返回关键字-它比这个简单得多,表达式序列中最后一个

我正在尝试将一些python代码翻译成scheme

def test(x):
    if x > 1:
        do something
    if x > 10:
        return
    if x == 4: 
        do something
test(11)
我没有在计划中找到“回报”。当x>10时,我想退出测试函数。 如何在方案中模拟“回报”? (我在用诡计)
感谢

在Scheme中没有显式的
返回
关键字-它比这个简单得多,表达式序列中最后一个表达式的值就是返回的值。例如,您的Python代码将转换为这个值,并注意到
(>x10)
大小写必须移动到底部,因此如果是真的,它可以使用
#f
值立即退出函数

(define (test x)
  (if (> x 1)
      (do-something))
  (if (= x 4)
      (do-something))
  (if (> x 10)
      #f))

(test 11)
=> #f
事实上,在对条件进行重新排序之后,我们可以删除最后一个条件,但要注意:根据Guile的说法,如果
x
不是
4
,则将返回一个未指定的值-换句话说,在每种情况下都应始终返回一个值,
if
表达式应同时包含后续部分和替代部分

(define (test x)
  (if (> x 1)
      (do-something))
  (if (= x 4)
      (do-something)))

(test 11)
=> unspecified

顺便说一句,我相信Python代码中的逻辑有点不正确。每当传递大于
1
x
值时,将始终计算第一个条件,但如果该值小于或等于
1
,则Python中的返回值将为
None
,Scheme中的返回值未指定。另外,原始函数没有显式返回值-在Python中,这意味着将返回
None
,在Scheme中,如果
x
恰好是
4
,则返回值将是
(做点什么)
,或在任何其他情况下未指定。

Scheme的隐式
返回可以通过比较如何在Python和Scheme中实现简单函数(如
square
)来说明

在Python中:

def square(x):
   return x*x;
在计划中:

(define (square x)
  (* x x))

在Racket中,最直译的是:

#lang racket    
(define (test x)
  (let/ec return
    (when (> x 1)
      (do-something))
    (when (> x 10)
      (return 42))
    (when (= x 4)
      (do-something))))

(define (do-something)
  (display "!"))
(test 11)
let/ec
是let/escape continuation的缩写。在手册中查找所选方案实施的等效控制结构


该示例显示了一个!然后返回42。

正如其他人所说,函数中最后一个表达式的值是它的返回值,因此您只需在代码中安排独占执行路径,即可实现此效果

(if)
是方案中的基本分支操作:

(define (test x)
    (if (> x 1)      
        (do_something)
        #f)
    (if (> x 10)
        #f                ; return #f
        ;; else:
        (if (= x 4)
           (do_something)
           ;; else:
           #f)))

(test 11)
或者我们可以使用
cond
来避免代码中不必要的嵌套结构:

(define (test x)
    (if (> x 1)
        (do_something)
        #f)
    (cond
       ( (> x 10)  #f)
       ( (= x 4)   (do_something))
       ( else      #f)))

您可以使用
call/cc

(define (test x) (call/cc (lambda (k)
                          (if x 
                             (k x)
                             (k))
                          (display "never displayed"))))
您可以使用
(k)
不返回任何值


阅读。

当我尝试实现“平铺”功能以多次复制列表时,我遇到了与您相同的问题。其思想是1)创建一个变量来存储临时结果;2) 在for循环中使用“append”函数;3) 返回临时结果

解决方案似乎很简单,如下所示:

(define (tile ls n) 
    (define r (list ))
    (do ((i 0 (+  i 1)))
        ((> i (- n 1)))
        (begin
            (set! r (append r ls))
        )
    )
    r
)

实际上,一个单独的变量名本身会让整个函数返回这个变量的值。这是因为Scheme总是将最后执行的语句作为该函数的值返回。

这并不是python代码的忠实翻译,它会执行第1部分和第2部分的操作。@amalloy你说得对,我用直接翻译更新了我的答案更忠实的翻译是
(define(test x)如果(>x1)(做某事))(如果(>x10))(如果(=x4)(做某事))
,因为
if(x)返回;{block}
相当于
if(!x){block}
@amalloy:你可以在这里使用
call/cc
作为转义继续:)这是一个计划问题,而不是一个骗局问题。将
let/ec
替换为
call/cc
以直接帮助OP有多困难?因此在您的示例中
做一些事情
做一些会导致副作用的事情?也许如果你说函数应该做什么,我们可以制作一个更惯用的Scheme版本供你查看。到目前为止,答案试图模仿您的代码,这是一个非常糟糕的方案。
(define (tile ls n) 
    (define r (list ))
    (do ((i 0 (+  i 1)))
        ((> i (- n 1)))
        (begin
            (set! r (append r ls))
        )
    )
    r
)