I don't understand what the differences are between (sorry for the contrived example):
(define average
(lambda (elems)
(define length
(lambda (xs)
(if (null? xs)
0
(+ 1 (length (cdr xs))))))
(define sum
(lambda (xs)
(if (null? xs)
0
(+ (car xs) (sum (cdr xs))))))
(define total (sum elems))
(define count (length elems))
(/ total count)))
and
(define average
(lambda (elems)
(letrec ((length
(lambda (xs)
(if (null? xs)
0
(+ 1 (length (cdr xs))))))
(sum
(lambda (xs)
(if (null? xs)
0
(+ (car xs) (sum (cdr xs))))))
(total (sum elems))
(count (length elems)))
(/ total count))))
As far as I can tell, they both create a new scope, and in that scope create 4 local variables that refer to each other and to themselves, and evaluate and return a body.
Am I missing something here, or is letrec
synonymous with scoped define
s?
I know this may be implementation dependent; I'm trying to get an understanding of the fundamentals of Lisps.
length
andsum
are guaranteed to be bound (to locations); what isn't guaranteed is that they have yet been assigned their initializing values. And even if they have been assigned them, the Scheme reports R5RS--R7RS say it's nonetheless an "error" to be referencing those values in the way you do in the initializing clauses fortotal
andcount
. (However, I don't think that implementations are required to detect and complain about this error.) Some more on differences btwletrec
/letrec*
: https://mcmap.net/q/1925586/-letrec-and-reentrant-continuations/272427 – Nurse