In article <··································@4ax.com>,
<·······@hotmail.com> wrote:
>
>How can I make a function defined in labels refer to another function defined
>in the same labels body?
>
>For example (this is from SICP page 223):
>(defun make-account (balance)
> (labels ((withdraw (amount)
> (if (>= balance amount)
> (progn
> (setf balance (- balance amount))
> balance)
> (format t "Insufficient funds")))
> (deposit (amount)
> (setf balance (+ balance amount))
> balance)
> (dispatch (m)
> (cond
> ((equal m 'withdraw) withdraw)
> ((equal m 'deposit) deposit)
> (t (format t "Unknown request -- MAKE-ACCOUNT")))))
> dispatch))
>
>This gets an error:
>; MAKE-WITHDRAW
>;;;*** Warning in (SUBFUNCTION (LABELS DISPATCH) MAKE-ACCOUNT): WITHDRAW
>assumed special
>;;;*** Warning in (SUBFUNCTION (LABELS DISPATCH) MAKE-ACCOUNT): DEPOSIT
>assumed special
>;;;*** Warning in MAKE-ACCOUNT: DISPATCH assumed special
>; MAKE-ACCOUNT
The reason you're getting these errors is because you're referring to the
function names as if they were variables. To refer to a function, you have
to use #'<function-name>, i.e.:
(dispatch (m)
(cond
((equal m 'withdraw) #'withdraw)
((equal m 'deposit) #'deposit)
(t (format t "Unknown request -- MAKE-ACCOUNT")))))
BTW, wouldn't it be better if the last clause used ERROR rather than
FORMAT? In fact, you could write it as:
(dispatch (m)
(ecase m
(withdraw #'withdraw)
(deposit #'deposit))))
ECASE will take care of the matching and error handling for you.
--
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.