[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
PROG1 as a function; meta-rules of CLtL
Date: Tue, 3 Jan 89 20:10 EST
From: Barry Margolin <barmar@Think.COM>
One of our users noticed today that Symbolics defines PROG1 as a
function, rather than as a macro as CLtL specifies. The definition is
essentially
(defun prog1 (first-form &rest rest-forms)
(declare (ignore rest-forms))
first-form)
This works because CL requires left-to-right evaluation of function
arguments; it just does a bit more consing than a macro implementation
would need to do.
Actually, it doesn't do any more consing than the macro definition,
because &REST arguments are stack-allocated on Symbolics machines (in
generally-agreed-on violation of CLtL). Even in Lucid's implementation
this definition would not cons, because the ignored rest argument is
never created in the first place.
The compiler open-codes PROG1 invocations, so this is
only used in the interpreter.
Does this seem valid? The only implementation leeway CLtL mentions is
that macros may be implemented as special forms, so long as an
equivalent macro definition is also made available; it doesn't
specifically mention implementing macros as functions (probably because
the developers thought that none of them COULD be implemented as
functions).
I don't see how this could cause any code to fail.
barmar
Someone writing a cross-compiler or other codewalking tool that did
macroexpansion might be surprised that PROG1 was not expanded. This
might not be a problem if the result were going to run in the same
environment, but it could cause trouble if it were going to be used in
an environment where PROG1 is a macro.
CLtL is silent on this topic (like many others). It is not
explicitly prohibited, nor is it explicitly permitted. This raises a
meta-question: If something is not mentioned, does that mean it is
permitted, or does that mean it is prohibited? I think it must be the
former, since CLtL defines a "core" language, which may be extended by
the implementor. The cleanup committee has tried to fill many of
these holes, but it is impossible to deal with all of them. It is
safe to say that ambiguities will be discovered as long as there are
prople using Common Lisp. Here are some choice ones, in increasing
order of bizarreness:
Is it OK to define Common Lisp functions with extra optional or
keyword parameters, with system dependent meanings? E.g. Lucid's
COMPILE-FILE has several keyword arguments not mentioned in CLtL.
Is it OK to return extra values from Common Lisp functions?
Is it OK to define the behavior of functions on datatypes not
explicitly permitted in CLtL? For example, suppose I defined + on
vectors to do componentwise addition on the elements? Arguments to +
"must" be numbers, meaning that it "is an error" to supply anything
other than numbers, meaning that anything can happen when you supply
arguments other than numbers.
Suppose an implementation printed
>>Attention: Taking CAR of (1 2 3)!
every time CAR was called. I don't suppose many people would use
it, but would it be a legal Common Lisp implementation?