You are not logged in.

#1 2013-06-19 16:26:04

alphaniner
Member
From: Ancapistan
Registered: 2010-07-12
Posts: 2,810

[Solved]{scheme} Error: (/) bad argument type: #<unspecified>

I'm working through Structure and Interpretation of Computer Programs, and I've run into some behaviour I don't understand.
The code:

(define (average x y)
        (/ (+ x y) 2))

(define (refine r g)
        (print "["r"]["g"]")
        (average (/ r g) g))

(define (sqrt-guess rad guess)
        (define oldguess guess)
        (define guess (refine rad guess))   # problem line
        (if (= oldguess guess)
            guess
            (sqrt-guess rad guess)))

It seems that when refine is called in the problem line the second argument is not being 'received' as I would expect.

#;1> (sqrt-guess 9 1)
[9][#<unspecified>]

Error: (/) bad argument type: #<unspecified>

	Call history:

	<syntax>	  (sqrt-guess 9 1)
	<eval>	  (sqrt-guess 9 1)
	<eval>	  [sqrt-guess] (refine r g)
	<eval>	  [refine] (print "[" r "][" g "]")
	<eval>	  [refine] (average (/ r g) g)
	<eval>	  [refine] (/ r g)	<--

I tried (define guess (refine rad oldguess)), same outcome. At this point, I figure it's some consequence of applicative-order processing that I don't understand. But things got more interesting when I added a standalone call to refine:

(define (sqrt-guess rad guess)
        (define oldguess guess)
        (refine rad oldguess)                  # new line
        (define guess (refine rad oldguess))   # (define guess (refine rad guess)) also works
        (if (= oldguess guess)
            guess
            (sqrt-guess rad guess)))

Now the code runs as expected and returns an answer. However, if I change "oldguess" to "guess" in the first refine line:

(define (sqrt-guess rad guess)
        (define oldguess guess)
        (refine rad guess)
        (define guess (refine rad oldguess))   # (define guess (refine rad guess)) also fails
        (if (= oldguess guess)
            guess
            (sqrt-guess rad guess)))

the original error re-occurrs. In every case the 'standalone' call to refine gets both arguments as expected; it's the one in "define guess" that has issues.

I'm not looking for help fixing the code, but for an explanation/breakdown of what's going on. Thanks.

Last edited by alphaniner (2013-06-20 13:20:34)


But whether the Constitution really be one thing, or another, this much is certain - that it has either authorized such a government as we have had, or has been powerless to prevent it. In either case, it is unfit to exist.
-Lysander Spooner

Offline

#2 2013-06-20 01:30:59

skottish
Forum Fellow
From: Here
Registered: 2006-06-16
Posts: 7,942

Re: [Solved]{scheme} Error: (/) bad argument type: #<unspecified>

I don't know much about Scheme, but I believe that redefining 'guess' is confusing the compiler. I do know that guess isn't seen as a number by the time that the function runs; maybe a reference to a function?

You are working too hard though. Defining guess and oldguess can be reduced to one let function:

(define (sqrt-guess rad guess)
  (let ((newguess (refine rad guess)))
    (if (= guess newguess)
      newguess
      (sqrt-guess rad newguess))))

I don't know if this is the best let form in this situation, but it's cleaner.

*** Edit to fix the indentation of the if block. In a world full of parenthesis, one needs their indentation. ***

Last edited by skottish (2013-06-20 18:23:47)

Offline

#3 2013-06-20 13:20:09

alphaniner
Member
From: Ancapistan
Registered: 2010-07-12
Posts: 2,810

Re: [Solved]{scheme} Error: (/) bad argument type: #<unspecified>

I believe that redefining 'guess' is confusing the compiler.

You're right. That was my first thought too, but I swear I tried something like (define foo (refine rad guess)) which didn't work either. I just tried it again and it works just fine. hmm

I haven't been introduced to let yet, and the way it's parenthesized I don't really understand how it works. I think of let in bash terms (ie. let x++) so maybe that's my problem. Anyway, I'll wait 'till I come across it in the text.

Using your suggestions I got it to work using only stuff I know:

(define (sqrt-guess rad guess)
        (define newguess (refine rad guess))
        (if (= newguess guess)
            guess
            (sqrt-guess rad newguess)))

Definitely cleaner. Thanks!


But whether the Constitution really be one thing, or another, this much is certain - that it has either authorized such a government as we have had, or has been powerless to prevent it. In either case, it is unfit to exist.
-Lysander Spooner

Offline

Board footer

Powered by FluxBB