summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/txr/stdlib/place.tl18
-rw-r--r--txr.125
2 files changed, 23 insertions, 20 deletions
diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl
index aa534e4a..72519795 100644
--- a/share/txr/stdlib/place.tl
+++ b/share/txr/stdlib/place.tl
@@ -117,28 +117,30 @@
(t (sys:eval-err "form ~s is not syntax denoting a deletable place" place)))))
(macro-time
- (defun sys:r-s-let-expander (bindings body e pred)
+ (defun sys:r-s-let-expander (bindings body e letsym pred)
(let ((exp-bindings (mapcar (aret ^(,@1 ,(macroexpand @2 e))) bindings)))
(let ((renames [keep-if pred exp-bindings second])
(regular [remove-if pred exp-bindings second]))
(cond ((and renames regular)
^(symacrolet ,renames
- (let ,regular ,*body)))
+ (,letsym ,regular ,*body)))
(renames ^(symacrolet ,renames ,*body))
- (regular ^(let ,regular ,*body))
+ (regular ^(,letsym ,regular ,*body))
(t ^(progn ,*body)))))))
(defmacro rlet (bindings :env e . body)
- [sys:r-s-let-expander bindings body e constantp])
+ [sys:r-s-let-expander bindings body e 'let constantp])
(defmacro slet (bindings :env e . body)
- (sys:r-s-let-expander bindings body e [orf constantp bindable]))
+ (sys:r-s-let-expander bindings body e 'let [orf constantp bindable]))
(defmacro alet (bindings :env e . body)
(let ((exp-bindings (mapcar (aret ^(,@1 ,(macroexpand @2 e))) bindings)))
- ^(,(if [all exp-bindings [orf constantp bindable] second]
- 'symacrolet 'let)
- ,exp-bindings ,*body)))
+ (if [some exp-bindings constantp second]
+ [sys:r-s-let-expander exp-bindings body e 'alet constantp]
+ ^(,(if [all exp-bindings bindable second]
+ 'symacrolet 'let)
+ ,exp-bindings ,*body))))
(defmacro with-gensyms (syms . body)
^(let ,(zip syms (repeat '((gensym)))) ,*body))
diff --git a/txr.1 b/txr.1
index d2d45722..d6b6a0ca 100644
--- a/txr.1
+++ b/txr.1
@@ -29221,21 +29221,22 @@ The macro
.code alet
("atomic" or "all") is a stronger form of the
.code slet
-macro. The transformation of any of the bindings to symbol macros takes place
-under the same conditions as under
-.codn slet .
-However,
-.code alet
-imposes the restriction that all the bindings must be transformed
-to symbol macros, or not at all.
+macro. All bindings initialized by constant expressions are
+turned to symbol macros. Then, if all of the remaining bindings are
+all initialized by symbol expressions, they are also turned to
+symbol macros. Otherwise, none of the remaining bindings
+are turned to symbol macros.
The
.code alet
-macro can be used to avoid introducing temporary variables in situations when
-it is suspected that the initializing forms for the variables have side
-effects through which they affect each others' evaluations. The suspicion is
-lifted if the all initializing forms (after expansion) are constants, or
-accesses to symbols.
+macro can be used even in situations when it is possible that the initializing
+forms the variables may have side effects through which they affect each
+others' evaluations. In this situation
+.code alet
+still propagates constants via symbol macros, and can eliminate the
+remaining temporaries if they can all be made symbol macros for
+existing variables: i.e. there doesn't exist any initialization form
+with interfering side effects.
.coNP Macro @ define-accessor
.synb