How to create a lambda procedures? - scheme

I need to complete an assignment for my college course using Scheme. I've never coded in Scheme before so I have no clue what I'm doing. Our assignment is to define an anonymous function that computes the discriminant of a quadratic function. I keep running into the error: "Invalid `define'. Any help would be appreciated.
(define roots (lambda(abc))(
(lambda(discriminant))(
list(/(+(-b) discriminant)(*2a))
(/(-(-b) discriminant)(*2a))
)
(sqrt - (*bb)(*4ac))
)

First, you should learn a bit about what Scheme code looks like; find some example code (in your textbook, or online, or in answers here on SO) and notice how parentheses and whitespace are used. Then emulate that. You can't arbitrarily place parentheses or arbitrarily remove whitespace in Scheme (or in any Lisp).
For example, in the posted code (-b) gets two things wrong. First, -b is treated as one symbol, not as the negation of the value of b. Further, placing the symbol in parentheses indicates a procedure call; given an s-expression (f x), f is either a syntactic keyword (in which case (f x) is interpreted as a macro call), or (f x) is interpreted as a procedure call. If it is a procedure call and f is not bound to a procedure, then an exception is raised. So (-b) attempts to call a procedure named -b, which does not exist (unless you have defined it), raising an exception. You can use (- b), with a space between the - procedure and the symbol b; this evaluates to the negation of the value of b.
Similarly, *2a is interpreted as a symbol, not an expression; placing the *2a between parentheses is interpreted as a procedure call. The interpreter (or compiler) is expecting that *2a is a procedure which takes no arguments. You need to add the spaces: (* 2 a); this is interpreted as a call to the procedure * with the arguments 2 and a.
(*bb) and (*4ac) have exactly the same problems. The second case is interesting because when it is correctly written it illustrates one of the advantages of prefix notation. Since * is associative, it does not matter what order multiple values are multiplied in. To express naively 4 * a * c in prefix notation you could write (* 4 (* a c)), explicitly ordering the multiplications. You could also write this as (* (* 4 a) c), multiplying in a different order. It does not matter what order you multiply in, so you might as well just write (* 4 a c), so long as your language supports this notation. It turns out that Scheme and other Lisps do support this notation.
Another problem with s-expression notation in the posted code (after fixing the problems noted above): (sqrt - (* b b) (* 4 a c)). This is attempting to call the sqrt procedure on the arguments -, (* b b), and (* 4 a c). But sqrt is not a higher-order procedure (i.e., it does not take procedures as arguments), and it in fact only takes one argument. It was meant to apply the - procedure to the arguments (* b b) and (* 4 a c), subtracting them before taking the square root: (sqrt (- (* b b) (* 4 a c))).
The first lambda expression has a formal parameter list containing only one parameter: abc. As before, this is a mistake. The intention was to define three parameters: don't skimp on spaces: (lambda (a b c)).
The other significant problem is that there are syntax errors in the lambda expressions: (lambda (a b c)) has no body, but a lambda expression must have at least one expression in its body. This was probably intended to wrap the lambda expression which follows. Similarly, the inner lambda expression is missing its body. It was probably intended to wrap the (list ;;...) form that follows.
With that done, the inner lambda expression is itself inside of a pair of parentheses, taking the expression (sqrt (- (* b b) (* 4 a c))) as its argument. This is the lambda form of a let binding. Thus, the inner lambda takes one argument, discriminant, and evaluates the list form that is its body. Since the inner lambda expression itself occurs in the first position of an s-expression, it is part of a procedure call, and this inner anonymous procedure is then called on its argument, binding discriminant to the value obtained by evaluating that argument, which is (sqrt (- (* b b) (* 4 a c))). This all occurs inside of the outer lambda, which takes the three arguments a, b, and c. So, root is a function taking three arguments, and returning a list of roots, after binding the result of the discriminant calculation to discriminant (as a way of both simplifying the expression of the roots and ensuring that the discriminant need only be calculated one time).
Here is the fixed-up code. Note that I only added some spaces and added or moved a few parentheses; nothing else was changed:
(define roots
(lambda (a b c)
((lambda (discriminant)
(list (/ (+ (- b) discriminant) (* 2 a))
(/ (- (- b) discriminant) (* 2 a))))
(sqrt (- (* b b) (* 4 a c))))))
Pay attention to what this looks like. In Lisps you should almost never leave parentheses hanging on lines by themselves, and you should always place a space between arguments. Remember that everything is a procedure call.
Here is a sample interaction. Notice that you can represent negative numbers as -1 instead of (- 1) (you can do either if you wish). You just can't express a negative value using a variable as -b.
> (roots 1 0 -1)
(1 -1)
> (roots 1 8 15)
(-3 -5)

Related

Understanding parentheticals on let

I'm having a hard time understanding the syntax of let vs some of the other statements. For example, a "normal" statement has one parentheses:
(+ 2 2)
$2 = 4
Yet the let statement has two:
(let ((x 2)) (+ x 2))
$3 = 4
Why is this so? I find it quite confusing to remember how many parentheses to put around various items.
Firstly, note that let syntax contains two parts, both of which can have zero or more elements. It binds zero or more variables, and evaluates zero or more forms.
All such Lisp forms create a problem: if the elements are represented as a flat list, there is an ambiguity: we don't know where one list ends and the other begins!
(let <var0> <var1> ... <form0> <form1> ...)
For instance, suppose we had this:
(let (a 1) (b 2) (print a) (list b))
What is (print a): is that the variable print being bound to a? Or is it form0 to be evaluated?
Therefore, Lisp constructs like this are almost always designed in such a way that one of the two lists is a single object, or possibly both. In other words: one of these possibilities:
(let <var0> <var1> ... (<form0> <form1> ...))
(let (<var0> <var1> ...) (<form0> <form1> ...))
(let (<var0> <var1> ...) <form0> <form1> ...)
Traditional Lisp has followed the third idea above in the design of let. That idea has the benefit that the pieces of the form are easily and efficiently accessed in an interpreter, compiler or any code that processes code. Given an object L representing let syntax, the variables are easily retrieved as (cadr L) and the body forms as (cddr L).
Now, within this design choice, there is still a bit of design freedom. The variables could follow a structure similar to a property list:
(let (a 1 b 2 c 3) ...)
or they could be enclosed:
(let ((a 1) (b 2) (c 3)) ...)
The second form is traditional. In the Arc dialect of Lisp designed Paul Graham, the former syntax appears.
The traditional form has more parentheses. However, it allows the initialization forms to be omitted: So that is to say if the initial value of a variable is desired to be nil, instead of writing (a nil), you can just write a:
;; These two are equivalent:
(let ((a nil) (b nil) (c)) ...)
(let (a b c) ...)
This is a useful shorthand in the context of a traditional Lisp which uses the symbol nil for the Boolean false and for the empty list. We have compactly defined three variables that are either empty lists or false Booleans by default.
Basically, we can regard the traditional let as being primarily designed to bind a simple list of variables as in (let (a b c) ...) which default to nil. Then, this syntax is extended to support initial values, by optionally replacing a variable var with a (var init) pair, where init is an expression evaluated to specify its initial value.
In any case, thanks to macros, you can have any binding syntax you want. In more than one program I have seen a let1 macro which binds just one variable, and has no parentheses. It is used like this:
(let1 x 2 (+ x 2)) -> 4
In Common Lisp, we can define let1 very easily like this:
(defmacro let1 (var init &rest body)
`(let ((,var ,init)) ,#body))
If we restrict let1 to have a one-form body, we can then write the expression with obsessively few parentheses;
(let1 x 2 + x 2) -> 4
That one is:
(defmacro let1 (var init &rest form)
`(let ((,var ,init)) (,#form)))
Remember that let allows you to bind multiple variables. Each variable binding is of the form (variable value), and you collect all the bindings into a list. So the general form looks like
(let ((var1 value1)
(var2 value2)
(var3 value3)
...)
body)
That's why there are two parentheses around x 2 -- the inner parentheses are for that specific binding, the outer parentheses are for the list of all bindings. It's only confusing because you're only binding one variable, it becomes clearer with multiple variables.

case and quotation in scheme & racket

I was a bit surprised by this racket code printing nay when I expected yeah:
(define five 5)
(case 5
[(five) "yeah"]
[else "nay"])
Looking at the racket documentation for case makes it clearer:
The selected clause is the first one with a datum whose quoted form is equal? to the result of val-expr.
So it's about quotation. I'm pretty sure that I did not yet fully grasp what quotation in lisps can buy me. I understand it in the viewpoint of macros and AST transformation. However I'm confused why is it helpful in the case of case for instance..?
I'm also curious, with this specification of case, can I use it to achieve what I wanted to (compare the actual values, not the quoted value), or should I use another construct for that? (cond, while strictly more powerful, is more verbose for simple cases, since you must repeat the predicate at each condition).
The problem is that case introduces implicit quote forms, which cause your example to work for 'five (whose value is 'five), instead of five (whose value is 5).
I almost never use case because of exactly this problem. Instead I use racket's match form with the == pattern:
(define five 5)
(define (f x)
(match x
[(== five) "yeah"]
[_ "nay"]))
(f 5) ; "yeah"
(f 6) ; "nay"
This produces "yeah" on only the value 5, just like you expected. If you wanted it to return "yeah" when it's equal to either five or six, you can use an or pattern:
(define five 5)
(define six 6)
(define (f x)
(match x
[(or (== five) (== six)) "yeah"]
[_ "nay"]))
(f 5) ; "yeah"
(f 6) ; "yeah"
(f 7) ; "nay"
And if you really want to match against quoted datums, you can do that by writing an explicit quote form.
(define (f x)
(match x
[(or 'five 'six) "yeah"]
[_ "nay"]))
(f 5) ; "nay"
(f 6) ; "nay"
(f 7) ; "nay"
(f 'five) ; "yeah"
(f 'six) ; "yeah"
These quote forms are implicit and invisible when you use case, lurking there waiting to cause confusion.
The Racket documentation gives this grammar:
(case val-expr case-clause ...)
where
case-clause = [(datum ...) then-body ...+]
| [else then-body ...+]
Let's compare to your example:
(define five 5)
(case 5 ; (case val-expr
[(five) "yeah"] ; [(datum) then-body1]
[else "nay"]) ; [else then-body2])
We see that (five) is interpreted as (datum). This means that five is
a piece of data (here a symbol), not an expression (later to be evaluated).
Your example of case is evaluated like this:
First the expression 5 is evaluated. The result is the value 5.
Now we look at a clause at a time. The first clause is [(five) "yeah"].
Is the value 5 equal (in the sense of equal?) to one of the datums in (five)? No, so we look at the next clause: [else "nay"]. It is an else-clause so the expression "nay" is evaluated and the result is the value "nay".
The result of the case-expression is thus the value "nay".
Note 1: The left-hand sides of case-clauses are datums (think: they are implicitly quoted).
Note 2: The result of val-expr is compared to the clause datums using equal?. (This is in contrast to Scheme, which uses eqv?.
UPDATE
Why include case? Let's see how one can write the example using cond:
(define five 5)
(let ([val five])
(cond
[(member val '(five)) "yeah"]
[(member val '(six seven)) "yeah"] ; added
[else "nay"])
This shows that one could do without case and just use cond.
However - which version is easier to read?
For a case expression it is easy to see which datums the value is compared to.
Here one must look closely to find the datums. Also in the example we know beforehand that we are trying to find the value among a few list of datums. In general we need to examine a cond-expression more closely to see that's what's happening.
In short: having a case-expression increases readability of your code.
For the historically interested: https://groups.csail.mit.edu/mac/ftpdir/scheme-mail/HTML/rrrs-1986/msg00080.html disussed whether to use eqv? or equal? for case.
UPDATE 2
I'll attempt to given an answer to:
I'm still not clear on the quotation vs working simply on the values though.
I'm wondering specifically why doing the quotation, why working on datum instead
of working on values. Didn't get that bit yet.
Both approaches make sense.
Let's for the sake of argument look at the case where case uses expressions rather than datums in the left hand side of a clause. Also following the Scheme tradition, let's assume eqv? is used for the comparison. Let's call such a
case-expression for ecase (short for expression-case).
The grammar becomes:
(ecase val-expr ecase-clause ...)
where
ecase-clause = [(expr ...) then-body ...+]
| [else then-body ...+]
Your example now becomes:
(define five 5)
(ecase five
[('five) "yeah"]
[else "nay")
This doesn't look too bad and the result is what we are used to.
However consider this example:
(ecase '(3 4)
[('five (list 3 4) "yeah"]
[else "nay")
The result of this would be "nay". The two lists resulting from evaluating the expressions '(3 4) and (list 3 4) are not equal in the sense of eqv?.
This shows that if one chooses to use eqv? for comparisions, having expressions available on the left hand side won't be helpful. The only values that work with eqv? atomic values - and therefore one could just as well use implicit quotations and restrict the left hand side to datums.
Now if equal? was used it would make much more sense to use expressions on the left hand side. The original Racket version of case was the same as the one in Scheme (i.e. it used eq?) later on it was changed to used equal?. If case was designed from scratch, I think, expressions would be allowed rather than datums.
The only remaining issue: Why did the authors of Scheme choose eqv? over equal? for comparisons? My intuition is that the reason were performance (which back in the day was more important than now). The linked to post from the rrrs-authors mailing list gives two options. If you dig a little further you might be able to find responses.
I can't find a reference right now, but case statements use literal, unevaluated data in their different clauses because it is both a frequent use-case and more easily subject to efficient compilation.
You could probably write your own version of Clojure's condp macro or a custom conditional operator to handle your use case.

don't understand scheme procedure in SICP

i'm working through SICP Chapter 1 "1.3 Formulating Abstractions with Higher-Order
Procedures"
the part i'm (currently) having trouble with is where the procedural template (shown below) is transformed into an actual procedure (shown below that) by having its 'slots' turned into formal parameters. What I don't get is where the hell they get the next b at the end of the transformed procedure (just before the closing brackets)?
Surely its just b as in the template?
Anyway, this is the template...
(define (<name> a b)
(if (> a b)
0
(+ (<term> a)
(<name> (<next> a) b))))
And this is the procedure once the parameter slots have been filled in
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
any illumination much appreciated
The key insight to understand here is that in Scheme we can pass functions as parameters to another function as easily as we would pass, say, numbers. Be aware that the template is incomplete, it should be:
(define (<name> <term> a <next> b)
(if (> a b)
0
(+ (<term> a)
(<name> <term> (<next> a) <next> b))))
The transformation from template to actual procedure is straightforward:
<name> is the placeholder for the name of the procedure, which happens to be sum
<term> is the placeholder for the procedure that is applied over each term in the series, in the actual procedure it's also called term but it could have any other name - for instance, identity would be an useful procedure to pass along
<next> is the placeholder for a procedure that calculates the next element in the series, for instance it could be as simple as passing along add1, but the authors chose to also call it next
The next b part at the end of the actual procedure is just providing the next (a function) and b (a number) parameters to the recursive call of the function, this is what's getting passed in the last line:
(sum term (next a) next b)
^ ^ ^ ^ ^
function call "term" function next number "next" function upper limit
Also notice that (next a) is actually applying the next procedure to the a parameter, and passing along to the recursion the result of that application - in fact, this is the only value that changes between calls, and it's effectively advancing the recursion up until the point when (> a b) becomes false. That's different from what's happening in the second-to-last parameter, where we are passing next, the function itself and not the result of applying it. As an example, here's how you'd call the sum procedure to add all the numbers between 1 and 10:
(sum identity 1 add1 10) ; <term> is `identity` and <next> is `add1`
=> 55

Algorithm evaluating user-defined functions

Hello I have some homework that consists of extending a lisp interpreter. We are to build three primitives with pre-evaluated arguments ( for exemple <= ), and three primitives who do their own evaluation ( for example if ).
I went beyond the call of duty and created the only fun function in the bounds of this exercice : (defun) [it's the common lisp keyword for defining a user-function].
I would like to know if my algorithm for managing a user-defined function call is worthwhile.
In pseudo code, here it goes :
get list of parameters # (x y z)
get list of arguments # (1 2 3)
get body of function # (+ x (* y z))
for each parameter, arg # x
body = replace(parameter, argument, body) # (+ 1 (* y z))
# (+ 1 (* 2 z))
# (+ 1 (* 2 3))
eval(body) # 7
Are there better ways to accomplish this?
Thanks.
EDIT: replace() is a function recursing on sub-lists of body.
I never found better, no one proposed better, the question generated no interest whatever, and I'm on a rampage to close my opened questions, so here is the answer :
my algorithm was good enough.

Scheme : using lambda as a parameter

hy everyone, for school i have to make a function where lambda is used as a parameter
like so : (string (lambda ...) 5 40) where we have to fill in the dots
this is the function we had to reinvent, the regular string version
(define (string decoration n r) >string decoration is a function that creates a string with either fish or pumpkins hanging on the string
(define (decorations k) >decorations is the recursive function which hangs all the decorations together
(if (= k 1)
(decoration r 10) > here decoration is to be replaced with either a pumpkin or a fish as stated in the parameters
(ht-append (decoration r 10) > ht-append is a function that appends 2 figures Horizontally at the Top
(decorations (- k 1)))))
(hang-by-thread (decorations n))) > hang by thread is a function that hangs all the decorations at a string
all the names should be self-explanatory, the function takes a decoration , either a fish or a pumpkin and hangs it by a thread. But the fish has 3 parameters and the pumpkin has 2 which caused an error. So in a previous exercise we had to make an extra definition called fish-square which uses only 2 parameters to make a fish. Now we have to implement this same squared fish but with a lambda. Any help is greatly appreciated
(define (fish-square wh l) > this is the fish square functio which makes a fish but with 2 times the same parameter so it looks like a square
(vc-append (filled-rectangle 2 l) (fish wh wh))) > the l is the length of the string that attaches the fish to the string at the top
the fish function is just (fish x y) x makes it longer, y makes it taller.
the pumpkin function is just (pumpkin x y) same story
so my question is, how do rewrite the given code , but with lambda as a parameter.
i would upload an image, but my repuation isn't high enough :s
The string procedure as it is already receiving a procedure as a parameter (you don't have to rewrite it!), decoration can be any two-argument function used for decorating. Now when you call it you can pass a named procedure, for example:
(define (decoration r n)
<body>)
(string decoration
5
40)
... Or just as easily, you can pass the same procedure in-line as a lambda, and if I understood correctly, this is what you're supposed to do:
(string (lambda (r n)
<body>)
5
40)
Just replace <body> with the actual body of the decoration you want to use. In othre words: the change you're expected to do is in the way you pass the parameters to the function at invocation time, but you're not expected to change the function itself.
Imagine you have the procedure +. It could be any really. It takes several arguments but you need a different procedure that takes one and adds that to an already constant value 3.
Thus you want to pass + with the extra information that it should add 3.
A full definition of such procedure would be
(define (add3 n)
(+ 3 n))
which is the short form of the full define
(define add3
(lambda (n)
(+ 3 n)))
Now when passing a procedure 3+ you could actually just pass it's definition. These two does the same:
(do-computation add3 data)
(do-computation (lambda (n) (+ 3 n)) data)

Resources