Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

#Hash#

3 views
Skip to first unread message

samwise gamgee

unread,
Apr 26, 2001, 1:32:08 PM4/26/01
to
Can anyone tell me the difference between these two lines of code:
(MAPCAR '+ '(2 3 4))
(MAPCAR #'+ '(2 3 4))
i.e. what does the hash symbol do (if anything)?

Kent M Pitman

unread,
Apr 26, 2001, 2:10:12 PM4/26/01
to
samwise gamgee <gamg...@yahoo.com> writes:

'x denotes (quote x).
#'x denotes (function x).

Conceptually, MAPCAR maps a "function".

Common Lisp allows two ways of "designating" a function. One is to use
the function itself, the other is to use a symbol whose function value
is the function.

The first usage maps '+ which yields a symbol. (SYMBOL-FUNCTION '+) is a
function. MAPCAR will, inside itself, do:

(DEFUN MAPCAR (FUNCTION &REST LISTS)
(WHEN (SYMBOLP FUNCTION) (SETQ FUNCTION (SYMBOL-FUNCTION FUNCTION)))
...)

or something like that.

The use of #'+ gets the symbol's function value, as would a use
oF (FUNCTION +). If there is no intervening binding (see FLET or LABELS),
then this is the same as SYMBOL-FUNCTION. You aren't permitted to make
a FLET or LABELS binding for system functions. But for a user function:

(DEFUN FOO (X) (+ X 1))

(FLET ((FOO (X) (+ X 10)))

(PRINT (MAPCAR 'FOO '(1 2 3))) ;uses global (SYMBOL-FUNCTION 'FOO)
(PRINT (MAPCAR #'FOO '(1 2 3))) ;uses local (FUNCTION FOO).

'DONE)

You'll note these do different things. The first PRINT prints (2 3 4) while
the second PRINT prints (11 12 13).

#'foo always gets you the FOO that doing (FOO ...) would get you
because (FOO ...) is the same as (FUNCALL #'FOO ...), assuming
FOO is not a macro nor special operator.

Barry Margolin

unread,
Apr 26, 2001, 2:16:35 PM4/26/01
to
In article <3AE85B97...@yahoo.com>,

#'<expr> is short for (function <expr>). The FUNCTION special operator
returns the functional binding of the symbol in the current lexical
environment. So the first expression passes the symbol + to the MAPCAR
function, while the second expression passes the function named + to the
MAPCAR function.

When MAPCAR receives a symbol as an argument, calls SYMBOL-FUNCTION on it
to get the function to use. This will return the symbol's global
definition. This can be different from its definition in the current
lexical environment if there's an FLET binding.

In the case of +, there should never be a local binding, so the two
expressions should be equivalent. But for user-defined function names,
there could be. Consider:

(defun adder (x)
(+ x 1))

(flet ((adder (x)
(+ x 2)))
(values (mapcar 'adder '(2 3 4))
(mapcar #'adder '(2 3 4))))

This will return two lists:

(3 4 5)
(4 5 6)

--
Barry Margolin, bar...@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.

Erik Naggum

unread,
Apr 26, 2001, 9:50:02 PM4/26/01
to
* samwise gamgee <gamg...@yahoo.com>

The hash is a reader macro character that, unlike ' and ( and ;, does not
immediately cause a reader function to be called. Instead, it reads
another character which determines which reader function to call. #'
means quote as function object, ' means quote as object. ( means start a
list, #( means start a vector. ; means start a comment, #; has no
meaning. :foobar is a keyword symbol, #:foobar is an uninterned symbol.
#P introduces a pathname, #A an array, #X a hexadecimal number. #\x is
the character x, which may be the name of a character, not just a literal.

The difference between #'+ and '+ is that #'+ is read as (function +),
while 'x is read as (quote x). Therefore the two lines of code are
actually read as the Common Lisp code:

(mapcar (quote +) (quote (2 3 4)))
(mapcar (function +) (quote (2 3 4)))

(quote +) returns the argument _unevaluated_, or quoted.

(function +) does not evaluate the argument, but looks it up in the
lexical environment for a functional definition. There are some subtle
differences between what mapcar will do with a symbol and what the
function special operator will do with its argument. E.g.,

(defun foo (x) (expt x 2))

(flet ((foo (x) (expt 2 x)))
(values (mapcar 'foo '(1 2 3 4))
(mapcar #'foo '(1 2 3 4))))
=> (1 4 9 16)
=> (2 4 8 16)

If you define a function named (setf foo), you cannot refer to it with
'(setf foo), but must use #'(setf foo), and you cannot access the global
version if you shadow it with flet using notation -- you need a separate
variable to hold the shadowed global value.

It may be pedagogically sound to write things out using explicit forms,
like quote and function, until you understand how they work, and then you
will appreciate their abbreviated syntactic expression.

#:Erik
--
I found no peace in solitude.
I found no chaos in catastrophe.
-- :wumpscut:

0 new messages