[cl-who-devel] semantic for (str NIL) and (esc NIL)

Mac Chan emailmac at gmail.com
Sat May 5 02:26:30 UTC 2007


Hi all,

This happened to me a couple times where I have a form like this

(with-html
  (:html
   (:body
    (str (get-error-messages)))))

Now if there's no error, (get-error-messages) returns NIL, otherwise
it returns a description of the problem.

This function also serve as a predicate for other code.

But (str (get-error-messages)) actually prints a "NIL" to the browser.

Of course I could replace (str (get-error-messages)) with

(let ((messages (get-error-messages))
  (when messages (str messages))))

or

(str (or (get-error-messages) ""))

however it's getting rather verbose.


But the real issue is that the string "NIL" really doesn't make sense
in HTML, XML or JSON.

It's only something that a Lisp programmer would understand.

So I'm purposing to change the substitution of

(str form) => (princ form1 s)

to

(str form) => (let ((#:result form1)) (when #:result (princ #:result s)))


Attached is a diff for this change in case you guys agree that this makes sense.

Thanks,
-- Mac
-------------- next part --------------
diff -r -u cl-who-0.8.1/doc/index.html cl-who-0.8.1patch/doc/index.html
--- cl-who-0.8.1/doc/index.html	2007-04-27 12:09:30.000000000 -0700
+++ cl-who-0.8.1patch/doc/index.html	2007-05-04 18:51:00.000000000 -0700
@@ -400,14 +400,20 @@
 
   <li>A form which is neither a string nor a keyword nor a list beginning with a keyword will be left as is except for the following <em>substitutions</em>:
     <ul>
-      <li>Forms that look like <code>(<b>str</b> <i>form1</i> <i>form*</i>)</code> will be substituted with <code>(princ <i>form1</i> s)</code>. (Note that all forms behind <code><i>form1</i></code> are ignored.)
-
-<table border=0 cellpadding=2 cellspacing=3><tr><td><pre>(loop for i below 10 do (str i)) <font color="red">=></font> (loop for i below 10 do (princ i s))</pre></td></tr></table>
+      <li>Forms that look like <code>(<b>str</b> <i>form1</i> <i>form*</i>)</code> will be substituted with <br>
+	  <code>(let ((result <i>form1</i>)) (when result (princ result s)))</code>. <br>
+	  (Note that all forms behind <code><i>form1</i></code> are ignored.)
+
+<table border=0 cellpadding=2 cellspacing=3><tr><td><pre>(loop for i below 10 do (str i)) <font color="red">=></font> 
+(loop for i below 10 do
+   (let ((#:result i))
+     (when #:result (princ #:result *standard-output*))))</pre></td></tr></table>
 
       <li>Forms that look like <code>(<b>fmt</b> <i>form*</i>)</code> will be substituted with <code>(format s <i>form*</i>)</code>.
 
 <table border=0 cellpadding=2 cellspacing=3><tr><td><pre>(loop for i below 10 do (fmt "~R" i)) <font color="red">=></font> (loop for i below 10 do (format s "~R" i))</pre></td></tr></table>
-      <li>Forms that look like <code>(<b>esc</b> <i>form1</i> <i>form*</i>)</code> will be substituted with <code>(write-string (<a href="#escape-string">escape-string</a> <i>form1</i>) s)</code>.
+      <li>Forms that look like <code>(<b>esc</b> <i>form1</i> <i>form*</i>)</code> will be substituted with <br>
+	  <code>(let ((result <i>form1</i>)) (when result (write-string (<a href="#escape-string">escape-string</a> result s))))</code>.
 
       <li>If a form looks like <code>(<b>htm</b> <i>form*</i>)</code> then each of the <code><i>forms</i></code> will be subject to the transformation rules we're just describing.
 
diff -r -u cl-who-0.8.1/who.lisp cl-who-0.8.1patch/who.lisp
--- cl-who-0.8.1/who.lisp	2007-04-27 02:33:42.000000000 -0700
+++ cl-who-0.8.1patch/who.lisp	2007-05-04 18:27:00.000000000 -0700
@@ -373,14 +373,15 @@
                      (case (first x)
                        ((esc)
                          ;; (ESC form ...) ->
-                         ;; (WRITE-STRING (ESCAPE-STRING form STREAM))
-                         (list 'write-string
-                               (list 'escape-string
-                                     (second x))
-                               stream))
+                         ;; (LET ((RESULT form)) (WHEN RESULT (WRITE-STRING (ESCAPE-STRING RESULT STREAM))))
+                        (let ((result (gensym)))
+                           `(let ((,result ,(second x)))
+                             (when ,result (write-string (escape-string ,result) ,stream)))))
                        ((str)
-                         ;; (STR form ...) --> (PRINC form STREAM)
-                         `(princ ,(second x) ,stream))
+                         ;; (STR form ...) --> (LET ((RESULT form)) (WHEN RESULT (PRINC RESULT STREAM)))
+                        (let ((result (gensym)))
+                          `(let ((,result ,(second x)))
+                            (when ,result (princ ,result ,stream)))))
                        ((fmt)
                          ;; (FMT form*) --> (FORMAT STREAM form*)
                          (list* 'format stream (rest x)))))


More information about the Cl-who-devel mailing list