diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-10-23 22:12:56 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-10-23 22:12:56 -0700 |
commit | 718995e74b8446d5cc66b3592efcf69e0c24133d (patch) | |
tree | c6e187563f7a6d6ad393c622b069802f3cc92bfe /lisplib.c | |
parent | 5bcfa40f0831c3f2ff266a260e0ca751b092b734 (diff) | |
download | txr-718995e74b8446d5cc66b3592efcf69e0c24133d.tar.gz txr-718995e74b8446d5cc66b3592efcf69e0c24133d.tar.bz2 txr-718995e74b8446d5cc66b3592efcf69e0c24133d.zip |
op/do: clean up documentation-implementation problem.
It was reported by astute user vapnik spaknik that the
documentation says thing about the do operator which are
not actually true in the implementation. I've decided that
one of them should be true, and so both implementation
and documentation are changing.
The documentation claims that (do set x) will produce
a function that can be called with one argument; that
argument will be assigned to x. That doesn't work, but this
commit will make it work.
The documentation has this example transformation:
(do + foo) -> (lambda rest (+ foo . rest))
that cannot be made to work because do works with macros
and special operators to which arguments can't be dynamically
applied. This patch will not make the above work; instead
the example is corrected.
How do is going to work inow is that (do sym ...) syntax in
which no implicit variables appear will be equialent
to (do sym ... @1). The generated variadic function has one
required argument which is implicitly added to the syntax.
Obviously, that only works if that positon of the syntax
is an evaluated form or place.
Values of the -C option equal to 225 or less will restore
the old do behavior.
* share/txr/stdlib/op.tl (sys:op-expand): Support the new
style of do, subject to backward compatibility. A hack is
required here. We cannot discover the @1, @2 .. variables
in the syntax until we fully expand it. But that code walk
requires the syntax to be valid. For instance if (do set x) is
specified, with the expectation that it is equivalent to
(do set x @1), we cannot process that by code walking (set x).
(set x) is invalid syntax. What we do is to *try* expanding
it as (set x). If that doesn't work, we add a dummy gensym
to the form to produce (set x #:gNNNN) and try expanding that.
In that case, rather than adding @1 to the form, we replace
the dummy gensym with @1. The algorithm is careful not to
accidentally conceal real syntax errors in the form.
If the form without the dummy gensym fails to expand, and
the one with the dummy gensym expands fine but contains
references to implicit parameters (@1, @2, ... @rest),
we expand it again without the gensym and allow the error
to propagate. Other aspects of this change are fairly trivial.
Because the do logic possibly introduces a @1 that doesn't
exist, near the end of this function we have to bind another
metas variable which has an up-to-date copy of the gens slot.
(op-ignerr): New macro; we can't use ignerr because that
will create a bootstrapping cycle; ignerr expands to catch,
and the catch macro uses do. Wrapping this in eval-only,
since we don't need an op-ignerr macro in the compiled image.
* txr.1: Documentation revised and updated. Differences
between do and op put clarified and put into point form.
Bad do examples corrected. Syntax of do now shown as having
a required parameter that is an operator. Compat notes added.
Diffstat (limited to 'lisplib.c')
0 files changed, 0 insertions, 0 deletions