Error: Can't bind name in null syntactic environment - scheme

I'm currently going through exercise 1.3 of the sicp book. Here's the description of the problem:
Define a procedure that takes three numbers as arguments and returns
the sum of the squares of the two larger numbers.
I tried to solve it with the following code
(define (square x) (* x x))
(define (sq2largest a b c)
((define large1 (if (> a b) a b))
(define small (if (= large1 a) b a))
(define large2 (if (> c small) c small))
(+ (square large1) (square large2))))
When I ran it in mit-scheme, I got the following error:
;Can't bind name in null syntactic environment: large1
#[reserved-name-item 13]
Googling this error doesn't yield many results. Does anyone know what's wrong with my code? (I'm not familiar with Scheme)

I'll try to break down the structure of your sq2largest procedure:
The basic structure is:
(define (sq2largest a b c)
; Body)
The Body you wrote is:
((define large1 (if (> a b) a b)) ; let this be alpha
(define small (if (= large1 a) b a)) ; let this be bravo
(define large2 (if (> c small) c small)) ; let this be charlie
(+ (square large1) (square large2)) ; let this be delta) ; This parentheses encloses body
So, the Body is structured as:
(alpha bravo charlie delta)
Which translates to: "Pass bravo, charlie and delta as arguments to alpha."
Now, alpha is being told to take a bunch of arguments, but inside the namespace reserved for large1, no provision was made for any argument... i.e. scheme encounters a null syntactic environment where it cannot bind any variable.
Parentheses are significant in Scheme (and most, if not all, Lisps) because they define the scope of a procedure and enforce[1] the order of application of operations.
[1] "No ambiguity can arise, because the operator is always the leftmost element and the entire combination is delimited by the parentheses." http://mitpress.mit.edu/sicp/full-text/sicp/book/node6.html

You have too many brackets. If you took out the extra brackets around the internal defines, things should work a lot better.

Related

Scheme: Proabably a typo in SICP. 1.3.2. Am I right?

In SICP, (1.3.2. page: 62), there is a solution for finding pi-sum using lambda. The solution is:
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2))))
a
(lambda (x) (+ x 4))
b))
However, I feel there should be a bracket enclosing ((lambda (x) (+ x 4) b). The program as such produces an error saying sum is expecting a number but getting a procedure.
Modifying the above code is giving no error.
(define (pi-sum a b)
(sum ((lambda (x) (/ 1.0 (* x (+ x 2))))
a)
((lambda (x) (+ x 4))
b)))
Please correct me if my understanding is wrong. I assume the book cannot be wrong.
The pi-sum procedure in the book is making use of the higher-order procedure sum, defined earlier in 1.3.1. The sum procedure takes a and b as arguments which describe the bounds of the summation, and it takes term and next as arguments which describe how to create a term from a, and how to get the next a from the current a. Both term and next need to be procedures. Here is the definition of sum from the book:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
If you add parentheses in the definition of pi-sum, you should get an exception because sum requires four arguments, but now only two are passed. I am not sure why you are getting an error like "sum is expecting a number but getting a procedure", but I suspect that you have a different definition for sum than the one intended by the book.

DrRacket define begin set! probably should work but dont

Im learning for exam of programming in lisp using DrRacket..
In presentation from lectures i found this code:
(define (f a b c)
(define delta)
(begin
(set! delta (- (* b b) (* 4 a c))
(if (>=? delta 0)
(writeln ”są pierwiastki”)
(writeln ”nie ma pierwiastków)))))
But it dont work.
DrRacket is showing:
. define: bad syntax (missing expression after identifier) in: (define delta)
Can't I set delta value later?
What is the problem?
thanks in advance
The original error message is because
(define delta)
is missing a value. Instead it should be something like:
(define delta 0)
There some other issues:
The double quotes weren't the " character and weren't recognized
by Racket.
Some parens were wrong.
Also I don't know why it was define-ing delta, then immediately
set!-ing it.
I tried to fix/simplify what you posted, and came up with the
following. But I'm not really sure what the function is supposed to
do, so I don't know if the example output is correct.
#lang racket
(define (f a b c)
(define delta (- (* b b) (* 4 a c)))
(if (>= delta 0)
(displayln "są pierwiastki")
(displayln "nie ma pierwiastków")))
;; Example output:
(f 1 2 3)
;;-> nie ma pierwiastków
(f 1 200 3)
;;-> są pierwiastki
Try this:
#lang racket
(define (f a b c)
(define delta 0)
(set! delta (- (* b b) (* 4 a c)))
(if (>= delta 0)
(displayln "są pierwiastki")
(displayln "nie ma pierwiastków")))
What was wrong with your code:
It's probably a copy-paste error, but in Scheme we delimit strings using the " character, not ” as in your code. And the last line is missing the closing ".
Although some interpreters accept a define without an initial value, the standard is that a value must be present after the variable name
A closing parenthesis is missing at the end of the set! line
The define and set! lines can be merged into a single line: (define delta (- (* b b) (* 4 a c)))
The >=? operator is not standard in Scheme, it might work in your interpreter but if possible use the standard >=
The writeln procedure is not standard in Scheme, in Racket you can substitute it for displayln
Not really an error, but you don't need to write a begin inside a procedure definition, it's implicit
In conclusion: the code in the question seems to be intended for a different interpreter, this question was tagged racket but believe me, what you have is not valid Racket code - heck, is not even standard Scheme. Make sure to use the correct interpreter, and be very alert for typos in the text.
I think Greg already has a perfect answer to your problem, but I just want to add the obvious let version of his code as well:
;; for a given ax^2+bx+c=0
;; this displays if it has at least one
;; real number answer or not
(define (equation-has-answer a b c)
(let ((delta (- (* b b) (* 4 a c))))
(if (>= delta 0)
(displayln "Has answer(s)")
(displayln "Has no answers"))))
To just make a predicate you can do this:
;; for a given ax^2+bx+c=0
;; this returns #t if it has at least one
;; real number answer and #f otherwise
(define (equation-has-answer? a b c)
(>= (- (* b b) (* 4 a c)) 0))

Variadic Function in Scheme

I have to define a variadic function in Scheme that takes the following form:
(define (n-loop procedure [a list of pairs (x,y)]) where the list of pairs can be any length.
Each pair specifies a lower and upper bound. That is, the following function call: (n-loop (lambda (x y) (inspect (list x y))) (0 2) (0 3)) produces:
(list x y) is (0 0)
(list x y) is (0 1)
(list x y) is (0 2)
(list x y) is (1 0)
(list x y) is (1 1)
(list x y) is (1 2)
Obviously, car and cdr are going to have to be involved in my solution. But the stipulation that makes this difficult is the following. There are to be no assignment statements or iterative loops (while and for) used at all.
I could handle it using while and for to index through the list of pairs, but it appears I have to use recursion. I don't want any code solutions, unless you feel it is necessary for explanation, but does anyone have a suggestion as to how this might be attacked?
The standard way to do looping in Scheme is to use tail recursion. In fact, let's say you have this loop:
(do ((a 0 b)
(b 1 (+ a b))
(i 0 (+ i 1)))
((>= i 10) a)
(eprintf "(fib ~a) = ~a~%" i a))
This actually get macro-expanded into something like the following:
(let loop ((a 0)
(b 1)
(i 0))
(cond ((>= i 10) a)
(else (eprintf "(fib ~a) = ~a~%" i a)
(loop b (+ a b) (+ i 1)))))
Which, further, gets macro-expanded into this (I won't macro-expand the cond, since that's irrelevant to my point):
(letrec ((loop (lambda (a b i)
(cond ((>= i 10) a)
(else (eprintf "(fib ~a) = ~a~%" i a)
(loop b (+ a b) (+ i 1)))))))
(loop 0 1 0))
You should be seeing the letrec here and thinking, "aha! I see recursion!". Indeed you do (specifically in this case, tail recursion, though letrec can be used for non-tail recursions too).
Any iterative loop in Scheme can be rewritten as that (the named let version is how loops are idiomatically written in Scheme, but if your assignment won't let you use named let, expand one step further and use the letrec). The macro-expansions I've described above are straightforward and mechanical, and you should be able to see how one gets translated to the other.
Since your question asked how about variadic functions, you can write a variadic function this way:
(define (sum x . xs)
(if (null? xs) x
(apply sum (+ x (car xs)) (cdr xs))))
(This is, BTW, a horribly inefficient way to write a sum function; I am just using it to demonstrate how you would send (using apply) and receive (using an improper lambda list) arbitrary numbers of arguments.)
Update
Okay, so here is some general advice: you will need two loops:
an outer loop, that goes through the range levels (that's your variadic stuff)
an inner loop, that loops through the numbers in each range level
In each of these loops, think carefully about:
what the starting condition is
what the ending condition is
what you want to do at each iteration
whether there is any state you need to keep between iterations
In particular, think carefully about the last point, as that is how you will nest your loops, given an arbitrary number of nesting levels. (In my sample solution below, that's what the cur variable is.)
After you have decided on all these things, you can then frame the general structure of your solution. I will post the basic structure of my solution below, but you should have a good think about how you want to go about solving the problem, before you look at my code, because it will give you a good grasp of what differences there are between your solution approach and mine, and it will help you understand my code better.
Also, don't be afraid to write it using an imperative-style loop first (like do), then transforming it to the equivalent named let when it's all working. Just reread the first section to see how to do that transformation.
All that said, here is my solution (with the specifics stripped out):
(define (n-loop proc . ranges)
(let outer ((cur ???)
(ranges ranges))
(cond ((null? ranges) ???)
(else (do ((i (caar ranges) (+ i 1)))
((>= i (cadar ranges)))
(outer ??? ???))))))
Remember, once you get this working, you will still need to transform the do loop into one based on named let. (Or, you may have to go even further and transform both the outer and inner loops into their letrec forms.)

Using let in Scheme

I want to write a program to find the roots of the quadratic equation in Scheme. I used LET for certain bindings.
(define roots-with-let
(λ (a b c)
(let ((4ac (* 4 a c))
(2a (* 2 a))
(discriminant (sqrt ( - (* b b) (4ac)))))
(cons ( / ( + (- b) discriminant) 2a)
( / ( - (- b) discriminant) 2a)))))
I defined the discriminant with 4ac since I did not want (* 4 a c). Even though I have defined (4ac (* 4 a c)), it is giving me this error:
expand: unbound identifier in module in: 4ac.
My question is how is let evaluated (what order)? And if i want 4ac in my let should i write another inner let? Is there a better way to do this?
Use let* instead of let.
The difference between let and let* is the following:
let* binds variables from left to right. Earlier bindings can be used in new binding further to the right (or down).
let on the other hand can be thought of as syntactic sugar (or macro) for simple lambda abstraction:
(let ((a exp1)
(b exp2))
exp)
is equivalent to
((lambda (a b)
exp)
exp1 exp2)
4ac is a variable with a numeric value, so (4ac) is not meaningful.
LET binds all variables, but the variables can't be used in the computations for the values.
This does not work:
(let ((a 1) (b 1) (c (* a b)))
c)
Use:
(let ((a 1) (b 1))
(let ((c (* a b)))
c))
Above introduces A and B with the first LET. In the second LET both A and B now can be used to compute C.
Or:
(let* ((a 1) (b 1) (c (* a b)))
c)
You'll need a special let-construct (let*) here since the variables inside the let-definition refer to each other.
It's rather a problem of defining a scope than of evaluating an expression (In usual let-definitions, the order of evaluation doesn't matter since the values may not use each other)
When you use let, the bindings are not visible in any of the bodies. Use let* instead and see the RNRS docs for details.

Beginner: Curried functions in Scheme

I'm using the SICP lectures and text to learn about Scheme on my own. I am looking at an exercise that says "An application of an expression E is an expression of the form (E E1,...En). This includes the case n=0, corresponding to an expression (E). A Curried application of E is either an application of E or an application of a Curried application of E."
(Edit: I corrected the above quote ... I'd originally misquoted the definition.)
The task is to define a Curried application of the procedure which evaluates to 3 for
(define foo1
(lambda (x)
(* x x)))
I really don't understand the idea here, and reading the Wikipedia entry on Curriying didn't really help.
Can anyone help with a more lucid explanation of what's being asked for here?
Actually even giving me the answer to this problem would be helpful, since there are five more to solve after this one. ... I just am not getting the basic idea.
Addition: Even after Brian Campbell's lengthy explanation, I'm still somewhat lost.
Is (foo1 (sqrt 3))) considered an application of foo, and therefore a curried application of foo?
Seems too simple, but maybe...
Typing (((foo1 2 )) 2) into DrScheme gives the following error (which I kind of expected)
procedure application: expected procedure, given: 4 (no arguments)
After re-reading What is Currying? I understand I can also re-define foo1 to be:
(define (foo1 a)
(lambda (b)
(* a b)))
So then I can type
((foo1 3 ) 4)
12
But this doesn't really get me any closer to producing 3 as an output, and it seems like this isn't really currying the original foo1, it's just re-defining it.
Damn, 20 years of C programming hasn't prepared me for this. :-) :-)
Hm, this problem is fairly confusingly phrased, compared to the usually much more clear style of the books. Actually, it looks like you might be misquoting the problem set, if you're getting the problem set from here; that could be contributing to your confusion.
I'll break the definition down for you, with some examples that might help you figure out what's going on.
An application of an expression E is an expression of the form (E E1 ... En).
Here's an example of an application:
(foo 1 2) ; This is an application of foo
(bar 1) ; This is an application of bar
This includes the case n=0, corresponding to an expression (E).
(baz) ; This is an application of baz
A Curried application of E is either an application of E or an application of a Curried application of E?...........
This is the one that you misquoted; above is the definition from the problem set that I found online.
There are two halves to this definition. Starting with the first:
A Curried application of E is either an application of E
(foo 1 2) ; (1) A Curried application of foo, since it is an application of foo
(bar 1) ; (2) A Curried application of bar, since it is an application of bar
(baz) ; (3) A Curried application of baz, since it is an application of baz
or an application of a Curried application of E
((foo 1 2) 3) ; (4) A Curried application of foo, since it is an application of (1)
((bar 1)) ; (5) A Curried application of bar, since it is an application of (2)
((baz) 1 2) ; (6) A Curried application of baz, since it is an application of (3)
(((foo 1 2) 3)) ; A Curried application of foo, since it is an application of (4)
(((bar 1)) 2) ; A Curried application of bar, since it is an application of (5)
; etc...
Does that give you the help you need to get started?
edit: Yes, (foo1 (sqrt 3)) is a Curried application of foo1; it is that simple. This is not a very good question, since in many implementations you'll actually get 2.9999999999999996 or something like that; it's not possible to have a value that will return exactly 3, unless your Scheme has some sort of representation of exact algebraic numbers.
Your second example is indeed an error. foo1 returns an integer, which is not valid to apply. It is only some of the later examples for which the recursive case, of an application of an application of the function, are valid. Take a look at foo3, for example.
edit 2: I just checked in SICP, and it looks like the concepts here aren't explained until section 1.3, while this assignment only mentions section 1.1. I would recommend trying to read through section 1.3 if you haven't yet.
See What is 'Currying'?
Currying takes a function and provides
a new function accepting a single
argument, and returning the specified
function with its first argument set
to that argument.
Most of the answers you've gotten are examples of 'partial evaluation'. To do true currying in Scheme you need syntactic help. Like such:
(define-syntax curry
(syntax-rules ()
((_ (a) body ...)
(lambda (a) body ...))
((_ (a b ...) body ...)
(lambda (a) (curry (b ...) body ...)))))
Which you then use as:
> (define adding-n3 (curry (a b c) (+ a b c)))
> (define adding-n2-to-100 (adding-n3 100))
> ((adding-n2-to-100) 1) 10)
111
> (adding-n3 1)
#<procedure>
> ((adding-n3 1) 10)
#<procedure>
I don't think James' curry function is correct - there's a syntax error when I try it in my scheme interpreter.
Here's an implementation of "curry" that I use all the time:
> (define curry (lambda (f . c) (lambda x (apply f (append c x)))))
> ((curry list 5 4) 3 2)
(5 4 3 2)
Notice, it also works for currying more than one argument to a function.
There's also a macro someone has written that let's you write functions that implicitly curry for you when you call them with insufficient arguments: http://www.engr.uconn.edu/~jeffm/Papers/curry.html
I think you are confusing yourself too much. Currying a function takes a function of type F(a1,a2,...aN) and turns it into F(a1) which returns a function that takes a2, (which returns a function that takes a3 ... etc.)
So if you have:
(define F (lambda (a b) (+ a b)))
(F 1 2) ;; ==> 3
you can curry it to make something that acts like the following:
(define F (lambda (a) (lambda (b) (+ a b))))
((F 1) 2) ;; ==> 3
in the case of your specific question, it seems very confusing.
(foo1 (sqrt 3))
seems to be suitable. I would recommend leaving it for now and reading more of the book.
you can actually make a function that does a simple curry for you:
(define (curry f x) (lambda (y) (apply f (cons x y))))
(curry = 0) ;; a function that returns true if input is zero
Depending on your Scheme implementation, there might be some utilities to be able to recover from errors/exceptions, for example, in Chicken Scheme, there is condition-case.
(condition-case (func)
((exn) (print "error")))
We can define a function which take a function of an arbitrary number of elements and return the curryed form :
(define curry
(lambda (func . args)
(condition-case (apply func args)
((exn)
(lambda plus
(apply curry func (append args plus)))))]))))
This is a bit ugly, because if you use too many argument one time, you'll never get the final result, but this turn any function into the curryed form.

Resources