<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Analysis</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>Recent changes to Analysis</description><atom:link href="https://sourceforge.net/p/readable/wiki/Analysis/feed" rel="self"/><language>en</language><lastBuildDate>Thu, 23 Aug 2012 11:56:34 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/readable/wiki/Analysis/feed" rel="self" type="application/rss+xml"/><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v9
+++ v10
@@ -269,12 +269,12 @@
 
 ## Sweet-expressions
 
-    defun print.tree [tree &amp;optional [depth 0]]
+    defun print.tree (tree &amp;optional (depth 0))
       tab depth
       format t "~A~%" first(tree)
       loop for subtree in cdr(tree) do
         tab {depth + 1}
-        format t "= ~A" [first subtree]
+        format t "= ~A" first(subtree)
         if atom(second(subtree))
           format t " =&gt; ~A~%" second(subtree)
           progn
@@ -286,7 +286,7 @@
 
     defun classify (instance tree)
       let
-        val branch
+        $ val branch
         if atom(tree) return-from(classify tree)
         setq val get.value(first(tree) instance)
         setq branch second(assoc(val cdr(tree)))
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Thu, 23 Aug 2012 11:56:34 -0000</pubDate><guid>https://sourceforge.net9a3e15e323ea5add453263a72bab36fda5cea23b</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v8
+++ v9
@@ -69,8 +69,7 @@
 
 ## Original Lisp
 
-Here's the original Common Lisp (slightly reformatted, and with some
-pieces skipped since the purpose here is just to consider formatting).
+Here's the original Common Lisp (slightly reformatted, and with some pieces skipped since the purpose here is just to consider formatting).
 
 
     (in-package "USER")
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 05 Aug 2012 02:29:24 -0000</pubDate><guid>https://sourceforge.net7bc541599ec9dc5b84d1935e178f1d40b0af1268</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v7
+++ v8
@@ -1,15 +1,8 @@
-Here is a large list of code examples that use sweet-expressions (which include modern-expressions and curly infix).
-
-Several Lisp-based languages are represented here, including Scheme, Common Lisp, Clojure, Arc, ACL2, and SMT-LIB.  That's important; past readability efforts tied their notation to specific semantics, so ensuring that it works with many languages helps avoid that mistake.
-
-Note: We have switched from "group" to "\\\\", and do not have a special meaning for unprefixed [ ... ].  The following have not yet been fully adjusted.
+Here is a large list of code examples that use sweet-expressions (which include neoteric-expressions and curly infix).  Several Lisp-based languages are represented here, including Scheme, Common Lisp, Clojure, Arc, ACL2, and SMT-LIB.  That's important; past readability efforts tied their notation to specific semantics, so ensuring that it works with many languages helps avoid that mistake.
 
 # Matrix multiply
 
-Matrix multiply example from http://www.scheme.com/tspl2d/examples.html
-mat-mat-mul multiplies one matrix by another, after verifying that the
-first matrix has as many columns as the second matrix has rows. I
-thought a matrix multiply function would show off infix capabilities.
+Matrix multiply example from http://www.scheme.com/tspl2d/examples.html mat-mat-mul multiplies one matrix by another, after verifying that the first matrix has as many columns as the second matrix has rows. I thought a matrix multiply function would show off infix capabilities.
 
 ## Original Scheme
 
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 05 Aug 2012 02:28:19 -0000</pubDate><guid>https://sourceforge.net9e5fc6a81100bbd464baa143d025b80ffa40475b</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v6
+++ v7
@@ -489,11 +489,7 @@
        {x = 0}     1
        otherwise   {x * fact{x - 1}}
 
-The ":" in many BitC contexts as a "type assertion" operator. The BitC
-reader handles ":" very specially. Instead of handling ":" specially, we
-can treat ":" as just another infix operator taking two parameters: the
-object and its type. Which means that instead of a special-case reader,
-we can use a general-case reader.
+The ":" in many BitC contexts as a "type assertion" operator. The BitC reader handles ":" very specially. Instead of handling ":" specially, we can treat ":" as just another infix operator taking two parameters: the object and its type. Which means that instead of a special-case reader, we can use a general-case reader.
 
 # PVS
 
@@ -510,8 +506,7 @@
         (then
           (if lemmas
             (let ((lemmata (if (listp lemmas) lemmas (list lemmas)))
-                 (x `(then ,@(loop for lemma in lemmata append `((skosimp*)(use ,le
-     mma))))))
+                 (x `(then ,@(loop for lemma in lemmata append `((skosimp*)(use ,lemma))))))
                 x)
              (skip))
            (if lazy-match
@@ -657,9 +652,7 @@
 
 ## Sweet-expressions
 
-Again, we'll keep it in all uppercase, so that you won't be misled by a
-difference in case. Notice that even with all-upper-case, it still is
-easier to follow than the original:
+Again, we'll keep it in all uppercase, so that you won't be misled by a difference in case. Notice that even with all-upper-case, it still is easier to follow than the original:
 
     DEFUN C:FIND ()
       SETQ SA GETSTRING(T "\nEnter string for search parameter: ")
@@ -689,8 +682,7 @@
       PRINC A
       PRINC()
 
-Today most people use lowercase, so let's see how this looks with that
-one change:
+Today most people use lowercase, so let's see how this looks with that one change:
 
     defun c:find ()
       setq sa getstring(t "\nEnter string for search parameter: ")
@@ -722,8 +714,7 @@
 
 # Kalotan puzzle (Scheme)
 
-["Teach Yourself Scheme in Fixnum days"](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html) includes a way to [solve the Kalotan puzzle solution using Scheme](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_sec_14.4.1).  It depends on the "amb" function, described further in the book. It has a large number of "ands" and "xors" which can be expressed using infix,
-which is interesting and useful for trying out variations.
+["Teach Yourself Scheme in Fixnum days"](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html) includes a way to [solve the Kalotan puzzle solution using Scheme](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_sec_14.4.1).  It depends on the "amb" function, described further in the book. It has a large number of "ands" and "xors" which can be expressed using infix, which is interesting and useful for trying out variations.
 
 ## Original Lisp
 
@@ -775,8 +766,7 @@
 
 ## Sweet-expressions
 
-Here's one way to convert this to infix non-default, emphasizing the use
-of indentation and function calls using prefixed():
+Here's one way to convert this to infix non-default, emphasizing the use of indentation and function calls using prefixed():
 
     define solve-kalotan-puzzle
       lambda ()
@@ -822,8 +812,7 @@
 
     solve-kalotan-puzzle()
 
-Let's use more infix operations; note that there's no requirement that
-we use infix everywhere:
+Let's use more infix operations; note that there's no requirement that we use infix everywhere:
 
     define solve-kalotan-puzzle
       lambda ()
@@ -901,9 +890,7 @@
 
     solve-kalotan-puzzle()
 
-And as a test, let's use even more of the infix operators. Frankly, I
-think the previous version is easier to follow, though this version is
-more similar to how it'd be done in many other languages:
+And as a test, let's use even more of the infix operators. Frankly, I think the previous version is easier to follow, though this version is more similar to how it'd be done in many other languages:
 
     define solve-kalotan-puzzle
       lambda ()
@@ -945,8 +932,7 @@
 
 ## Original Lisp
 
-Here's the original Lisp of a trivial example, "All farmers like
-tractors":
+Here's the original Lisp of a trivial example, "All farmers like tractors":
 
     (forall (?F ?T)
       (=&gt;
@@ -966,9 +952,7 @@
            instance(?T Tractor)
         likes ?F ?T
 
-However, both "and" and "=\&gt;" (implies) are traditionally used as infix
-operators, rather than prefix operators. Using {...}, we can use them in
-that traditional manner:
+However, both "and" and "=\&gt;" (implies) are traditionally used as infix operators, rather than prefix operators. Using {...}, we can use them in that traditional manner:
 
     forall (?F ?T)
       {{instance(?F Farmer) and instance(?T Tractor)} =&gt; likes(?F ?T)}
@@ -1915,8 +1899,7 @@
 
 ## Sweet-expressions
 
-Here is the "infix is not default" version. Note that there is a space
-after the "\`" and ",":
+Here is the "infix is not default" version. Note that there is a space after the "\`" and ",":
 
     bind-keys global-keymap "H-e"
      ` jump-or-exec "GVIM"
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 05 Aug 2012 02:27:04 -0000</pubDate><guid>https://sourceforge.net6810a7a242ba53dc0cf1ed72c046412f0b0e34c6</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v5
+++ v6
@@ -35,23 +35,6 @@
 
 
 ## Sweet-expressions
-
-     define mat-mat-mul
-        lambda [m1 m2]
-           let* [ [nr1 matrix-rows(m1)]
-                  [nr2 matrix-rows(m2)]
-                  [nc2 matrix-columns(m2)]
-                  [r   make-matrix(nr1 nc2)]]
-              if not{matrix-columns(m1) = nr2} ; f{infix}
-                  match-error(m1 m2)
-              do [[i 0 {i + 1}]]
-                 [{i = nr1} r]
-                 do [[j 0 {j + 1}]]
-                    [{j = nc2}]
-                    do [[k 0 {k + 1}]
-                        [a 0 {a + {matrix-ref(m1 i k) * matrix-ref(m2 k j)}}]]
-                       [{k = nr2} matrix-set!(r i j a)]
-
 
 Or, if you use groups:
 
@@ -306,10 +289,10 @@
             terpri()
             print.tree(second(subtree) {depth + 5})
 
-    defun tab [n]
+    defun tab (n)
       loop for i from 1 to n do format(t " ")
 
-    defun classify [instance tree]
+    defun classify (instance tree)
       let
         val branch
         if atom(tree) return-from(classify tree)
@@ -317,7 +300,7 @@
         setq branch second(assoc(val cdr(tree)))
         classify instance branch
 
-    defun entropy [p]
+    defun entropy (p)
       {{-1.0 * p * log(p 2)} +
        {-1.0 * {1 - p} * log({1 - p} 2)}}
 
@@ -328,13 +311,7 @@
 
 ## Original
 
-Here's [an example of the Fibonacci numbers in Scheme by Hanson
-Char](http://hansonchar.blogspot.com/2006/01/fibonacci-numbers-in-scheme.html),
-modified. I include a version similar to the original (using cond) and
-bigger modification of it (using if). I may use the Fibonacci example
-(using if) as a better example for the ruleset; the factorial example
-hides ordinary function calls in the infix non-default case, even though
-they are critical.
+Here's [an example of the Fibonacci numbers in Scheme by Hanson Char](http://hansonchar.blogspot.com/2006/01/fibonacci-numbers-in-scheme.html), modified. I include a version similar to the original (using cond) and bigger modification of it (using if). I may use the Fibonacci example (using if) as a better example for the ruleset; the factorial example hides ordinary function calls in the infix non-default case, even though they are critical.
 
     ; Original, using "cond"
     (define (fibfast n)
@@ -436,8 +413,7 @@
 
 ## Original Lisp
 
-[Here's a longer ACL2 example, from a brief tutorial by
-Kaufmann](http://www.cs.utexas.edu/users/kaufmann/tutorial/rev3.html#slide3).
+[Here's a longer ACL2 example, from a brief tutorial by Kaufmann](http://www.cs.utexas.edu/users/kaufmann/tutorial/rev3.html#slide3).
 
     (defun rev3 (x)
       (cond
@@ -479,23 +455,11 @@
 
 # BitC Example
 
-[BitC](http://www.bitc-lang.org/) is, according to its creators, "a
-systems programming language that combines the \`\`low level'' nature of
-C with the semantic rigor of Scheme or ML. BitC was designed by careful
-selection and exclusion of language features in order to support proving
-properties (up to and including total correctness) of critical systems
-programs." See the [BitC specification for more
-information](http://www.bitc-lang.org/docs/bitc/spec.html). BitC is in
-development, the following example is from the version 0.10+ (June 17,
-2006) specification. The BitC reader is actually not quite a standard
-s-expression reader; in particular, it treats ":" specially. Hopefully,
-a sweet-expression reader will be even better.
+[BitC](http://www.bitc-lang.org/) is, according to its creators, "a systems programming language that combines the \`\`low level'' nature of C with the semantic rigor of Scheme or ML. BitC was designed by careful selection and exclusion of language features in order to support proving properties (up to and including total correctness) of critical systems programs." See the [BitC specification for more information](http://www.bitc-lang.org/docs/bitc/spec.html). BitC is in development, the following example is from the version 0.10+ (June 17, 2006) specification. The BitC reader is actually not quite a standard s-expression reader; in particular, it treats ":" specially. Hopefully, a sweet-expression reader will be even better.
 
 ## Original BitC
 
-Here's the original BitC. I've cheated slightly with the definition of
-"\&gt;", pulling it out of context. One complication: BitC's reader is not
-a "pure" s-expression reader; it handles ":" specially.
+Here's the original BitC. I've cheated slightly with the definition of "\&gt;", pulling it out of context. One complication: BitC's reader is not a "pure" s-expression reader; it handles ":" specially.
 
     (deftypeclass 
       (forall ((Eql 'a)) (Ord 'a))
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 05 Aug 2012 02:21:10 -0000</pubDate><guid>https://sourceforge.net17814f4b1caf718ccd7cd62095b9c1666031c1de</guid></item><item><title>WikiPage Analysis modified by Alan Manuel Gloria</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v4
+++ v5
@@ -169,7 +169,7 @@
     defun queue-next (queue ptr)
       "Increment a queue pointer by 1 and wrap around if needed."
       let
-        group
+        \\
           length length(queue-elements(queue))
           try the(fixnum (1+ ptr))
         if {try = length} 0 try
@@ -177,7 +177,7 @@
     defun queue-get (queue &amp;optional (default nil))
       check-type(queue queue)
       let
-        group
+        \\
           get queue-get-ptr(queue)
           put queue-put-ptr(queue)
         if {get = put} ;; Queue is empty.
@@ -193,7 +193,7 @@
       "Store ELEMENT in the QUEUE and return T on success or NIL on failure."
       check-type(queue queue)
       let*
-        group
+        \\
           get queue-get-ptr(queue)
           put queue-put-ptr(queue)
           next queue-next(queue put)
@@ -213,7 +213,7 @@
       (let ((First (gensym "FIRST-"))
             (Second (gensym "SECOND-"))
             (Sum (gensym "SUM-")))
-        '(let* ((,First ,X)
+        `(let* ((,First ,X)
                 (,Second ,Y)
                 (,Sum (+ ,First ,Second)))
            (* ,Sum ,Sum))
@@ -224,16 +224,16 @@
 
     defmacro Square-Sum2 (X Y)
       let
-        group
+        \\
           First gensym("FIRST-")
           Second gensym("SECOND-")
           Sum gensym("SUM-")
-        'let*
-          group
-            ,First ,X
-            ,Second ,Y
-            ,Sum {,First + ,Second}
-          {,Sum * ,Sum}
+        ` let*
+            \\
+              ,First ,X
+              ,Second ,Y
+              ,Sum {,First + ,Second}
+            {,Sum * ,Sum}
 
 
 
@@ -241,7 +241,7 @@
 
 I use the trivial "factorial" example above because, well, it's trivial. But often when writing recursive functions you'll include an accumulator. Here is [Dick Gabriel's factorial function](http://www.testing.com/cgi-bin/blog/2004/01/25) that does this, using Common Lisp.
 
-I'll just show the version using "group"; it takes more lines, but I like the look of it.
+I'll just show the version using "\\\\"; it takes more lines, but I like the look of it.
 
 ## Original Lisp
 
@@ -256,7 +256,7 @@
 
      defun fact (n)
        labels
-         group
+         \\
            f (n acc)
              if {n &lt;= 1} acc f({n - 1} {n * acc})
          f n 1
@@ -465,7 +465,7 @@
        endp(cdr(x)) list(car(x))
        t
          let*
-           group
+           \\
              b@c        cdr(x)
              c@rev-b    rev3(b@c)    ; note recursive call of rev3
              rev-b      cdr(c@rev-b)
@@ -567,7 +567,7 @@
         then
           if lemmas
             let
-              group
+              \\
                 lemmata
                   if listp(lemmas) lemmas list(lemmas)
                 x `[then ,@[loop for lemma in lemmata append
@@ -897,12 +897,12 @@
 
     solve-kalotan-puzzle()
 
-Now let's add use the "group" command to get rid of some more brackets:
+Now let's add use the "\\\\" SPLIT symbol to get rid of some more brackets:
 
     define solve-kalotan-puzzle
       lambda ()
         let
-          group
+          \\
             parent1         amb('m 'f)
             parent2         amb('m 'f)
             kibi            amb('m 'f)
@@ -944,7 +944,7 @@
     define solve-kalotan-puzzle
       lambda ()
         let
-          group
+          \\
             parent1         amb('m 'f)
             parent2         amb('m 'f)
             kibi            amb('m 'f)
@@ -1561,19 +1561,19 @@
 ## Sweet-expressions
 
 Here is one way to rewrite this in a readable format. In this example
-I've chosen to use "group" for the lists of variables in forall and let,
+I've chosen to use "\\\\" for the lists of variables in forall and let,
 but given short lists like these you could also use traditional list
 notation:
 
     forall
-       group
+       \\
          x List(Int)
          y List(Int)
        = append(x y)
          ite {x = as(nil List(Int))}
            y
            let
-             group
+             \\
                h head(x)
                t tail(x)
              insert h append(t y)
@@ -1963,7 +1963,7 @@
       lambda (w prop value)
         declare (unused prop)
         let
-          group
+          \\
             keymap {window-get(w 'keymap) or
                     window-put(w 'keymap copy-sequence(window-keymap))}
           mapcar
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Alan Manuel Gloria</dc:creator><pubDate>Fri, 03 Aug 2012 15:19:19 -0000</pubDate><guid>https://sourceforge.net700b4fab9f80f12ce7f33632025eee2e11acff36</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v3
+++ v4
@@ -2,7 +2,7 @@
 
 Several Lisp-based languages are represented here, including Scheme, Common Lisp, Clojure, Arc, ACL2, and SMT-LIB.  That's important; past readability efforts tied their notation to specific semantics, so ensuring that it works with many languages helps avoid that mistake.
 
-Note: We have switched from "group" to "\\\\"; the following have not yet been fully adjusted.
+Note: We have switched from "group" to "\\\\", and do not have a special meaning for unprefixed [ ... ].  The following have not yet been fully adjusted.
 
 # Matrix multiply
 
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 29 Jul 2012 13:07:34 -0000</pubDate><guid>https://sourceforge.net024abe0517907d8f528ae427d5bb4b2a21ddd37c</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v2
+++ v3
@@ -2,8 +2,7 @@
 
 Several Lisp-based languages are represented here, including Scheme, Common Lisp, Clojure, Arc, ACL2, and SMT-LIB.  That's important; past readability efforts tied their notation to specific semantics, so ensuring that it works with many languages helps avoid that mistake.
 
-
-Note: We are switching from "group" to "\\\\"; the following have not yet been adjusted.
+Note: We have switched from "group" to "\\\\"; the following have not yet been fully adjusted.
 
 # Matrix multiply
 
@@ -401,7 +400,7 @@
 
 ## Sweet-expressions
 
-There are different ways to format this. One way emphasizes indentation:
+There are different ways to format this.  One way emphasizes indentation:
 
       thm
         implies
@@ -410,7 +409,7 @@
                integerp(n)
                {0 &lt;= n}
                rationalp(u)
-          { {len(x) * u} &lt; {u + n + 3} }
+          {{len(x) * u} &lt; {u + n + 3}}
 
 Another way emphasizes infix:
 
@@ -418,7 +417,20 @@
         {not(endp(x)) and endp(cdr(x)) and integerp(n) and {0 &lt;= n}
           and rationalp(u)}
         implies
-          { {len(x) * u} &lt; {u + n + 3} } }
+          {{len(x) * u} &lt; {u + n + 3}}}
+
+Perhaps the best uses SUBLIST:
+
+      thm $ implies
+        and
+          not(endp(x))
+          endp(cdr(x))
+          integerp(n)
+          {0 &lt;= n}
+          rationalp(u)
+        {{len(x) * u} &lt; {u + n + 3}}
+
+
 
 # Longer ACL2 example (ACL2)
 
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 29 Jul 2012 13:06:13 -0000</pubDate><guid>https://sourceforge.neta63dfae4db0be2cd12bf82a4ef75d763a7f8486f</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>&lt;pre&gt;--- v1
+++ v2
@@ -4,6 +4,88 @@
 
 
 Note: We are switching from "group" to "\\\\"; the following have not yet been adjusted.
+
+# Matrix multiply
+
+Matrix multiply example from http://www.scheme.com/tspl2d/examples.html
+mat-mat-mul multiplies one matrix by another, after verifying that the
+first matrix has as many columns as the second matrix has rows. I
+thought a matrix multiply function would show off infix capabilities.
+
+## Original Scheme
+
+     (define mat-mat-mul
+        (lambda (m1 m2)
+           (let* ((nr1 (matrix-rows m1))
+                  (nr2 (matrix-rows m2))
+                  (nc2 (matrix-columns m2))
+                  (r   (make-matrix nr1 nc2)))
+              (if (not (= (matrix-columns m1) nr2))
+                  (match-error m1 m2))
+              (do ((i 0 (+ i 1)))
+                  ((= i nr1) r)
+                  (do ((j 0 (+ j 1)))
+                      ((= j nc2))
+                      (do ((k 0 (+ k 1))
+                           (a 0
+                              (+ a
+                                 (* (matrix-ref m1 i k)
+                                    (matrix-ref m2 k j)))))
+                          ((= k nr2)
+                           (matrix-set! r i j a))))))))
+
+
+## Sweet-expressions
+
+     define mat-mat-mul
+        lambda [m1 m2]
+           let* [ [nr1 matrix-rows(m1)]
+                  [nr2 matrix-rows(m2)]
+                  [nc2 matrix-columns(m2)]
+                  [r   make-matrix(nr1 nc2)]]
+              if not{matrix-columns(m1) = nr2} ; f{infix}
+                  match-error(m1 m2)
+              do [[i 0 {i + 1}]]
+                 [{i = nr1} r]
+                 do [[j 0 {j + 1}]]
+                    [{j = nc2}]
+                    do [[k 0 {k + 1}]
+                        [a 0 {a + {matrix-ref(m1 i k) * matrix-ref(m2 k j)}}]]
+                       [{k = nr2} matrix-set!(r i j a)]
+
+
+Or, if you use groups:
+
+     define mat-mat-mul
+        lambda [m1 m2]
+           let*
+             \\
+               nr1 matrix-rows(m1)
+               nr2 matrix-rows(m2)
+               nc2 matrix-columns(m2)
+               r   make-matrix(nr1 nc2)
+             if not{matrix-columns(m1) = nr2} ; f{infix} = f({infix}).
+               match-error(m1 m2)
+             do
+               \\
+                 i 0 {i + 1}
+               \\
+                 {i = nr1} r
+               do
+                 \\
+                   j 0 {j + 1}
+                 \\
+                   {j = nc2}
+                 do
+                  \\
+                    k 0 {k + 1}
+                    a 0 {a + {matrix-ref(m1 i k) * matrix-ref(m2 k j)}}
+                  \\
+                    {k = nr2}
+                    matrix-set!(r i j a)
+
+
+
 
 # Queue (Common Lisp)
 
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 29 Jul 2012 12:58:25 -0000</pubDate><guid>https://sourceforge.net52ca4b362dc1cfe3b59b827aa8bd7d1c8d35f2c9</guid></item><item><title>WikiPage Analysis modified by David A. Wheeler</title><link>https://sourceforge.net/p/readable/wiki/Analysis/</link><description>Here is a large list of code examples that use sweet-expressions (which include modern-expressions and curly infix).

Several Lisp-based languages are represented here, including Scheme, Common Lisp, Clojure, Arc, ACL2, and SMT-LIB.  That's important; past readability efforts tied their notation to specific semantics, so ensuring that it works with many languages helps avoid that mistake.


Note: We are switching from "group" to "\\\\"; the following have not yet been adjusted.

# Queue (Common Lisp)


Here's some [Common Lisp sample code from lispworks.com](http://www.lispworks.com/documentation/lcl50/ug/ug-22.html).

## Original Lisp

Here's the original Common Lisp (slightly reformatted, and with some
pieces skipped since the purpose here is just to consider formatting).


    (in-package "USER")
    ;; Define a default size for the queue.
    (defconstant default-queue-size 100 "Default size of a queue")
    ;;; The following structure encapsulates a queue. It contains a
    ;;; simple vector to hold the elements and a pair of pointers to
    ;;; index into the vector. One is a "put pointer" that indicates
    ;;; where the next element is stored into the queue. The other is
    ;;; a "get pointer" that indicates the place from which the next
    ;;; element is retrieved.
    ;;; When put-ptr = get-ptr, the queue is empty.
    ;;; When put-ptr + 1 = get-ptr, the queue is full.
    (defstruct (queue (:constructor create-queue)
                      (:print-function queue-print-function))
      (elements #() :type simple-vector) ; simple vector of elements
      (put-ptr 0 :type fixnum) ; next place to put an element
      (get-ptr 0 :type fixnum) ; next place to take an element
      )

    (defun queue-next (queue ptr)
      "Increment a queue pointer by 1 and wrap around if needed."
      (let ((length (length (queue-elements queue)))
            (try (the fixnum (1+ ptr))))
           (if (= try length) 0 try)))

    (defun queue-get (queue &amp;optional (default nil))
      (check-type queue queue)
      (let ((get (queue-get-ptr queue)) (put (queue-put-ptr queue)))
         (if (= get put) ;; Queue is empty.
            default
            (prog1 (svref (queue-elements queue) get)
                   (setf (queue-get-ptr queue) (queue-next queue get))))))

    ;; Define a function to put an element into the queue. If the
    ;; queue is already full, QUEUE-PUT returns NIL. If the queue
    ;; isn't full, QUEUE-PUT stores the element and returns T.
    (defun queue-put (queue element)
      "Store ELEMENT in the QUEUE and return T on success or NIL on failure."
      (check-type queue queue)
      (let* ((get (queue-get-ptr queue))
             (put (queue-put-ptr queue))
             (next (queue-next queue put)))
            (unless (= get next) ;; store element
              (setf (svref (queue-elements queue) put) element)
              (setf (queue-put-ptr queue) next) ; update put-ptr
              t))) ; indicate success 


## Sweet-expressions


    in-package("USER")

    ;; Define a default size for the queue.
    defconstant(default-queue-size 100 "Default size of a queue")

    ;;; The following structure encapsulates a queue. It contains a
    ;;; simple vector to hold the elements and a pair of pointers to
    ;;; index into the vector. One is a "put pointer" that indicates
    ;;; where the next element is stored into the queue. The other is
    ;;; a "get pointer" that indicates the place from which the next
    ;;; element is retrieved.
    ;;; When put-ptr = get-ptr, the queue is empty.
    ;;; When put-ptr + 1 = get-ptr, the queue is full.
    defstruct queue(:constructor(create-queue)
                    :print-function(queue-print-function))
      elements(#() :type simple-vector) ; simple vector of elements
      put-ptr(0 :type fixnum) ; next place to put an element
      get-ptr(0 :type fixnum) ; next place to take an element

    defun queue-next (queue ptr)
      "Increment a queue pointer by 1 and wrap around if needed."
      let
        group
          length length(queue-elements(queue))
          try the(fixnum (1+ ptr))
        if {try = length} 0 try

    defun queue-get (queue &amp;optional (default nil))
      check-type(queue queue)
      let
        group
          get queue-get-ptr(queue)
          put queue-put-ptr(queue)
        if {get = put} ;; Queue is empty.
            default
            prog1
              svref queue-elements(queue) get
              setf queue-get-ptr(queue) queue-next(queue get)

    ;; Define a function to put an element into the queue. If the
    ;; queue is already full, QUEUE-PUT returns NIL. If the queue
    ;; isn't full, QUEUE-PUT stores the element and returns T.
    defun queue-put (queue element)
      "Store ELEMENT in the QUEUE and return T on success or NIL on failure."
      check-type(queue queue)
      let*
        group
          get queue-get-ptr(queue)
          put queue-put-ptr(queue)
          next queue-next(queue put)
        unless {get = next} ;; store element
          setf svref(queue-elements(queue) put) element
          setf queue-put-ptr(queue) next ; update put-ptr
          t ; indicate success 


# Macro for Common Lisp

Here's an example from ["Lecture Notes: Macros"](http://www.apl.jhu.edu/~hall/Lisp-Notes/Macros.html) (on how to do Common Lisp macros). This one shows how to create fully clean Common Lisp macros that don't accidentally capture local variables, using gensym.

## Original Lisp

    (defmacro Square-Sum2 (X Y)
      (let ((First (gensym "FIRST-"))
            (Second (gensym "SECOND-"))
            (Sum (gensym "SUM-")))
        '(let* ((,First ,X)
                (,Second ,Y)
                (,Sum (+ ,First ,Second)))
           (* ,Sum ,Sum))
    ))


## Sweet-expressions

    defmacro Square-Sum2 (X Y)
      let
        group
          First gensym("FIRST-")
          Second gensym("SECOND-")
          Sum gensym("SUM-")
        'let*
          group
            ,First ,X
            ,Second ,Y
            ,Sum {,First + ,Second}
          {,Sum * ,Sum}



# Accumulating factorial (Common Lisp)

I use the trivial "factorial" example above because, well, it's trivial. But often when writing recursive functions you'll include an accumulator. Here is [Dick Gabriel's factorial function](http://www.testing.com/cgi-bin/blog/2004/01/25) that does this, using Common Lisp.

I'll just show the version using "group"; it takes more lines, but I like the look of it.

## Original Lisp


     (defun fact (n)
       (labels ((f (n acc)
                  (if (&lt;= n 1) acc (f (- n 1) (* n acc)))))
           (f n 1)))


## Sweet-expressions

     defun fact (n)
       labels
         group
           f (n acc)
             if {n &lt;= 1} acc f({n - 1} {n * acc})
         f n 1



# Decision Learning Example (Common Lisp)

Here's a [tiny extract of some Decision tree learning code](http://www.cs.cmu.edu/afs/cs/project/theo-11/www/decision-trees.lisp) that accompanies the textbook "Machine Learning," Tom M. Mitchell, McGraw Hill, 1997. "Copyright 1998 Tom M. Mitchell. This code may be freely distributed and used for any non-commericial purpose, as long as this copyright notice is retained. The author assumes absolutely no responsibility for any harm caused by bugs in the code."

## Original Lisp

    (defun print.tree (tree &amp;optional (depth 0))
      (tab depth)
      (format t "~A~%" (first tree))
      (loop for subtree in (cdr tree) do
            (tab (+ depth 1))
            (format t "= ~A" (first subtree))
            (if (atom (second subtree))
              (format t " =&gt; ~A~%" (second subtree))
              (progn (terpri)(print.tree (second subtree) (+ depth 5))))))
    (defun tab (n)
      (loop for i from 1 to n do (format t " ")))

    (defun classify (instance tree)
      (let (val branch)
        (if (atom tree) (return-from classify tree))
        (setq val (get.value (first tree) instance))
        (setq branch (second (assoc val (cdr tree))))
        (classify instance branch)))

    (defun entropy (p)
      (+ (* -1.0 p (log p 2))
         (* -1.0 (- 1 p) (log (- 1 p) 2))))

## Sweet-expressions

    defun print.tree [tree &amp;optional [depth 0]]
      tab depth
      format t "~A~%" first(tree)
      loop for subtree in cdr(tree) do
        tab {depth + 1}
        format t "= ~A" [first subtree]
        if atom(second(subtree))
          format t " =&gt; ~A~%" second(subtree)
          progn
            terpri()
            print.tree(second(subtree) {depth + 5})

    defun tab [n]
      loop for i from 1 to n do format(t " ")

    defun classify [instance tree]
      let
        val branch
        if atom(tree) return-from(classify tree)
        setq val get.value(first(tree) instance)
        setq branch second(assoc(val cdr(tree)))
        classify instance branch

    defun entropy [p]
      {{-1.0 * p * log(p 2)} +
       {-1.0 * {1 - p} * log({1 - p} 2)}}



# Fibonacci Numbers (Scheme)


## Original

Here's [an example of the Fibonacci numbers in Scheme by Hanson
Char](http://hansonchar.blogspot.com/2006/01/fibonacci-numbers-in-scheme.html),
modified. I include a version similar to the original (using cond) and
bigger modification of it (using if). I may use the Fibonacci example
(using if) as a better example for the ruleset; the factorial example
hides ordinary function calls in the infix non-default case, even though
they are critical.

    ; Original, using "cond"
    (define (fibfast n)
     (cond ((&lt; n 2) n)
           (else (fibup n 2 1 0))))

    (define (fibup max count n-1 n-2)
     (cond ((= max count) (+ n-1 n-2))
           (else (fibup max (+ count 1) (+ n-1 n-2) n-1))))


    ; Using "if"
    (define (fibfast n)
     (if (&lt; n 2) n
         (fibup n 2 1 0)))

    (define (fibup max count n-1 n-2)
     (if (= max count) (+ n-1 n-2)
         (fibup max (+ count 1) (+ n-1 n-2) n-1)))


    ; Original, using "cond"
    define fibfast(n)
      cond
        {n &lt; 2} n
        else       fibup(n 2 1 0)

    define fibup(max count n-1 n-2)
      cond
        {max = count} {n-1 + n-2}
        else          fibup(max {count + 1} {n-1 + n-2} n-1)

## Sweet-expressions

    ; Using "if"
    define fibfast(n)
      if {n &lt; 2}
        n
        fibup(n 2 1 0)

    define fibup(max count n-1 n-2)
      if {max = count}
        {n-1 + n-2}
        fibup(max {count + 1} {n-1 + n-2} n-1)


# Flying demo (ACL2)

[ACL2 is an interactive mechanical theorem prover](http://www.cs.utexas.edu/users/moore/acl2/) designed for use in modeling hardware and software and proving properties about those models. It is released under the GPL license.

ACL2 is powerful, but it's often avoided specifically because many people find its Lisp notation to be user-hostile. For example, David Duffy's book "Principles of Automated Theorem Proving" (1991) devotes a whole chapter to the Boyer-Moore Theorem Prover (ACL2 is the latest version of this series). The chapter specifically states that one of ACL2's key problems is the "difficulty of reading the LISP-like prefix notation" and that "To improve readability here, this notation will often be abused to include the use of prefix and infix symbols" (page 176-177). For the rest of the chapter, the author modifies ACL2 input and output, instead of showing actual input, so that readers could understand what is going on. In contrast, in a different chapter the author did not modify Prolog's notation, because Prolog's notation is much easier to read for those trained in traditional mathematics or other programming languages.

## Original Lisp

This is a [simple example from their "flying demo"](http://www.cs.utexas.edu/users/moore/publications/flying-demo/script.html#next6).

    (thm (implies (and (not (endp x))
                              (endp (cdr x))
                              (integerp n)
                              (&lt;= 0 n)
                              (rationalp u))
                         (&lt; (* (len x) u) (+ u n 3))))

## Sweet-expressions

There are different ways to format this. One way emphasizes indentation:

      thm
        implies
          and not(endp(x))
               endp(cdr(x))
               integerp(n)
               {0 &lt;= n}
               rationalp(u)
          { {len(x) * u} &lt; {u + n + 3} }

Another way emphasizes infix:

      thm {
        {not(endp(x)) and endp(cdr(x)) and integerp(n) and {0 &lt;= n}
          and rationalp(u)}
        implies
          { {len(x) * u} &lt; {u + n + 3} } }

# Longer ACL2 example (ACL2)

## Original Lisp

[Here's a longer ACL2 example, from a brief tutorial by
Kaufmann](http://www.cs.utexas.edu/users/kaufmann/tutorial/rev3.html#slide3).

    (defun rev3 (x)
      (cond
       ((endp x)
        nil)
       ((endp (cdr x))
        (list (car x)))
       (t
        (let* ((b@c (cdr x))
               (c@rev-b (rev3 b@c)) ; note recursive call of rev3
               (rev-b (cdr c@rev-b))
               (b (rev rev-b))      ; note call of rev
               (a (car x))
               (a@b (cons a b))
               (rev-b@a (rev a@b))  ; note call of rev
               (c (car c@rev-b))
               (c@rev-b@a (cons c rev-b@a)))
          c@rev-b@a))))

## Sweet-expressions

    defun rev3 (x)
      cond
       endp(x)      nil
       endp(cdr(x)) list(car(x))
       t
         let*
           group
             b@c        cdr(x)
             c@rev-b    rev3(b@c)    ; note recursive call of rev3
             rev-b      cdr(c@rev-b)
             b          rev(rev-b)   ; note call of rev
             a          car(x)
             a@b        cons(a b)
             rev-b@a    rev(a@b)     ; note call of rev
             c          car(c@rev-b)
             c@rev-b@a  cons(c rev-b@a)
           c@rev-b@a

# BitC Example

[BitC](http://www.bitc-lang.org/) is, according to its creators, "a
systems programming language that combines the \`\`low level'' nature of
C with the semantic rigor of Scheme or ML. BitC was designed by careful
selection and exclusion of language features in order to support proving
properties (up to and including total correctness) of critical systems
programs." See the [BitC specification for more
information](http://www.bitc-lang.org/docs/bitc/spec.html). BitC is in
development, the following example is from the version 0.10+ (June 17,
2006) specification. The BitC reader is actually not quite a standard
s-expression reader; in particular, it treats ":" specially. Hopefully,
a sweet-expression reader will be even better.

## Original BitC

Here's the original BitC. I've cheated slightly with the definition of
"\&gt;", pulling it out of context. One complication: BitC's reader is not
a "pure" s-expression reader; it handles ":" specially.

    (deftypeclass 
      (forall ((Eql 'a)) (Ord 'a))
      &lt; : (fn ('a 'a) 'a))

    (define (&gt; x y)
      (not (or (&lt; x y) (== x y))))

    (define (fact x:int32)
      (cond ((&lt; x 0) (- (fact (- x))))
            ((= x 0) 1)
            (otherwise
              (* x (fact (- x 1))))))

## Sweet-expressions

    deftypeclass 
      forall (Eql('a)) Ord('a)
      &lt; : fn(('a 'a) 'a)

    define &gt;(x y)
      not{ {x &lt; y} or {x == y} }

    define fact{x : int32}
      cond
       {x &lt; 0}     -(fact(-(x)))
       {x = 0}     1
       otherwise   {x * fact{x - 1}}

The ":" in many BitC contexts as a "type assertion" operator. The BitC
reader handles ":" very specially. Instead of handling ":" specially, we
can treat ":" as just another infix operator taking two parameters: the
object and its type. Which means that instead of a special-case reader,
we can use a general-case reader.

# PVS

[PVS is a verification system](http://pvs.csl.sri.com/), i.e., "a specification language integrated with support tools and a theorem prover". It is released under the GNU GPL license. It's implemented using Common Lisp. PVS implements its own specification language that supports infix, etc., and that doesn't need replacing. However, when proving theories, you must interact with a essentially a Lisp read-eval-print loop, and that *does* use ordinary s-expression syntax.  This would be especially valuable when defining new strategies.

## Original Lisp

Here's a definition for non-default strategy called "stew". I can't remember where I got this; I think I got this definition from elsewhere and then tweaked it.

Oh, one warning: both "if" and "then" are *commands* in this notation; an "if" does *not* have a "then" keyword. I mention this, because in this example it can look confusing.

      (defstep stew (&amp;optional lazy-match (if-match t) (defs !) rewrites theories
                     exclude (updates? t) &amp;rest lemmas)
        (then
          (if lemmas
            (let ((lemmata (if (listp lemmas) lemmas (list lemmas)))
                 (x `(then ,@(loop for lemma in lemmata append `((skosimp*)(use ,le
     mma))))))
                x)
             (skip))
           (if lazy-match
             (then (grind$ :if-match nil :defs defs :rewrites rewrites
                           :theories theories :exclude exclude :updates? updates?)
                   (reduce$ :if-match if-match :updates? updates?))
             (grind$ :if-match if-match :defs defs :rewrites rewrites
                           :theories theories :exclude exclude :updates? updates?))
     )
      "Does a combination of (lemma) and (grind)."
      "~%Grinding away with the supplied lemmas,")

## Sweet-expressions

      defstep stew (&amp;optional lazy-match (if-match t) (defs !) rewrites theories
                     exclude (updates? t) &amp;rest lemmas)
        then
          if lemmas
            let
              group
                lemmata
                  if listp(lemmas) lemmas list(lemmas)
                x `[then ,@[loop for lemma in lemmata append
                              `[skosimp*() use(,lemma)]]]
              x
            skip()
          if lazy-match
             then
               grind$(:if-match nil :defs defs :rewrites rewrites
                       :theories theories :exclude exclude :updates? updates?)
               reduce$ :if-match if-match :updates? updates?
             grind$(:if-match if-match :defs defs :rewrites rewrites
                    :theories theories :exclude exclude :updates? updates?)
        "Does a combination of (lemma) and (grind)."
        "~%Grinding away with the supplied lemmas,"

# Emacs Lisp

Here's an example of emacs Lisp, this time from a [page on emacs Lisp by Xah Lee](http://xahlee.org/emacs/elisp_examples.html). (Note: Emacs Lisp's variable scoping is dynamic, a fossil from very old versions of Lisp. Scheme and Common Lisp's variable scope is not.)

## Original emacs Lisp

    (defun replace-html-chars (start end)
      "Replace '&lt;' to '&amp;lt;' and other chars in HTML.
    This works on the current selection."
      (interactive "r")
      (save-restriction 
        (narrow-to-region start end)
        (goto-char (point-min))
        (while (search-forward "&amp;" nil t) (replace-match "&amp;amp;" nil t))
        (goto-char (point-min))
        (while (search-forward "&lt;" nil t) (replace-match "&amp;lt;" nil t))
        (goto-char (point-min))
        (while (search-forward "&gt;" nil t) (replace-match "&amp;gt;" nil t))
        )
      )

## Sweet-expressions emacs Lisp

    defun replace-html-chars (start end)
      "Replace '&lt;' to '&amp;lt;' and other chars in HTML.
    This works on the current selection."
      interactive("r")
      save-restriction 
        narrow-to-region start end
        goto-char point-min()
        while search-forward("&amp;" nil t) replace-match("&amp;amp;" nil t)
        goto-char point-min()
        while search-forward("&lt;" nil t) replace-match("&amp;lt;" nil t)
        goto-char point-min()
        while search-forward("&gt;" nil t) replace-match("&amp;gt;" nil t)


# Find (AutoCAD Lisp / AutoLisp)

AutoCAD includes its own Lisp languages, Autolisp. From the [Free Autolisp routines](http://members.aol.com/autolisper/software.htm) I arbitrarily chose the "Find" program, whose purpose is to "Find text in [a] drawing field".

## Original Lisp

Here's the original code, as provided:

    (DEFUN C:FIND ( )
        (SETQ SA(GETSTRING T "\nEnter string for search parameter: "))
        (SETQ AR(SSGET "X" (LIST(CONS 1 SA))))
        (IF(= AR NIL)(ALERT "This string does not exist"))
        (SETQ SB(SSLENGTH AR))

        (C:CONT)
        )
    (DEFUN C:CONT ()
       (SETQ SB(- SB 1))

       (SETQ SC(SSNAME AR SB))
       (SETQ SE(ENTGET SC))
       (SETQ SJ(CDR(ASSOC 1 SE)))
       (IF(= SJ SA)(PROGN
          (SETQ H(CDR(ASSOC 10 SE)))
          (SETQ X1(LIST(- (CAR H) 50)(- (CADR H)50)))
          (SETQ X2(LIST(+ 50(CAR H))(+ 50 (CADR H))))
          (COMMAND "ZOOM" "W" X1 X2 ))(C:CONT)
          )
     (IF(= SB 0)(ALERT "END OF SELECTIONS"))
    (SETQ A(+ SB 1))
    (SETQ A(RTOS A 2 0))
    (SETQ A(STRCAT "\nThere are &lt;" A "&gt; selections Enter CONT to advance to next"))
    (IF(= SB 0)(EXIT))
    (PRINC A)
    (PRINC)
       )

That's so hideously formatted that we can create a much more readable
version without needing a new reader. We'll stick to uppercase, so that
we can see that the improvement is unrelated to using uppercase or
lowercase:

    (DEFUN C:FIND ()
      (SETQ SA (GETSTRING T "\nEnter string for search parameter: "))
      (SETQ AR (SSGET "X" (LIST (CONS 1 SA))))
      (IF (= AR NIL) (ALERT "This string does not exist"))
      (SETQ SB (SSLENGTH AR))
      (C:CONT))

    (DEFUN C:CONT ()
      (SETQ SB (- SB 1))
      (SETQ SC (SSNAME AR SB))
      (SETQ SE (ENTGET SC))
      (SETQ SJ (CDR (ASSOC 1 SE)))
      (IF (= SJ SA)
        (PROGN
          (SETQ H (CDR (ASSOC 10 SE)))
          (SETQ X1 (LIST (- (CAR H) 50) (- (CADR H) 50)))
          (SETQ X2 (LIST (+ 50 (CAR H)) (+ 50 (CADR H))))
          (COMMAND "ZOOM" "W" X1 X2))
        (C:CONT))
      (IF (= SB 0) (ALERT "END OF SELECTIONS"))
      (SETQ A (+ SB 1))
      (SETQ A (RTOS A 2 0))
      (SETQ A
        (STRCAT "\nThere are &lt;" A "&gt; selections Enter CONT to advance to next"))
      (IF (= SB 0) (EXIT))
      (PRINC A)
      (PRINC))

## Sweet-expressions

Again, we'll keep it in all uppercase, so that you won't be misled by a
difference in case. Notice that even with all-upper-case, it still is
easier to follow than the original:

    DEFUN C:FIND ()
      SETQ SA GETSTRING(T "\nEnter string for search parameter: ")
      SETQ AR SSGET("X" LIST(CONS(1 SA)))
      IF {AR = NIL} ALERT("This string does not exist")
      SETQ SB SSLENGTH(AR)
      C:CONT()

    DEFUN C:CONT ()
      SETQ SB {SB - 1}
      SETQ SC SSNAME(AR SB)
      SETQ SE ENTGET(SC)
      SETQ SJ CDR(ASSOC(1 SE))
      IF {SJ = SA}
        PROGN
          SETQ H CDR(ASSOC(10 SE))
          SETQ X1 LIST({CAR(H) - 50} {CADR(H) - 50})
          SETQ X2 LIST({50 + CAR(H)} {50 + CADR(H)})
          COMMAND("ZOOM" "W" X1 X2)
        C:CONT()
      IF {SB = 0} ALERT("END OF SELECTIONS")
      SETQ A {SB + 1}
      SETQ A RTOS(A 2 0)
      SETQ A
        STRCAT "\nThere are &lt;" A "&gt; selections Enter CONT to advance to next"
      IF {SB = 0} EXIT()
      PRINC A
      PRINC()

Today most people use lowercase, so let's see how this looks with that
one change:

    defun c:find ()
      setq sa getstring(t "\nEnter string for search parameter: ")
      setq ar ssget("x" list(cons(1 sa)))
      if {ar = nil} alert("This string does not exist")
      setq sb sslength(ar)
      c:cont()

    defun c:cont ()
      setq sb {sb - 1}
      setq sc ssname(ar sb)
      setq se entget(sc)
      setq sj cdr(assoc(1 se))
      if {sj = sa}
        progn
          setq h cdr(assoc(10 se))
          setq x1 list({car(h) - 50} {cadr(h) - 50})
          setq x2 list({50 + car(h)} {50 + cadr(h)})
          command("ZOOM" "W" x1 x2)
        c:cont()
      if {sb = 0} alert("END OF SELECTIONS")
      setq a {sb + 1}
      setq a rtos(a 2 0)
      setq a
        strcat "\nThere are &lt;" a "&gt; selections Enter CONT to advance to next"
      if {sb = 0} exit()
      princ a
      princ()

# Kalotan puzzle (Scheme)

["Teach Yourself Scheme in Fixnum days"](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html) includes a way to [solve the Kalotan puzzle solution using Scheme](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_sec_14.4.1).  It depends on the "amb" function, described further in the book. It has a large number of "ands" and "xors" which can be expressed using infix,
which is interesting and useful for trying out variations.

## Original Lisp

Here's the original Lisp:

    (define solve-kalotan-puzzle
      (lambda ()
        (let ((parent1 (amb 'm 'f))
              (parent2 (amb 'm 'f))
              (kibi (amb 'm 'f))
              (kibi-self-desc (amb 'm 'f))
              (kibi-lied? (amb #t #f)))
          (assert
           (distinct? (list parent1 parent2)))
          (assert
           (if (eqv? kibi 'm)
               (not kibi-lied?)))
          (assert
           (if kibi-lied?
               (xor
                (and (eqv? kibi-self-desc 'm)
                     (eqv? kibi 'f))
                (and (eqv? kibi-self-desc 'f)
                     (eqv? kibi 'm)))))
          (assert
           (if (not kibi-lied?)
               (xor
                (and (eqv? kibi-self-desc 'm)
                     (eqv? kibi 'm))
                (and (eqv? kibi-self-desc 'f)
                     (eqv? kibi 'f)))))
          (assert
           (if (eqv? parent1 'm)
               (and
                (eqv? kibi-self-desc 'm)
                (xor
                 (and (eqv? kibi 'f)
                      (eqv? kibi-lied? #f))
                 (and (eqv? kibi 'm)
                      (eqv? kibi-lied? #t))))))
          (assert
           (if (eqv? parent1 'f)
               (and
                (eqv? kibi 'f)
                (eqv? kibi-lied? #t))))
          (list parent1 parent2 kibi))))

    (solve-kalotan-puzzle)

## Sweet-expressions

Here's one way to convert this to infix non-default, emphasizing the use
of indentation and function calls using prefixed():

    define solve-kalotan-puzzle
      lambda ()
        let ((parent1 amb('m 'f))
              (parent2 amb('m 'f))
              (kibi amb('m 'f))
              (kibi-self-desc amb('m 'f))
              (kibi-lied? amb(#t #f)))
          assert
           distinct?(list(parent1 parent2))
          assert
           if eqv?(kibi 'm)
               not(kibi-lied?)
          assert
           if kibi-lied?
              xor
                and eqv?(kibi-self-desc 'm)
                    eqv?(kibi 'f)
                and eqv?(kibi-self-desc 'f)
                    eqv?(kibi 'm)
          assert
           if not(kibi-lied?)
              xor
                and eqv?(kibi-self-desc 'm)
                    eqv?(kibi 'm)
                and eqv?(kibi-self-desc 'f)
                    eqv?(kibi 'f)
          assert
           if eqv?(parent1 'm)
              and
                eqv?(kibi-self-desc 'm)
                xor
                 and eqv?(kibi 'f)
                     eqv?(kibi-lied? #f)
                 and eqv?(kibi 'm)
                     eqv?(kibi-lied? #t)
          assert
           if eqv?(parent1 'f)
              and
                eqv?(kibi 'f)
                eqv?(kibi-lied? #t)
          list(parent1 parent2 kibi)

    solve-kalotan-puzzle()

Let's use more infix operations; note that there's no requirement that
we use infix everywhere:

    define solve-kalotan-puzzle
      lambda ()
        let ((parent1 amb('m 'f))
              (parent2 amb('m 'f))
              (kibi amb('m 'f))
              (kibi-self-desc amb('m 'f))
              (kibi-lied? amb(#t #f)))
          assert
           distinct?(list(parent1 parent2))
          assert
           if eqv?(kibi 'm)
               not(kibi-lied?)
          assert
           if kibi-lied?
              xor
                {eqv?(kibi-self-desc 'm) and eqv?(kibi 'f)}
                {eqv?(kibi-self-desc 'f) and eqv?(kibi 'm)}
          assert
           if not(kibi-lied?)
              xor
                {eqv?(kibi-self-desc 'm) and eqv?(kibi 'm)}
                {eqv?(kibi-self-desc 'f) and eqv?(kibi 'f)}
          assert
           if eqv?(parent1 'm)
              and
                eqv?(kibi-self-desc 'm)
                xor
                 {eqv?(kibi 'f) and eqv?(kibi-lied? #f)}
                 {eqv?(kibi 'm) and eqv?(kibi-lied? #t)}
          assert
           if eqv?(parent1 'f)
              {eqv?(kibi 'f) and eqv?(kibi-lied? #t)}
          list(parent1 parent2 kibi)

    solve-kalotan-puzzle()

Now let's add use the "group" command to get rid of some more brackets:

    define solve-kalotan-puzzle
      lambda ()
        let
          group
            parent1         amb('m 'f)
            parent2         amb('m 'f)
            kibi            amb('m 'f)
            kibi-self-desc  amb('m 'f)
            kibi-lied?      amb(#t #f)
          assert
           distinct?(list(parent1 parent2))
          assert
           if eqv?(kibi 'm)
               not(kibi-lied?)
          assert
           if kibi-lied?
              xor
                {eqv?(kibi-self-desc 'm) and eqv?(kibi 'f)}
                {eqv?(kibi-self-desc 'f) and eqv?(kibi 'm)}
          assert
           if not(kibi-lied?)
              xor
                {eqv?(kibi-self-desc 'm) and eqv?(kibi 'm)}
                {eqv?(kibi-self-desc 'f) and eqv?(kibi 'f)}
          assert
           if eqv?(parent1 'm)
              and
                eqv?(kibi-self-desc 'm)
                xor
                 {eqv?(kibi 'f) and eqv?(kibi-lied? #f)}
                 {eqv?(kibi 'm) and eqv?(kibi-lied? #t)}
          assert
           if eqv?(parent1 'f)
              {eqv?(kibi 'f) and eqv?(kibi-lied? #t)}
          list(parent1 parent2 kibi)

    solve-kalotan-puzzle()

And as a test, let's use even more of the infix operators. Frankly, I
think the previous version is easier to follow, though this version is
more similar to how it'd be done in many other languages:

    define solve-kalotan-puzzle
      lambda ()
        let
          group
            parent1         amb('m 'f)
            parent2         amb('m 'f)
            kibi            amb('m 'f)
            kibi-self-desc  amb('m 'f)
            kibi-lied?      amb(#t #f)
          assert
           distinct?(list(parent1 parent2))
          assert
           if eqv?(kibi 'm)
               not(kibi-lied?)
          assert
           if kibi-lied?
              {{eqv?(kibi-self-desc 'm) and eqv?(kibi 'f)}   xor
               {eqv?(kibi-self-desc 'f) and eqv?(kibi 'm)}}
          assert
           if not(kibi-lied?)
              {{eqv?(kibi-self-desc 'm) and eqv?(kibi 'm)}   xor
               {eqv?(kibi-self-desc 'f) and eqv?(kibi 'f)}}
          assert
           if eqv?(parent1 'm)
              {eqv?(kibi-self-desc 'm) and
                {{eqv?(kibi 'f) and eqv?(kibi-lied? #f)}     xor
                 {eqv?(kibi 'm) and eqv?(kibi-lied? #t)}}}
          assert
           if eqv?(parent1 'f)
              {eqv?(kibi 'f) and eqv?(kibi-lied? #t)}
          list(parent1 parent2 kibi)

    solve-kalotan-puzzle()

# SUO-KIF

[Standard Upper Ontology Knowledge Interchange Format (SUO-KIF)](http://sigmakee.cvs.sourceforge.net/*checkout*/sigmakee/sigma/suo-kif.pdf) is a language designed for use in the authoring and interchange of knowledge, e.g., by the [Suggested Upper Merged Ontology (SUMO)](http://www.ontologyportal.org/).

## Original Lisp

Here's the original Lisp of a trivial example, "All farmers like
tractors":

    (forall (?F ?T)
      (=&gt;
        (and
           (instance ?F Farmer)
           (instance ?T Tractor))
        (likes ?F ?T)))

## Sweet-expressions

Without using any infix operators, we can get a nicer result:

    forall (?F ?T)
      =&gt;
        and
           instance(?F Farmer)
           instance(?T Tractor)
        likes ?F ?T

However, both "and" and "=\&gt;" (implies) are traditionally used as infix
operators, rather than prefix operators. Using {...}, we can use them in
that traditional manner:

    forall (?F ?T)
      {{instance(?F Farmer) and instance(?T Tractor)} =&gt; likes(?F ?T)}

or

    forall (?F ?T)
      { {instance(?F Farmer) and instance(?T Tractor)}
        =&gt;
        likes(?F ?T)}

# Scsh (Scheme Shell)

[Scheme shell](http://www.scsh.net/about/what.html) is an implementation of Scheme, plus a high-level process notation for doing shell-script-like tasks (running programs, establishing pipelines, and I/O redirection).

[Scsh's documentation (section 1.4)](http://www.scsh.net/docu/docu.html) notes that scsh is (currently) "primarily designed for the writing of shell scripts - programming. It is not a very comfortable system for interactive command use: the current release lacks job control, command-line editing, a terse, convenient command syntax, and it does not read in an initialisation file analogous to .login or .profile." Most of these limitations can be easily fixed by reusing existing code; e.g., job control code can be copied from other shells, there are trivial libraries (such as readline) that implement command-line editing, and reading an initialization file is trivially done. But the "convenient command syntax" is a serious stumbling block to using scsh as a shell, and that is *not* trivially fixed by simply reusing arbitrary code. It *can* be fixed by using sweet-expressions.

## Original Lisp

In traditional shells, you might write a command like this:

    gunzip &lt; paper.tex.gz | detex | spell | lpr -Ppulp &amp;

In scsh, this could be written as:

    (&amp; (| (gunzip) (detex) (spell) (lpr -Ppulp)) ; background a pipeline 
        (&lt; paper.tex.gz))                        ; with this redirection

## Sweet-expressions

In sweet-expressions, the same expression of scsh can be written as:

    &amp;
      | gunzip() detex() spell() lpr(-Ppulp) ; background a pipeline 
      &lt; paper.tex.gz                         ; with this redirection

or as:

    &amp;
      {gunzip() | detex() | spell() | lpr(-Ppulp)} ; background a pipeline 
      &lt; paper.tex.gz                               ; with this redirection

I think it's better if punctuation-only names are used primarily for infix operators; it helps with consistency. At the least, I'd rename "&amp;" into the synonym "background". Then it becomes:

    background
      {gunzip() | detex() | spell() | lpr(-Ppulp)} ; background a pipeline 
      &lt; paper.tex.gz                               ; with this redirection

# Arc

Paul Graham is developing a new dialect of Lisp named Arc; [Paul Graham's Arc site](http://www.paulgraham.com/arc.html) and [Arclanguage.org](http://arclanguage.org/) have more information.  Semantically, it's a lot like a special combination of Common Lisp and Scheme. For example, like Common Lisp, both "false" and "empty list" are nil (Scheme has separate objects for false and the empty list). But like Scheme, Arc has a single namespace (it's a Lisp-1), as compared with Common Lisp (which is a Lisp-2). Arc has some cool ideas, but Paul Graham seems to be very busy on other things, so [an informal community called 'Anarki'](http://arcfn.com/2008/02/git-and-anarki-arc-repository-brief.html) has formed to evolve Arc. (It uses "=" for assignment, which I think is unfortunate because "=" is often confused with is-equal-to, but anyway...). A good place to start is the [Arc tutorial](http://ycombinator.com/arc/tut.txt).

In Arc, [ ... ] has a special meaning. More specifically, "[ ... \_ ... ]"
is an abbreviation for "(fn (\_) (... \_ ...))". For example:

     arc&gt; (map [+ _ 10] '(1 2 3))
     (11 12 13)

This is why sweet-expressions do
not mandate that [ ... ] be equivalent to (...), necessarily
(early on that was an idea).
A Scheme using sweet-expressions might consider [ ... ]
equivalent to (...), since the normal Scheme R6 does, but it doesn't
necessarily follow that this must be true for all languages.

## Original Lisp

The [Arc tutorial](http://ycombinator.com/arc/tut.txt) has several
really tiny examples; let's pick out a few and put them in one place:

    (+ (+ 1 2) (+ 3 (+ 4 5)))
    (def average (x y) 
           (/ (+ x y) 2))
    (let x 10
      (while (&gt; x 5)
        (= x (- x 1))
        (pr x)))
    (mac repeat (n . body)
      `(for ,(uniq) 1 ,n ,@body))
    (def firstn (n xs)
      (if (and (&gt; n 0) xs)
          (cons (car xs) (firstn (- n 1) (cdr xs)))
          nil))
    (def nthcdr (n xs)    
      (if (&gt; n 0)
          (nthcdr (- n 1) (cdr xs))
          xs))  
    (def tuples (xs (o n 2))
      (if (no xs)
          nil
          (cons (firstn n xs)
                (tuples (nthcdr n xs) n))))

    (def mylen (xs)
          (if (no xs)
              0
              (+ 1 (mylen (cdr xs)))))

    (mac n-of (n expr)
      (w/uniq ga
        `(let ,ga nil
           (repeat ,n (push ,expr ,ga))
           (rev ,ga))))
    (if
      condition1 result1
      condition2 result2
      default-result)

## Sweet-expressions

Here are the sweet-expression equivalents:

    {{1 + 2} + {3 + {4 + 5}}}
    def average (x y) 
           {{x + y} / 2}
    let x 10
      while {x &gt; 5}
        {x = {x - 1}}
        pr x
    mac repeat (n . body)
      `for ,uniq() 1 ,n ,@body
    def firstn (n xs)
      if {{n &gt; 0} and xs}
          cons car(xs) firstn({n - 1} cdr(xs))
          nil
    def nthcdr (n xs)    
      if {n &gt; 0}
          nthcdr {n - 1} cdr(xs)
          xs
    def tuples (xs (o n 2))
      if no(xs)
          nil
          cons firstn(n xs)
               tuples nthcdr(n xs) n

    def mylen (xs)
          if no(xs)
              0
              {1 + mylen(cdr(xs))}

    mac n-of (n expr)
      w/uniq ga
        `let ,ga nil
           repeat ,n push(,expr ,ga)
           rev ,ga
    if(
      condition1 result1
      condition2 result2
      default-result)

Note the macro "n-of"; even though it's short, the original required 4
closing parentheses to complete it, while the sweet-expression required
none.

Indentation processing doesn't work as easily when there's an implied
pairing of list elements that isn't actually in the list structure, like
Arc's "if". See the [backslash operator](#backslash-operator) idea,
below, for more about this.

# RTL (GCC Register Transfer Language)

The GNU Compiler Collection (GCC) has an internal structure for representing programs (at a low level), the [GCC Register Transfer Language (RTL)](http://gcc.gnu.org/onlinedocs/gccint/RTL.html). It's often useful to print out RTL; it's useful for debugging, and other tools use it too (such as [RTL-check](http://rtlcheck.sourceforge.net/) and [Egypt](http://www.gson.org/egypt/egypt.html). [Here's a summary of some RTL semantics.](http://www.cs.berkeley.edu/~billm/cs265/project/rtl.html) RTL has a Lisp-like external representation, which is why it's noted
here.

## Original Lisp

["Compilation of Functional Programming Languages using GCC - Tail Calls" by Andreas Bauer](http://home.in.tum.de/~baueran/thesis/baueran_thesis.pdf), has some RTL examples.

Section 2.3 shows a trivial C program:

      int foo ()
      {
         return bar (5);
      }

Here is an incomplete translation to RTL expressions (before any sibling
call optimization):

     (call_insn 19 9 20 (nil) (call_placeholder 16 10 0 0
         (call_insn 17 16 18 (nil)
         (set (reg:SI 0 eax)
                  (call (mem:QI (symbol_ref:SI ("bar")) [0 S1 A8])
                          (const_int 4 [0x4]))) -1 (nil)
              (expr_list:REG_EH_REGION (const_int 0 [0x0])
                   (nil))
              (nil))) -1 (nil)
         (nil)
         (nil))

     (insn 20 19 21 (nil) (set (reg:SI 58)
              (reg:SI 59)) -1 (nil)
         (nil))

     (jump_insn 21 20 22 (nil) (set (pc)
              (label_ref 25)) -1 (nil)
         (nil))

     (barrier 22 21 23)

     (note 23 22 27 NOTE_INSN_FUNCTION_END)

     (insn 27 23 28 (nil) (clobber (reg/i:SI 0 eax)) -1 (nil)
         (nil))

     (insn 28 27 25 (nil) (clobber (reg:SI 58)) -1 (nil)
         (nil))

     (code_label 25 28 26 6 "" [0 uses])

     (insn 26 25 29 (nil) (set (reg/i:SI 0 eax)
             (reg:SI 58)) -1 (nil)
         (nil))

     (insn 29 26 0 (nil) (use (reg/i:SI 0 eax)) -1 (nil)
         (nil))

## Sweet-expressions

Below is a sweet-expression equivalent. One question: Should lists here be represented as x(...) or (x ...)? They are equivalent; it's merely a matter of what is clearer. The first parameter is a special marker, so it's reasonable to represent them as x(...); besides, it helps to show off sweet-expressions. I won't do that with strings; a list beginning with a string will be shown as ("x"). RTL isn't really typical Lisp, but has its own syntactic extensions. I'll show RTL bracketed expressions [...] exactly as they would be in RTL (leaving them as-is). So here's one approach to representing RTL:

     call_insn 19 9 20 nil()
       call_placeholder 16 10 0 0
         call_insn 17 16 18 nil()
          set reg:SI(0 eax)
            call(mem:QI(symbol_ref:SI(("bar")) [0 S1 A8]) const_int(4 [0x4]))
          -1
          nil()
          expr_list:REG_EH_REGION const_int(0 [0x0]) nil()
          nil()
       -1
       nil()
       nil()
       nil()

     insn 20 19 21 nil() set(reg:SI(58) reg:SI(59)) -1 nil() nil()

     jump_insn 21 20 22 nil() (set pc() (label_ref 25)) -1 nil() nil()

     barrier 22 21 23

     note 23 22 27 NOTE_INSN_FUNCTION_END

     insn 27 23 28 nil() clobber(reg/i:SI(0 eax)) -1 nil() nil()

     insn 28 27 25 nil() clobber(reg:SI(58)) -1 nil() nil()

     code_label 25 28 26 6 "" [0 uses]

     insn 26 25 29 nil() set(reg/i:SI(0 eax) reg:SI(58)) -1 nil() nil()

     insn 29 26 0 nil() use(reg/i:SI(0 eax)) -1 nil() nil()

# MELT (MiddleEndLispTranslator)


[MELT (MiddleEndLispTranslator)](http://gcc.gnu.org/wiki/MiddleEndLispTranslator) is a "high-level Lisp-like language designed to fit very closely in the [GNU Compile Collection (GCC)] internal representations, thru an automated translation of MELT code into GCC specific C code, compiled by a C compiler (usually some GCC) and then loaded as plugins. This enables easier development of high-level static analysis and transformation, working on GCC middle end representation (GIMPLE tuple)." If you're interested in the general topic of gcc plug-ins, see ["Plugging into GCC" (lwn.net)](http://lwn.net/Articles/301135/).

The MELT work is partly funded by the French Ministery of Economy, thru ITEA within the [GlobalGCC (GGCC) project](http://www.ggcc.info/). The lead, Basile Starynkevitch, has contributed his GCC contributions using a copyright transfer signed by CEA to FSF. It was presented at the GCC Summit 2007. A special MELT branch was created on February 19, 2008.  

Semantically, MELT is a "Lisp1" Lisp dialect (so it's more like Scheme than like Common Lisp regarding names and bindings). You can define primitives, which get translated to C, compiled, and linked into the compiler during the compilation process. The (unboxed) integer addition is pre-defined in MELT as:

      (defprimitive +i (:long a b) :long "((" a ") + (" b "))")

Where "the first :long occurrence describes the types of the formal arguments a and b, the second occurrence describes the result. There is an minimal object system (single-inheritance hierarchy, rooted at CLASS\_ROOT... Tail-recursion is not handled (looping should use the forever keyword, and loops are can be exited)".

## Original Lisp

Here is an example from the main MELT page. This is "a sample MELT
function repeat-times [that applies] a function f to an argument x some
specified n times. f and x are values, n is an unboxed long argument.":

    (defun repeat-times (f x :long n) ; n is an unboxed formal argument of type long
      (forever reploop                ; infinite loop called reploop
         (if (&lt;=i n 0)                ; test if the unboxed n is negative
             (exit reploop))          ; exit the loop if yes
         (f x)                        ; call f
         (setq n (-i n 1))))          ; decrement n

## Sweet-expressions

Here is a sweet-expression equivalent:

    defun repeat-times (f x :long n) ; n is an unboxed formal argument of type long
      forever reploop                ; infinite loop called reploop
        if {n &lt;=i 0}                 ; test if the unboxed n is negative
          exit reploop               ; exit the loop if yes
        f x                          ; call f
        setq n -i(n 1)               ; decrement n


# Satisfiability Modulo Theories Library (SMT-LIB) 1.2

The [Satisfiability Modulo Theories Library (SMT-LIB)](http://www.smt-lib.org/) The major goal of the SMT-LIB initiative is to "establish a library of benchmarks for Satisfiability Modulo Theories, that is, satisfiability of formulas with respect to background theories for which specialized decision procedures exist...  [these] have applications in formal verification, compiler optimization, and scheduling, among others... the initiative first aims at establishing a common standard for the specification of benchmarks and of background theories."

The SMT-LIB syntax is "attribute-based and Lisp-like". It permits a syntactic category "user value", used for user-defined annotations or attributes, that start with an open brace "{" and end with a closed brace "}".  

## Original Lisp

The QF\_RDL benchmarks's "check" subset includes this small benchmark as
bignum\_rd1.smt. I've re-indented the last lines slightly so that it
fits inside the usual 80 columns:

    (benchmark bignum
      :source { SMT-COMP'06 Organizers }
      :notes "This benchmark is designed to check if the DP supports bignumbers."
      :status sat
        :difficulty { 0 }
        :category { check }
      :logic QF_RDL
      :extrafuns ((x1 Real))
        :extrafuns ((x2 Real))
        :extrafuns ((x3 Real))
        :extrafuns ((x4 Real))
      :formula
      (and (&lt;= (- x1 x2) (/ 1 1000000000000000000000000000000000))
           (&lt;= (- x2 x3) (/ 1 2000000000000000000000000000000011))
           (&lt;= (- x3 x4) (~ (/ 1 1000000000000000000000000000000000)))
           (&lt;= (- x4 x1) (~ (/ 1 2000000000000000000000000000000012)))))

The indentation above is misleading, since "difficulty" isn't a part of
":status". So let's first use a reasonable indentation, trying to make
it as readable as possible without changing Lisp syntax. Also, "user
values" are written with {...}, which isn't standard Lisp; let's rewrite
them as strings ("...."), since they have essentially the same role
(they are uninterpreted data):

    (benchmark bignum
      :source "SMT-COMP'06 Organizers"
      :notes "This benchmark is designed to check if the DP supports bignumbers."
      :status sat
      :difficulty "0"
      :category "check"
      :logic QF_RDL
      :extrafuns ((x1 Real))
      :extrafuns ((x2 Real))
      :extrafuns ((x3 Real))
      :extrafuns ((x4 Real))
      :formula
      (and (&lt;= (- x1 x2) (/ 1 1000000000000000000000000000000000))
           (&lt;= (- x2 x3) (/ 1 2000000000000000000000000000000011))
           (&lt;= (- x3 x4) (~ (/ 1 1000000000000000000000000000000000)))
           (&lt;= (- x4 x1) (~ (/ 1 2000000000000000000000000000000012)))))

## Sweet-expressions

One problem with this data is that there is an implied syntax that isn't actually embedded in the Lisp formatting. Namely, an atom beginning with ":" is followed by a parameter in this syntax. A pretty-printer that wasn't specially rigged with this convention would not show this format in a pretty way, and a normal sweet-expression reader wouldn't know about this either. This means that the "obvious" sweet-expression notation isn't right. E.G., this fragment:

    benchmark bignum
      :source "SMT-COMP'06 Organizers"
      :notes "This benchmark is designed to check if the DP supports bignumbers."
      :status sat

Would be interpreted as: (benchmark bignum (:source "SMT-COMP'06
Organizers") (:notes "This benchmark is designed to check if the DP
supports bignumbers.") (:status sat))

We *could* use this kind of formatting, but I find it ugly and
counter-intuitive; it also wastes lots of space:

    benchmark bignum
      :source
      "SMT-COMP'06 Organizers"
      :notes
      "This benchmark is designed to check if the DP supports bignumbers."
      :status
      sat

But this isn't really a problem. One way to make this "pretty" would be to use "(...)" at an outer level - such as with function-calling syntax - which disables indentation processing. Then, we can choose any indentation we like, just as we can in traditional Lisp syntax. We can still use {...} for infix operators. In our examples, I won't use "and" as an infix operator, because the sub-expressions are so long, but I will use infix for "\&lt;=", "-", and "/". I'll also use "\~" (unary minus) as a one-parameter function.

    benchmark( bignum
      :source "SMT-COMP'06 Organizers"
      :notes "This benchmark is designed to check if the DP supports bignumbers."
      :status sat
      :difficulty "0"
      :category "check"
      :logic QF_RDL
      :extrafuns ((x1 Real))
      :extrafuns ((x2 Real))
      :extrafuns ((x3 Real))
      :extrafuns ((x4 Real))
      :formula
        and  { {x1 - x2} &lt;= {1 / 1000000000000000000000000000000000} }
             { {x2 - x3} &lt;= {1 / 2000000000000000000000000000000011} }
             { {x3 - x4} &lt;= ~({1 / 1000000000000000000000000000000000}) }
             { {x4 - x1} &lt;= ~({1 / 2000000000000000000000000000000012})} )

The above looks reasonable enough. But if you were able to change the
required expressions, you could make the structure of the parameters
much clearer by connecting the parameter names and their values inside
lists, instead of merely implying it through a naming convention. This
would be an annoyance in traditional Lisp, because it'd require
additional parentheses for each parameter, but this is a non-problem for
sweet-expressions. If this was done, you could write it this way:

    benchmark bignum
      :source "SMT-COMP'06 Organizers"
      :notes "This benchmark is designed to check if the DP supports bignumbers."
      :status sat
      :difficulty "0"
      :category "check"
      :logic QF_RDL
      :extrafuns ((x1 Real))
      :extrafuns ((x2 Real))
      :extrafuns ((x3 Real))
      :extrafuns ((x4 Real))
      :formula
        and  { {x1 - x2} &lt;= {1 / 1000000000000000000000000000000000} }
             { {x2 - x3} &lt;= {1 / 2000000000000000000000000000000011} }
             { {x3 - x4} &lt;= ~({1 / 1000000000000000000000000000000000}) }
             { {x4 - x1} &lt;= ~({1 / 2000000000000000000000000000000012})}

Backslash operator

One challenge with this format is that there's an implied pairing of
list elements that doesn't actually result in list pairing... so the
indentation processing doesn't help. A similar problem occurs with Arc's
"if".

I posted a [splicing proposal on the mailing list](http://www.mail-archive.com/readable-discuss@lists.sourceforge.net/msg00124.html), using the backslash character. When doing indentation processing, if the first character of a form is "\\" followed by whitespace:

1.  If it's the last character of the line (other than 0 or more
    spaces/tabs), then the newline is considered a space, and the next
    line's indentation is irrelevant. This continues the line. (Note
    that comments cannot follow, because that would be confusing.)
2.  If it's between items on a line, it's interpreted as a line break to
    the same indentation level.
3.  Otherwise, if it's at the beginning of a line (after 0+
    spaces/tabs), it's ignored - but the first non-whitespace
    character's indentation level is used.

So Arc's:

    (if
      (condition1) (dothis1)
      (condition2) (dothis2)
      default-result)

Could be written these ways:

    ; When condition1, dothis1, etc. are lengthy, you can do this:
    if
      condition1()
      \ dothis1()
      condition2()
      \ dothis2()
      default-result

    ; When condition1, dothis1, etc. are short, you can do this:
    if
      condition1() \ dothis1()
      condition2() \ dothis2()
      default-result

So we can now write the SMT-LIB examples this way:

    benchmark bignum
      :source \ "SMT-COMP'06 Organizers"
      :notes \ "This benchmark is designed to check if the DP supports bignumbers."
      :status \ sat
      :difficulty \ "0"
      :category \ "check"
      :logic \ QF_RDL
      :extrafuns \ ((x1 Real))
      :extrafuns \ ((x2 Real))
      :extrafuns \ ((x3 Real))
      :extrafuns \ ((x4 Real))
      :formula
      \ and  { {x1 - x2} &lt;= {1 / 1000000000000000000000000000000000} }
             { {x2 - x3} &lt;= {1 / 2000000000000000000000000000000011} }
             { {x3 - x4} &lt;= ~({1 / 1000000000000000000000000000000000}) }
             { {x4 - x1} &lt;= ~({1 / 2000000000000000000000000000000012})} )

    ; or alternatively:
    benchmark bignum \
      :source "SMT-COMP'06 Organizers" \
      :notes "This benchmark is designed to check if the DP supports bignumbers." \
      :status sat \
      :difficulty "0" \
      :category "check" \
      :logic QF_RDL \
      :extrafuns ((x1 Real)) \
      :extrafuns ((x2 Real)) \
      :extrafuns ((x3 Real)) \
      :extrafuns ((x4 Real)) \
      :formula \
      and  { {x1 - x2} &lt;= {1 / 1000000000000000000000000000000000} }
             { {x2 - x3} &lt;= {1 / 2000000000000000000000000000000011} }
             { {x3 - x4} &lt;= ~({1 / 1000000000000000000000000000000000}) }
             { {x4 - x1} &lt;= ~({1 / 2000000000000000000000000000000012})} )

    ; If you reorder the ":formula" entry you can see why just the "\ at the end"
    ; doesn't completely solve the problem.  You can't really do that here:
    benchmark bignum
      :logic \ QF_RDL
      :formula
      \ and  { {x1 - x2} &lt;= {1 / 1000000000000000000000000000000000} }
             { {x2 - x3} &lt;= {1 / 2000000000000000000000000000000011} }
             { {x3 - x4} &lt;= ~({1 / 1000000000000000000000000000000000}) }
             { {x4 - x1} &lt;= ~({1 / 2000000000000000000000000000000012})} )
      :source \ "SMT-COMP'06 Organizers"
      :notes \ "This benchmark is designed to check if the DP supports bignumbers."
      :status \ sat
      :difficulty \ "0"
      :category \ "check"
      :extrafuns \ ((x1 Real))
      :extrafuns \ ((x2 Real))
      :extrafuns \ ((x3 Real))
      :extrafuns \ ((x4 Real))

This has a nice and very convenient side-effect; you can create
single-line sequences when they make sense. E.G.:

    define showstats()
      write a \ write b \ write c

    ; is the same as:
    define showstats()
      write a
      write b
      write c

    ; Which is the same as:
    (define (showstats)
      (write a) (write b) (write c))

Thus, "\\ " as an in-line separator is a lot like ";" as a statement
terminator or separator in ALGOL-descended languages (like C and
Pascal). That's useful when you have highly related sets of short
statements.

# Satisfiability Modulo Theories Library (SMT-LIB) 2.0

The [Satisfiability Modulo Theories Library
(SMT-LIB)](http://www.smt-lib.org/) was discussed above; version 2.0 had
a number of big changes.

## Original Lisp

Here's an example from section 3.6 of the SMT-LIB 2.0 specification
dated August 28, 2010:

    (forall ((x (List Int)) (y (List Int)))
       (= (append x y)
          (ite (= x (as nil (List Int)))
                 y
                 (let ((h (head x)) (t (tail x)))
                    (insert h (append t y))))))

This is an example of ite(x,y,z), an "if-then-else" that returns y if x
is true, otherwise it returns z (this is not included in traditional
first order logic, a major weakness in the traditional language). The
"ite" operator was added in version 2.0 of SMT-LIB.

## Sweet-expressions

Here is one way to rewrite this in a readable format. In this example
I've chosen to use "group" for the lists of variables in forall and let,
but given short lists like these you could also use traditional list
notation:

    forall
       group
         x List(Int)
         y List(Int)
       = append(x y)
         ite {x = as(nil List(Int))}
           y
           let
             group
               h head(x)
               t tail(x)
             insert h append(t y)

# NewLisp

[NewLisp](http://www.newlisp.org/) is "Lisp-like, general purpose scripting language", with an implementation released under the GPL.

## Original Lisp

Here is a sample from their [Code patterns](http://www.newlisp.org/CodePatterns.html) document:

        (dolist (file-name (3 (main-args))) 
            (set 'file (open file-name "read"))
            (println "file ---&gt; " file-name)
            (while (read-line file)
                (if (find (main-args 2) (current-line) 0)
                (write-line)))
            (close file))

This is the original formatting. It's a little misleading; the
write-line is actually *inside* the "if", not a sibling of it. Yet
another example of how formatting can mislead a reader, when humans use
it but computers don't.

Here's another example from its documentation on apply:

    (define (gcd_ a b)
        (let (r (% b a))
            (if (= r 0) a (gcd_ r a))))

    (define-macro (my-gcd)
        (apply gcd_ (args) 2))

## Sweet-expressions

Same thing for the first one, with sweet-expressions:

        dolist (file-name (3 (main-args))) 
            set 'file open(file-name "read")
            println "file ---&gt; " file-name
            while read-line(file)
                if find(main-args(2) current-line() 0)
                  write-line()
            close file

Here's a readable version of the gcd and apply example::

    define gcd_(a b)
        let r %(b a)
            if {r = 0} a gcd_(r a)

    define-macro my-gcd()
        apply gcd_ (args) 2

# Clojure

[Clojure](http://clojure.org/) is a Lisp dialect running on top of a Java JVM. [differences with other Lisps](http://clojure.org/lisps) explains some of the differences.

Clojure is inspired by Lisp, but it also has several syntactic additions. As discussed in its [section on the reader](http://clojure.org/reader), its syntax includes support for:

-   Lists. Lists are zero or more forms enclosed in parentheses: (a b c)
-   Vectors. Vectors are zero or more forms enclosed in square brackets:
    [1 2 3]
-   Maps. Maps are zero or more key/value pairs enclosed in braces: {:a
    1 :b 2} Commas are considered whitespace, and can be used to
    organize the pairs: {:a 1, :b 2} Keys and values can be any forms.
-   Sets. Sets are zero or more forms enclosed in braces preceded by \#:
    \#{:a :b :c}

## Original Lisp

The example of Clojure [agents](http://clojure.org/agents) gives this example, which is "an implementation of the send-a-message-around-a-ring test. A chain of n agents is created, then a sequence of m actions are dispatched to the head of the chain and relayed through it":

    (defn setup [n next]
      (if (zero? n)
         next
       (recur (dec n) (agent {:next next}))))
    (defn relay [x m]
      (when (:next x)
        (send (:next x) relay m))
      (when (and (zero? m) (:report-queue x))
        (. (:report-queue x) (put m)))
      x)
    (defn run [m n]
     (let [q (new java.util.concurrent.SynchronousQueue)
           tl (agent {:report-queue q})
           hd (setup (dec n) tl)]
       (doseq m (reverse (range m))
          (send hd relay m))
       (. q (take))))
    ; Time 1 million message sends:
    (time (run 1000 1000))

[Tim Bray loves Clojure, but not its
syntax](http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses),
and gives this example:

    (apply merge-with +
      (pmap count-lines
        (partition-all *batch-size*
          (line-seq (reader filename)))))

## Sweet-expressions

Sweet-expressions work well with Clojure, but a few notes should be made first. Clojure uses [...] to notate vectors; to me, this suggests that the rule for sweet-expressions should be 'interpret unprefixed [...] as whatever the base language does' (which would help Clojure and Arc, among others). For sweet-expressions, I'll assume that [...] disable indentation processing inside, just as (...) and {...} do. In Scheme, unprefixed [...] should be considered the same as (...), since that's the meaning for Scheme R6. So, Arc and Clojure have refined the sweet-expression rules for [...].

It's easy to imagine an extension of sweet-expressions that has additional syntactic support for special types, just as Clojure's built-in syntax does. But for the moment, I'll just use map(...) to transform a list into a map, instead of having more syntactic support.  Clojure uses curly braces for maps, but we'll continue to use curly braces for infix lists.

Finally, one odd thing is that in Closure, "." is a symbol, and an important one you can include at the beginning of a list. That is weird; in many Lisps, "(. hi)" is the same as "hi" because of the way list reading is typically implemented, and I presumed that when I spec'ed sweet-expressions. For the moment, I'll write the symbol "." as "\\.".

Given all that, here's one way to notate this in sweet-expressions:

    defn setup [n next]
      if zero?(n)
        next
        recur dec(n) agent(map(:next next))
    defn relay [x m]
      when :next(x)
        send :next(x) relay m
      when {zero?(m) and :report-queue(x)}
        \. :report-queue(x) put(m)
      x
    defn run [m n]
     let [q new(java.util.concurrent.SynchronousQueue)
          tl agent(map(:report-queue q))
          hd setup(dec(n) tl)]
       doseq m reverse(range(m)) send(hd relay m)
       \. q take()
    ; Time 1 million message sends:
    time(run(1000 1000))

And here is Bray's, rewritten:

    apply merge-with +
      pmap count-lines
        partition-all *batch-size*
          line-seq reader(filename)

# ISLisp

[ISLisp](http://en.wikipedia.org/wiki/ISLisp) (also capitalized as ISLISP) is a programming language standardized by the ISO. Its intent was define a small core language based on only the features shared between existing LISPs, particularly Common Lisp, EuLisp, Le Lisp, and Scheme. It provides basic functionality and object-orientation, and was intended to "give priority to industrial needs over academic needs". It has separate function and value namespaces (hence it is a Lisp-2). It is standardized as ISO/IEC 13816:1997 and later revised as ISO/IEC 13816:2007 - Information technology - Programming languages, their environments and system software interfaces - Programming language ISLISP. ISLisp is rarely used; Common Lisp and Scheme are *far* more common.

## Original Lisp

Sadly, ISO still hasn't arrived at the 21st century, so it still doesn't release standards to the web as a matter of course. [A draft of the ISLisp spec draft 23](http://ryujin.kuis.kyoto-u.ac.jp/~yuasa/lispwg/is23.pdf) is available, and it gives these examples for "and":

    (and (= 2 2) (&gt; 2 1)) ; t
    (and (= 2 2) (&lt; 2 1)) ; nil
    (and (eql a a) (not (&gt; 1 2))) ; t
    (let ((x a)) (and x (setq x b))) ; b
    (let ((time 10))
      (if (and (&lt; time 24) (&gt; time 12))
          (- time 12) time)) ; 10

## Sweet-expressions

Here's a version using sweet-expressions:

    {{2 = 2} and {2 &gt; 1}} ; t
    {{2 = 2} and {2 &lt; 1}} ; nil
    {{a eql a} and not({1 &gt; 2})} ; t
    let ((x a)) {x and setq(x b)} ; b
    let ((time 10))
      if {{time &lt; 24} and {time &gt; 12}}
         {time - 12} time ; 10

# COMFY-65

["The COMFY 6502 Compiler" by Henry G.  Baker](http://home.pipeline.com/~hbaker1/sigplannotices/sigcol04.pdf) is an an implementation of the [COMFY language](http://home.pipeline.com/~hbaker1/sigplannotices/sigcol03.pdf), which is intended to be a replacement for assembly languages when programming on \`bare' machines. COMFY-65 is specifically targetd for the MOS 6502 8-bit processor, which, as the brains of the Apple II and the Atari personal computers, was one of the most popular microprocessors of all time. Its author describes COMFY-65 as follows:

 &gt; "COMFY-65 is a \`medium level' language for programming on the MOS
 &gt; Technology 6502 microcomputer [MOSTech76]. COMFY-65 is \`higher
 &gt; level' than assembly language because 1) the language is structured-
 &gt; while-do, if-then-else, and other constructs are used instead of
 &gt; goto's; and 2) complete subroutine calling conventions are provided,
 &gt; including formal parameters. On the other hand, COMFY-65 is \`lower
 &gt; level' than usual compiler languages because there is no attempt to
 &gt; shield the user from the primitive structure of the 6502 and its
 &gt; shortcomings. Since COMFY-65 ismeant to be a replacement for assembly
 &gt; language, it attempts to provide for the maximumflexibility; in
 &gt; particular, almost every sequence of instructions which can be
 &gt; generated by an assembler can also be generated by COMFY. This
 &gt; flexibility is due to the fact that COMFY provides all the
 &gt; non-branching operations of the 6502 as primitives. Why choose COMFY
 &gt; over assembly language? COMFY provides most of the features of
 &gt; assembly language with few of the drawbacks...

COMFY is really nothing like traditional LISP, so a little explanation is needed here. It's compiling to the 6502 8-bit processor, which is very limited, and it has interesting semantics:

 &gt; "Executable instructions in COMFY come in three flavors: tests,
 &gt; actions, and jumps. Tests have two possible outcomes: succeed and
 &gt; fail and therefore have two possible continuations-i.e., streams of
 &gt; instructions to execute next. If the test succeeds, the win
 &gt; continuation is executed; if the test fails, the lose continuation is
 &gt; executed. On the 6502, the tests are carry, zero, negative, and
 &gt; overflow, which succeed if the corresponding flags are on and fail if
 &gt; they are off. Actions are simply executed and always succeed;
 &gt; therefore the win continuation always follows and the lose
 &gt; continuation is always ignored. On the 6502, the actions are all the
 &gt; instructions which do not divert the program counter. Jumps are
 &gt; executed and ignore both their continuations. On the 6502 the only
 &gt; two jump instructions are Return (from subroutine) and Resume (after
 &gt; interrupt)."

COMFY compiles branches extremely efficiently, and it eliminates the
need to create lots of names just to give branches to go to. It also
includes a very sophisticated macro capability (as you'd expect for a
language using Lisp constructs).

Some key functions:

-   **(not e)**\
     not is a unary operator which has a COMFY expression as an
    argument. not has the effect of interchanging the win and lose
    continuations for its argument expression. In other words, the win
    continuation of (not e) becomes the lose continuation of e and the
    lose continuation of (not e) becomes the win continuation for e.
-   **(seq e1 e2 ... en)**\
     seq takes a sequence of COMFY expressions and tries to execute them
    in sequence. If they all succeed, then the whole expression
    succeeds. If any one fails, the sequence is immediately terminated
    and the lose continuation for the whole expression is executed.
-   **(if e1 e2 e3)**\
     if takes as arguments three expressions-e1, e2, and e3. COMFY first
    executes e1 and if it succeeds, e2 is executed. The success or
    failure of e2 then determines the success or failure of the whole if
    expression. If, on the other hand, e1 fails, then e3 is executed and
    its success or failure determines that for the whole if expression.
    In other words, if uses the success or failure of e1 to choose which
    of e2 or e3 to execute next; whichever one is not chosen is not
    executed at all. Notice that the failure of e1 cannot cause the
    failure of the whole expression.
-   **(alt e1 e2 ... en)**\
     alt is the \`dual' of seq. alt takes a sequence of COMFY
    expressions and tries to execute them in sequence. If they all fail,
    then the entire alt expression fails. If any one succeeds, the
    sequence is immediately terminated (i.e., the rest of the sequence
    is not executed) and the entire alt expression succeeds. In usual
    usage, the ei are tests; thus, (alt e1 e2) succeeds if and only if
    either e1 or e2 succeeds (we don't even find out if both would have
    succeeded because only the first is executed in this case).
-   **(compile e win lose)**\
     ;;; compile expression e with success continuation "win" and ;;;
    failure continuation "lose". ;;; "win" an "lose" are both addresses
    of stuff higher in memory.
-   **(fori from to body)**\
     Using the 6502 X register ("i" in this language), loop from "from"
    to "to" executing "body".
-   **(l i location)**\
     Load from location+i (6502 X register).
-   **(st i location)**\
     Store into location+i (6502 X register).
-   **(NUMBER action)**\
     Perform action NUMBER of times; this is a repeat operator.

The symbols are set using setq, which alternates between a name and the
values given the name.

## Original Lisp

This is an example of COMFY-65 programming, to compute a Universal
Product Code (\`UPC') parity check digit. "This example is not intended
as a tutorial on computing this function, nor as an example of
particularly good code, but only to show the flavor of COMFY
programming."

    ;;; Universal Product Code Wand parity check.
    (setq
     upctable (compile '(seq 13 25 19 61 35 49 47 59 55 11) 0 0)
     code 10           ; upc code buffer
     digit (+ code 12) ; digit buffer
     temp (+ digit 12) ; temporary location.
     upcwand
     (compile
      '(alt
         (seq (fori (\# 6) (\# 12) ; complement right 6 upc digits.
                    (l i code)
                    (lxor \# 127)
                    (st i code))
              (fori (\# 0) (\# 12) ; map codes using upctable.
                    (l i code)
                    (not
                      (forj (\# 0) (\# 10)
                                   (c j upctable)
                                  -=\?))           ; fail if equal.
                    (stj i digit)) ; store index of upctable.
              decimal                ; set decimal arithmetic mode.
              (l \# 0)               ; clear ac.
              (fori (\# 0) (\# 12)   ; add up the even digits.
                 (+ i digit)         ; loop control clears carry!
                 i+1)                ; only every other one.
              (st temp)              ; save partial sum.
              c=0                    ; clear the carry.
              (2 (+ temp))           ; multiply by 3.
              (fori (\# 1) (\# 12)   ; add up the odd digits.
                    (+ i digit)      ; loop cotrol clears carry.
                    i+1)             ; only every other one.
              (lxor \# 15)           ; select low decimal digit.
              =0\?                   ; fails if non-zero.
              return)
         (seq break ; signal failure.
              return))
      0 0))

## Sweet-expressions

    ;;; Universal Product Code Wand parity check.
    setq
     upctable compile('seq(13 25 19 61 35 49 47 59 55 11) 0 0)
     code 10           ; upc code buffer
     digit {code + 12} ; digit buffer
     temp {digit + 12} ; temporary location.
     upcwand
     compile
      'alt
         seq
           fori \#(6) \#(12) ; complement right 6 upc digits.
                l i code
                lxor \# 127
                st i code
           fori \#(0) \#(12) ; map codes using upctable.
                l i code
                not
                   forj \#(0) \#(10)
                        c j upctable
                        -=\?           ; fail if equal.
                stj i digit       ; store index of upctable.
           decimal                ; set decimal arithmetic mode.
           l \# 0                 ; clear ac.
           fori \#(0) \#(12)      ; add up the even digits.
              {i + digit}         ; loop control clears carry!
              i+1                 ; only every other one.
           st temp                ; save partial sum.
           c=0                    ; clear the carry.
           2 (+ temp))            ; multiply by 3.
           fori \#(1) \#(12)      ; add up the odd digits.
                 {i + digit}      ; loop cotrol clears carry.
                 i+1              ; only every other one.
           lxor \# 15             ; select low decimal digit.
           =0\?                   ; fails if non-zero.
           return
         seq break return            ; signal failure
       0
       0

# Sawfish

[Sawfish is a window manager that uses a Lisp-based scripting language called librep](http://sawfish.wikia.com/wiki/Programming). The [Building a Better Window Manager](http://twistedmatrix.com/~teratorn/better_wm/better_wm.html) tutorial describes how to write programs in its Lisp-based language.

## Original Lisp

Here are some examples:

    (bind-keys global-keymap
       "H-e" `(jump-or-exec "GVIM"
           ,(lambda ()
              (system
               "gvim &amp;"))
           ,(lambda (wind)
              (display-window wind))))

    (define-match-window-setter 'keymap-trans
      (lambda (w prop value)
        (declare (unused prop))
        (let ((keymap (or (window-get w 'keymap)
                          (window-put w 'keymap (copy-sequence window-keymap)))))
          (mapcar
           (lambda (pair)         ; pair of from and to keys
             (bind-keys
              keymap (car pair)
              (lambda () (interactive)
                (synthesize-event (lookup-event (cadr pair)) (input-focus)))))
           value))))

## Sweet-expressions

Here is the "infix is not default" version. Note that there is a space
after the "\`" and ",":

    bind-keys global-keymap "H-e"
     ` jump-or-exec "GVIM"
           , lambda ()     system("gvim &amp;")
           , lambda (wind) display-window(wind)

    define-match-window-setter 'keymap-trans
      lambda (w prop value)
        declare (unused prop)
        let
          group
            keymap {window-get(w 'keymap) or
                    window-put(w 'keymap copy-sequence(window-keymap))}
          mapcar
            lambda (pair)         ; pair of from and to keys
              bind-keys keymap car(pair)
                lambda ()
                  interactive()
                  synthesize-event lookup-event(cadr(pair)) input-focus()
            value

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">David A. Wheeler</dc:creator><pubDate>Sun, 29 Jul 2012 12:54:29 -0000</pubDate><guid>https://sourceforge.net736496b80c2c13376d35d82ff9e5d3cb7e95e088</guid></item></channel></rss>