I am trying to translate some python code to scheme.
def test(x):
if x > 1:
do something
if x > 10:
return
if x == 4:
do something
test(11)
I did not find the "return" in scheme. I want to quit from the test function when x >10.
How can I simulate the "return" in scheme?
(I am using guile)
Thanks
In Scheme there isn't an explicit return
keyword - it's a lot simpler than that, the value of the last expression in a sequence of expressions is the one that gets returned. For example, your Python code will translate to this, and notice that the (> x 10)
case had to be moved to the bottom, so if it's true it can exit the function immediately with a #f
value.
(define (test x)
(if (> x 1)
(do-something))
(if (= x 4)
(do-something))
(if (> x 10)
#f))
(test 11)
=> #f
In fact, after reordering the conditions we can remove the last one, but beware: an unspecified value will be returned if x
is not 4
, according to Guile's documentation - in other words, you should always return a value in each case, and an if
expression should have both consequent and alternative parts.
(define (test x)
(if (> x 1)
(do-something))
(if (= x 4)
(do-something)))
(test 11)
=> unspecified
And by the way, I believe the logic in the Python code is a bit off. The first condition will always be evaluated whenever a value of x
greater than 1
is passed, but if it is less than or equal to 1
the returned value in Python will be None
and in Scheme is unspecified. Also the original function isn't explicitly returning a value - in Python this means that None
will be returned, in Scheme the returned value will be either (do-something)
if x
happens to be 4
, or unspecified in any other case.
In Racket the most literal translation is:
#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)
The let/ec
is short for let/escape-continuation. Look up the equivalent control structure in the manual for your Scheme implementation of choice.
The example displays one ! and then returns 42.
The implicit return
of Scheme can be illustrated by comparing how you can implement a simple function, such as square
, in Python and scheme.
In Python:
def square(x):
return x*x;
In Scheme:
(define (square x)
(* x x))
As others have said, the last expression's value in a function is its return value, so you just have to arrange for exclusive execution pathways in your code, to achieve this effect.
(if <test> <consequent> <alternative>)
is the basic branching operation in Scheme:
(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)
Or we could use cond
to avoid the needlessly nested structure in the code:
(define (test x)
(if (> x 1)
(do_something)
#f)
(cond
( (> x 10) #f)
( (= x 4) (do_something))
( else #f)))
You may use call/cc
(define (test x) (call/cc (lambda (k)
(if x
(k x)
(k))
(display "never displayed"))))
> (test 3)
3
> (test #f)
>
You can return no value using (k)
.
Read about Continuations.