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

A lisp question

11 views
Skip to first unread message

rf...@fell.shore.net

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

in common lisp, is it posible to define a function that will return itself
unevaluated ? For example,
a function of two arguments, call it dp, so that the invocation (dp arg1
arg1) will return the same thing?
Thanks


Sunil Mishra

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

It's not entirely clear what your question is.

Do you want the call (dp arg1 arg1) to evaluate to the list (dp arg1 arg1)?
This can be done quite easily:

(defun dp (x y)
(list 'dp x y))

But I doubt this is what you mean, since I can't see any possible use for
such a function. Could you give a clearer example, with perhaps a reason
for why you might want to do this? (There might be a better way to tackle
this, and a bigger picture is necessary for that.)

Sunil

Kent M Pitman

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

rf...@fell.shore.net writes:

> in common lisp, is it posible to define a function that will return itself
> unevaluated ? For example,
> a function of two arguments, call it dp, so that the invocation (dp arg1
> arg1) will return the same thing?

It's trivial possible modulo some interminiable philosophical debates.

(1) Can a function know it's own name?

One approach to this problem is to go down the whole big rut that
the folks did with the Lambda calculus and the Y operator.
Theorists will rant on forever about this, and it does indeed
sometimes cause practical problems, but MOSTLY it does not. For
MOST practical purposes, in my experience, the answer is simply to
tell the function its name, which works unless you're going to go
around renaming your operators. As such, you can make a function
that returns its own name by simply using the name quoted in the
body, as in:

(defun foo () 'foo)

So, are we home free? Not quite....

(2) What does it mean to return an argument?

This is a MUCH more interesting problem than the Y operator will
ever be in my opinion because it confronts one directly and is
not immediately subject to a single answer. But again it is
possible to settle arbitrarily. You just have to understand the
myriad hidden questions you're asking well enough to realize how
many arbitrary-yet-important decisions you need to make.

First, by "argument" do you mean the "argument form" or
"argument value". e.g., when I write:

(f (+ 1 2))

the function f will not see (+ 1 2) but rather 3 as its argument.
I can, by making f a macro or by making f a two-place function with
a laborious calling convention arrange to pass both:

(f '(+ 1 2) (+ 1 2))

Returning neither of these is likely to be what you really want, though.
(f (+ 1 2)) as a result will force a re-evaluation. This is ok for
pure-functional stuff but bad for side-effects like
(f '(setq x (+ x 1)) (setq x (+ x 1)))
will have side-effects that will expose the fact that an evaluation was
attempted (not to mention the fact that returning the form will leave
you with an object that must be evaluted in the global rather than
lexical contour.

You could pass '(+ 1 2) only and allow the function F to do the
evaluation (or not). This approach is used by some embedded languages
in Lisp. At least the form you evaluate and the result you return will
have meaning in the same, global, environment.

There's also a problem of re-evaluation. Consider:

(defun add (x y)
(if (and (numberp x) (numberp y))
(+ x y)
(list 'add x y)))

Some people might replace (list 'add x y) with
`(add ,x ,y) but it would amount to the same.

(add 3 4) => 7
(add 'x 'y) => (add x y)

The problem is that re-evaluating this would not again yield the
same value because the quotes on x and y are lost. You might be
better off returning not "the same argument subforms" but "quoted
argument subforms" so that said subforms would later re-evaluate
to the same thing. e.g.,

(defun add (x y)
(if (and (numberp x) (numberp y))
(+ x y)
(list 'add (list 'quote x) (list 'quote y))))

where again some might prefer to hae written instead of
(list 'add (list 'quote x) (list 'quote y))
the more perspicuous:
`(add ',x ',y)
But that depends on personal style and your intent to later
side-effect; the result of backquote is not something you may
later modify. Having done this version of the function:

(add 3 4) => 7
(add 'x 'y) => (add 'x 'y)

The nice thing about this is that calling EVAL on the result
yields the same answer. Well, mostly. I'll leave you to ponder
whether the following yields a good result:

(add (add 'x 'y) (add 3 4))

and whether additional calls to EVAL and/or CONSTANTP might
yield a better result.

For documentation of CONSTANTP, see the Common Lisp HyperSpec(TM)
at http://www.harlequin.com/books/HyperSpec/FrontMatter/
To get there fastest, look in the Symbol Index.

In the end, the decision will come down to WHY you want to return
the function. For debugging? For later re-evaluation using the
same processor? For later re-evaluation using a different processor?
Because this is a homework assignment with no such later purpose?
All of these lead you in potentially different directions...

Good luck.

Joseph H. Fasel

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

I'm not sure what the arguments are for, but is

(defun self () #'self)

about what you had in mind?

rf...@fell.shore.net wrote:

> in common lisp, is it posible to define a function that will return itself
> unevaluated ? For example,
> a function of two arguments, call it dp, so that the invocation (dp arg1
> arg1) will return the same thing?

> Thanks

--
Joseph H. Fasel, Ph.D. email: j...@lanl.gov
Technology Modeling and Analysis phone: +1 505 667 7158
University of California fax: +1 505 667 2960
Los Alamos National Laboratory post: TSA-7 MS F609; Los Alamos, NM 87545


Erik Naggum

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

* Kent M Pitman
| ... where again some might prefer to hae written instead of

| (list 'add (list 'quote x) (list 'quote y))
| the more perspicuous:
| `(add ',x ',y)
| But that depends on personal style and your intent to later side-effect;
| the result of backquote is not something you may later modify.

no? I'm aware that _quoted_ structures may be constants, but backquoted
lists and vectors always appeared me to be required guaranteed fresh,
insofar as structure was not specifically shared with `,.'. according to
the definition in 2.4.6 Backquote in the standard, it does indeed appear
that only in the case of ,. will list structured be shared, and otherwise
not. in other words, I view backquote as a list _constructor_. is this
really unwarranted?

#:Erik
--
religious cult update in light of new scientific discoveries:
"when we cannot go to the comet, the comet must come to us."

Thomas A. Russ

unread,
Apr 13, 1998, 3:00:00 AM4/13/98
to

rf...@fell.shore.net writes:

> in common lisp, is it posible to define a function that will return itself
> unevaluated ? For example,
> a function of two arguments, call it dp, so that the invocation (dp arg1
> arg1) will return the same thing?
> Thanks

That depends on exactly what you want. A very strict interpretation
says that you have to use a Macro, but that would be rather silly since
you could achieve the same result by simply using QUOTE:

'(dp arg1 arg1) => (DP ARG1 ARG1)

Assuming you actually want ARG1 evaluated, such as:

(let ((arg1 3))
(dp arg1 arg1)) => (DP 3 3)

then it is easy:

(defun dp (x y)
`(dp ,x ,y))


--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu

Kent M Pitman

unread,
Apr 14, 1998, 3:00:00 AM4/14/98
to

Erik Naggum <cle...@naggum.no> writes:

>
> * Kent M Pitman
> | ... where again some might prefer to hae written instead of
> | (list 'add (list 'quote x) (list 'quote y))
> | the more perspicuous:
> | `(add ',x ',y)
> | But that depends on personal style and your intent to later side-effect;
> | the result of backquote is not something you may later modify.
>
> no? I'm aware that _quoted_ structures may be constants, but backquoted
> lists and vectors always appeared me to be required guaranteed fresh,
> insofar as structure was not specifically shared with `,.'. according to
> the definition in 2.4.6 Backquote in the standard, it does indeed appear
> that only in the case of ,. will list structured be shared, and otherwise
> not. in other words, I view backquote as a list _constructor_. is this
> really unwarranted?

Unless it says the structure is fresh, I wouldn't assume it. Surely
nothing tells you it's fresh. [Didn't you see recent discussion about
whether ARRAY-DIMENSIONS returns fresh structure--surely you want the
reason to assume the structure "fragile" [the new term I'm trying to
push for as meaning "potentially not fresh"] is that it's not
specified fresh, and not that the user is required to engage in some
complicated study of what ARRAY-DIMENSIONS really does, and where it's
called for, and what the price of returning fresh structure is, and
what the price of not doing so is, and so on... I'm hoping that in a
next-round standard, any compound object (array or cons or structure
or standard class...perhaps needs a term, too) will be defined to be
one of constant, interned, fragile, fresh, etc. (Note too: I presently
presume a fragile object might still be fresh but just not advertised
as such.)

There was a mighty war right at the instant of backquote's
introduction (in Maclisp in the late 70's) over this issue. At that
time, backquote was advertise to produce fresh structure and I eagerly
rewrote my code to assume this. Then about a week later, someone
complained that this would make things like:
`(lambda (,x y) (member ,x y))
inefficient because to avoid unnecessary consing you'd have to do:
`(lambda (,x ,@'(y)) (member ,x ,@'(y)))
which would defeat the whole purpose of having a template language
that LOOKS like the result. So they incompatibly changed it and yours
truly spent a long time repairing his code again to NOT use backquote
as a fresh constructor.

There is a philosophical battle that has raged forever about
`(a b ,c)
and whether it's possible to side-effect that. One school says that
it's impractical to build a constructor for this which does NOT make
the objects fresh and so people should be told that it's ok to side-effect.
Another school finds it too hard to describe where it's impractical and/or
it worries that someone will use a hashing-canonicalizer and in fact
uniquify the result against all odds. I tend to swim with the middle
camp who tells people you should never depend on this and then sometimes
does depend on it. (On a good day, I put a comment that says
`(a b ,c) ;hope this is fresh since it's side-effected later
or something. :-)

Erik Naggum

unread,
Apr 14, 1998, 3:00:00 AM4/14/98
to

* Kent M Pitman

| Surely nothing tells you it's fresh.

actually, the use of APPEND does. however, since an implementation is
allowed to do anything as long as it is EQUAL to that specified with
APPEND, I guess that means "stay away".

| There was a mighty war right at the instant of backquote's introduction
| (in Maclisp in the late 70's) over this issue.

did it result in any papers that might still be available? this is not
the first time I have managed to stumble onto old battlefields.

| There is a philosophical battle that has raged forever about
| `(a b ,c)
| and whether it's possible to side-effect that. One school says that it's
| impractical to build a constructor for this which does NOT make the
| objects fresh and so people should be told that it's ok to side-effect.
| Another school finds it too hard to describe where it's impractical
| and/or it worries that someone will use a hashing-canonicalizer and in
| fact uniquify the result against all odds. I tend to swim with the
| middle camp who tells people you should never depend on this and then
| sometimes does depend on it. (On a good day, I put a comment that says
| `(a b ,c) ;hope this is fresh since it's side-effected later
| or something. :-)

I appreciate the elucidation, but considering the difficulty of building
guaranteed fresh lists and vectors without using backquote, and the
inefficiency of COPY-TREE on the result of a backquoted form, not to
mention the need to cover vectors specially, wouldn't it be smart to
provide some internal mechanism that would guarantee freshness without
all the needless consing that copying everything afterwards requires?

Kai Grossjohann

unread,
Apr 14, 1998, 3:00:00 AM4/14/98
to

smi...@peachtree.cc.gatech.edu (Sunil Mishra) writes:

> Do you want the call (dp arg1 arg1) to evaluate to the list (dp
> arg1 arg1)? This can be done quite easily:
>
> (defun dp (x y)
> (list 'dp x y))

(let ((x 1) (y 2)) (dp x y))

Your function returns (dp 1 2), not (dp x y) as I think the original
poster requested.

Thus, I think it isn't possible with a function, but it is possible
with a macro.

kai
--
Really cancel? [OK] [Cancel]

Bill Coderre

unread,
Apr 15, 1998, 3:00:00 AM4/15/98
to

Maybe the original poster was after one o' them-there "self-replicating
functions"?

You know, something that looks like
(defun foo $#((*$@)_!(#)_ )
that when evaluated returns the same exact thing, ie.:
(defun foo $#((*$@)_!(#)_ )

I seem to recall that there was a particularly egregiously obdurate
version that had almost no letters of the alphabet, just quotes,
backquotes, commas, at-signs, etc.

Or is this some kind of homework assignment that shouldn't be helped with?
If so, I pity the person. That's a tough 'un.

bc

--
This posting in no way represents the official opinion of Apple Computer,
Inc. Contact me at b...@wetware.com or b...@apple.com to discuss my personal
opinions and those of Apple Computer, Inc. Have A Nice Day.

rf...@fell.shore.net

unread,
Apr 16, 1998, 3:00:00 AM4/16/98
to

In <bc-150498...@codebi.apple.com> Bill Coderre wrote:
> Maybe the original poster was after one o' them-there "self-replicating
> functions"?
>
> You know, something that looks like
> (defun foo $#((*$@)_!(#)_ )
> that when evaluated returns the same exact thing, ie.:
> (defun foo $#((*$@)_!(#)_ )
>
> I seem to recall that there was a particularly egregiously obdurate
> version that had almost no letters of the alphabet, just quotes,
> backquotes, commas, at-signs, etc.
>
> Or is this some kind of homework assignment that shouldn't be helped with?
> If so, I pity the person. That's a tough 'un.
>
> bc
>
>This is not a homework problem. I have written a set of function using
Macsyma, the symbolic algebra system, to do the dirac algebra in quantum
electrodynamics. These routines have been successfully used to do state of
the art qed calculations (Phys Rev Lett 18 (1997)).My main efforts are to try
to improve the effeciency of these functions by writing them in lisp, which
Macsyma is written in.
Perhaps I should post some questions relevant to that issue since they may be
of general interest to readers of this group. So, more to come.
Thanks to all that replied to my original post,
Dick Fell


0 new messages