Re: newLISP is simple, terse, and well documented



On 2009-01-22, Rainer Joswig <joswig@xxxxxxx> wrote:
In article <87vdsakl8b.fsf.mdw@xxxxxxxxxxxxxxxxxxxxxxxxxx>,
Mark Wooding <mdw@xxxxxxxxxxxxxxxx> wrote:

Majorinc Kazimir <false@xxxxxxxxxxxxx> writes:

So, CL chose an option that leads to speed, and Newlisp chose the
option that leads to expressive power. That is exactly what I said.

Err..., no, MACLISP chose speed and Common Lisp followed.

Scheme chose correctness and Common Lisp followed.

FEXPRs are a runtime feature that makes debugging harder and
makes compilation next to useless.

Kent Pitman, _Special Forms in Lisp_, Conclusions:

``It should be clear from this discussion that FEXPR's are only safe
if no part of their ``argument list'' is to be evaluated, and even
then only when there is a declaration available in the environment
in which they appear. Using FEXPR's to define control primitives will
be prone to failure due to problems of evaluation context and due to
their potential for confusing program-manipulating programs such as
compilers and macro packages.''

``MACRO's on the other hand, offer a more straightforward and reliable
approach to all of the things which we have said should be required
of a mechanism for defining special forms.''

``It is widely held among members of the MIT Lisp community that FEXPR,
NLAMBDA, and related concepts could be omitted from the Lisp language
with no loss of generality and little loss of expressive power, and that
doing so would make a general improvement in the quality and reliability
of program-manipulating programs.''

[Pitman, 1980]

The following paper looks like it promises a contrasting viewpoint, but
I don't have access to it:

_Sometimes an FEXPR is beter than a macro_, Z. Lichtman, ACM SIGART
Bulletin, Issue 97, July 1986.

We /do/ have the abstract, at least, which suggests that the reason a FEXPR is
sometimes better has to do with efficiency, not expressiveness --- ``despite
its negative aspects''! Even the author of this paper defending fexprs
recognizes that there are negative aspects:

``Common Lisp, which is becoming THE Lisp standard, does not support
call by text (FEXPR mechanism in Mac/Franz Lisp). This effect can
be obtained using macros. Based on the experience of converting an
OPS5 implementation from Franz Lisp to Common Lisp, it is argued that
sometimes call by text is needed for efficiency, despite its negative
aspects. In the case of languages embedded in a Lisp system, using
the macro alternative for call by text can cause macro expansion at
execution time. This leads to a some-what less efficient implementation
of the embedded language.''

[Z. Lichtman, 1986]

Without having the full text of the paper paper, we can nevertheless easily
conjecture what the Abstract might be talking about. How would macro-expansion
happen at execution time? You'd have to EVAL or COMPILE some form that is a
macro call, or contains one. Sure, doing the macro expansion could be a waste
of time, if the expansion is only evaluated once (or, more generally, a small
number of times). The expanded text of the macro might run no faster than the
original form being interpreted by the FREXP, plus you're pay for the cost of
the macroexpansion, so it could be the case that no matter how many times the
macroexpansion is re-evaluated, it does not pay for the cost of macroexpansion.

Macros are often written with the assumption that expansion time is not
important, and so it could spend many cycles and do a lot of consing; the
efficiency of the code that the macro generates is important. Given that you
are EVAL'ing this code already, an interpretive alternative to macroexpansion
(call by source code) may be faster.

Indeed, an frexp behaves a lot like an extension to /interpreter/ for handling
a special form, whereas a macro is an extension to a /compiler/ for handling a
special form. So, in a sense, if code is purely interpreted, it doesn't always
make sense to be invoking a /compiler/ extension for the handling of some
special form.

Sometimes interpreting can even be outright faster than compiling. This
happens, for instance, when some straightforward compiled code generates a loop
that exceeds the size of a small cache on the processor, whereas encoding the
algorithm as a tiny interpreter plus a compact piece of data behaving as code,
allows everything to fit into the cache.

But where is the paper that argues that fexprs are sometimes better than macros
because they are more flexible and powerful than macros? Or easier to use,
learn, etc? It sounds like Mr. Majorinc is confident enough that he should be
able to set about writing that paper. I'm looking forward to it!
.



Relevant Pages

  • Re: Three questions
    ... of the functionality you are doing here already exists in lisp. ... Another way to implement this macro, ... really understand all of the binding forms in Common Lisp and also make ... often KEY for properly implementing control structures. ...
    (comp.lang.lisp)
  • [OT] PostLisp, a language experiment
    ... IMHO the worst thing in Lisp is its many parentheses. ... The worst thing about Forth IMHO is the stack clutter. ... And while I could write a macro like (with bla ... The ret is the explicit return continuation. ...
    (comp.lang.lisp)
  • Re: Program compression
    ... problems to be solved much more concisely than with Lisp. ... In Common Lisp, it's another one line of code: ... My point is that different languages are based on different things ... it would be impossible for the author of a macro (in the Lisp ...
    (comp.programming)
  • Re: Why is LISP syntax superior?
    ... that lisp was the most powerful programming language ever invented, ... It is precisely the lack of syntax that I admire in Lisp ... (setf (elt seq i) ... I guess one could write a reader macro to transform foointo (elt ...
    (comp.lang.lisp)
  • Re: How to prevent cdr from capitalizing symbols?
    ... proof underwear) of the ANSI Common Lisp Specification. ... i.e. Common Lisp is not the only place where StudlyCaps are not so welcome. ... >>the macro is hard-coded to work against one list. ...
    (comp.lang.lisp)