From: akopa
Subject: A function
Date: 
Message-ID: <b81bc24b-d426-42cd-8536-706a2bc7b53e@w34g2000hsg.googlegroups.com>
Could some explain, or point to a thread that discusses the history of
what kind of values can specify functions?  For instance I was a
little surprised a symbol was funcallable: (funcall '+ 1 2 3) -> 6.

Is this good style since it doesn't seem to work local functions?

(flet ((foo (&rest args) (apply '+ args)))
       (funcall 'foo 1 2 3))

*** - FUNCALL: undefined function FOO

Matt

From: D Herring
Subject: Re: A function
Date: 
Message-ID: <F5ydnerUL8R8iczanZ2dnUVZ_uGknZ2d@comcast.com>
akopa wrote:
> Could some explain, or point to a thread that discusses the history of
> what kind of values can specify functions?  For instance I was a
> little surprised a symbol was funcallable: (funcall '+ 1 2 3) -> 6.
> 
> Is this good style since it doesn't seem to work local functions?
> 
> (flet ((foo (&rest args) (apply '+ args)))
>        (funcall 'foo 1 2 3))
> 
> *** - FUNCALL: undefined function FOO

In many cases, 'fn works fine; in this case, you need the #'fn syntax. 
  Basically with 'fn, SYMBOL-FUNCTION needs to be called to retrieve 
the function; but 'fn is a lexical token, not a bound symbol...  The 
#' macro is an abbreviation for the special operator FUNCTION; this 
operator returns the current lexical function.

Try using lispdoc.com to find the HyperSpec (and other) documentation 
on FUNCALL, FUNCTION, SYMBOL-FUNCTION, and #'.

- Daniel
From: Matthew D. Swank
Subject: Re: A function
Date: 
Message-ID: <pan.2007.12.01.20.35.18.503557@gmail.com>
On Sat, 01 Dec 2007 03:01:36 -0500, D Herring wrote:

> Try using lispdoc.com to find the HyperSpec (and other) documentation 
> on FUNCALL, FUNCTION, SYMBOL-FUNCTION, and #'.

I know the specification details (mostly).  What I'm interested in is the
history.  It seems an arbitrary convenience, and, as you noted, in
Common Lisp a symbol-function form could be used in its place.  

Matt

-- 
"You do not really understand something unless you
 can explain it to your grandmother." -- Albert Einstein.
From: Rob Warnock
Subject: Re: A function
Date: 
Message-ID: <y7ydnfS7I-DC48_anZ2dnUVZ_jWdnZ2d@speakeasy.net>
In article <······························@gmail.com>,
+---------------
| D Herring wrote:
| > Try using lispdoc.com to find the HyperSpec (and other) documentation 
| > on FUNCALL, FUNCTION, SYMBOL-FUNCTION, and #'.
| 
| I know the specification details (mostly).  What I'm interested in is the
| history.  It seems an arbitrary convenience, and, as you noted, in
| Common Lisp a symbol-function form could be used in its place.  
+---------------

As noted by someone previously, SYMBOL-FUNCTION
can't be used for a lexical function:

    > (defun foo () 'global)

    FOO
    > (flet ((foo () 'local))
	(list (foo)
	      (funcall (function foo))
	      (funcall 'foo)
	      (funcall (symbol-function 'foo))))

    (LOCAL LOCAL GLOBAL GLOBAL)
    > 


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Matthew D. Swank
Subject: Re: A function
Date: 
Message-ID: <pan.2007.12.02.10.16.37.391129@gmail.com>
On Sun, 02 Dec 2007 03:43:59 -0600, Rob Warnock wrote:

> In article <······························@gmail.com>,
> +---------------
> | D Herring wrote:
> | > Try using lispdoc.com to find the HyperSpec (and other) documentation 
> | > on FUNCALL, FUNCTION, SYMBOL-FUNCTION, and #'.
> | 
> | I know the specification details (mostly).  What I'm interested in is the
> | history.  It seems an arbitrary convenience, and, as you noted, in
> | Common Lisp a symbol-function form could be used in its place.  
> +---------------
> 
> As noted by someone previously, SYMBOL-FUNCTION
> can't be used for a lexical function:
> 
>     > (defun foo () 'global)
> 
>     FOO
>     > (flet ((foo () 'local))
> 	(list (foo)
> 	      (funcall (function foo))
> 	      (funcall 'foo)
> 	      (funcall (symbol-function 'foo))))
> 
>     (LOCAL LOCAL GLOBAL GLOBAL)
>     > 
> 
> 
> -Rob
> 
Precisely. Any place a symbol 'foo can be used to denote a function,
the form (symbol-function 'foo) can be used in its place. Symbols as
function denotations are convenient but superfluous.  Hence my (seemingly
unshared at this point) wonder at their history. Common Lisp dropped
conses for function denotation, but not symbols.  I suppose the obvious
difficulty with a quoted lambda expression, is the lexical environment of
the function that it denotes.

Matt 

-- 
"You do not really understand something unless you
 can explain it to your grandmother." -- Albert Einstein.
From: Kent M Pitman
Subject: Re: A function
Date: 
Message-ID: <ud4tp47vb.fsf@nhplace.com>
"Matthew D. Swank" <··················@gmail.com> writes:

> > As noted by someone previously, SYMBOL-FUNCTION
> > can't be used for a lexical function:
> > 
> >     > (defun foo () 'global)
> > 
> >     FOO
> >     > (flet ((foo () 'local))
> > 	(list (foo)
> > 	      (funcall (function foo))
> > 	      (funcall 'foo)
> > 	      (funcall (symbol-function 'foo))))
> > 
> >     (LOCAL LOCAL GLOBAL GLOBAL)
> >     > 
> > 
> > 
> > -Rob
> > 
> Precisely. Any place a symbol 'foo can be used to denote a function,
> the form (symbol-function 'foo) can be used in its place.

Not so.  Anywhere in code.  But if you do
 (setf (gethash "foo" *my-function-table*) 'foo)
so you can later do
 (funcall (gethash "foo" *my-function-table*))
it will be more obvious to you that one cannot substitute for the other
as data.

Using a symbol allows you to subsequently redefine the function by name
and have calls to whoever is holding it see the new values.  It's a common
practice to give things like readmacros symbols.  Of course, you could 
give a closure whose only purpose was to delay evaluation, but it's
probably not as efficient in some cases.  That is, you could give the
result of (lambda () (foo)) rather than 'foo.  It's also uglier to look
at when debugging.

And there are other issues: punning, for example. There are times it's
useful to make something that is both a function and a symbol.  The fact
that you personally have no need for it was not reason for us to break
people's programs.  See
 http://www.nhplace.com/kent/CL/x3j13-86-020.html

> Symbols as
> function denotations are convenient but superfluous.

Not really.

> Hence my (seemingly
> unshared at this point) wonder at their history. Common Lisp dropped
> conses for function denotation, but not symbols.

Conses were a problem because you had to compile them to run them.
That meant that implementors trying to implement functionality usually
called something like "suspend-image" (save to a .exe file) had to dump
out the interpreter and/or compiler any time they saw funcall.
That's not true for symbols--all you have to dump out is symbol-value,
which is much smaller.

> I suppose the obvious
> difficulty with a quoted lambda expression, is the lexical environment of
> the function that it denotes.

Not really an issue for the language designers--it used to just get the
null lexical environment.  Users probably didn't like that, but it wasn't
why it went away.
From: Pascal Costanza
Subject: Re: A function
Date: 
Message-ID: <5rfn16F14aintU1@mid.individual.net>
Kent M Pitman wrote:

> See http://www.nhplace.com/kent/CL/x3j13-86-020.html

What's the meaning of bullet (i) "Validation"?


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Kent M Pitman
Subject: Re: A function
Date: 
Message-ID: <u63zg4ur9.fsf@nhplace.com>
Pascal Costanza <··@p-cos.net> writes:

> Kent M Pitman wrote:
> 
> > See http://www.nhplace.com/kent/CL/x3j13-86-020.html
> 
> What's the meaning of bullet (i) "Validation"?

The short answer is: Knowing you and your interests, it's probably 
just what you're thinking it is--testing whether implementations are
valid.  And maybe programs too, I don't recall.

The question I assume you will ask next is "Then why isn't it
mentioned in the spec?"  So I'll just save you asking it and will
go on to answer:

Well now, working just from memory, and some of this comes back better
as I write but I might be forgetting something or misremembering
something:

We discussed extensively in the committee the question of whether it
would be a good idea for the committee itself to do validation.  There
was a group that even worked on it for a while but then they decided
to stop.  (If memory serves, some key person wanted to move on in life
and do something else unrelated, like start a rock band or
something... not that what they wanted to do in particular matters,
since people have many agendas in their lives, but it is interesting
at least to note that people who aren't involved in these things
frequently model the driving force as being "what's technically
correct" and "what's needed", when in fact in small groups you're
often not driven by statistically valid criteria but rather by the
idiosyncracies of the individuals involved.  That a certain person
likes or doesn't like a particular thing, that a certain person missed
a certain meeting and so couldn't offer advice -- or the reverse, that
someone happened in at the right time to change something.  See Dan
Weinreb's remarks in the thread on conditions for examples of this.
But it happened a lot in all kinds of ways.)

One thing that wasn't chance, though, and was a big trend at that
time, which might have changed lately, is that the vendors saw it as a
key piece of their proprietary advantage to have test suites they
developed.  So when the validation committee tried to get people to
offer them up, there was a problem: vendors who'd paid a lot to
develop tests didn't want to share them with people who hadn't--the
vendors were cordial to a degree, but they also had a living to make,
and vendors did go out of business during the lengthy process so this
was not a theoretical matter. 

And, at a more subtle level, vendors didn't want to have to bargain
with other vendors about whether the tests they'd developed were
right.  They wanted, at minimum, to be able to say "I made it for this
reason, and I want to see that reason continued."  This meta-issue,
appropriately abstracted from the domain, is at the heart of "free
software" as a philosophical enterprise--that people like to invest
but they don't want their investment hijacked.  Heck, I have had
certain software I might have open sourced at various times if only I
could be sure that whatever happened to it, I could still come back
and use the evolved version later because anyone building on it was
going to care about my issues.  But to give something away and then
have the world move on without caring about allegiance to those who
got them there is as troubling to free software folks as to non free
software folks--all that seems to vary is what is being valued, not
concern about the continued value.

And again in world politics, it's the same, hence the political fight
between people over whether it's ok to burn flags--many people have
fought and died for the sake of protecting the flag from dishonor, but
people widely disagree about what constitutes dishonor.  Some people
think spitting on or burning the flag is the worst thing that could
happen to it, and some think having the state tell you that you have
no liberty to choose what you do with private property is the worst
thing.  Ironically, if you listened only to the rhetoric of what the
two major parties stand for, you'd peg the wrong groups as protecting
the wrong side of the flag people.  The Democrats are mostly all about
political correctness at all costs, and the Republicans mostly about
protecting private property and liberty at all costs ... if you listen
to the words, anyway.  But so it goes.  My point here is not about
which one is right, but merely that people can differ on big issues
like this ... and yet, they all agree that continuity of investment
is important, so whatever they believe, they get incensed when others
build on their work in a way that they don't feel is compatible.

So people end up keeping things private, to protect their investment.
Not even always because they fear sharing per se, but because giving
someone with an incompatible theory of the world a leg up when they
have no commitment to you in return can be bad and vendors have been
rightly concerned.

And so that's how the validation committee died--by simple economics,
as I recall.  It was an interesting idea but there was no resource for
making it happen at the committee level and we were assured that it
was something that could be done privately, perhaps even better,
after-the-fact.  It was not criterial to the success of the standard.

I think that was a right choice and that the market has done a fine
job sorting things out.  It would have increased committee overhead to
do more than what we did, and uselessly so.  But my saying so is not
to say that I oppose people privately offering validation services.
I'm only middling on the notion that a single validation service
should exist--I think probably only one will be needed, and a "natural
monopoly" (the good kind of monopoly) will result.  Probably the
market won't bear more than that anyway, if it wants that much at all.
But if there's a minority viewpoint and someone wanted a second
validation service, I wouldn't oppose that either.  Competition helps
in that regard, I think.

I also actually think that it's easy to complain about myriad things
in a language that don't much matter, and to overlook the big things.
So having validation, if there is any, be market driven, rather than
required by the process, means that if it isn't giving value, it will
die of its own weight.  It's not like vendors don't respond to bug
reports, and it's not like there aren't lots of tools for getting
around small glitches.  The big weakness is commonality of library
support, and we don't need a validation committee to tell us.  Nor is
that a weakness of the language per se, since it could be fixed
without changing the language.

In the days when design was ongoing, I think back even before ANSI,
using metaphors from phone companies, we used to refer to page color
informally: white pages, yellow pages, red pages, blue pages,
... white was the spec, yellow the libraries, and I can't remember for
sure what red and blue were but I think one or the other might have
been implementor's notes and design rationales.  We knew we were only
doing white pages, and we talked about the need for yellow pages.

Back to the original question, just to close, the charter was a list
of things we were going to investigate and decide action on--not a
required list of things we had to do in order to succeed. It was
primarily about limiting scope, not about making it larger.  It was
much harder to do projects that were not on the charter agenda, and
that helped us stay focused on things to do to finish.  But it was
considered procedurally acceptable to dismiss some of those as "not at
this time".  And I don't think anything in the process required us to
publish a rationale for why we did that, which is why there's no written
record that I can think to appeal to in understanding what happened.

By contrast, for Public Review, when someone "proposed" something as
a bug or feature suggestion, for each and every comment made, the
committee had a more affirmative obligation, if they didn't want to
take the suggestion, to say why in a substantive way.  We couldn't just
say "we're tired" or "that's stupid", we had to defend what we did
in a manner to be judged as giving due consideration by other parts of
the process who were not lispers and who were just auditing procedure.
But as far as I know, strangely enough, that was not a requirement of
followup on the charter; maybe because I don't think a charter was even
required.  Susan Ennis (of Amoco, I believe) made us do the charter.
She was only with the committee a short time, but I considered her 
contribution quite important.  Having it saved us from a lot of problems.

But I guess the Public Review was the procedural safeguard against people
thinking we had shirked out duty by not doing some charter items (or
anything else), so perhaps ANSI/CBEMA/X3 thought no additional process
check (meta-validation?) was needed.
From: Pascal Costanza
Subject: Re: A function
Date: 
Message-ID: <5rgp7eF14ld4hU1@mid.individual.net>
Kent M Pitman wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> Kent M Pitman wrote:
>>
>>> See http://www.nhplace.com/kent/CL/x3j13-86-020.html
>> What's the meaning of bullet (i) "Validation"?
> 
> The short answer is: Knowing you and your interests, it's probably 
> just what you're thinking it is--testing whether implementations are
> valid.  And maybe programs too, I don't recall.
> 
> The question I assume you will ask next is "Then why isn't it
> mentioned in the spec?"  

No, I wouldn't have asked that. ;)

Your response is pretty interesting anyway. ;)


Thanks,
Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Daniel Weinreb
Subject: Re: A function
Date: 
Message-ID: <BFw5j.11460$Lg.591@trndny09>
Kent M Pitman wrote:

> In the days when design was ongoing, I think back even before ANSI,
> using metaphors from phone companies, we used to refer to page color
> informally: white pages, yellow pages, red pages, blue pages,
> ... white was the spec, yellow the libraries, and I can't remember for
> sure what red and blue were but I think one or the other might have
> been implementor's notes and design rationales.  We knew we were only
> doing white pages, and we talked about the need for yellow pages.

Way before ANSI, even before we got under way on CLTL.  It was a
good idea but too hard to do in the time allowed, sadly.  Yellow
pages were implementation-independent libraries that can be loaded
in, and red pages were implementation-dependent libraries such
as device drivers.

I don't think there were any "red pages" and "blue pages" until
the introduction of Myst. :)

> 
> By contrast, for Public Review, when someone "proposed" something as
> a bug or feature suggestion, for each and every comment made, the
> committee had a more affirmative obligation, if they didn't want to
> take the suggestion, to say why in a substantive way.  We couldn't just
> say "we're tired" or "that's stupid", we had to defend what we did
> in a manner to be judged as giving due consideration by other parts of
> the process who were not lispers and who were just auditing procedure.

Yeah, they did.  Even though they were tired, nay, weary.  Imagine
how much work that was.  That's why I bowed out at this point,
leaving Kent and others to shoulder the burden.  Selfish, I guess.

Kent, everything you said in your post corresponds to my
recollection as well.
From: Matthew D. Swank
Subject: Re: A function
Date: 
Message-ID: <pan.2007.12.02.23.26.51.536891@gmail.com>
On Sun, 02 Dec 2007 07:08:08 -0500, Kent M Pitman wrote:

> "Matthew D. Swank" <··················@gmail.com> writes:
> 
>> > As noted by someone previously, SYMBOL-FUNCTION
>> > can't be used for a lexical function:
>> > 
>> >     > (defun foo () 'global)
>> > 
>> >     FOO
>> >     > (flet ((foo () 'local))
>> > 	(list (foo)
>> > 	      (funcall (function foo))
>> > 	      (funcall 'foo)
>> > 	      (funcall (symbol-function 'foo))))
>> > 
>> >     (LOCAL LOCAL GLOBAL GLOBAL)
>> >     > 
>> > 
>> > 
>> > -Rob
>> > 
>> Precisely. Any place a symbol 'foo can be used to denote a function,
>> the form (symbol-function 'foo) can be used in its place.
> 
> Not so.  Anywhere in code.  But if you do
>  (setf (gethash "foo" *my-function-table*) 'foo)
> so you can later do
>  (funcall (gethash "foo" *my-function-table*))
> it will be more obvious to you that one cannot substitute for the other
> as data.

I'm not trying to be needlessly thick, but couldn't you write:
	(setf (gethash "foo" *my-function-table*) 'foo)
and later do:
	 (funcall (symbol-function (gethash "foo" *my-function-table*)))
and get the same results?

Matt
-- 
"You do not really understand something unless you
 can explain it to your grandmother." -- Albert Einstein.
From: Kent M Pitman
Subject: Re: A function
Date: 
Message-ID: <ubq98lha6.fsf@nhplace.com>
"Matthew D. Swank" <··················@gmail.com> writes:

> On Sun, 02 Dec 2007 07:08:08 -0500, Kent M Pitman wrote:
> 
> > "Matthew D. Swank" <··················@gmail.com> writes:
> > 
> >> > As noted by someone previously, SYMBOL-FUNCTION
> >> > can't be used for a lexical function:
> >> > 
> >> >     > (defun foo () 'global)
> >> > 
> >> >     FOO
> >> >     > (flet ((foo () 'local))
> >> > 	(list (foo)
> >> > 	      (funcall (function foo))
> >> > 	      (funcall 'foo)
> >> > 	      (funcall (symbol-function 'foo))))
> >> > 
> >> >     (LOCAL LOCAL GLOBAL GLOBAL)
> >> >     > 
> >> > 
> >> > 
> >> > -Rob
> >> > 
> >> Precisely. Any place a symbol 'foo can be used to denote a function,
> >> the form (symbol-function 'foo) can be used in its place.
> > 
> > Not so.  Anywhere in code.  But if you do
> >  (setf (gethash "foo" *my-function-table*) 'foo)
> > so you can later do
> >  (funcall (gethash "foo" *my-function-table*))
> > it will be more obvious to you that one cannot substitute for the other
> > as data.
> 
> I'm not trying to be needlessly thick,

That's ok.  It's good to just ask questions until you get it.

> but couldn't you write:
> 	(setf (gethash "foo" *my-function-table*) 'foo)
> and later do:
> 	 (funcall (symbol-function (gethash "foo" *my-function-table*)))
> and get the same results?

Yes, if you controlled both halves of the code.  But also no, if you
were told that you were to give someone a function to call and you
wanted it to do this without prompting.  In other words, you're still
not getting the significance of protocol.

Let me put it another way:  Suppose I told you that no data could be
other than integers.  You'd say, "But I need strings."  And I'd say,
but can't you just encode strings as binary?  (And anyway, there
are multiple different binary encodings.)

It matters who controls the conditions of the situation.

In calculus class in high school, we used to play the game I called
"deltas and epsilons".  ("For any delta you pick, I can pick an
epsilon such that...") I always thought it odd that the same person
always got to start and wanted to swap ... sort of like someone
playing chess wants to have one player not always get the white
pieces.  But it turns out that it's meaningless to play certain games
in the other order because the game isn't a game of chance, it's a
game of challenge/response, and it doesn't work to play it in the
order of response/challenge.

In understanding a protocol, you have to take the protocol as fixed
and the things you do as "contingent truth" in which you take the
givens of the protocol as axiomatic.  In that world, the gaming you
suggest is not available (unless you say no one can write a protocol
that takes a function as an argument, which would be a weird thing to
have as a "given").

Does any of this help or am I just making it more messy?
From: Matthew D. Swank
Subject: Re: A function
Date: 
Message-ID: <pan.2007.12.03.08.35.10.713269@gmail.com>
On Sun, 02 Dec 2007 20:05:05 -0500, Kent M Pitman wrote:

> "Matthew D. Swank" <··················@gmail.com> writes:
> 
>> On Sun, 02 Dec 2007 07:08:08 -0500, Kent M Pitman wrote:
>> 
>> > "Matthew D. Swank" <··················@gmail.com> writes:
>> > 
>> >> > As noted by someone previously, SYMBOL-FUNCTION
>> >> > can't be used for a lexical function:
>> >> > 
>> >> >     > (defun foo () 'global)
>> >> > 
>> >> >     FOO
>> >> >     > (flet ((foo () 'local))
>> >> > 	(list (foo)
>> >> > 	      (funcall (function foo))
>> >> > 	      (funcall 'foo)
>> >> > 	      (funcall (symbol-function 'foo))))
>> >> > 
>> >> >     (LOCAL LOCAL GLOBAL GLOBAL)
>> >> >     > 
>> >> > 
>> >> > 
>> >> > -Rob
>> >> > 
>> >> Precisely. Any place a symbol 'foo can be used to denote a function,
>> >> the form (symbol-function 'foo) can be used in its place.
>> > 
>> > Not so.  Anywhere in code.  But if you do
>> >  (setf (gethash "foo" *my-function-table*) 'foo)
>> > so you can later do
>> >  (funcall (gethash "foo" *my-function-table*))
>> > it will be more obvious to you that one cannot substitute for the other
>> > as data.
>> 
>> I'm not trying to be needlessly thick,
> 
> That's ok.  It's good to just ask questions until you get it.
> 
>> but couldn't you write:
>> 	(setf (gethash "foo" *my-function-table*) 'foo)
>> and later do:
>> 	 (funcall (symbol-function (gethash "foo" *my-function-table*)))
>> and get the same results?
> 
> Yes, if you controlled both halves of the code.  But also no, if you
> were told that you were to give someone a function to call and you
> wanted it to do this without prompting.  In other words, you're still
> not getting the significance of protocol.
> 
..
> It matters who controls the conditions of the situation.
...
> 
> In understanding a protocol, you have to take the protocol as fixed
> and the things you do as "contingent truth" in which you take the
> givens of the protocol as axiomatic.  In that world, the gaming you
> suggest is not available (unless you say no one can write a protocol
> that takes a function as an argument, which would be a weird thing to
> have as a "given").
> 
> Does any of this help or am I just making it more messy?

I think so.

The spirit of my original point was that we could get along without
symbols as function denotations.

Looking over the thread, however, I see I made a somewhat more sweeping
claim of substitutablity btw 'foo and (symbol-function 'foo).  Obviously
this is not so.

So, in the spirit of of hobbling ourselves....

The point of the original example for me was that you can exploit the
actual specification of lisp function denotations to provide an easy way
to use symbols as the funcallable "things" in a hashtable.  However, if I
am allowed to be especially perverse, let's suppose we cannot denote
top-level function with symbols.

The current game, as I understand it, amounts to a contract with the
consumer of a hash access that stipulates the return object be
funcallallable. In addition, the point of originally storing a symbol in
the hash is to make sure the consumer gets the current function object
associated with that symbol. 

Originally we have:
(setf (gethash "foo" *my-function-table*) 'foo)
Which lets us do:
(funcall (gethash "foo" *my-function-table*))

In the post apocalyptic world I posit we can still do this:
(setf (gethash "foo" *my-function-table*) 
      (lambda (&rest rest) 
        (apply (symbol-function 'foo) rest)))
Which still lets us do:
(funcall (gethash "foo" *my-function-table*))

Messy, inconvenient, probably slower, but I haven't broken any rules.


Matt

-- 
"You do not really understand something unless you
 can explain it to your grandmother." -- Albert Einstein.
From: Kent M Pitman
Subject: Re: A function
Date: 
Message-ID: <ufxyjce6x.fsf@nhplace.com>
"Matthew D. Swank" <··················@gmail.com> writes:

> The spirit of my original point was that we could get along without
> symbols as function denotations.

One issue though is that you mean in the program domain.  Common Lisp
has both program semantics and data semantics.  A symbol is callable
even when just sitting there as a data object, independent of EVAL
ever getting involved.

> Looking over the thread, however, I see I made a somewhat more sweeping
> claim of substitutablity btw 'foo and (symbol-function 'foo).  Obviously
> this is not so.

'FOO means (QUOTE FOO), the semantics of which is that if EVAL is invoked
on it will yield FOO, the original datum in question.  If EVAL is not 
invoked, this is just a list whose car is QUOTE and such a list is not
funcallable either.

(SYMBOL-FUNCTION 'FOO) has a similar analysis.  I won't belabor it, I'll
just say that it's not funcallable either, so you're presupposing EVAL
(or some equivalent language processor).

Another way of saying what I'm saying is that Lisp does not have what Macsyma
called INFEVAL, that is, an evaluator option saying to keep evaluating 
something until it turns into what you need.  It evaluates a specific number
of levels.  Some things self-evaluate, tolerating extra evaluations and 
yielding back the same result, but nothing autoevaluates, producing a value
that's more useful than another value just because contextually that seems
useful to an observer wishing he'd designed his program differently.

> So, in the spirit of of hobbling ourselves....
> 
> The point of the original example for me was that you can exploit the
> actual specification of lisp function denotations to provide an easy way
> to use symbols as the funcallable "things" in a hashtable.

Which, incidentally, allows the punning I alluded to before.  That is,
the symbol can do dual duty that the function cannot. e.g., you can
put properties on it. (Although you could implement equivalent
functionality with hash tables, that would require communicating the
hash table to use, while the function GET is well-known/pre-provided
and does not require communication.

> However, if I am allowed to be especially perverse, let's suppose we
> cannot denote top-level function with symbols.

Ok, let's suppose that. I'm always up for a good hypothetical.
 
> The current game, as I understand it, amounts to a contract with the
> consumer of a hash access that stipulates the return object be
> funcallallable. In addition, the point of originally storing a symbol in
> the hash is to make sure the consumer gets the current function object
> associated with that symbol. 

Yes.
 
> Originally we have:
> (setf (gethash "foo" *my-function-table*) 'foo)
> Which lets us do:
> (funcall (gethash "foo" *my-function-table*))

I'll bite my tongue on the case-translation issue, which is irrelevant
here anyway.

> In the post apocalyptic world I posit we can still do this:
> (setf (gethash "foo" *my-function-table*) 
>       (lambda (&rest rest) 
>         (apply (symbol-function 'foo) rest)))

Yes, although you'll get the same semantics from

 (setf (gethash "foo" *my-function-table*) 
       (lambda (&rest rest) (apply #'foo rest)))
 
and you'll even pick up lexical fdefinitions of FOO at no extra cost.

> Which still lets us do:
> (funcall (gethash "foo" *my-function-table*))

Yes.

> Messy, inconvenient, probably slower, but I haven't broken any rules.

Broken rules? No. Done the same thing? No.

I appeal back to my earlier remark about putprop.  If you had wanted
instead to do
 (defun call-if-in-vogue (fn) ;this requires FN to be a symbol
   (if (get fn 'in-vogue-right-now) ;make up some
       (funcall fn)))

or

 (defun call-if-in-vogue-too (fn) ;this allows FN to be a symbol
   (ecase fn
     (symbol ;; Allow users to put a property on a fn
             ;; enabling it (or disabling it)
       (if (get fn 'in-vogue-right-now)
           (funcall fn)))
     (function (funcall fn))))

No, I didn't test this code.

> "You do not really understand something unless you
>  can explain it to your grandmother." -- Albert Einstein.

Spoken like someone who knew the true value of his relativities.

I guess I'm done understanding things for this lifetime. :(

"You do not really understand relativity unless you
 can go back and explain it to Albert Einstein." -- Kent Pitman.
From: Matthew D. Swank
Subject: Re: A function
Date: 
Message-ID: <pan.2007.12.05.05.48.02.715333@gmail.com>
On Mon, 03 Dec 2007 22:48:54 -0500, Kent M Pitman wrote:

> "Matthew D. Swank" <··················@gmail.com> writes:
> 
>> The spirit of my original point was that we could get along without
>> symbols as function denotations.
> 
> One issue though is that you mean in the program domain.  Common Lisp
> has both program semantics and data semantics.  A symbol is callable
> even when just sitting there as a data object, independent of EVAL
> ever getting involved.
...
> That is, the symbol can do dual duty that the function cannot. e.g., you
> can put properties on it. (Although you could implement equivalent
> functionality with hash tables, that would require communicating the
> hash table to use, while the function GET is well-known/pre-provided and
> does not require communication.
>
... 
>  [What if] you had wanted [...] to do
>  (defun call-if-in-vogue (fn) ;this requires FN to be a symbol
>    (if (get fn 'in-vogue-right-now) ;make up some
>        (funcall fn)))
> 
> or
> 
>  (defun call-if-in-vogue-too (fn) ;this allows FN to be a symbol
>    (ecase fn
>      (symbol ;; Allow users to put a property on a fn
>              ;; enabling it (or disabling it)
>        (if (get fn 'in-vogue-right-now)
>            (funcall fn)))
>      (function (funcall fn))))
> 
> No, I didn't test this code.
> 

Yes, we lose the funcallablity of symbols as data.  I understand that
symbols provide a place to hang semantics.  It is nice, it is lispy, but
for every concrete example where we can use a symbol, as data, to stand
for a function, it is possible to replace this with what is essentially
an extra level of indirection. 

Instead of having a piece of data that is directly understood by the
run-time as a function, we have to do a look-up or an interpretation. 
There are consequences to the idioms that can be used, but essentially the
the same thing happens: a function is dynamically associated with a
symbol (I am of course disregarding how smart a compiler can be about
functions associated with symbol literals, especially in the common-lisp
package). The only difference is who does the look-up.

>> "You do not really understand something unless you
>>  can explain it to your grandmother." -- Albert Einstein.
> 
> Spoken like someone who knew the true value of his relativities.
> 
> I guess I'm done understanding things for this lifetime. :(

I'm sorry.  My grandmother smiles politely when I explain things, but I'm
fairly sure I really don't understand anything.

> 
> "You do not really understand relativity unless you
>  can go back and explain it to Albert Einstein." -- Kent Pitman.

Matt
From: Kent M Pitman
Subject: Re: A function
Date: 
Message-ID: <usl2hqw49.fsf@nhplace.com>
"Matthew D. Swank" <··················@gmail.com> writes:

> Yes, we lose the funcallablity of symbols as data.  I understand that
> symbols provide a place to hang semantics.  It is nice, it is lispy, but
> for every concrete example where we can use a symbol, as data, to stand
> for a function, it is possible to replace this with what is essentially
> an extra level of indirection. 

Short form:   No.  (IMO, of course. But it's not a weakly held opinion.)

I don't have time to go into this right now, and I realize it's an
insufficient debate strategy for me to take this particular tactic at
this point, but consider this response not an argument but a bookmark.

I simply do not concur with this assessment.  Symbols are
philosophically more than this in a way that is complicated and
insufficiently summarized by your saying "Lispy".  Their use to stand
for a function is part of that.  That the use appears sloppy seems to
invalidate it to you, but I consider that like many things in Lisp,
the usefulness precedes the formality, and the formality will one day
follow.

But there is more to symbolness than a pointer, and more to overloading
than sloppiness.

It may be that this is all YOU mean, and therefore that YOU would be 
satisfied substituting this.  But that's not the same as saying that's
all there is.  Something about this argument is like saying that it's ok
to replace a pipe organ with a MIDI player since they do essentially the
same thing.

> Instead of having a piece of data that is directly understood by the
> run-time as a function, we have to do a look-up or an interpretation. 
> There are consequences to the idioms that can be used, but essentially the
> the same thing happens: a function is dynamically associated with a
> symbol (I am of course disregarding how smart a compiler can be about
> functions associated with symbol literals, especially in the common-lisp
> package). The only difference is who does the look-up.

I don't think that's the only difference.  Material differences occur due to
who does the lookup.  If I said that you could no longer carry the keys to
your house, but must register them with the police, who will come and open
your door any time you ask, would you sum that up as saying "it's only a
difference in who opens the door, but is essentially the same in all other
respects?"
From: Pascal Costanza
Subject: Re: A function
Date: 
Message-ID: <5rffnnF14g5ekU1@mid.individual.net>
Matthew D. Swank wrote:
> On Sun, 02 Dec 2007 03:43:59 -0600, Rob Warnock wrote:
> 
>> In article <······························@gmail.com>,
>> +---------------
>> | D Herring wrote:
>> | > Try using lispdoc.com to find the HyperSpec (and other) documentation 
>> | > on FUNCALL, FUNCTION, SYMBOL-FUNCTION, and #'.
>> | 
>> | I know the specification details (mostly).  What I'm interested in is the
>> | history.  It seems an arbitrary convenience, and, as you noted, in
>> | Common Lisp a symbol-function form could be used in its place.  
>> +---------------
>>
>> As noted by someone previously, SYMBOL-FUNCTION
>> can't be used for a lexical function:
>>
>>     > (defun foo () 'global)
>>
>>     FOO
>>     > (flet ((foo () 'local))
>> 	(list (foo)
>> 	      (funcall (function foo))
>> 	      (funcall 'foo)
>> 	      (funcall (symbol-function 'foo))))
>>
>>     (LOCAL LOCAL GLOBAL GLOBAL)
>>     > 
>>
>>
>> -Rob
>>
> Precisely. Any place a symbol 'foo can be used to denote a function,
> the form (symbol-function 'foo) can be used in its place. Symbols as
> function denotations are convenient but superfluous.  Hence my (seemingly
> unshared at this point) wonder at their history. Common Lisp dropped
> conses for function denotation, but not symbols.  I suppose the obvious
> difficulty with a quoted lambda expression, is the lexical environment of
> the function that it denotes.

Symbols as function denotations are useful when you want to be able to 
change function definitions at runtime.

(declaim (inline foo))

(defun foo (x) (+ x x))

(defun bar (x) (funcall 'foo x))

(defun baz (x) (funcall #'foo x))

? (bar 5)
10
? (baz 5)
10
?
(setf (symbol-function 'foo) (lambda (x) (* x x)))
#<Anonymous Function #x83DD4BE>
? (bar 5)
25
? (baz 5)
10

In other words, (funcall 'foo ...) is guaranteed to call the function 
definition which is current at runtime, while (funcall #'foo ...) 
doesn't give you that guarantee.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Geoff Wozniak
Subject: Re: A function
Date: 
Message-ID: <541ee77e-55fc-4dde-a873-40aab793a1ea@o6g2000hsd.googlegroups.com>
On Dec 2, 5:16 am, "Matthew D. Swank" <··················@gmail.com>
wrote:
> Symbols as function denotations are convenient but superfluous.

As others have mentioned, this is not the case.  For a practical spin,
denoting functions with symbols is very useful when you want to avoid
some circularity issues in loading and for redefinition later.

In one of my projects, I have a class whose instances act as proxy
objects.  They look something like this.

(defclass proxy-class () (actual-object actions))

The ACTIONS slot contains functions that are to be executed when
certain events happen concerning the object.  I originally put
function objects in the ACTION slot and realized that when I wanted to
redefine an action (say, while debugging) it didn't take effect!  I
switched to symbols and the problem went away.  It was one of those "a-
ha" moments during the "live and learn" time of using CL.  (Up until
then, I always thought that being able to FUNCALL a symbol was a bit
of an anachronism.)

Furthermore, when some of the proxy objects get instantiated, the
functions may not exist.  It turned out to be very difficult to figure
out when to actually put something in the ACTION slot and it was a lot
easier if I just put symbols in there ahead of time.
From: Tobias C. Rittweiler
Subject: Re: A function
Date: 
Message-ID: <878x4dfgw1.fsf@freebits.de>
"Matthew D. Swank" <··················@gmail.com> writes:

> Precisely. Any place a symbol 'foo can be used to denote a function,
> the form (symbol-function 'foo) can be used in its place. Symbols as
> function denotations are convenient but superfluous.  Hence my (seemingly
> unshared at this point) wonder at their history.

It's not just convenience, but consistency, too! Symbols have ever
played a crucial role in Lisp (and this continues to be one of the
unique properties of Lisp compared to other languages.)

Notice that all designators for entities registered in the global
environment include symbols---or in other words, symbols are used to
name entities in Lisp. Entities such a functions.


> Common Lisp dropped conses for function denotation, but not symbols.
> I suppose the obvious difficulty with a quoted lambda expression, is
> the lexical environment of the function that it denotes.

There are other issues. One is the introduction of a real function
type. Traditionally, this has been fuzzy territory. E.g. if something
like (FUNCALL '(LAMBDA (X) ...) ...) is allowed, what should FUNCTIONP
return on something like that? Traditionally the answer wasn't as easy
as it may seem today to be.

And for the case that you really want to do something like this, notice
that (COERCE '(LAMBDA (X) ...) 'FUNCTION) is there for you. (And the
reason that you've got to be explicit about this, but not about the symbol
case above, is simply that symbols are ubiquitous.)

  -T.
From: Kent M Pitman
Subject: Re: A function
Date: 
Message-ID: <ueje69h1n.fsf@nhplace.com>
akopa <··················@gmail.com> writes:

> Could some explain, or point to a thread that discusses the history of
> what kind of values can specify functions?  For instance I was a
> little surprised a symbol was funcallable: (funcall '+ 1 2 3) -> 6.
> 
> Is this good style since it doesn't seem to work local functions?
> 
> (flet ((foo (&rest args) (apply '+ args)))
>        (funcall 'foo 1 2 3))
> 
> *** - FUNCALL: undefined function FOO

It doesn't fail to work on local functions, it just doesn't denote a local function.
Local functions have no denotation as a symbol.

As for dataypes, functions under CLTL were either symbols, "true" functions, or
lists whose car was LAMBDA.  The list one has gone away in ANSI CL.
From: Daniel Weinreb
Subject: Re: A function
Date: 
Message-ID: <iSB4j.10812$t31.132@trnddc02>
akopa wrote:
> Could some explain, or point to a thread that discusses the history of
> what kind of values can specify functions?  For instance I was a
> little surprised a symbol was funcallable: (funcall '+ 1 2 3) -> 6.
> 
> Is this good style since it doesn't seem to work local functions?
> 
> (flet ((foo (&rest args) (apply '+ args)))
>        (funcall 'foo 1 2 3))
> 
> *** - FUNCALL: undefined function FOO
> 
> Matt

I think the answer is that doing (funcall 'foo 1 2 3)
would have worked if flet were defined to work by
dynamically binding the "function cell" of the symbol
"foo". In that case, any time anything in the body
of your function OR in anything that is CALLED, foo
would be redefined.  Instead, flet does the analogy
of "lexical scoping": the newly-defined foo is only
available within the lexical scope of the flet, and
if callees of the body refer to foo, they'll get the
global definition of foo, not the one from the flet.

I'm not sure whether X3J13 Common Lisp has a way to
dynamically bind the "function cell" of a symbol.
You could do it in Zetalisp (the Lisp machine).

I hope someone (Kent?) will check over what I just said
and make sure it's accurate...
From: Pascal Costanza
Subject: Re: A function
Date: 
Message-ID: <5rg9u6F14op7sU1@mid.individual.net>
Daniel Weinreb wrote:
> akopa wrote:
>> Could some explain, or point to a thread that discusses the history of
>> what kind of values can specify functions?  For instance I was a
>> little surprised a symbol was funcallable: (funcall '+ 1 2 3) -> 6.
>>
>> Is this good style since it doesn't seem to work local functions?
>>
>> (flet ((foo (&rest args) (apply '+ args)))
>>        (funcall 'foo 1 2 3))
>>
>> *** - FUNCALL: undefined function FOO
>>
>> Matt
> 
> I think the answer is that doing (funcall 'foo 1 2 3)
> would have worked if flet were defined to work by
> dynamically binding the "function cell" of the symbol
> "foo". In that case, any time anything in the body
> of your function OR in anything that is CALLED, foo
> would be redefined.  Instead, flet does the analogy
> of "lexical scoping": the newly-defined foo is only
> available within the lexical scope of the flet, and
> if callees of the body refer to foo, they'll get the
> global definition of foo, not the one from the flet.
> 
> I'm not sure whether X3J13 Common Lisp has a way to
> dynamically bind the "function cell" of a symbol.
> You could do it in Zetalisp (the Lisp machine).

With a little bit of straightforward macrology, you can also get dynamic 
scoping for functions in Common Lisp. See 
http://p-cos.net/documents/dynfun.pdf


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/