Search code examples
syntaxschemeracketsicp

Scheme/Racket - Undefined Function; Cannot use before initialization


Currently going through SICP, and near the end of the first chapter, they ask you to program a value for pi, with pi/4 = (2 * 4 * 4 * 6 * 6 * 8 * ...) / (3 * 3 * 5 * 5 * 7 * 7 *..)

I have the following functions defined:

;Term and Next are both functions, a and b are the range of the product
(define (product term a next b) 
  (if (> a b) 1
      (* (term a) (product term (next a) next b))))

and

(define (pi-approx n)
  (define (square x) (* x x))

  (define (num-prod ind) (* (* 2 ind) (* 2 (+ ind 1)))) ; calculates the product in the numerator for a certain term
  (define (denom-prod ind) (square (+ (* ind 2 ) 1))) ;Denominator product at index ind

  (define num (product num-prod 1 inc n))
  (define denom (product denom-prod 1 inc n))

  (* 4 (/ num denom))) ;;Resulting value

When I run this code in DrRacket, I get the following error: num-prod: Undefined; Cannot use before initialization, even though I initialize num-prod a couple of lines before I use it.

What am I doing wrong syntactically?


Solution

  • This is one of the top Google results for the question, so I thought I'd add some more detail:

    In most Scheme implementations (such as R5RS), there is no guarantee of the order in which your definitions are parsed. In other words, they are not parsed sequentially. Yes, you defined num-prod a few lines before, but it's entirely possible that num is compiled first, hence the error.

    In Racket, lambdas are compiled to letrec* operators instead of letrec, meaning that there is a guarantee of sequential parsing. That's why changing languages helped.