Alternatives November 15th, 2014
Patrick Stein

When someone is writing code, there is often more than one way they could accomplish a given task. After they have explored a number of options, they usually remove all but the final version from the code. If they were being extraordinarily careful, there might be separate commits in the version control system which contained the alternatives. If they were being extraordinarily forward-looking, they may have left a comment in the code about what alternatives they tried and why they settled on the one that they did.

Even if they did both of those things, there might be reasons you would want to try out the alternatives again to see if the original assumptions still hold. You could futz around with version control and try to bring the old versions of that function into the current code base. Or, you could try to rewrite and re-debug the alternatives yourself. But, wouldn’t it be nice if the alternatives were still all at your fingertips, at least while the code is still in active development?

The ALTERNATIVES macro provides one way of accomplishing this. One can specify tagged alternatives. The macro will expand into the body of one of the alternative clauses. Each alternative clause is of the form (TAG &BODY BODY) where the TAG is either a SYMBOL or STRING.

If any clause is preceded by a symbol or string ***, the macro expands to the BODY of the first such clause. Otherwise, if the TAG of any clause is the symbol or string ***, FINAL, or BLESSED, then the macro expands to the body of the first such clause. Otherwise, the macro expands to the body of the last alternative clause.

In the following example, the macro expands into the body of the final alternative clause:

(defun sum-of-squares (n)
  (alternatives
    (i-wanted-to-do-this
     (loop :for i :to n :summing (* i i)))

    (my-first-attempt-was-something-like-this
     (do ((i 0 (1+ i))
          (sum 0 (+ sum (* i i))))
         ((> i n) sum)))

    (but-i-could-not-do-that-because
     "Some people find a do-loop too hard to read.")

    (now-i-know-better-and-can-do-this
     (/ (* n (1+ n) (1+ (+ n n)) 6)))))

If we wanted to quickly try out the MY-FIRST-ATTEMPT-... clause, we could precede it with a ***:

(defun sum-of-squares (n)
  (alternatives
    (i-wanted-to-do-this
     (loop :for i :to n :summing (* i i)))

    ***
    (my-first-attempt-was-something-like-this
     (do ((i 0 (1+ i))
          (sum 0 (+ sum (* i i))))
         ((> i n) sum)))

    (but-i-could-not-do-that-because
     "Some people find a do-loop too hard to read.")

    (now-i-know-better-and-can-do-this
     (/ (* n (1+ n) (1+ (+ n n)) 6)))))

If one uses ALTERNATIVES* and provides a name for the alternatives, then one can check the #'DOCUMENTATION for the alternative at a later time to see which alternative was last macroexpanded.

(defun sum-of-squares (n)
  (alternatives* sum-of-squares-implementations
    (i-wanted-to-do-this
     (loop :for i :to n :summing (* i i)))

    ***
    (my-first-attempt-was-something-like-this
     "Using a DO-loop"
     (do ((i 0 (1+ i))
          (sum 0 (+ sum (* i i))))
         ((> i n) sum)))

    (but-i-could-not-do-that-because
     "Some people find a do-loop too hard to read.")

    (now-i-know-better-and-can-do-this
     (/ (* n (1+ n) (1+ (+ n n)) 6)))))

(documentation 'sum-of-squares-implementations
               'alt:alternatives)
   => "MY-FIRST-ATTEMPT-WAS-SOMETHING-LIKE-THIS
      Using a DO-loop"

Alternatives (v0.2.20141117) Released November 17th, 2014
Patrick Stein

I have uploaded a new version of my Alternatives library. In addition to the ALTERNATIVES macro, there is an ALTERNATIVES* macro which allows one to specify a name for the set of choices. Then, one can check the DOCUMENTATION to see which alternative was last macroexpanded. (defun random-letter ()   (alt:alternatives* random-letter-algorithm     *** […]

Alternatives (v0.1.20141115) Released November 16th, 2014
Patrick Stein

I have now released the code that I mentioned in my previous post Code That Tells You Why which lets one keep multiple implementations around in code and switch between them manually without much trouble. A link to the source code is here: nklein.com/software/alternatives/.

Code That Tells You Why November 13th, 2014
Patrick Stein

A 2006 article by Jeff Atwood titled Code Tells You How, Comments Tell You Why showed up on reddit/r/programming today. It makes a good point. However, it got me thinking that for cases like the binary-search example in the article, it might be nice to see all of the alternatives in the code and easily […]

Updates In Email

Email:

l