Scheme 什么是「;return";计划中?
我正在尝试将一些python代码翻译成schemeScheme 什么是「;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中没有显式的返回关键字-它比这个简单得多,表达式序列中最后一个
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
)