Dr racket define error in student language. define: expected only one expression for the function body, but found 3 extra parts - scheme

When I write code in Dr Racket, I got error message
unsaved-editor:8:2: define: expected only one expression for the
function body, but found 3 extra parts in: (define (improve guess x)
(average guess (/ x guess)))
But this code can run in Racket or repl.it.
I want to know why error is happening in Dr Racket and is my code really wrong?
My code is this:
(define (average x y) (/ (+ x y) 2))
(define (square x) (* x x))
(define (sqrt1 x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
(sqrt1 9)

Your code is OK for Scheme/Racket. However Student Language is a subset of Scheme, highly limited so it's easier for beginners. It's also used in How To Design Programs book. You can read more about Student Languages (actually there is five of them) on https://docs.racket-lang.org/htdp-langs/index.html.
In case of define there are important limitations:
You can have only one expression in the function body.
In function body you can only use expressions, not definitions (so no define inside define).
To make your code valid for Student Language, depending on Level (Beginner, Intermediate etc), you can:
use letrec* or local instead of define for all local definitions
or
define good-enough, improve and sqrt-iter as top level functions.

Related

Racket: Trying to subtract numbers, getting list

I'm currently learning Racket/Scheme for a course (I'm not sure what's the difference, actually, and I'm not sure if the course covered that). I'm trying a basic example, implementing the Newton method to find a square root of a number; however, I ran into a problem with finding the distance between two numbers.
It seems that for whatever reason, when I'm trying to apply the subtraction operator between two numbers, it returns a list instead.
#lang racket
(define distance
(lambda (x y) (
(print (real? x))
(print (real? y))
(abs (- x y))
)
)
)
(define abs
(lambda x (
(print (list? x))
(if (< x 0) (- x) x)
)
)
)
(distance 2 5)
As you can see, I've added printing of the types of variables to make sure the problem is what I think it is, and the output of all those prints is #t. So:
In calling distance, x and y are both real.
In calling abs, x is a list.
So, the conclusion is that (- x y) returns a list, but why?
I double-checked with the documentation and it seems I'm using the subtraction operator correctly; I've typed (- 2 5) and then (real? (- 2 5)) into the same REPL I'm using to debug my program (Dr. Racket, to be specific), and I'm getting the expected results (-3 and #t, respectively).
Is there any wizard here that can tell me what kind of sorcery is this?
Thanks in advance!
How about this...
(define distance
(lambda (x y)
(print (real? x))
(print (real? y))
(abs (- x y))))
(define abs
(lambda (x) ;; instead of (lambda x ...), we are using (lambda (x) ...) form which is more strict in binding with formals
(print (list? x))
(if (< x 0) (- x) x)))
Read further about various lambda forms and their binding with formals.

Difference between usage of set! and define

In the following code:
(define x 14)
(display x) ; x = 14
(set! x 13)
(display x) ; x = 13
(define x 14)
(display x) ; x = 14
(set! y 13) ; SchemeError: y not found!
(display y)
What we a use case where someone would want to use set! over just define, if define can be used for everything that set! can be used for + the actual definition itself?
define creates a new binding between a name and a value (a variable), set! mutates an existing binding. These are not the same operation, languages like Python which confuse the operations notwithstanding.
In particular something like
(define x 1)
...
(define x 2)
is illegal: you can only create the variable once. Implementations may not check this, but that doesn't make it legal. Once you've created the binding, if you want to modify it you need to do that with set!.
A particular case where implementations (including Racket) are intentionally sloppy about this is when they are being used interactively. Quite often if you're interacting with the system you may want to say, for instance:
> (define square (λ (x) (+ x x)))
... ooops, that's not right, is it?
... Better fix it using the command-line editing
> (define square (λ (x) (* x x)))
In cases like that it's clearly better for the implementation just to allow this repeated definition of things, because it's going to make the life of users enormously easier.
But in programs such repeated definitions in the same scope are (almost?) always bugs, and they really ought to be caught: if you want to mutate a binding, use set!. Racket in particular will certainly puke on these.
Finally note that define is simply not legal in all the places set! is: even in Racket (which allows define in many more places than Scheme does) this is not even slightly legal code:
(define (foo x)
(define v x)
(if (odd? x)
(define v (* v 2))
(define v (/ v 2)))
v)
While this is
(define (foo x)
(define v x)
(if (odd? x)
(set! v (* v 2))
(set! v (/ v 2)))
v)
(It's still terrible code, but it is legal.).

Nested function in programing

I am reading Newton's method in SICP, where he introduce the block structure which have the function nested, say
(define (sqrt x)
(define (good enough ? guess x)
(<(abs(-(square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter(improve guess x)x)))
(sqrt-iter 1.0 x))
I am quite confused because in my understanding of nested, "good enough ?" and "improve guess" should be nested
in the body of "sqrt-iter", and "sqrt iter" should be put in the body of "sqrt x"
(define (sqrt x)
(sqrt-iter 1.0 x
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter(improve guess x)x)
(define (good enough ? guess x)
(<(abs(-(square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
))
))
why it is not like that.I am using LISP
Notice that sqrt-iter is already defined inside the body of sqrt. But the way you wrote it doesn't make sense, you're trying to call sqrt-iter but you're defining it inside the call as a third parameter. This isn't right:
(sqrt-iter 1.0 x (define (sqrt-iter ...)))
You must define it before calling it, and you can't define it as if it were a parameter, as part of the procedure call. This is the correct way:
(define (sqrt-iter guess x) ...) ; first define
(sqrt-iter 1.0 x) ; after defining, you can call it
Your other suggestion makes more sense, it'd be possible to define good-enough? and improve inside sqrt-iter, but maybe it's clearer in the way they wrote it in the book. This is valid, but has the disadvantage that good-enough? and improve will be redefined each time sqrt-iter is called:
(define (sqrt x)
(define (sqrt-iter guess x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)x)))
(sqrt-iter 1.0 x))
You should read more carefully the section of the book that explains how procedures are defined and used in Scheme, you seem to be confusing concepts, mixing parameters, procedure definitions and procedure invocations.

Function Definitions After Expressions in Scheme

I understand I can't define a function inside an expression, but I'm getting errors defining one after an expression within the same nested function. I'm using R5RS with DrScheme.
For example, this throws an error, 'define: not allowed in an expression context':
(define (cube x)
(if (= x 0) 0) ;just for example, no reason to do this
(define (square x) (* x x))
(* x (square x)))
In R5RS you can only use define in rather specific places: in particular you can use it at the beginning (only) of forms which have a <body>. This is described in 5.2.2. That means in particular that internal defines can never occur after any other expression, even in a <body>.
Native Racket (or whatever the right name is for what you get with#lang racket) is much more flexible in this regard: what you are trying to do would (apart from the single-armed if) be legal in Racket.
You can use define inside another definition. Some Schemes won't allow you to have an if without the else part, though. This works for me:
(define (cube x)
(if (= x 0) 0 1) ; just for example, no reason to do this
(define (square x) (* x x))
(* x (square x)))
Have you tried making the definition at the beginning? maybe that could be a problem with your interpreter.
define inside a procedure body (that includes all forms that are syntactic sugar for procedures, like let, let*, and letrec) are only legal before other expressions and never after the first expression and it can not be the last form.
Your example shows no real reason for why you would want to have an expression before definitions. There is no way you can get anything more than moving all define up to the beginning. eg.
(define (cube x)
;; define moved to top
(define (square x) (* x x))
;; dead code moved under define and added missing alternative
(if (= x 0) 0 'undefined)
(* x (square x)))
If the code isn't dead. eg. it's the tail expression you can use let to make a new body:
(define (cube x)
(if (= x 0)
0
(let ()
;; this is top level in the let
(define (square x) (* x x))
;; required expression
(* x (square x)))))
I think perhaps we would need an example where you think it would be warranted to have the define after the expression and we'll be happy to show how to scheme it up.

Adding the result of computation as an argument in Scheme

I try to do a program that calculates the square of a number in Scheme but it gives me as an error that I gave the abs procedure two arguments instead of one. This is my first program in Scheme and have no clue how to do it. I tried to change the position of the brackets but it doesn't work.
(define (square X)
(try 1 X))
(define (try guess X)
(if (good-enaugh? guess X)
guess
((try improve guess X) X)))
(define (good-enaugh? guess X)
(< (abs(- (* guess guess) X)) 0.0001))
(define (improve guess X)
(/(+ (/ X guess) guess) 2))
You are almost there. The problem is that the second branch of your conditional in try has a pair of parentheses too much.
(define (try guess X)
(if (good-enaugh? guess X)
guess
((try improve guess X) X)))
Should become:
(define (try guess X)
(if (good-enaugh? guess X)
guess
(try (improve guess X) X)))
You make a call to the function try. The first parameter is the result of (improve guess X) and the second argument is the number X. Notice that I also changed the parenthesis around the call to improve. The way you wrote it was calling the function try with as first argument the function improve, second argument guess and third argument X.
Full source
For good measure the complete source is listed below.
(define (square X)
(try 1 X))
(define (try guess X)
(if (good-enaugh? guess X)
guess
(try (improve guess X) X)))
(define (good-enaugh? guess X)
(< (abs(- (* guess guess) X)) 0.0001))
(define (improve guess X)
(/(+ (/ X guess) guess) 2))
> (square 13)
3,....
Link to repl.it

Resources