Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the "return" in scheme?

Tags:

scheme

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

like image 513
scot Avatar asked Apr 27 '14 19:04

scot


People also ask

What is begin in Scheme?

A begin returns the value of the last expression in the sequence. For example, the begin expression above returns the value returned by the call to bar .

What is the work of return?

A return statement ends the execution of a function, and returns control to the calling function. Execution resumes in the calling function at the point immediately following the call. A return statement can return a value to the calling function. For more information, see Return type.

What is let Scheme?

In Scheme, you can use local variables pretty much the way you do in most languages. When you enter a let expression, the let variables will be bound and initialized with values. When you exit the let expression, those bindings will disappear.


4 Answers

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.

like image 90
Óscar López Avatar answered Oct 10 '22 14:10

Óscar López


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.

like image 32
soegaard Avatar answered Oct 10 '22 14:10

soegaard


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))
like image 41
R Sahu Avatar answered Oct 10 '22 14:10

R Sahu


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)))
like image 21
Will Ness Avatar answered Oct 10 '22 15:10

Will Ness