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
In article <6gt2lj$...@fridge.shore.net> 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
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.)
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.,
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.
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...
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
* 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."
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 > | ... 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. :-)
* 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?
#:Erik -- religious cult update in light of new scientific discoveries: "when we cannot go to the comet, the comet must come to us."
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.
> 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