Search code examples
racket

why is this define not an expression?


I can't figure out the problem DrRacket (IDE) complains about with regard to the (define (bifurcate f a f_a b f_b)... Please advise. The define block is said to be an improper expression, and perhaps an implicit begin. Note, if I copy and paste the define into the REPL window (and, of course, define the f_a, f_b, etc.) it works fine. Thanks much!
(p.s., Its rather early-days in my self study of scheme with two to three books)


#lang racket
;function to return root of y = f(x) where we know solution is in some bracket [a, b]
;subject to a < b and
;sign(f(a)) != sign(f(b))
;
;my version of "search" on pg 67 "Structure and Interpretation of Computer Programs"
;
(define (bifurcate-wrapper f a b)
  (if (or (positive? (* (f a) (f b))) (>= a b)) ;check for erroneous input
      #f 
      (let ((f_a (f a)) (f_b (f b))); initial values, don't recalculate BOTH f(a) and f(b) ea. time
        (define (bifurcate f a f_a b f_b); DrRacket says this define is not an expression...
      (let ((midpoint (/ (+ a b) 2.0)))
    (if (close-enough? a b)
        midpoint
        (let ((f_mid (f midpoint)))
          (cond ((positive? (* f_a f_mid))
                 (bifurcate f midpoint f_mid b f_b))
                ((positive? (* f_mid f_b))
                 (bifurcate f a f_a midpoint f_mid))
                (else midpoint)))))); end of define
        )
  )
) 


(define (close-enough? x y)
  (< (abs (- x y)) 0.001))

(bifurcate-wrapper sin 2.0 4.0) ;expect pi

Solution

  • The full error message is

    49-unsaved-editor:7:8: begin (possibly implicit): the last form is not an expression
      at: (define (bifurcate f a f_a b f_b) (let ((midpoint (/ (+ a b) 2.0))) (if (close-enough? a b) midpoint (let ((f_mid (f midpoint))) (cond ((positive? (* f_a f_mid)) (bifurcate f midpoint f_mid b f_b)) ((positive? (* f_mid f_b)) (bifurcate f a f_a mid...
      in: (begin (define (bifurcate f a f_a b f_b) (let ((midpoint (/ (+ a b) 2.0))) (if (close-enough? a b) midpoint (let ((f_mid (f midpoint))) (cond ((positive? (* f_a f_mid)) (bifurcate f midpoint f_mid b f_b)) ((positive? (* f_mid f_b)) (bifurcate f a ...
      #(242 502)
    

    That's because the only thing in the body of the outer let is the definition of binfurcate, and a define is one of the few things in scheme and Racket that's not an expression. let allows 0 or more internal defines followed by expressions (Possibly mixed with more internal definitions, but it has to end with an expression).

    You just have to call your bifurcation function after defining it so satisfy that requirement. I'd also clean up your indentation (Racket menu -> Reindent All in DrRacket) and move all those single-line closing parens so they cuddle with the rest in normal Lispy style.

    For working SICP problems, also consider installing the SICP package and using #lang sicp. That provides some things that the book assumes are present in the host Scheme that aren't in standard Racket.