Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker!bloom-beacon!eru!luth!sunic!tut!pk From: pk@tut.fi (Kellom{ki Pertti) Newsgroups: comp.lang.lisp Subject: Re: FUNCALL question Message-ID: Date: 2 Feb 90 13:36:58 GMT References: <3277@accuvax.nwu.edu> <1990Jan28.175437.19293@hellgate.utah.edu> <1655@skye.ed.ac.uk> <386@forsight.Jpl.Nasa.Gov> <19471@mephisto.UUCP> Sender: News@tut.fi Organization: Tampere Univ. of Technology, Finland. Lines: 90 In-reply-to: buff@pravda.gatech.edu's message of 1 Feb 90 20:11:05 GMT It seems to me that the whole mess with funcall is caused by implementations that extend the Common Lisp as defined by CLtL. The confusion stems from the semantics of funcall. CLtL states that "(funcall fn a1 a2 ... an) applies the function fn to the arguments a1, a2, ..., an. [stuff about macros etc. deleted]" Most Common Lisp implementations (Allegro, Kyoto, Symbolics among others), however, extend the semantics by saying that if fn evaluates to a symbol, then the *global* (yuch!) function definition of that symbol is used. This causes a great deal of confusion, as can be seen from the ongoing discussion. Specifically, some of the examples given by Richard Billington work only because of this hack. (Please do not understand me wrong: I can understand the reasoning behind it, it just gives my schemy mind the shivers!) >>>>> On 1 Feb 90 20:11:05 GMT, buff@pravda.gatech.edu (Richard Billington) said: buff> (defun foo (x) buff> (flet ((hi () (print "hi there")) ;same for labels buff> (bye () (print "good-bye"))) buff> (funcall x))) buff> and then got an error (that the function hi is undefined) when I buff> tried the following: buff> (foo 'hi) Because funcall got the symbol 'hi' as the first argument, and didn't find a global function definition for it. buff> Whereas the following works fine: buff> (defun hi () (print "hi there")) buff> (defun foo (x) (funcall x)) buff> (foo 'hi) => "hi there" Because this time there is a global function definition. buff> (defun foo1 () buff> (flet ((hi () (print "hi there")) ;same for labels buff> (bye () (print "good-bye"))) buff> (funcall 'hi))) buff> (defun foo2 () buff> (flet ((hi () (print "hi there")) ;same for labels buff> (bye () (print "good-bye"))) buff> (funcall #'hi))) buff> foo2 works, foo1 doesn't. Now consider Same thing here, foo1 does not find a global function definition. foo2 works, because "within the body of the flet form, function names matching those defined by flet refer to the locally defined function rather than to the global definitions of the same name" (CLtL). buff> (defun foo3 (x) buff> (let ((hi #'(lambda () (print "hi there"))) buff> (bye #'(lambda () (print "hi there")))) buff> (funcall x))) buff> This does work. I got an error message from this (using Allegro CL 3.0.3). I suspect that you had a global function called 'hi', and everything works as before. The thing that bothers my puritan mind here, is that somehow the distinction between functions and symbols is blurred. In Scheme everything is clear: a procedure is a procedure and a symbol is a symbol. Once you introduce special treatment for some data types, you get confusion because the language is no more logical. One thing that surprises me is that CLtL does specify treatment for both functions and symbols when given as arguments to apply (with the same semantics as discussed before) but not for funcall. I must say that this whole thing has really made me feel bad about CL. Previously all I had against CL was it sheer size, but this funcall stuff has really pissed me off. Using global function bindings seems to me to violate all the nice rules of lexical scoping. To me it is simply a dirty hack. Moreover, the treatment of functions with all the special forms and procedures seems to imply that functions in CL are not really first class citizens, because one has to go thru a *lot* of trouble when passing them around. -- Pertti Kellom\"aki (TeX format) # These opinions are mine, Tampere Univ. of TeXnology # ALL MINE ! Software Systems Lab # (but go ahead and use them, if you like)