[alexandria-cvs] updated branch master: 34949e1... new macro: ENSUREF

Nikodemus Siivola nsiivola at common-lisp.net
Mon Mar 8 11:50:37 UTC 2010


The branch master has been updated:
       via  34949e184e892240d0197bae46ad0924fcb2f51b (commit)
      from  a2c71efed048596cb0fbc734e814248d00a2601f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 34949e184e892240d0197bae46ad0924fcb2f51b
Author: Nikodemus Siivola <nikodemus at random-state.net>
Date:   Mon Mar 8 13:48:49 2010 +0200

    new macro: ENSUREF
    
      Code by: Tobias C. Rittweiler <tcr at freebits.de>

-----------------------------------------------------------------------

Summary of changes:
 control-flow.lisp |   39 +++++++++++++++++++++++++++++++++++++++
 package.lisp      |    1 +
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/control-flow.lisp b/control-flow.lisp
index bf64728..8225442 100644
--- a/control-flow.lisp
+++ b/control-flow.lisp
@@ -104,3 +104,42 @@ NIL."
   "Like CL:MULTIPLE-VALUE-PROG1, except it saves the values of the
 second form."
   `(progn ,first-form (multiple-value-prog1 ,second-form , at body)))
+
+(defmacro ensuref (place thing &rest more &environment env)
+ "If PLACE evaluates to NIL set it to THING, otherwise leave PLACE unchanged.
+
+\(ENSUREF PLACE THING) is approximately equivalent to
+
+  (SETF PLACE (OR PLACE THING))
+
+except that ENSUREF ensures that PLACE is evaluated only once, and except that
+PLACE isn't set at all if it evaluated to NIL.
+
+Example:
+
+  (let ((a nil)
+        (b :foo)
+        (c (list 1 2 nil 4)))
+    (ensuref a :a
+             b :b
+             (third c) :c)
+    (values a b c))
+
+       ==> :A, :FOO, (1 2 :C 4)
+"
+ (multiple-value-bind (gvars vals gstorevars setter getter)
+     (get-setf-expansion place env)
+   (when (second gstorevars)
+     (error "ENSUREF does not support setting multiple values ~
+             via the (VALUES ...) place."))
+   (if (null more)
+       (let ((gstorevar (first gstorevars))
+             (gtmp (gensym "CURVAL+")))
+         `(let ,(mapcar #'list gvars vals)
+            (let ((,gtmp ,getter))
+              (if ,gtmp
+                  ,gtmp
+                  (let ((,gstorevar ,thing))
+                    ,setter)))))
+       `(progn (ensuref ,place ,thing)
+               (ensuref , at more)))))
diff --git a/package.lisp b/package.lisp
index 81c1e58..61ba06c 100644
--- a/package.lisp
+++ b/package.lisp
@@ -230,4 +230,5 @@
    #:symbolicate
    #:assoc-value
    #:rassoc-value
+   #:ensuref
    ))
-- 
Alexandria hooks/post-receive




More information about the alexandria-cvs mailing list