How to return a function in scheme (racket) using conditionals? - scheme

How do I return a function using conditionals in scheme? What I want to do is to return the product of 2 numbers (when r = 0), or the sum (when r=1) or the difference (when r=2) or 0 (otherwise) depending on the value of r.
What I tried is below, but the return value is always 0. How do I fix that?
(define (f r)( lambda (x y)
(cond (equal? r 0)
((* x y))
( (equal? r 1)
( (+ x y)))
( (equal? r 2))
( (- x y))
(else
0 ))))
(( f 0) 2 3)
I would expect 6, but I get 0. Thanks in advance.

cond works like this:
(cond (test-expr then-body)
(test-expr2 then-body2)
(else then-body3))
The test-exprs are tested one by one, and the first test-expr that returns a non-false value causes its corresponding then-body to be executed. The last value in the executed then-body is the value of the whole cond.
To know why you got 0 (and not 6), look carefully at your first cond clause: (cond (equal? r 0) ...). equal? is the test-expr, and since equal? itself is not false, its then-body is executed (i.e. r and 0 are executed). Since 0 is the last value in the then-body, 0 is the value of the whole cond. That's why you got 0.
Note that nearly all lines in your cond have parentheses that have been incorrectly placed. Here's a fixed version:
(define (f r)
(lambda (x y)
(cond ((equal? r 0) ; <- Parentheses fixed.
(* x y)) ; <- Parentheses fixed.
((equal? r 1) ; <- Parentheses fixed.
(+ x y)) ; <- Parentheses fixed.
((equal? r 2) ; <- Parentheses fixed.
(- x y)) ; <- Parentheses fixed.
(else 0))))
Here's an arguably better way to define the same function:
(define (f r)
(cond ((= r 0) *)
((= r 1) +)
((= r 2) -)
(else (lambda _ 0))))
For example:
((f 0) 2 3)
;; '(f 0)' returns '*', so this reduces to: (* 2 3)
;; Answer:
6
This version is technically better as it is not restricted to taking only two arguments. For example, you can now do this: ((f 1) 1 2 3 4 5 6) (reduces to (+ 1 2 3 4 5 6)).

The cond expression in your code has some syntax errors:
There are brackets missing in each condition
You must not surround a procedure application with double brackets, this is a mistake: ((* x y))
Notice that you require to return an arithmetic procedure and, for example, we can simply return + which is similar to returning (lambda (x y) (+ x y)) (except that it'll work for more than two parameters, but that's a win!).
Bear in mind that in Racket the solution can be written in a more concise way: for example, by using case to simplify the conditions and const for the last case, when we want to return a procedure that returns 0 no matter what are the parameters. Here's how:
(define (f r)
(case r
((0) *)
((1) +)
((2) -)
(else (const 0))))
It works as expected, by returning a procedure that you can apply to the given arguments:
((f 0) 6 7)
=> 42
((f 3) 2 3)
=> 0

Related

dont understood lambda expression on scheme

i try to realize what this expiration, and don't get it.
( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))
i think,
a is a number, and b is #t or #f,
on the if statement we ask if b is true, if yes return first expression(sum 3 numbers), else the second(Subtract 3 numbers)
what i need to write on Racket to run this?
i try
(define question( lambda (a b) (lambda (x y) (if b (+ x y a) (-x y a)))))
and than
(question 5 #f)
and nothing not going well in this language.
This is not a complete answer as I don't want to do your homework for you.
First of all formatting and indenting your code is going to help you in any programming language. You almost certainly have access to an editor which will do this. Below I've done this.
So, OK, what does a form like (λ (...) ...) denote? Well, its a function which takes some arguments (the first ellipsis) and returns the value of the last form in its body (the second ellipsis), or the only form in its body in a purely functional language.
So, what does:
(λ (a b)
(λ (x y)
...))
Denote? It's a function of two arguments, and it returns something: what is the thing it returns? Well, it's a form which looks like (λ (...) ...): you know what those forms mean already.
And finally we can fill out the last ellipsis (after correcting an error: (-x ...) is not the same as (- x ...)):
(λ (a b)
(λ (x y)
(if b
(+ x y a)
(- x y a))))
So now, how would you call this, and how would you make it do something interesting (like actually adding or subtracting some things)?
(lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a))))
is a function that takes two arguments (that's what (lambda (a b) ...) says).
You can use the substitution method to discover what it produces.
Apply it to 5 and #f:
((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f)
[Replace a with 5 and b with #f in the body]:
(lambda (x y) (if #f (+ x y 5) (- x y 5)))
And this is a function that takes two numbers and produces a new number.
(Note that the #f and the 5 became fixed by the application of the outer lambda.)
It's easier to use the function if we name it (interactions from DrRacket):
> (define question (lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))))
> (question 5 #f)
#<procedure>
which is as expected, based on the reasoning above.
Let's name this function as well:
> (define answer (question 5 #f))
and use it:
> (answer 3 4)
-6
or we could use it unnamed:
> ((question 5 #f) 3 4)
-6
or you could do it all inline, but that's a horrible unreadable mess:
> (((lambda (a b) (lambda (x y) (if b (+ x y a) (- x y a)))) 5 #f) 3 4)
-6

Make procedure in Scheme by lambda

I am learning Scheme by 'Structure and Interpretation of Computer Programs'
In Chapter 1.3.2 Constructing Procedures Using lambda.
I understood lambda like this.
The value to match the lambda is written outside the parenthesis of the lambda.
((lambda (x) (+ x 4) 4) ; (x) is matched to 4, result is 8
But in SICP, another example code is different.
The code is :
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 3))))
a
(lambda (x) (+ x 4))
b
))
(pi-sum 3 6)
I think if (lambda (x) (/ 1.0 (* x (+ x 3)))) want match to a, lambda and a must bound by parenthesis.
But in example code, don't use parenthesis.
When I run this code, error is occurs.
error is this :
***'sum: expects only 2 arguments, but found 4'***
When I use more parenthesis like this :
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum ((lambda (x) (/ 1.0 (* x (+ x 3))))
a)
((lambda (x) (+ x 4))
b)
))
(pi-sum 2 6) ; result is 10.1
Code is run.
I'm confused because of SICP's example code.
Am I right on the principle of lambda?
If I am right, why SICP write like that?
It says to use the sum from 1.3.1. On page 77 (actually starting on 77 and ending on 78) it looks like this:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
As you can see it looks a lot different from your sum that just adds two number together. You also had a typo in pi-sum:
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2)))) ; multiplied by 2, not 3!
a
(lambda (x) (+ x 4))
b))
(* 8 (pi-sum 1 1000))
; ==> 3.139592655589783
So the point here is that you can pass lambdas instead of named procedures. Since (define (name . args) body ...) is just syntax sugar for (define name (lambda args body ...)) passing (lambda args body ...) instead of defining it and pass a name is just an equal refactoring.
Parentheses around a variable (+) or a lambda ((lambda args body ...)) calls whatever procedure the operator expression evaluates. It is not what you want since you pass procedures to be used by sum as an abstraction. sum can do multiplications or any number of things based on what you pass. in sum term is the procedure (lambda (x) (/ 1.0 (* x (+ x 2)))) and you see it calls it as apart of its code.

Returning the sum of positive squares

I'm trying to edit the current program I have
(define (sumofnumber n)
(if (= n 0)
1
(+ n (sumofnumber (modulo n 2 )))))
so that it returns the sum of an n number of positive squares. For example if you inputted in 3 the program would do 1+4+9 to get 14. I have tried using modulo and other methods but it always goes into an infinite loop.
The base case is incorrect (the square of zero is zero), and so is the recursive step (why are you taking the modulo?) and the actual operation (where are you squaring the value?). This is how the procedure should look like:
(define (sum-of-squares n)
(if (= n 0)
0
(+ (* n n)
(sum-of-squares (- n 1)))))
A definition using composition rather than recursion. Read the comments from bottom to top for the procedural logic:
(define (sum-of-squares n)
(foldl + ; sum the list
0
(map (lambda(x)(* x x)) ; square each number in list
(map (lambda(x)(+ x 1)) ; correct for range yielding 0...(n - 1)
(range n))))) ; get a list of numbers bounded by n
I provide this because you are well on your way to understanding the idiom of recursion. Composition is another of Racket's idioms worth exploring and often covered after recursion in educational contexts.
Sometimes I find composition easier to apply to a problem than recursion. Other times, I don't.
You're not squaring anything, so there's no reason to expect that to be a sum of squares.
Write down how you got 1 + 4 + 9 with n = 3 (^ is exponentiation):
1^2 + 2^2 + 3^2
This is
(sum-of-squares 2) + 3^2
or
(sum-of-squares (- 3 1)) + 3^2
that is,
(sum-of-squares (- n 1)) + n^2
Notice that modulo does not occur anywhere, nor do you add n to anything.
(And the square of 0 is 0 , not 1.)
You can break the problem into small chunks.
1. Create a list of numbers from 1 to n
2. Map a square function over list to square each number
3. Apply + to add all the numbers in squared list
(define (sum-of-number n)
(apply + (map (lambda (x) (* x x)) (sequence->list (in-range 1 (+ n 1))))))
> (sum-of-number 3)
14
This is the perfect opportunity for using the transducers technique.
Calculating the sum of a list is a fold. Map and filter are folds, too. Composing several folds together in a nested fashion, as in (sum...(filter...(map...sqr...))), leads to multiple (here, three) list traversals.
But when the nested folds are fused, their reducing functions combine in a nested fashion, giving us a one-traversal fold instead, with the one combined reducer function:
(define (((mapping f) kons) x acc) (kons (f x) acc)) ; the "mapping" transducer
(define (((filtering p) kons) x acc) (if (p x) (kons x acc) acc)) ; the "filtering" one
(define (sum-of-positive-squares n)
(foldl ((compose (mapping sqr) ; ((mapping sqr)
(filtering (lambda (x) (> x 0)))) ; ((filtering {> _ 0})
+) 0 (range (+ 1 n)))) ; +))
; > (sum-of-positive-squares 3)
; 14
Of course ((compose f g) x) is the same as (f (g x)). The combined / "composed" (pun intended) reducer function is created just by substituting the arguments into the definitions, as
((mapping sqr) ((filtering {> _ 0}) +))
=
( (lambda (kons)
(lambda (x acc) (kons (sqr x) acc)))
((filtering {> _ 0}) +))
=
(lambda (x acc)
( ((filtering {> _ 0}) +)
(sqr x) acc))
=
(lambda (x acc)
( ( (lambda (kons)
(lambda (x acc) (if ({> _ 0} x) (kons x acc) acc)))
+)
(sqr x) acc))
=
(lambda (x acc)
( (lambda (x acc) (if (> x 0) (+ x acc) acc))
(sqr x) acc))
=
(lambda (x acc)
(let ([x (sqr x)] [acc acc])
(if (> x 0) (+ x acc) acc)))
which looks almost as something a programmer would write. As an exercise,
((filtering {> _ 0}) ((mapping sqr) +))
=
( (lambda (kons)
(lambda (x acc) (if ({> _ 0} x) (kons x acc) acc)))
((mapping sqr) +))
=
(lambda (x acc)
(if (> x 0) (((mapping sqr) +) x acc) acc))
=
(lambda (x acc)
(if (> x 0) (+ (sqr x) acc) acc))
So instead of writing the fused reducer function definitions ourselves, which as every human activity is error-prone, we can compose these reducer functions from more atomic "transformations" nay transducers.
Works in DrRacket.

Racket: How to write foldl using foldr

I'm currently preparing for an exam and thought that writing foldl with foldr would be a nice question to get tested on.
Anyways, I know that (foldl f base lst) returns (f xn (f x(n-1) . . . (f x1 base)
with the lst being (x1 . . . xn)
So what I currently have is this:
(define (foldl/w/foldr f base lst)
(foldr (lambda (x y) (f y (f x base))) base lst)))
This doesn't quite work, and I am unsure on how to proceed.
Using Haskell's documentation as a starting point (as mentioned by #soegaard in the comments), here's a working solution for this problem, using Racket syntax:
(define (foldl/w/foldr f base lst)
((foldr (λ (ele acc) (λ (x) (acc (f ele x))))
identity
lst)
base))
For example:
(foldl/w/foldr cons '() '(1 2 3 4 5))
=> '(5 4 3 2 1)
(foldl/w/foldr + 0 '(1 2 3 4 5))
=> 15
The key to understand this is that we're accumulating lambdas with delayed computations, not values, and at the end we invoke all the chain of lambdas passing the base value to start the computation. Also notice that the identity procedure is used as the first accumulator, and we accumulate more lambdas on top of it. For instance, this call:
(foldl/w/foldr + 0 '(1 2))
Will be evaluated as follows:
((lambda (x) ; this lambda is the value returned by foldr
((lambda (x)
(identity (+ 1 x))) ; add first element in the list (this gets executed last)
(+ 2 x))) ; add second element in the list (this gets executed first)
0) ; at the end, we invoke the chain of lambdas starting with the base value
=> 3
I am not a Lisp programmer, so this maybe not syntactically perfect, but it will be something like
foldl f a l = (foldr (lambda (h p) (lambda (x) (p (f x h))) )
l
(lambda (x) (x))
a))
The trick is to accumulate function instead of result value. I am applying four arguments to foldr, because in this case regular foldr returns function, that will take "a" as an argument.

Unable to understand the error in Guile Scheme Code

I am trying to print a Pascal's Triangle on terminal using Guile Scheme.
What is Pascal's Triangle?
Here is the script:
#!/usr/local/bin/guile \
-e main -s
!#
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product) (+ counter 1) max-count)))
(define (factorial n)
(fact-iter 1 1 n))
(define (n-C-r n r)
(/ (factorial n) (* (factorial (- n r)) (factorial r))
)
)
(define (row-iter r l n)
(cond ((= r 0) ((display 1) (row-iter (+ r 1) l n)))
((and (> r 0) (< r l)) ((display (n-C-r l r)) (display " ") (row-iter (+ r 1) l n)))
((= r l) (display 1))
)
)
(define (line-iter l n)
(cond ((<= l n) ( (row-iter 0 l n)
(line-iter (+ l 1) n) ) )
)
)
(define (pascal-triangle n)
(line-iter 0 n) )
(define (main args)
(pascal-triangle (string->number (car (cdr args)) 10))
)
File name is pascalTriangle.scm
The Shebang notation on the top has correct path to guile.
I have given the permissions by chmod +x pascalTriangle.scm
Run the program using the command ./pascalTriangle.scm 5
When run, the above script, the following output/error is observed:
1Backtrace: In ice-9/boot-9.scm:
157: 5 [catch #t #<catch-closure ac8400> ...]
In unknown file:
?: 4 [apply-smob/1 #<catch-closure ac8400>]
In ice-9/boot-9.scm:
63: 3 [call-with-prompt prompt0 ...]
In ice-9/eval.scm:
432: 2 [eval # #]
In /home/tarunmaganti/./pascalTriangle.scm:
27: 1 [line-iter 0 4]
In unknown file:
?: 0 [#<unspecified> #<unspecified>]
ERROR: In procedure #<unspecified>:
ERROR: Wrong type to apply: #<unspecified>
Notice that, the first character of the output is 1 which implies that the code executed until first part of procedure row-iter i.e., (display 1) and there might be an error after it.
But the output says that error is in procedure line-iter. I do not understand.
I would appreciate if any error in the program is pointed-out and corrected to make it print a Pascal's Triangle.
Edit1: I edited the error/output text, I replaced '<' and '>' with HTML entities. The text inside the angular brackets wasn't visible before.
The problem is that you have added excess parentheses around your consequence expressions in cond. Since cond has explicit begin you code that looks like this today:
(define (row-iter r l n)
(cond ((= r 0)
;; you see the double (( ?
((display 1)
(row-iter (+ r 1) l n)))
((and (> r 0) (< r l))
;; you see the double (( ?
((display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n)))
((= r l)
;; without double (( and thus ok
(display 1))))
Needs to have it's excess parentheses removed like this:
(define (row-iter r l n)
(cond ((= r 0)
(display 1)
(row-iter (+ r 1) l n))
((and (> r 0) (< r l))
(display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n))
((= r l)
(display 1))))
If you would have used if instead you would have to use begin:
(define (row-iter r l n)
(if (= r 0)
(begin
(display 1)
(row-iter (+ r 1) l n))
(if (and (> r 0) (< r l))
(begin
(display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n))
(display 1))))
Just fixing this procedure wont fix you problem since you have the same error in line-iter as well. You might see double (( in the beginning of each cond term but unless you are doing something fancy you should not expect it anywhere else.
When adding excess parentheses ((display "something") #t) it gets interpreted as (display "something") will return a procedure and that you want to check what the result of that procedure with argument #t will become. When all the parts is evaluated it fails since then it finds out the undefined value is not a procedure. There are cases where it works:
((if (< x 0) - +) x 1) ; absolute increment value without changing sign
Here you see the first part gets evaluated to the result of evaluating - when x is less than zero. If it's -10 the result would be -11 and if it is 10 the procedure applied will be the evaluation of + with the result 11.
Later it will find that the value 3 isn't a procedure and you get th eerror. and to get the result Scheme should do (apply 3 '(#t))and it detects that 3 (in your case whatdesiplayreturns which is an unspecified value)
Scheme interprets this by evaluating(display (n-C-r l r)` which prints something and the returned value, which by the spec i undefined and thus free choice of the implementers, is then applied as a procedure because of excess parentheses.
In Guile the result of values undefined in the spec becomes a singleton that displays #<unspecified> and that is ignored by the REPL. You might find a Scheme implementation where the unspecified value is a procedure that takes no arguments where your implementation will work flawlessly but will not be portable.
The error as stated by Sylwester in his answer is in ((display (n-C-r l r)) (display " ") (row-iter (+ r 1) l n))) expression. The statement indeed interprets this by evaluating ((display (n-C-r l r)) which prints something and return undefined value and is applied as a procedure considering ((display (n-C-r l r)) as excessively parenthesized.
I resolved the problem using the Sequencing. The begin special form is used to combine multiple statements and returns the value of the last statement.
Sequencing in MIT-Scheme. This worked in guile scheme too.
Syntax of begin special form: (begin <e1> <e2> <e3>....<en>)
It returns return value of <en> expression.
Here is the changed code:
(define (row-iter n r)
(cond ((= r 0) (begin (display 1) (display " ") (row-iter n (+ r 1))))
((and (> r 0) (< r n)) (begin (display (n-C-r n r)) (display " ") (row-iter n (+ r 1))))
((= r n) (display 1))
)
)
Although the output isn't properly formatted as a "triangle", we can get left indented pascal triangle after changing the code.
By running ./pascalTriangle 5, we get the output as
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

Resources