From: A J Le Couteur Bisson
Subject: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <aq7dhb$23a$1@venus.btinternet.com>
I recently asked a question about function quoting in
my (Lisp 1) interpreter recently and there were some
interesting responses but nothing that directly answered
my question.

Well, I think I may have cracked it.

<digression>
I should first clarify the convention that I use for
optional and defaulted arguments.

(defun demo-args (a (b) (c .3)) (list a b c))

(demo-args 'x)       => (x nil 3)
(demo-args 'x 'y)    => (x y 3)
(demo-args 'x 'y 'z) => (x y z)

I rather like the simplicity of this method and find it
suprisingly flexible.  I also allow definitions like
(defun func x ....) to pass all arguments as a list.
<\digression>

It occurred to me (from a remark that Kaz made) that
the purpose of function quoting  is not to save the
entire outer environment but to capture the values of
the free-variables in the quoted function.  It seems
so obvious and easy now   (Doh!)

The idea expressed in the following code.  This is
written in my dialect but I think its clear.

(setq y 5)

(defun addy (x) (+ x y))

(defun do-it(f y) (f y))

(do-it (function-quote addy) 3) => 8

(function-quote f) => (lambda (x (y . 5)) (+ x y))

The precise action of function-quote is clear from the
last expression.  The outer binding of y is added to the
argument list of the quoted function.

Since I have only one name-space I need to make a minor
restriction that all primitive function names are always
global.  I don't really consider this a real restriction
but just good sense.  I use a syntax highlighting editor
(SciTE) that I have primed with all the primitive names
so I won't inadvertantly shadow these names either.

This restriction means that the list of free variables that
function-quote must create is of a reasonable size.

As I said above, this seems very obvious now but I would
appreciate it if someone here would verify that this is a
complete solution to the fungarg problem with no hidden
gotchas.  Note that I don't need scheme-like closures.

I am also curious if the argument convention that I use
originated because of the simplicity of implementation of
function quoting.

Thanks,

Andy

From: Barry Watson
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <3DC79621.BE0C84B0@uab.ericsson.se>
I think LiSP chapter 2 would clear all this up nicely. Personally, I
can't see how making function-quote being the same as quote wouldn't
work, but  that's jsut me.
From: Pierpaolo BERNARDI
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <6yOx9.73350$aL4.2277958@news1.tin.it>
"A J Le Couteur Bisson" <·······@thanks.com> ha scritto nel messaggio ·················@venus.btinternet.com...

> It occurred to me (from a remark that Kaz made) that
> the purpose of function quoting  is not to save the
> entire outer environment but to capture the values of
> the free-variables in the quoted function.  It seems
> so obvious and easy now   (Doh!)

Nevertheless this is not correct. In lisp, you must 
capture the bindings, not the values.

What does the following evaluates to? :

(setq y 5)
 
(defun addy (x) (+ x y))
 
(defun do-it(f y) (f y))

(setq f (function-quote addy))

(setq y 42)
 
 (do-it f 3) => ??
From: A J Le Couteur Bisson
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <aq92ov$o16$1@sparta.btinternet.com>
"Pierpaolo BERNARDI" <··················@hotmail.com> wrote in message
news:<·······················@news1.tin.it>...
>
>
> Nevertheless this is not correct. In lisp, you must
> capture the bindings, not the values.
>
> What does the following evaluates to? :
>
> (setq y 5)
>
> (defun addy (x) (+ x y))
>
> (defun do-it(f y) (f y))
>
> (setq f (function-quote addy))
>
> (setq y 42)
>
>  (do-it f 3) => ??
>

Aha! Thanks, you just helped one penny drop.

(Please feel free to pick holes pedantically
 in the following.)

To take this one step further:

(setq y 5)

(defun addy (x) (+ x y))

(defun do-it(f y) (f y))

(let ((y 12))
     (setq f (function-quote addy)) )

(setq y 42)

(function-quote f) => (lambda (x (y . 5)) (+ x y))

(do-it f 3) =/=> (+ 3 12)


This is what I understand to be an upward-funarg and
I can see that the scope inside let must be captured
and available after the extent of the let.
I don't believe this is practical in a simple Lisp like
mine.  I would like it to work for your example however.

I have been led to believe that there is a useful
and useable halfway-house between full dynamic scope
and full lexical scope.  A sort of limited lexical
scope explicitly invoked with function-quote.  Maybe
this was only ever done on interpreters that used
deep binding; I don't know. I think I can see how deep
binding would make things easier.  Is it necessarily
a big performance hit?  I know that there are many
'obvious' conclusions in this area that are actually
incorrect.  Perhaps this is one of them.

In practice I don't meet the funarg problem very often.
All the same would like to understand this issue.  I
really feel that I am missing some very obvious point.
I also want to be sure that my interpreter is as powerful
and flexible as it can be given the basic design choices
that I have made.

I have spent hours trawling the web for information
on how the early Lisp interpreters were developed from
the point that mine presently occupies but the details
are always missing.  The code for most modern interpreters
look as though it has been written from a formal
mathematical specification.  Usually full of tiny functions
performing obscure operations that are impossible to
appreciate without knowing the bigger picture.  It has
always been my goal to ensure that the code of my
interpreter is readable and that a Lisp user, capable
in C++, could learn how the interpreter works directly
from the code.  This is, frankly, the main real reason
why anyone else would want the program.  It has the
additional benefit, for myself, that everything works
precisely the way I want it to (apart from function
quoting....)

I notice that Barry Watson suggests the book "Lisp in
Small Pieces".  I have heard a lot of good things said
about it and I guess I should have bought it ages ago.
I'll make it a priority now.

Thanks again for your reply, even though you did blow my
idea out of the water.  I really thought I had it there
for a while : (

Andy
From: Paul
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <3DC83AA3.5010604@hotmail.com>
A J Le Couteur Bisson wrote:
> "Pierpaolo BERNARDI" <··················@hotmail.com> wrote in message
> news:<·······················@news1.tin.it>...
> 
> ...
> I have spent hours trawling the web for information
> on how the early Lisp interpreters were developed from
> the point that mine presently occupies but the details
> are always missing.  The code for most modern interpreters
> look as though it has been written from a formal
> mathematical specification.  Usually full of tiny functions
> performing obscure operations that are impossible to
> appreciate without knowing the bigger picture.  It has
> always been my goal to ensure that the code of my
> interpreter is readable and that a Lisp user, capable
> in C++, could learn how the interpreter works directly
> from the code.  This is, frankly, the main real reason
> why anyone else would want the program.  It has the
> additional benefit, for myself, that everything works
> precisely the way I want it to (apart from function
> quoting....)
> ...

Try "The Art of the Interpreter..." by Steele and Sussman. I think it is 
available somewhere on the web.

Paul
From: A J Le Couteur Bisson
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <aq9fle$8qo$1@helle.btinternet.com>
"Paul" <········@hotmail.com> wrote in message
·····················@hotmail.com...
>
> Try "The Art of the Interpreter..." by Steele and Sussman. I think it is
> available somewhere on the web.
>
> Paul
>

Thanks, I look it up.

Andy
From: Pierpaolo BERNARDI
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <i2%x9.76414$aL4.2379691@news1.tin.it>
"A J Le Couteur Bisson" <·······@thanks.com> ha scritto nel messaggio ·················@sparta.btinternet.com...
 
> This is what I understand to be an upward-funarg and
> I can see that the scope inside let must be captured
> and available after the extent of the let.
> I don't believe this is practical in a simple Lisp like
> mine.  I would like it to work for your example however.

It looks like you fear environments!

If you don't already know them, try a search 
for "flat environments".  Maybe you'll like them
better than the non-flat ones.

> I notice that Barry Watson suggests the book "Lisp in
> Small Pieces".  I have heard a lot of good things said
> about it and I guess I should have bought it ages ago.
> I'll make it a priority now.

I second this suggestion.

You may also look at SICP, which is available 
on line (HTML and info)

P.
From: Jens Axel Søgaard
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <3dc9ca45$0$50022$edfadb0f@dread13.news.tele.dk>
A J Le Couteur Bisson wrote:

> I have spent hours trawling the web for information
> on how the early Lisp interpreters were developed from
> the point that mine presently occupies but the details
> are always missing. 

I also recommend LiSP, that is "LISP in Small Pieces"
by Quinnec.

On line I know Wilsons:

http://www.cs.utexas.edu/users/wilson/schintro/schintro_toc.html
From: William D Clinger
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <b84e9a9f.0211051328.2e5908c4@posting.google.com>
Assuming a single-threaded system, do you think

    (setq y 0)
    (defun f (x) (setq y x) y)
    ((function-quote f) 7)

should return 0 or 7?

Will
From: A J Le Couteur Bisson
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <aq9f9m$ab8$1@knossos.btinternet.com>
"William D Clinger" <······@qnci.net> wrote in message
·································@posting.google.com...
> Assuming a single-threaded system, do you think
>
>     (setq y 0)
>     (defun f (x) (setq y x) y)
>     ((function-quote f) 7)
>
> should return 0 or 7?
>
> Will

My approach will return 7 as required, but (and I think this is
what you were trying to illustrate) the global y would still be 0
when it should be 7.  As I said before I have confused values
and bindings which are concepts that I am  actually very familiar
with.  Once I start to get confused it can snowball.....

Thanks,
Andy
From: William D Clinger
Subject: Re: Function quoting - Is this a valid implementation?
Date: 
Message-ID: <b84e9a9f.0211052253.135d6c2f@posting.google.com>
A J Le Couteur Bisson wrote:
> My approach will return 7 as required, but (and I think this is
> what you were trying to illustrate) the global y would still be 0
> when it should be 7.  As I said before I have confused values
> and bindings which are concepts that I am  actually very familiar
> with.  Once I start to get confused it can snowball.....

There's no objective right or wrong in language design, but the Law
of Least Astonishment is worth heeding.  Depending on your answer,
I was going to ask further questions that would be intended to show
how your semantics yields behavior that most programmers would regard
as peculiar, but you seem to have figured that out already.

Will