Scheme - How do I return a function? - scheme

This function is displaying the correct thing, but how do I make the output of this function another function?
;;generate an Caesar Cipher single word encoders
;;INPUT:a number "n"
;;OUTPUT:a function, whose input=a word, output=encoded word
(define encode-n
(lambda (n);;"n" is the distance, eg. n=3: a->d,b->e,...z->c
(lambda (w);;"w" is the word to be encoded
(if (not (equal? (car w) '()))
(display (vtc (modulo (+ (ctv (car w)) n) 26)) ))
(if (not (equal? (cdr w) '()))
((encode-n n)(cdr w)) )
)))

You're already returning a function as output:
(define encode-n
(lambda (n)
(lambda (w) ; <- here, you're returning a function!
(if (not (equal? (car w) '()))
(display (vtc (modulo (+ (ctv (car w)) n) 26))))
(if (not (equal? (cdr w) '()))
((encode-n n)(cdr w))))))
Perhaps a simpler example will make things clearer. Let's define a procedure called adder that returns a function that adds a number n to whatever argument x is passed:
(define adder
(lambda (n)
(lambda (x)
(+ n x))))
The function adder receives a single parameter called n and returns a new lambda (an anonymous function), for example:
(define add-10 (adder 10))
In the above code we created a function called add-10 that, using adder, returns a new function which I named add-10, which in turn will add 10 to its parameter:
(add-10 32)
=> 42
We can obtain the same result without explicitly naming the returned function:
((adder 10) 32)
=> 42
There are other equivalent ways to write adder, maybe this syntax will be easier to understand:
(define (adder n)
(lambda (x)
(+ n x)))
Some interpreters allow an even shorter syntax that does exactly the same thing:
(define ((adder n) x)
(+ n x))
I just demonstrated examples of currying and partial application - two related but different concepts, make sure you understand them and don't let the syntax confound you.

Related

SICP Exercise 2.04

Reading SICP I am now at exercise 2.04, which is a procedural representation of cons, car and cdr, given in the book as follows:
(define (cons x y)
(lambda (m)
(m x y)))
(define (car z)
(z
(lambda (p q)
(p))))
Note, that for running the code I use racket with the following preamble in my code:
#lang racket
(define (Mb-to-B n) (* n 1024 1024))
(define MAX-BYTES (Mb-to-B 64))
(custodian-limit-memory (current-custodian) MAX-BYTES)
I also tried #lang scheme to no avail.
Here is what I understand:
About cons
cons returns a function.
This function which will apply another function given as parameter to the two parameters x and y of cons.
This means by calling cons we retain the possibility to apply a function to the two parameters and are able to treat them as some unit.
About car
car now uses the fact, that we can apply a function to the unit of 2 values given to cons, by giving a function as a parameter to the function, which we get returned from cons.
It supplies that function with a lambda expression, which always returns the first of two given values.
Usage
At first I tried the following:
(car (cons 1 2))
(car (cons 2 3))
(car (cons (cons 1 1) (cons 2 2)))
(car (car (cons (cons 1 1) (cons 2 2))))
However, that leads to errors:
:racket -l errortrace -t exercise-2.04-procedural-representation-of-pairs.rkt
application: not a procedure;
expected a procedure that can be applied to arguments
given: 1
arguments...: [none]
errortrace...:
/home/xiaolong/development/LISP/Racket/SICP/exercise-2.04-procedural-representation-of-pairs.rkt:24:6: (p)
/home/xiaolong/development/LISP/Racket/SICP/exercise-2.04-procedural-representation-of-pairs.rkt:33:0: (car (cons 1 2))
context...:
/home/xiaolong/development/LISP/Racket/SICP/exercise-2.04-procedural-representation-of-pairs.rkt: [running body]
I could not understand what was wrong with my code, so I looked up some usage examples in other people's solutions. One is on http://community.schemewiki.org/?sicp-ex-2.4:
(define x (cons 3 4))
(car x)
But to my surprise, it doesn't work! The solution in the wiki seems to be wrong. I get the following error:
application: not a procedure;
expected a procedure that can be applied to arguments
given: 3
arguments...: [none]
errortrace...:
/home/xiaolong/development/LISP/Racket/SICP/exercise-2.04-procedural-representation-of-pairs.rkt:24:6: (p)
/home/xiaolong/development/LISP/Racket/SICP/exercise-2.04-procedural-representation-of-pairs.rkt:42:0: (car x)
context...:
/home/xiaolong/development/LISP/Racket/SICP/exercise-2.04-procedural-representation-of-pairs.rkt: [running body]
What am I doing wrong here?
You have an error in your code. Instead of:
(define (car z)
(z
(lambda (p q)
(p))))
you should have written (see the book):
(define (car z)
(z
(lambda (p q)
p)))
Note that in the last row p is written without parentheses.
The message: application: not a procedure means that p is not a procedure (it is actually a number), while with the notation (p) you are calling it as a parameterless procedure.

Implementing sublist? using accumulate in Racket

I need to implement sublist? as a one-liner function that uses accumulate.
It is suppose to return true if set1 is in set2.
Something like this:
(define subset?
(lambda (set1 set2)
(accumulate member? (car set1) (lambda (x) x) set2)))
Honestly I think I'm just confused on how accumulate is suppose to work with member, or if member is even the right choice for the operator.
My accumulate function is:
(define accumulate
(lambda (op base func ls)
(if (null? ls)
base
(op (func (car ls))
(accumulate op base func (cdr ls))))))
and member?:
(define member?
(lambda (item ls)
(cond ((null? ls) #f)
((equal? item (car ls)) #t)
(else (member? item (cdr ls))))))
To give the correct definition of subset? first we must understand how the function accumulate works and the meaning of its parameters.
If we “unfold” the recursive definition, we can see that accumulate applies the binary operator op to all the results of applying func to the elements of list ls. And since the list can be empty, in these cases the function is defined to give back the value base.
So, for instance, assuming the recursive execution of the function, the following expression
(accumulate + 0 sqr '(1 2 3))
produces 14, since it is equivalent to:
(+ (sqr 1) (+ (sqr 2) (+ (sqr 3) 0)))
that is 1 + 4 + 9 + 0.
To solve your problem, you have to define a call to accumulate that applies the same operator to a list of elements and then combine the results. In you case, the operation to be applied is a test if an element is member of a list (member?), and you can apply it to all the elements of set1. And you should know, from the definition of the subset, that a set s1 is subset of another set s2 if and only if all the elements of s1 are contained in s2. So the operator that must be applied to combine all the results of the test is just the and boolean operator, so that it will be true if all the elements of s1 are member of s2 and false otherwise. The last thing to decide is the base value: this should be true, since an empty set is always contained in another set.
So this is a possible definition of subset?:
(define (subset? set1 set2)
(accumulate
(lambda (x y) (and x y)) ;; the combination operator
#t ;; the value for the empty list
(lambda(x) (member x set2)) ;; the function to be applied to all the elements of
set1)) ;; the set set1

Product of squares of odd elements in list in Scheme

I wanted to write a code in Scheme that writes the square odd elements in list.For example (list 1 2 3 4 5) for this list it should write 225.For this purpose i write this code:
(define (square x)(* x x))
(define (product-of-square-of-odd-elements sequence)
(cond[(odd? (car sequence)) '() (product-of-square-of-odd-elements (cdr sequence))]
[else ((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))
For run i write this (product-of-square-of-odd-elements (list 1 2 3 4 5))
and i get error like this:
car: contract violation
expected: pair?
given: '()
What should i do to make this code to run properly? Thank you for your answers.
First of all, you need to do proper formatting:
(define (square x) (* x x))
(define (product-of-square-of-odd-elements sequence)
(cond
[(odd? (car sequence))
'() (product-of-square-of-odd-elements (cdr sequence))]
[else
((square (car sequence)) (product-of-square-of-odd-elements (cdr sequence)))]))
Now there are multiple issues with your code:
You are trying to work recursively on a sequence, but you are missing a termination case: What happens when you pass '() - the empty sequence? This is the source of your error: You cannot access the first element of an empty sequence.
You need to build up your result somehow: Currently you're sending a '() into nirvana in the first branch of your cond and put a value into function call position in the second.
So let's start from scratch:
You process a sequence recursively, so you need to handle two cases:
(define (fn seq)
(if (null? seq)
;; termination case
;; recursive case
))
Let's take the recursive case first: You need to compute the square and multiply it with the rest of the squares (that you'll compute next).
(* (if (odd? (car seq)
(square (car seq))
1)
(fn (cdr seq)))
In the termination case you have no value to square. So you just use the unit value of multiplication: 1
This is not a good solution, as you can transform it into a tail recursive form and use higher order functions to abstract the recursion altogether. But I think that's enough for a start.
With transducers:
(define prod-square-odds
(let ((prod-square-odds
((compose (filtering odd?)
(mapping square)) *)))
(lambda (lst)
(foldl prod-square-odds 1 lst))))
(prod-square-odds '(1 2 3 4 5))
; ==> 225
It uses reusable transducers:
(define (mapping procedure)
(lambda (kons)
(lambda (e acc)
(kons (procedure e) acc))))
(define (filtering predicate?)
(lambda (kons)
(lambda (e acc)
(if (predicate? e)
(kons e acc)
acc))))
You can decompose the problem into, for example:
Skip the even elements
Square each element
take the product of the elements
With this, an implementation is naturally expressed using simpler functions (most of which exist in Scheme) as:
(define product-of-square-of-odd-elements (l)
(reduce * 1 (map square (skip-every-n 1 l))))
and then you implement a helper function or two, like skip-every-n.

Why Scheme requires apply in Y-combinator implementation, but Racket doesn't?

Here is the Y-combinator in Racket:
#lang lazy
(define Y (λ(f)((λ(x)(f (x x)))(λ(x)(f (x x))))))
(define Fact
(Y (λ(fact) (λ(n) (if (zero? n) 1 (* n (fact (- n 1))))))))
(define Fib
(Y (λ(fib) (λ(n) (if (<= n 1) n (+ (fib (- n 1)) (fib (- n 2))))))))
Here is the Y-combinator in Scheme:
(define Y
(lambda (f)
((lambda (x) (x x))
(lambda (g)
(f (lambda args (apply (g g) args)))))))
(define fac
(Y
(lambda (f)
(lambda (x)
(if (< x 2)
1
(* x (f (- x 1))))))))
(define fib
(Y
(lambda (f)
(lambda (x)
(if (< x 2)
x
(+ (f (- x 1)) (f (- x 2))))))))
(display (fac 6))
(newline)
(display (fib 6))
(newline)
My question is: Why does Scheme require the apply function but Racket does not?
Racket is very close to plain Scheme for most purposes, and for this example, they're the same. But the real difference between the two versions is the need for a delaying wrapper which is needed in a strict language (Scheme and Racket), but not in a lazy one (Lazy Racket, a different language).
That wrapper is put around the (x x) or (g g) -- what we know about this thing is that evaluating it will get you into an infinite loop, and we also know that it's going to be the resulting (recursive) function. Because it's a function, we can delay its evaluation with a lambda: instead of (x x) use (lambda (a) ((x x) a)). This works fine, but it has another assumption -- that the wrapped function takes a single argument. We could just as well wrap it with a function of two arguments: (lambda (a b) ((x x) a b)) but that won't work in other cases too. The solution is to use a rest argument (args) and use apply, therefore making the wrapper accept any number of arguments and pass them along to the recursive function. Strictly speaking, it's not required always, it's "only" required if you want to be able to produce recursive functions of any arity.
On the other hand, you have the Lazy Racket code, which is, as I said above, a different language -- one with call-by-need semantics. Since this language is lazy, there is no need to wrap the infinitely-looping (x x) expression, it's used as-is. And since no wrapper is required, there is no need to deal with the number of arguments, therefore no need for apply. In fact, the lazy version doesn't even need the assumption that you're generating a function value -- it can generate any value. For example, this:
(Y (lambda (ones) (cons 1 ones)))
works fine and returns an infinite list of 1s. To see this, try
(!! (take 20 (Y (lambda (ones) (cons 1 ones)))))
(Note that the !! is needed to "force" the resulting value recursively, since Lazy Racket doesn't evaluate recursively by default. Also, note the use of take -- without it, Racket will try to create that infinite list, which will not get anywhere.)
Scheme does not require apply function. you use apply to accept more than one argument.
in the factorial case, here is my implementation which does not require apply
;;2013/11/29
(define (Fact-maker f)
(lambda (n)
(cond ((= n 0) 1)
(else (* n (f (- n 1)))))))
(define (fib-maker f)
(lambda (n)
(cond ((or (= n 0) (= n 1)) 1)
(else
(+ (f (- n 1))
(f (- n 2)))))))
(define (Y F)
((lambda (procedure)
(F (lambda (x) ((procedure procedure) x))))
(lambda (procedure)
(F (lambda (x) ((procedure procedure) x))))))

How Do For Loops Work In Scheme?

I'm having some difficulty understanding how for loops work in scheme. In particular this code runs but I don't know why
(define (bubblesort alist)
;; this is straightforward
(define (swap-pass alist)
(if (eq? (length alist) 1)
alist
(let ((fst (car alist)) (scnd (cadr alist)) (rest (cddr alist)))
(if (> fst scnd)
(cons scnd (swap-pass (cons fst rest)))
(cons fst (swap-pass (cons scnd rest)))))))
; this is mysterious--what does the 'for' in the next line do?
(let for ((times (length alist))
(val alist))
(if (> times 1)
(for (- times 1) (swap-pass val))
(swap-pass val))))
I can't figure out what the (let for (( is supposed to do here, and the for expression in the second to last line is also a bit off putting--I've had the interpreter complain that for only takes a single argument, but here it appears to take two.
Any thoughts on what's going on here?
That's not a for loop, that's a named let. What it does is create a function called for, then call that; the "looping" behavior is caused by recursion in the function. Calling the function loop is more idiomatic, btw. E.g.
(let loop ((times 10))
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))
gets expanded to something like
(letrec ((loop (lambda (times)
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))))
(loop 10))
This isn't actually using a for language feature but just using a variation of let that allows you to easily write recursive functions. See this documentation on let (it's the second form on there).
What's going on is that this let form binds the name it's passed (in this case for) to a procedure with the given argument list (times and val) and calls it with the initial values. Uses of the bound name in the body are recursive calls.
Bottom line: the for isn't significant here. It's just a name. You could rename it to foo and it would still work. Racket does have actual for loops that you can read about here.

Resources