What is the return statement in Scheme? - return

I am trying to translate this Python program to Scheme:
def test(x):
if x > 1:
print('foo')
if x > 10:
return
if x == 4:
print('bar')
test(1)
test(2) # prints 'foo'
test(4) # prints 'foo\nbar'
test(11) # prints 'foo'
What is the return statement in Scheme?

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.

I meet same question as you asked when I tried to implement a "tile" function to duplicate a list for multiple times. The idea is 1) create a variable to store the temporary result; 2) use "append" function in a for-loop; 3) return the temporary result.
The solution seems easy, as follows:
(define (tile ls n)
(define r (list ))
(do ((i 0 (+ i 1)))
((> i (- n 1)))
(begin
(set! r (append r ls))
)
)
r
)
actually a sole variable name itself will let the whole function return the value of this variable. This is because the Scheme always returns the last executed statement as the value of this function.

There is no return statement in Scheme. The body of a procedure is a sequence of expressions and the return value is the value of the last expression. So here is an equivalent Scheme program:
(define (test x)
(if (> x 1)
(display "foo\n"))
(if (not (> x 10))
(if (= x 4)
(display "bar\n"))))
(test 1)
(test 2) ; prints "foo"
(test 4) ; prints "foo\nbar"
(test 11) ; prints "foo"
You can simplify it to this program:
(define (test x)
(if (> x 1)
(display "foo\n"))
(if (= x 4)
(display "bar\n"))))

Related

delete! function for R5RS

I'm trying to write a delete! function that mutates a list and removes from it a specified value. This is the code I have so far.
(define (extend! l . xs)
(if (null? (cdr l))
(set-cdr! l xs)
(apply extend! (cdr l) xs)))
(define (delete! lis y)
(define returnLis '())
(for-each (lambda(x) (if(not(eq? x y))
(extend! returnLis x))) lis)
returnLis)
The problem I am having is that I am trying to add to an empty list which can't be done in Scheme.
Desired outcome:
(delete! '(1 2 3 4 5) 3)
=> (1 2 4 5)
Your extend function use actually would make a copy of each element in a fresh pair, but since the initial value is '() it cannot be set-cdr!. The whole point of mutating something is that old variables will continue point to the changed data and making a copy won't do that.
You need to see the pairs. You want to remove 3
[1,-]->[2,-]->[3,-]->[4,-]->[5,-]->()
So When you have found 3, you need to change the cdr of the pair that holds 2 and pint it the pair that holds 3s cdr like this:
[1,-]->[2,-]->[4,-]->[5,-]->()
Something like this then:
(define (delete lst e)
(if (and (not (null? lst)) (not (null? (cdr lst))))
(if (equal? (cadr lst) e)
(set-cdr! lst (cddr lst))
(delete (cdr lst) e))
'undefined))
(define test (list 1 2 3 4 5))
(delete lst 3)
lst ; ==> (1 2 4 5)
Notice I'm using list since a quoted literal cannot be used here since you are not allowed to change constant data like '(1 2 3 4 5). The result will be undefined or it will signal an error.
It won't work if the element in question is the first. It's because the variable points to the first pair and this only changes the pointers in pairs, not bindings. One could just switch the two first and delete the second, but in the event you have a one element list you are still stuck. Scheme implementations of mutable queues usually have a head consisting of a dummy element not considered part of the list to delete the first element.
All you need is a head-sentinel technique:
(define (delete! lis y)
(define returnLis (list 1))
(for-each (lambda(x) (if(not(eq? x y))
(extend! returnLis x))) lis)
(cdr returnLis))
Well, not all... because as it is, this is a quadratic algorithm. It re-searches the returnLis from top anew while adding each new element with extend!. Better just maintain the last cdr cell and update it:
(define (delete! lis y)
(define returnLis (list 1))
(define last-cell returnLis)
(for-each (lambda(x) (cond ((not(eq? x y))
; (extend! last-cell x)
(set-cdr! last-cell (list x))
(set! last-cell (cdr last-cell)))))
lis)
(cdr returnLis))
But, as #Sylwester points out, with this approach you shouldn't use an exclamation mark in the name, as this will return a freshly built list instead of mutating the argument's structure.

Do Racket streams memoize their elements?

Does Racket use memoization when computing large amounts of numbers from an infinite stream? So, for example, if I printed out (aka, computed and displayed) the first 400 numbers on the infinite stream of integers:
(1 2 3 ... 399 400)
And right after I asked to print the first 500 numbers on this infinite stream. Would this second set of computations use memoization? So the first 400 numbers would not be computed again?
Or does this functionality need to be coded by the user/obtained from libraries?
The built-in racket/stream library uses lazy evaluation and memoization to draw elements from a stream:
(require racket/stream)
(define (print-and-return x)
(displayln "drawing element...")
x)
(define (in-range-stream n m)
(if (= n m)
empty-stream
(stream-cons (print-and-return n) (in-range-stream (add1 n) m))))
(define s (in-range-stream 5 10))
(stream-first s)
(stream-first s)
(stream-first (stream-rest s))
The expressions passed to stream-cons are not evaluated until requested either with stream-first or stream-rest. Once evaluated, they are memoized. Notice that despite the four stream operations performed on s, only two `"drawing element..." messages are displayed.
You can use the memoize package.
GitHub source: https://github.com/jbclements/memoize/tree/master
raco pkg install memoize
Using it is as simple as replacing define with define/memo. To quote its example:
(define (fib n)
(if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
> (time (fib 35))
cpu time: 513 real time: 522 gc time: 0
14930352
> (define/memo (fib n)
(if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
> (time (fib 35))
cpu time: 0 real time: 0 gc time: 0
14930352
Also, it is generally quite easy to implement memoization yourself using a Racket hash-table.
For other Scheme implementations that use SRFI 41 streams, those streams also fully memoise all the materialised elements.
In fact, in my Guile port of SRFI 41 (which has been in Guile since 2.0.9), the default printer for streams will print out all the elements so materialised (and nothing that isn't):
scheme#(guile-user)> ,use (srfi srfi-41)
scheme#(guile-user)> (define str (stream-from 0))
scheme#(guile-user)> (stream-ref str 4)
$1 = 4
scheme#(guile-user)> str
$2 = #<stream ? ? ? ? 4 ...>
Any of the elements that aren't being printed out as ? or ... have already been memoised and won't be recomputed. (If you're curious about how to implement such a printer, here's the Guile version.)

lisp parsing for 'not'

(defun simplify (x)
(if (and (not (null x)) (listp x))
(if (and (equal '(car x) '(cadr x)) (equal '(car x) 'not))
(simplify (cddr x))
(cons (car x) (simplify (cdr x)))
)
'nil
)
)
This lisp function is meant to take an expression as an argument then remove superfluous 'not's from it and return it. It checks if the argument is a non-empty list and returns nil if it isn't (base case). If it is non-empty, I want to check if the car(x) = car(cdr(x)) = 'not'. If they aren't detected to be a pair of 'not's then it should recurse and build on a list to return. If they are detected to be both 'not' then it should still recurse but also skipping both car(x) and car(cdr(x)). Right now all this code does is return an expression identical to the argument so I assume the problem is that my condition in the nested if statement isn't being set off properly, how can I check if car(x) and cadr(x) are both 'not'?
"when you assume..."
Actually, the test is semi-ok (but you'll end up taking (car nil) if x is (not) ). The problem is the recursion. Try it on paper:
(simplify '(and (not (not y)) (or x (not (not z))))`
(car x) is not not.
so: (cons (car x) (simplify (cdr x))
Now x is '((not (not y)) (or x (not (not z))))So(car x)is(not (not y)), which is not equal tonot`. Recurse again
Now x is ((or x (not (not z)))and(car x)is(or x (not (not z)))`. But you probably get the picture.
Hint: (map simplify x) and fix your termination condition to return x if x is an atom.
(equal '(car x) '(cadr x)) is always false, because the list (car x) is different from the list (cadr x). If you want to get the car and cadr of some particular x, you need to not quote these expressions.

Scheme streams with Taylor series

I've been doing some homework, wrote some code and can't actually find the reason why it doesn't work. The main idea of this part of the work is to make a stream that will give me elements of Taylor series of cosine function for a given X (angle i guess). anyways here is my code, I'd be happy if some one could point me to the reasons it doesn't work :)
(define (force exp) exp)
(define (s-car s) (car s))
(define (s-cdr s) (force (cdr s)))
; returns n elements of stream s as a list
(define (stream->list s n)
(if (= n 0)
'()
(cons (s-car s) (stream->list (s-cdr s) (- n 1)))))
; returns the n-th element of stream s
(define stream-ref (lambda (s n)
(if (= n 1)
(s-car s)
(stream-ref (s-cdr s) (- n 1)))))
; well, the name kinda gives it away :) make factorial n!
(define (factorial x)
(cond ((= x 0) 1)
((= x 1) 1)
(else (* x (factorial (- x 1))))))
; this function is actually the equation for the
; n-th element of Taylor series of cosine
(define (tylorElementCosine x)
(lambda (n)
(* (/ (expt -1 n) (factorial (* 2 n))) (expt x (* 2 n)))))
; here i try to make a stream of those Taylor series elements of cosine
(define (cosineStream x)
(define (iter n)
(cons ((tylorElementCosine x) n)
(lambda() ((tylorElementCosine x) (+ n 1)))))
(iter 0))
; this definition should bind cosine
; to the stream of taylor series for cosine 10
(define cosine (cosineStream 10))
(stream->list cosine 10)
; this should printi on screen the list of first 10 elements of the series
However, this doesn't work, and I don't know why.
I'm using Dr.Scheme 4.2.5 with the language set to "Essentials of Programming Languages 3rd ed".
Since I was feeling nice (and nostalgic about scheme) I actually waded through your code to finde the mistakes. From what I can see there are 2 problems which keeps the code from running as it should:
If I understand your code correctly (force exp) should evaluate exp, however you directly return it (unevaluated). So it probably should be defined as (define (force exp) (exp))
The second problem is in your lambda: (lambda() ((tylorElementCosine x) (+ n 1)) ) will evaluate to the next element of the taylor series, while it should evaluate to a stream. You probably want something like this: (lambda() (iter (+ n 1)) )
I haven't checked if the output is correct, but with those modifications it does at least run. So if there are any more problems with the code the should be in the formula used.
However I'd suggest that next time you want help with your homework you at least tell us where exactly the problem manifests and what you tried already (the community does frown on "here is some code, please fix it for me" kind of questions).

Symbolic mathematical calculations in Clojure vs. F#

I have come across the following F# sample and found it intriguing.
http://www.codeproject.com/KB/net-languages/SymbolicCalcInFS.aspx
Does Clojure have language/library facilities for doing something like this with ease? It is ok to force Polish notation for formulas, if that makes things easier.
Thanks, and let me know if there are questions.
Lisp has long history in symbolic computing. See the AI case study book by Peter Norvig. Lisp provides a lot of great language features to abstract the common operations on the symbols. Sometimes you can write really concise code (more concise/short than F#).
Static languages like F# have strong type systems and convenient pattern matching on the data types. The compiler could find errors that are caught by the type system, e.g. lack of considering one special case. Thinking about types with your data could also reduce the chances for runtime error. The type inference in F# also makes F# code very concise.
I don't know much about Clojure, but here are, at least, some pointers.
The key feature that makes the F# code nice is pattern matching on algebraic data types. An algebraic data type is for example the declaration of the Expression type (that is used to represent mathematical expressions) and pattern matching is the match construct that is used to check for various known cases when implementing simplification or differentiation.
I don't think that Clojure has any built-in support for pattern matching, but it can be implemented as a library. One library that looks quite interesting is the patter-match module (in Clojars). Here is an example that uses it to implement algebraic evaluator (which is quite close to the F# article).
Another thing that appears in the F# article is active patterns (which allow you to declare and reuse patterns). I don't think that there is a Clojure library for that, but given the flexibility of the language, it should be possible to implement them too (however, they are not really that necessary in the F# article)
Symbolic differentiation was one of the first applications of lisp!
I made a blogpost about a simple symbolic differentiator. It only deals with + and *, but it is easily extended.
It was part of a series I wrote to introduce beginners to clojure at a conference in London, to show how easy it is for clojure to manipulate its own code.
Of course the cute thing is that having done the differentiation, the code can then be compiled! So you can produce differentiated versions of user input, or macros that produce functions and their derivatives, etc.
The original's here, and nicely syntax highlighted:
http://www.learningclojure.com/2010/02/clojure-dojo-4-symbolic-differentiation.html
But I've posted the code here so you can have a look:
;; The simplest possible symbolic differentiator
;; Functions to create and unpack additions like (+ 1 2)
(defn make-add [ a b ] (list '+ a b))
(defn addition? [x] (and (=(count x) 3) (= (first x) '+)))
(defn add1 [x] (second x))
(defn add2 [x] (second (rest x)))
;; Similar for multiplications (* 1 2)
(defn make-mul [ a b ] (list '* a b))
(defn multiplication? [x] (and (=(count x) 3) (= (first x) '*)))
(defn mul1 [x] (second x))
(defn mul2 [x] (second (rest x)))
;; Differentiation.
(defn deriv [exp var]
(cond (number? exp) 0 ;; d/dx c -> 0
(symbol? exp) (if (= exp var) 1 0) ;; d/dx x -> 1, d/dx y -> 0
(addition? exp) (make-add (deriv (add1 exp) var) (deriv (add2 exp) var)) ;; d/dx a+b -> d/dx a + d/dx b
(multiplication? exp) (make-add (make-mul (deriv (mul1 exp) var) (mul2 exp)) ;; d/dx a*b -> d/dx a * b + a * d/dx b
(make-mul (mul1 exp) (deriv (mul2 exp) var)))
:else :error))
;;an example of use: create the function x -> x^3 + 2x^2 + 1 and its derivative
(def poly '(+ (+ (* x (* x x)) (* 2 (* x x))) 1))
(defn poly->fnform [poly] (list 'fn '[x] poly))
(def polyfn (eval (poly->fnform poly)))
(def dpolyfn (eval (poly->fnform (deriv poly 'x))))
;;tests
(use 'clojure.test)
(deftest deriv-test
(testing "binary operators"
(is (= (let [m '(* a b)] [(multiplication? m) (make-mul (mul1 m) (mul2 m))]) [true '(* a b)]))
(is (= (let [m '(* a b)] [(addition? m) (make-add (add1 m) (add2 m))]) [false '(+ a b)])))
(testing "derivative function"
(is (= (deriv '0 'x) '0))
(is (= (deriv '1 'x) '0))
(is (= (deriv 'x 'x) '1))
(is (= (deriv 'y 'x) '0))
(is (= (deriv '(+ x x) 'x) '(+ 1 1)))
(is (= (deriv '(* x x) 'x) '(+ (* 1 x) (* x 1))))
(is (= (deriv '(* x x) 'y) '(+ (* 0 x) (* x 0))))
(is (= (deriv '(* x (* x x)) 'x) '(+ (* 1 (* x x)) (* x (+ (* 1 x) (* x 1)))))))
(testing "function creation: d/dx (x^3 + 2x^2 + 1) = 3x^2 + 4x "
(let [poly '(+ (+ (* x (* x x)) (* 2 (* x x))) 1)]
(is (= ((eval (poly->fnform poly)) 3) 46))
(is (= ((eval (poly->fnform (deriv poly 'x))) 3))))))
I haven't tried it, but Clojuratica looks very interesting.
Well, now Clojure offer powerful pattern matching libraries :
matchure : https://github.com/dcolthorp/matchure
match : https://github.com/swannodette/match
Yes, a system such as you describe now exists on Clojure! It is none other than Gerry Sussman's companion system to his -and Wisdom's- SICM (Structure and Interpretation of Classical Mechanics) book. For Clojure it's been named sicmutils, and ported by Colin Smith.
I've described it briefly elsewhere - https://stackoverflow.com/a/41646455/4070712 - but in short yes, it definitely does the four things you F# article mentions, viz.
Differentiation:
Simplification of algebraic expressions
Formatting
Parsing of expressions
and much, much more...
1) Differentiation (full partial differentiation supported)
> (defn ff [x y] (* (expt x 3)(expt y 5)))
> ((D ff) 'x 'y) ==> (down (* 3 (expt x 2) (expt y 5)) (* 5 (expt x 3) (expt y 4)))
> ;; i.e. vector of results wrt to both variables
NB. Two types of vectors are supported, "up" and "down" to accomodate covariant and contravariant expressions
2) Simplification of expressions: Oh, yes...
> (def unity (+ (square sin) (square cos)))
> (unity 'x) ==> 1 ;; yes we can deal with symbols
3) Formatting: Expressions can be rendered in TeX for beautiful display.
I can't show this easily here, but currently a Maple-style notebook/workshhet is under development, using Clojure's "Gorilla"
4) Parsing: Obviously. Converting between expressions and functions is a core part of the system.
Have a look at https://github.com/littleredcomputer/sicmutils . you don't even need Clojure to run it, you can use the supplied Java jar file.

Resources