how assign values to variables in racket? - scheme

if I have this list
'((x 3) (y 4) (z 2))
how do I assign 3 to x and y to 4 and z to 2 to use it to do math like?
3 + x
or
y + z
Thanks

You can use let to declare local variables in Scheme. For example, to create bindings with the given values in the list:
(let ((x 3) (y 4) (z 2))
(+ y z)) ; body
=> 6
Now you can evaluate any expression involving the declared variables in the <body> part. You can even create a let from a list of bindings, for instance using macros:
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(define-syntax my-let
(syntax-rules ()
[(_ lst exp)
(eval `(let ,lst ,exp) ns)]))
(my-let '((x 3) (y 4) (z 2)) ; bindings as an association list
'(+ y z)) ; expression to be evaluated
=> 6
The above creates a macro called my-let which receives a list of bindings and an expression to be evaluated with those bindings, and returns the result of the evaluation.

A simple, straightforward and portable way would be to define an accessor (in this example, getval) using assq:
(define vars '((x 3) (y 4) (z 2)))
(define (getval sym) (cadr (assq sym vars)))
or any variation thereof. Then use as follows:
(+ 3 (getval 'x))
=> 6
(+ (getval 'y) (getval 'z))
=> 6

Related

output of map function?

Hi I am trying to understand the output of the following code
(define p (lambda (x) (lambda (y) (x (x y)))))
(define q (lambda (x) (* x x)))
when I use
(map (p q) (list 1 2 3))
the result is
(1 16 81)
shouldn't the answer be
(1 4 9) ?
You're mapping (p q) over the list, so start with figuring out what that is.
Using the subsitution method, you get
(p q)
==> ((lambda (x) (lambda (y) (x (x y)))) q)
==> (lambda (y) (q (q y)))
==> (lambda (y) (q ((lambda (x) (* x x)) y)))
==> (lambda (y) (q (* y y)))
==> (lambda (y) ((lambda (x) (* x x)) (* y y)))
==> (lambda (y) (* (* y y) (* y y)))
so (p q) is a function that takes a number and squares its square.
Two functions are provided:
(define p (lambda (x) (lambda (y) (x (x y)))))
(define q (lambda (x) (* x x)))
q is a function which takes a number and squares it.
p is a function which takes a function x, and returns another function where x is applied twice to y. Please note that in p, that x is in the function location of the forms, and has been highlighted in the listing to show this.
The use of x in both expressions is unfortunately confusing. You can replace any variable in a lambda expression with any other variable, for example function - this is called alpha-conversion - https://en.wikipedia.org/wiki/Lambda_calculus - and you can change the name of any named function to something more sensible. So, I've renamed q to square, the squaring function, and I've renamed p to do-twice.
(define do-twice (lambda (function) (lambda (y) (function (function y)))))
(define square (lambda (x) (* x x)))
It then becomes obvious what is happening when you evaluate do-twice square.
Francis King's answer is very clear,
this is just an extended footnote inspired by it.
Replacing identifiers with mnemonic ones (rewriting q as square) can make it easier to understand code [1]
Procedures as [first-class] values in Scheme [2] are often introduced with examples using lambda:
> (define twelve 12)
> (define square (lambda (x) (* x x)))
> (square twelve)
144
>
just as the characters 12 in the code above are the representation of a Number,
the characters (lambda (x) (* x x)) are the representation of a Procedure:
(number? 12) => #t, (procedure? (lambda (x) (* x x))) => #t
Two further code rewritings may be helpful:
using the "short-form" define for procedures, and annotating the definition
with a type signature (argument and result types):
> (define (square x) (* x x)) ;; Number -> Number
> (square 3)
9
> (define (do-twice f x) ;; (X -> X) X -> X
(f (f x)))
> (do-twice square 3)
81
> (map (lambda (x) (do-twice square x))
'(1 2 3))
(1 16 81)
>
Note that this do-twice does not yet correspond to the p of the question: making
this do-twice the first argument of map would require:
(map do-twice (make-list 3 square) '(1 2 3))
Mapping one list needs a function of one argument, so something has to produce the do-twice of
(define (do-twice x) (f (f x))) as its value:
> (define (do-twice-with f) ;; (X -> X) -> (X -> X)
(define (do-twice x) ;; X -> X
(f (f x)))
do-twice)
> ((do-twice-with square) 3)
81
> (map (do-twice-with square)
'(1 2 3))
(1 16 81)
>
So do-twice-with is the function p in the question.
do-twice-with requires a function argument (X -> X), but X can be any type, so:
> (define (repeat s) ;; String -> String
(string-append s " " s))
> ((do-twice-with repeat) "buffalo")
"buffalo buffalo buffalo buffalo"
and do-twice-with itself has type (X' -> X') (with X' standing for (X -> X)), so can be
applied to itself:
> (((do-twice-with do-twice-with) square) 3)
43046721
> (((do-twice-with do-twice-with) repeat) "buffalo") [3]
"buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo"
((((do-twice-with do-twice-with) do-twice-with) square) 3) is left as an
exercise for the reader...
[1] "Naming is perhaps the most powerful abstracting notion we have" [Guy L Steele]
[2] https://walker.cs.grinnell.edu/courses/151.sp04/readings/procedures-as-values.xhtml
[3] https://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo

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.

Calling a function that takes no parameter with a parameter in scheme

How does this code work? It does not seem like any of these functions have a parameter but yet you are able to call it with a parameter
(define (make-add-one)
(define (inc x) (+ 1 x))
inc)
(define myfn (make-add-one))
(myfn 2)
This runs and returns 3.
Lets use substitution rules. make-add-one can be rewritten like this:
(define make-add-one (lambda ()
(define inc (lambda (x) (+ 1 x))
inc))
Since inc is just returned we can simplify it further to this:
(define make-add-one (lambda ()
(lambda (x) (+ 1 x)))
Now myfn we can replace the call to make-add-one with the code that the lambda has inside:
(define myfn (make-add-one)) ; ==
(define myfn (lambda (x) (+ 1 x)))
And at last, we can use substitution rules on the last call:
(myfn 2) ; ==
((lambda (x) (+ 1 x)) 2) ; ==
(+ 1 2) ; ==
3
Now make-add-one makes a new function that is identical to all other functions it makes. It doesn't really add anything. A good example of where this is useful is this example:
(define (make-add by-what)
(lambda (value) (+ value by-what)))
(define inc (make-add 1))
(define add5 (make-add 5))
(map add5 '(1 2 3)) ; ==> (6 7 8)
(map inc '(1 2 3)) ; ==> (2 3 4)
Just to see it's the same:
(add5 2) ; ==
((make-add 5) 2) ; ==
((lambda (value) (+ value 5)) 2) ; ==
(+ 2 5) ; ==
; ==> 7
And how does this work. In a lexically scoped language, all lambda forms captures the variables that are not bound in their own parameter list from the scope which it was created. This is known as a closure. A simple example of this is here:
(define x 10)
(define test
(let ((x 20)
(lambda (y) (+ x y))))
(test 2) ; ==> 22
So in Scheme test uses x from the let even after the scope is out since the lambda was created in that scope. In a dynamically scoped language (test 2) would return 12 and the two previous examples would also produce other results and errors.
Lexical scoping came first to Algol, which is the predecessor to all the C language family languages like C, java, perl. Scheme was proably the first lisp and it was the essential design of the language itself. Without closure first version of Scheme was the same as its host langugage, MacLisp.
Lift the definition of inc out of make-add-one:
(define (inc x) (+ 1 x))
(define (make-add-one)
inc)
Now it's clearer that the expression (make-add-one) is the same as inc, and inc is clearly a procedure with one parameter.
In other words, invoking make-add-one with no arguments produces a procedure that takes one argument.
You can use the substitution method to follow the evaluation:
(myfn 2)
==> ((make-add-one) 2)
==> (inc 2)
==> (+ 1 2)
==> 3

How are these procedures able to access the input value of another procedure that is called within them?

So the p-cons procedure takes x and y as input and returns an anonymous procedure that takes z as input (and remembers x and y?)
What I'm struggling to understand is when I run this in REPL:
(p-car (p-cons 1 2))
it returns 1, and 2 with p-cdr, which is what they are intended to do.However I just can't understand how they are able to access the values of the p-cons procedure? Can someone explain how this works and what I might not be grasping fully?
Here are the procedures:
(define (p-cons x y)
(lambda (z) (z x y)))
(define (p-car proc)
(proc (lambda (x y) x)))
(define (p-cdr proc)
(proc (lambda (x y) y)))
To see why 1 and 2 are not lost, you can step through the expression as follows:
(p-car (p-cons 1 2))
=> (p-car (lambda (z) (z 1 2)))
=> ((lambda (z) (z 1 2)) (lambda (x y) x))
=> ((lambda (x y) x) 1 2)
=> 1
(p-cons 1 2) is essentially producing the procedure: (lambda (z) (z 1 2)). You can pass any function f to this procedure and it will return (f 1 2). For example:
((lambda (z) (z 1 2)) +) ; => 3
((lambda (z) (z 1 2)) (lambda (x y) x)) ; => 1
((lambda (z) (z 1 2)) (lambda (x y) y)) ; => 2
Scheme procedures are closures. They can references variables from the environment in which the procedure was defined.
When variables are referenced in a closure, they won’t be destroyed when you leave the scope where it was defined. Instead, they will live on until the closure still exists.
A textbook example of using closures is a counter:
<!-- language: scheme -->
(define (make-counter)
(let ((x 0))
(lambda ()
(set! x (+ x 1))
x)))
(define counter (make-counter))
(counter) => 1
(counter) => 2
(counter) => 3
(counter) => 4
Here, the (lambda () (set! x (+ x 1)) x) procedure references x from the environment where it was defined (i.e. x from make-counter). So, even though the execution of make-counter has been finished, x variable continues to live on, because it’s referenced in the procedure counter.
Please refer to the question What is a ‘Closure’ for more information (the answer that has examples in Scheme might be most relevant).

Resources