<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-6508797467947601724</id><updated>2009-12-02T20:10:01.126-05:00</updated><title type='text'>smuglispweeny</title><subtitle type='html'>Grossly unfair, unreliable, biased, and pretty much delusional rants and ravings on Lisp from a simple working application programmer.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default?start-index=26&amp;max-results=25'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-8431785601885283345</id><published>2009-10-31T13:11:00.004-04:00</published><updated>2009-10-31T14:03:19.019-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clojure Scala Groovy Coherent Reaction Trellis Cells Guy Steele James Strachan Johnathan Edwards'/><title type='text'>The King is Dead!? Long live... Scala? Clojure?!</title><content type='html'>&lt;div&gt;Whoa, why wasn't I told Java is &lt;a href="http://www.jroller.com/scolebourne/entry/no_more_java_7"&gt;closing its doors&lt;/a&gt;? I guess I have been out of touch, word seems to be everywhere. I had to go &lt;a href="http://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html"&gt;here&lt;/a&gt; (blog of the guy who created &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;) to find out. James is whooping it up over &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; as Java's successor. Yes, the guy who invented Groovy prefers Scala. Quite a bit:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;I can honestly say if someone had shown me the Programming in Scala book by by Martin Odersky, Lex Spoon &amp;amp; Bill Venners back in 2003 I'd probably have never created Groovy. -- James Strachan&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Damn. So he pretty much invented Groovy by mistake? Did not know about the two-year old Scala? No one mentioned it to him? Groovy got admitted to the standard in the meantime?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, &lt;a href="http://coherence-lang.org/Onward09.pdf"&gt;Johnathan Edwards&lt;/a&gt; reinvented Python &lt;a href="http://peak.telecommunity.com/DevCenter/Trellis"&gt;Trellis&lt;/a&gt; (ergo &lt;a href="http://smuglispweeny.blogspot.com/2008/02/cells-manifesto.html"&gt;Cells&lt;/a&gt;) without knowing it,  and I did not know about &lt;a href="http://www.faqs.org/faqs/garnet-faq/"&gt;Garnet&lt;/a&gt;'s KR or constraints -- but Groovy got adopted as official Java! You think Scala might have come up over coffee. Anyway...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Steele said Java brought the world half-way to Lisp. I do not think Lisp means what he thinks it means. Proof might be how hard it is for folks to climb out of the pit of javathink. If Java had been a stepping stone to Lisp it would have made the next step easier, not harder. But Java still cannot do closures. Please. And a quick look at closures in Scala has me thinking, omigod, they call &lt;i&gt;that&lt;/i&gt; closures? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; starts to look like a Good Move. I see it mentioned in writings on the death throes of Java and that is a big marketing win. The superwhacky thing here is that both Scala and Clojure are syntactically discontinuous from Java. Folks always thought successors had to have syntax similar to the succeeded though &lt;a href="http://www.opendylan.org/"&gt;Dylan&lt;/a&gt; should have served as cautionary counter-evidence. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No, it is not the syntax. The necessary bridging element seems to be....wait for it...the Java runtime! How did that tail end up wagging the language adoption dog? But Clojure gets the nod along with Scala just for sitting atop the JRE! You people scare me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, if Steele were right Clojure would prevail over Scala. Right now googlefight has Scala winning five to one. Maybe Rich Hickey can move 17% of the world 90% of the way to Lisp?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-8431785601885283345?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/8431785601885283345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=8431785601885283345' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/8431785601885283345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/8431785601885283345'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/10/king-is-dead-long-live-scala-clojure.html' title='The King is Dead!? Long live... Scala? Clojure?!'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-7008785515259142802</id><published>2009-08-10T06:01:00.000-04:00</published><updated>2009-08-10T06:02:20.800-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='writing Lisp comedy Socrates Izzard'/><title type='text'>To write, or not to write?</title><content type='html'>&lt;div&gt;&gt;&gt;  By the way, to change the subject a little, who was it who said,&lt;/div&gt;&lt;div&gt;&gt;&gt;  "there are no dead languages, only dead minds"?&lt;/div&gt;&lt;div&gt;&gt; &lt;/div&gt;&lt;div&gt;&gt; Dunno, but to change the subject even more, Socrates objected to writing&lt;/div&gt;&lt;div&gt;&gt; since it deprives an idea of a mind in which it can "live". So yeah.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interesting. "Free writing" is a form that lives within a mind but also create a permanent record and slow the mind down enough to achieve more coherence so the mind can work out hard problems. Comedy writing is necessary to trigger a laugh response because every word matters, but then the words must be delivered as if they were coming live from a mind. Exceptions are improv and semi-improv such as Eddie Izzard, of which Mr. Socrates would approve because they arise within a living mind. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I get a lot of complaints about the writing in this blog because I deliberately write as chaotically as I think. Other times I found I gave a much better talk if I read from something written beforehand precisely because otherwise the living mind is too chaotic to get the talk done in anywhere near the time available. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was just getting ready to videotape an improvised bit to get the good bits to then pull into a fixed, written bit because I am finding good stuff comes out only if the mind is not slowed down as by free writing. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The question is whether Eddie Izzard is lazy, or if Socrates is right on this. Does Izzard do better by capturing his improv and distilling it down to a precise fixed bit, or does he do worse? Or does he just lack the ability to deliver the prepared as if it were unprepared.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We're getting pretty close to talking about programming in Lisp vs NotLisp now. Lisp programming unconstrained by static typing and blessed with a rich library once that library is mastered such that it is all at the programmer's fingertips allows the code to flow freely yet mostly correctly from a live mind even as that mind is forming the solution the code embodies. Diagram that.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-7008785515259142802?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/7008785515259142802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=7008785515259142802' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/7008785515259142802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/7008785515259142802'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/08/to-write-or-not-to-write.html' title='To write, or not to write?'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-7230566389574006646</id><published>2009-06-26T00:47:00.007-04:00</published><updated>2009-06-26T01:25:00.030-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp Erik Naggum quads XML SGML HTML'/><title type='text'>I Feel A Naggum (RIP) Coming On: Quads</title><content type='html'>I sometimes begin c.l.l rants with "I feel a naggum coming on...". What is a naggum? Normally:&lt;div&gt;&lt;blockquote&gt;naggum (n): A rant along one of Erik Naggum(1965-2009)'s themes.&lt;/blockquote&gt;That might be self-referentially hopeless which is fine because that is not what I am talking about, I just thought that would be a clever title. In this case a "naggum" is a nugget of Erikian technology. First, his specification of what he called quads (see below), and my poor implementation (even further below and good luck even figuring out how to test it) .&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;kt&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;#|&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;From: Erik Naggum (erik@naggum.no)&lt;/div&gt;&lt;div&gt;Subject: Re: XML-&gt;sexpr ideas&lt;/div&gt;&lt;div&gt;Newsgroups: comp.lang.lisp&lt;/div&gt;&lt;div&gt;Date: 2004-01-19 04:24:43 PST&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Kenny Tilton&lt;/div&gt;&lt;div&gt;| Of course it is easy enough for me to come up with a sexpr format off&lt;/div&gt;&lt;div&gt;| the top of my head, but I seem to recall someone (Erik? Tim? Other?)&lt;/div&gt;&lt;div&gt;| saying they had done some work on a formal approach to an alternative&lt;/div&gt;&lt;div&gt;| to XML/HTML/whatever.&lt;/div&gt;&lt;div&gt;| &lt;/div&gt;&lt;div&gt;| True that? If so, I am all ears.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Really?  You are?  Maybe I didn't survive 2003 and this is some Hell&lt;/div&gt;&lt;div&gt;  where people have to do eternal penance, and now I get to do SGML all&lt;/div&gt;&lt;div&gt;  over again.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Much processing of SGML-like data appears to be stream-like and will&lt;/div&gt;&lt;div&gt;  therefore appear to be equivalent to an in-order traversal of a tree,&lt;/div&gt;&lt;div&gt;  which can therefore be represented with cons cells while the traverser&lt;/div&gt;&lt;div&gt;  maintains its own backward links elsewhere, but this is misleading.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  The amount of work and memory required to maintain the proper backward&lt;/div&gt;&lt;div&gt;  links and to make the right decisions is found in real applications to&lt;/div&gt;&lt;div&gt;  balloon and to cause random hacks; the query languages reflect this&lt;/div&gt;&lt;div&gt;  complexity.  Ease of access to the parent element is crucial to the&lt;/div&gt;&lt;div&gt;  decision-making process, so if one wants to use a simple list to keep&lt;/div&gt;&lt;div&gt;  track of this, the most natural thing is to create a list of the&lt;/div&gt;&lt;div&gt;  element type, the parent, and the contents, such that each element has&lt;/div&gt;&lt;div&gt;  the form (type parent . contents), but this has the annoying property&lt;/div&gt;&lt;div&gt;  that moving from a particular element to the next can only be done by&lt;/div&gt;&lt;div&gt;  remembering the position of the current element in a list, just as one&lt;/div&gt;&lt;div&gt;  cannot move to the next element in a list unless you keep the cons&lt;/div&gt;&lt;div&gt;  cell around.  However, the whole point of this exercise is to be able&lt;/div&gt;&lt;div&gt;  to keep only one pointer around.  So the contents of an element must&lt;/div&gt;&lt;div&gt;  have the form (type parent contents . tail) if it has element contents&lt;/div&gt;&lt;div&gt;  or simply a list of objects, or just the object if simple enough.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Example: &lt;foo&gt;123&lt;/foo&gt; would thus be represented by (foo nil "123"),&lt;/div&gt;&lt;div&gt;  &lt;foo&gt;123&lt;/foo&gt;&lt;bar&gt;456&lt;/bar&gt; by (foo nil "123" bar nil "456"), and&lt;/div&gt;&lt;div&gt;  &lt;zot&gt;&lt;foo&gt;123&lt;/foo&gt;&lt;bar&gt;456&lt;/bar&gt;&lt;/zot&gt; by #1=(zot nil (foo #1# "123"&lt;/div&gt;&lt;div&gt;  bar #1# "456")).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Navigation inside this kind of structure is easy: When the contents in&lt;/div&gt;&lt;div&gt;  CADDR is exhausted, the CDDDR is the next element, or if NIL, we have&lt;/div&gt;&lt;div&gt;  exhausted the contents of the parent and move up to the CADR and look&lt;/div&gt;&lt;div&gt;  for its next element, etc.  All the important edges of the containers&lt;/div&gt;&lt;div&gt;  that make up the *ML document are easily detectible and the operations&lt;/div&gt;&lt;div&gt;  that are usually found at the edges are normally tied to the element&lt;/div&gt;&lt;div&gt;  type (or as modified by its parents), are easily computable.  However,&lt;/div&gt;&lt;div&gt;  using a list for this is cumbersome, so I cooked up the «quad».  The&lt;/div&gt;&lt;div&gt;  «quad» is devoid of any intrinsic meaning because it is intended to be&lt;/div&gt;&lt;div&gt;  a general data structure, so I looked for the best meaningless names&lt;/div&gt;&lt;div&gt;  for the slots/accessors, and decided on QAR, QBR, QCR, and QDR.  The&lt;/div&gt;&lt;div&gt;  quad points to the element type (like the operator in a sexpr) in the&lt;/div&gt;&lt;div&gt;  QAR, the parent (or back) quad in the QBR, the contents of the element&lt;/div&gt;&lt;div&gt;  in the QCR, and the usual pointer to the next quad in the QDR.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Since the intent with this model is to «load» SGML/XML/SALT documents&lt;/div&gt;&lt;div&gt;  into memory, one important issue is how to represent long stretches of&lt;/div&gt;&lt;div&gt;  character content or binary content.  The quad can easily be used to&lt;/div&gt;&lt;div&gt;  represent a (sequence of) entity fragments, with the source in QAR,&lt;/div&gt;&lt;div&gt;  the start position in QBR, and the end position in QCR, thereby using&lt;/div&gt;&lt;div&gt;  a minimum of memory for the contents.  Since very large documents are&lt;/div&gt;&lt;div&gt;  intended to be loaded into memory, this property is central to the&lt;/div&gt;&lt;div&gt;  ability to search only selected elements for their contents -- most&lt;/div&gt;&lt;div&gt;  searching processors today parse the entire entity structure and do&lt;/div&gt;&lt;div&gt;  very little to maintain the parsed element structure.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Speaking of memory, one simple and efficient way to implement the quad&lt;/div&gt;&lt;div&gt;  on systems that lack the ability to add native types without overhead,&lt;/div&gt;&lt;div&gt;  is to use a two-dimensional array with a second dimension of 4 and let&lt;/div&gt;&lt;div&gt;  quad pointers be integers, which is friendly to garbage collection and&lt;/div&gt;&lt;div&gt;  is unambiguous when the quad is used in the way explained above.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  Maybe I'll talk about SALT some other day.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;-- &lt;/div&gt;&lt;div&gt;Erik Naggum | Oslo, Norway&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Act from reason, and failure makes you rethink and study harder.&lt;/div&gt;&lt;div&gt;Act from faith, and failure makes you blame someone and push harder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;|#&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(in-package :ukt)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;;;;(defstruct (juad jar jbr jcr jdr)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;div&gt;(defun qar (q) (car q))&lt;/div&gt;&lt;div&gt;(defun (setf qar) (v q) (setf (car q) v))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun qbr (q) (cadr q))&lt;/div&gt;&lt;div&gt;(defun (setf qbr) (v q) (setf (cadr q) v))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun qcr (q) (caddr q))&lt;/div&gt;&lt;div&gt;(defun (setf qcr) (v q) (setf (caddr q) v))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun qdr (q) (cdddr q))&lt;/div&gt;&lt;div&gt;(defun (setf qdr) (v q) (setf (cdddr q) v))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun sub-quads (q)&lt;/div&gt;&lt;div&gt;  (loop for childq on (qcr q) by #'qdr&lt;/div&gt;&lt;div&gt;      collecting childq))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun sub-quads-do (q fn)&lt;/div&gt;&lt;div&gt;  (loop for childq on (qcr q) by #'qdr&lt;/div&gt;&lt;div&gt;      do (funcall fn childq)))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun quad-traverse (q fn &amp;amp;optional (depth 0))&lt;/div&gt;&lt;div&gt;  (funcall fn q depth)&lt;/div&gt;&lt;div&gt;  (sub-quads-do q&lt;/div&gt;&lt;div&gt;    (lambda (subq)&lt;/div&gt;&lt;div&gt;      (quad-traverse subq fn (1+ depth)))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun quad (operator parent contents next)&lt;/div&gt;&lt;div&gt;  (list operator parent contents next))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun quad* (operator parent contents next)&lt;/div&gt;&lt;div&gt;  (list operator parent contents next))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun qups (q)&lt;/div&gt;&lt;div&gt;  (loop for up = (qbr q) then (qbr up)&lt;/div&gt;&lt;div&gt;        unless up do (loop-finish)&lt;/div&gt;&lt;div&gt;        collecting up))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun quad-tree (q)&lt;/div&gt;&lt;div&gt;  (list* (qar q)&lt;/div&gt;&lt;div&gt;    (loop for childq on (qcr q) by #'qdr&lt;/div&gt;&lt;div&gt;        while childq&lt;/div&gt;&lt;div&gt;          collecting (quad-tree childq))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun tree-quad (tree &amp;amp;optional parent)&lt;/div&gt;&lt;div&gt;  (let* ((q (quad (car tree) parent nil nil))&lt;/div&gt;&lt;div&gt;         (kids (loop for k in (cdr tree)&lt;/div&gt;&lt;div&gt;                     collecting (tree-quad k q))))&lt;/div&gt;&lt;div&gt;    (loop for (k n) on kids&lt;/div&gt;&lt;div&gt;          do (setf (qdr k) n))&lt;/div&gt;&lt;div&gt;    (setf (qcr q) (car kids))&lt;/div&gt;&lt;div&gt;    q))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;#+test&lt;/div&gt;&lt;div&gt;(test-qt)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun test-qt ()&lt;/div&gt;&lt;div&gt;  (print (quad-tree #1='(zot nil (foo #1# ("123" "abc")&lt;/div&gt;&lt;div&gt;                                . #2=(bar #1# (ding #2# "456"&lt;/div&gt;&lt;div&gt;                                                dong #2# "789")))))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(print #1='(zot nil (foo #1# ("123" "abc")&lt;/div&gt;&lt;div&gt;                          . #2=(bar #1# (ding #2# "456"&lt;/div&gt;&lt;div&gt;                                          dong #2# "789")))))&lt;/div&gt;&lt;div&gt;#+xxxx&lt;/div&gt;&lt;div&gt;(test-tq)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun test-tq ()&lt;/div&gt;&lt;div&gt;  (let ((*print-circle* t)&lt;/div&gt;&lt;div&gt;        (tree '(zot (foo ("123")) (bar (ding) (dong)))))&lt;/div&gt;&lt;div&gt;    (assert (equal tree (quad-tree (tree-quad tree))))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun testq ()&lt;/div&gt;&lt;div&gt;  (let ((*print-circle* t))&lt;/div&gt;&lt;div&gt;    (let ((q #1='(zot nil (foo #1# ("123" "abc")&lt;/div&gt;&lt;div&gt;                            . #2=(bar #1# (ding #2# "456"&lt;/div&gt;&lt;div&gt;                                            dong #2# "789"))))))&lt;/div&gt;&lt;div&gt;      (print '(traverse showing each type and data preceded by its depth))&lt;/div&gt;&lt;div&gt;      &lt;/div&gt;&lt;div&gt;      (quad-traverse q (lambda (q depth)&lt;/div&gt;&lt;div&gt;                         (print (list depth (qar q)(qcr q)))))&lt;/div&gt;&lt;div&gt;      (print `(listify same ,(quad-tree q))))&lt;/div&gt;&lt;div&gt;    (let ((q #2='(zot nil (ding #2# "456"&lt;/div&gt;&lt;div&gt;                                  dong #2# "789"))))&lt;/div&gt;&lt;div&gt;      (print '(traverse showing each "car" and itd parentage preceded by its depth))&lt;/div&gt;&lt;div&gt;      (print '(of data (zot (ding (dong)))))&lt;/div&gt;&lt;div&gt;      (quad-traverse q (lambda (q depth)&lt;/div&gt;&lt;div&gt;                         (print (list depth (qar q)&lt;/div&gt;&lt;div&gt;                                  (mapcar 'qar (qups q)))))))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;;;;(defun tree-quad (tree)&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(defun testq2 ()&lt;/div&gt;&lt;div&gt;  (let ((*print-circle* t))&lt;/div&gt;&lt;div&gt;    (let ((q #2='(zot nil (ding #2# "456"&lt;/div&gt;&lt;div&gt;                            dong #2# "789"))))&lt;/div&gt;&lt;div&gt;      (print '(traverse showing each "car" and itd parentage preceded by its depth))&lt;/div&gt;&lt;div&gt;      (print '(of data (zot (ding (dong)))))&lt;/div&gt;&lt;div&gt;      (quad-traverse q (lambda (q depth)&lt;/div&gt;&lt;div&gt;                         (print (list depth (qar q)&lt;/div&gt;&lt;div&gt;                                  (mapcar 'qar (qups q)))))))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;              &lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-7230566389574006646?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/7230566389574006646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=7230566389574006646' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/7230566389574006646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/7230566389574006646'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/06/i-feel-naggum-rip-coming-on-quads.html' title='I Feel A Naggum (RIP) Coming On: Quads'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-5586079771938783666</id><published>2009-06-22T01:16:00.002-04:00</published><updated>2009-06-22T01:20:50.414-04:00</updated><title type='text'>American &amp; Iran: Separated at Birth?</title><content type='html'>Am I the only one grooving specifically on the fact that Iranians are telling their authority figures to go f*ck themselves? Here is the country we thought we hated but it turns out they are as kick-ass as us when it comes to political freedom, and we utterly respect them for their strength. Omigod, Americans and Iranians are going to get along great!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-5586079771938783666?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/5586079771938783666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=5586079771938783666' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5586079771938783666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5586079771938783666'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/06/american-iran-separated-at-birth.html' title='American &amp; Iran: Separated at Birth?'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-7865367019335228012</id><published>2009-05-11T00:34:00.006-04:00</published><updated>2009-05-11T01:45:23.710-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math eductaion'/><title type='text'>How to teach math</title><content type='html'>&lt;div&gt;&gt; On Sat, 09 May 2009 15:30:52 -0400, Kenneth Tilton wrote:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;Well, i was not really trolling, I was forking the thread to make fun of  the New Math that tried to get the numeral/number distinction across to five year olds.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Someone responded:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;You find it better to start with medieval concepts working gradually on to the mathematics of XIX century, while explaining each next year what was wrong with the things they learnt a year ago?&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I said all that? Ma's gonna be right proud. But... &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Funny you should ask. Yes, I suspect the path society took to get to what it knows now about math is the path an individual neuronal mass should follow. ie, kids should encounter zero and roman numerals and place value and algebraic variables in the same order society developed those ideas.  The history of math is your math curriculum guide.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The New Math erred by selecting the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;logical &lt;/span&gt;organization of mathematical concepts as its curricular pole star. Next came Constructivism, which wanted kids to reinvent math. From scratch. Cool idea, but too slow.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instead, let the history of mathematics dictate the &lt;span class="Apple-style-span" style="font-style: italic; "&gt;order &lt;/span&gt;in which things are &lt;span class="Apple-style-span" style="font-style: italic;"&gt;directly taught&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt;. &lt;/span&gt;&lt;span class="Apple-style-span" style=""&gt;Maybe &lt;/span&gt;go further and teach math as history with less emphasis on computation. Math often advanced when needed to solve real problems. Maybe we can shut up the little devils asking why they need to learn this stuff.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As for explaining all along the way what was wrong with the ideas taught the day before, hey, ever read a book on programming? They typically develop a chunk of code iteratively, presenting ever more improved variations on a primitive original. Come to think of it, ever develop some software? Same thing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's the deal: most folks do not even &lt;span class="Apple-style-span" style="font-style: italic;"&gt;know &lt;/span&gt;zero had to be invented. One understands zero better if one has done without it and then the teacher invents it for you. Something like that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-7865367019335228012?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/7865367019335228012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=7865367019335228012' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/7865367019335228012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/7865367019335228012'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/05/how-to-teach-math.html' title='How to teach math'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-1451611794856733046</id><published>2009-02-04T11:10:00.002-05:00</published><updated>2009-02-13T11:31:42.535-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cells ECLM OOPS Fred Brooks No Silver Bullet dataflow FRP functional reactive programming'/><title type='text'>Cells: The Secret Transcript</title><content type='html'>&lt;span class="Apple-style-span"  style="font-family:'Times New Roman';"&gt;&lt;div style="border-width: 0px; margin: 0px; padding: 3px; width: auto; font-family: Georgia,serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 100%; line-height: normal; font-size-adjust: none; font-stretch: normal; text-align: left;"&gt;&lt;div&gt;The Boss asked me to give the group fifteen minutes on Cells because I have been talking about it for a while as a future better mousetrap for us and then suddenly last week threatened actually to apply it to qooxdoo and the front end.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I forwarded to everyone a link to a reasonably complete yet relatively brief write-up which tells you &lt;a href="http://smuglispweeny.blogspot.com/2008/02/cells-manifesto.html"&gt;everything you need to know about Cells&lt;/a&gt;. I know that if I were in your shoes I would not have read it so I presume no one has. But I would like to determine how many folks I will be boring to tears if I review said document, so I will first cut to the chase and ask if anyone has any questions based on what they read.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;........silence..............&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK. Cells is at once the simplest and hardest thing in the world for programmers to understand. Simple because the idea is just to have slot values of objects work like cells in a spreadsheet, and everyone knows how spreadsheets work. What is hard is understanding that one can program computers this way. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I only have fifteen minutes so: Yes, you can. Program inputs are assigned by good old imperative code to input cells the same way a user types values into a spreadsheet when they are doing what-if analysis or recording, say, actual monthly expenditure into a budget spreadsheet. Intermediate, derived, and aggregate cells compute new values based on those new inputs from predefined rules just as user changes to a spreadsheet propagate to other spreadsheet cells. Observers on cells let the emergent working model manifest its decisions with more good old fashioned imperative code, usually by simply updating the screen or playing a sound or controlling some external device over a serial port or updating a database.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Boom, we're done. Why is it so great? What part of the superiority of functional and declarative paradigms should I explain first? As I outlined in the material you did not read, a lot of things have to happen when a program receives an input. The programmer coding the event handler has to look at the event and decide all the things that have to happen in light of that event, and any things that follow from those first things. Not only must they reliably see to all those things, but they must do them in the right order. The analogy to a real spreadsheet is quite strong, if you imagine hand-implementing a spreadsheet with old-fashioned pencil and paper.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So the first things Cells does is eliminate a lot of work and thus a lot of bugs. Because the work eliminated is tedious, Cells also makes programming a lot more fun. But there is more.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The declarative paradigm means I always know why a slot has a certain value, because all the logic appears in one place, in the rule assigned to that slot. Without Cells any number of lines of code may have assigned a value to a particular slot and a unified deriving rule certainly cannot be divined even if one were to track them all down.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is more. Most people hate OO because it never quite panned out. Objects turned out not to be reusable. One of the nicest features of Cells is that two different instances can have different rules for the same slot. That makes objects reusable. Yayyyyyyy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I did not use Cells in the Kleaner because that was more of a straight calculation running from start to finish. I like to decribe the role for Cells being in any situation where one has an unpredictable stream of data and one is keeping a model with a sufficiently large amount of internal state consistent with that stream of inputs. Two examples being a GUI and a RoboCup client. The Kleaner worked by compiling statistics from a fixed store and then translating exactly once dirty data into corrected data. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Where Cells would have been useful would have been in implementing Phil's ideas about an ongoing stream of data leading to rediscernment of things previously discerned. Cell rules would take new raw inputs and propagate them over to tables of probabilities which would then reach out to existing cleaned data and possibly redecide from the original raw state a new cleaned state. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So no, I do not use Cells for everything, but in this case it was only because the full functionality had not been addressed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A fun note is that I have in the past applied Cells to a database, specifically the old AllegroStore persistent CLOS database. This works two ways. One is that a user can be looking at a screen and as the underlying data changes the screen changes. That may sound like old news but with Cells one doe not have to write any code to make it happen. One just says "this view shows this users overdue books" and when the date changes the overdue status on every book gets updated and a new book appears in the list on the screen if someone happens to be looking, simply by someone having written code to list overdue books on the screen as if it were an unchanging value.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The other thing that happens is hinted at above. Things like overdue books and amount of fines owed and paid can be calculated from scratch by reading a users entire history of checkouts and returns, but sometimes it is useful to record such derived values in the database and update them incrementally as books are checked out and returned. We can have code in programs do it and hope they run at the right time, or we can have the code in the database (as datapoints mediated by Cells) and be sure they run and run immediately. We get timeliness of data, efficiency, and we still get consistency even as we introduce redundancy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I left something out. That is bad because the thing I left out is the thing I am planning to do with Cells on my own anyway and then apply to the FE. Cells makes it dead easy to drive a separate framework from Lisp. In my note I mentioned tcl/Tk and Gtk. These are two killer C GUI frameworks with their own homebrewed little object models. We want to program in Lisp, and we want our models driven by Cells for all the reasons above. No problem. We build a model out of instances of CLOS classes mapping isomorphically onto Tk or GTk classes and use Cell observers to pipe information (thru an FFI or even literally a pipe) to the C library or runtime to drive there the creation and animation of C instances. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Works great, and one amazing programmer Peter Hildebrandt pulled off a trifecta in which he had Cells driving and driven by both GTk and a C physics engine, name forgotten.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For a while I kinda marvelled at how Cells could be so useful for such disparate activities, and do so in the same application, the two activities being building an application model and having some other programming framework dance to that model's tune. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I figured it out in time for ECLM 2008, not they were able to understand me. I opened by telling them that Cells was the single most powerful library they could use, because Cells is about change and nothing is more fundamental than change.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Programming is hard because like someone doing a spreadsheet on paper we programmers end up with the burden of propagating change thoughout our models. It is tedious work, it must be done reliably, and there is a lot of it as internal program state multiplies, exponentially a lot. This exponential growth in interdependence of program state is what led Brooks to declare that a silver bullet was not only unlikely to be found but that it would be impossible to find; he felt the complexity was ineluctable because as states multiply there is nothing that can be done to avoid the explosion of interdependence.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I wrote to Dr Brooks recently and asked him if he had ever looked at dataflow. He said he was familiar with the concept, but no. Oops.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-1451611794856733046?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/1451611794856733046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=1451611794856733046' title='29 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1451611794856733046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1451611794856733046'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/02/cells-secret-transcript.html' title='Cells: The Secret Transcript'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>29</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-94725993430236426</id><published>2009-01-25T15:12:00.001-05:00</published><updated>2009-01-25T21:23:54.217-05:00</updated><title type='text'>Tinkering</title><content type='html'>&lt;span class="Apple-style-span"  style=" ;font-family:'Times New Roman';"&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;&lt;div&gt;Spring cannot come soon enough for Bobi, who is losing it badly these days on comp.lang.lisp:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Slobodan Blazeski wrote:&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;Dear board members&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm baseball player for a several time periods (days,&lt;/div&gt;&lt;div&gt;moths ,years,decades) I've noticed that interest in baseball is&lt;/div&gt;&lt;div&gt;dwindling, and baseball is becoming less and less relevant and will&lt;/div&gt;&lt;div&gt;soon become extinct with only baby boomers supporting it, and even&lt;/div&gt;&lt;div&gt;those are either going to die or switch to golf. In order to save our&lt;/div&gt;&lt;div&gt;favorite sport I propose we make drastic changes and adapt more modern&lt;/div&gt;&lt;div&gt;things like:&lt;/div&gt;&lt;div&gt;a. Playing on the beach sand wearing swimwear like in beach&lt;/div&gt;&lt;div&gt;volleyball, very modern sport. Check Thiobe for growth rate&lt;/div&gt;&lt;div&gt;b. Replacing bats  with  hockey sticks. Note that hockey is popular in&lt;/div&gt;&lt;div&gt;many world countries and we should think international&lt;/div&gt;&lt;div&gt;c. Including  24-Second Shot Clock like in NBA that will make our&lt;/div&gt;&lt;div&gt;sport more lively and fast paced&lt;/div&gt;&lt;div&gt;d. Square playing fields should be replaced with the more common&lt;/div&gt;&lt;div&gt;rectangular one like found in many popular sports : soccer, football,&lt;/div&gt;&lt;div&gt;tennis etc&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Including this will make baseball prosper.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;very truly yours&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Concerned Semi-Ex Baseball Player&lt;/div&gt;&lt;div&gt;Avenue of delusional weirdos Number 23&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bobi may not be as crazy as he thinks he is. Baseball suffered extreme popularity anxiety in the late Sixties and did indeed tinker with the game. Thinking more offense would attract more fans the pitching mound was lowered so pitchers did not get extra energy into the ball from falling into a pitch. The American League adopted the designated hitter to eliminate the 11% nil pitcher from batting lineups (eliminating as well an awful lot of interesting strategy). They avoided the salary caps of the NBA and instituted free agency (well, no, they lost a lawsuit) which allowed bigger markets like NYC, Boston, and LA to buy better teams, and bigger markets are always good for ratings. Minnesota fans will follow the Dodgers, Los Angeles fans will not follow the Twins. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The changes went beyond the playing field. Ballparks added mascots and a disgusting cacophony of party music between innings so loud you can barely talk, and limited alcohol sales late in games to make the experience more family-friendly cuz you know how the losing fans get in their third hour of drinking.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now baseball is hugely popular again so tinkering with grand institutions can work. Right?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wrong. In the end, baseball is just a great game: multi-dimensional and deep. Quality tells, and which quality one emphasizes matters. Hockey and basketball have non-stop action and are fading in popularity, while baseball and football like great music have a variety, a rhythm, a balancing of quiet against intense. Baseball has the pitch, football has the snap. All scales from small to large from inning or drive to the game or season always and invariably end up condensed into one point of explosive tension when the pitcher releases or the center snaps the ball.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Intense without quiet merely exhausts. A boxing match with two brawlers spurning defense landing bombs back and forth brings the crowd to its feet but those who love the sport do so for its nickname, The Sweet Science. They still talk about one genius of defense who won a round without throwing a punch. Between evenly matched fighters one solid punch (forget the knockout, the cartoon haymakers of Rocky &lt;span class="Apple-style-span" style="font-style: italic; "&gt;n&lt;/span&gt;) brings the crowd screaming to its feet, the culmination of rounds of careful, tentative, mutual exploration. A single knockdown becomes a cause for pandemonium and one punch knockouts almost do not happen between the best and when they do they are talked about for a long time. I digress.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tinkering. Basketball has all the action in the world and now faces its own popularity crisis. Racism is one factor, another is probably the salary cap that has San Antonio in the championship series instead of New York. Another problem: poor defense, and a twenty-point lead does not mean anything. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But worst of all is the lack of dimensionality. There just is not that much to these games to argue about over the water cooler. Baseball? Boston still talks about the time Grady Little [thx, Xach. ed.] left Pedro Martinez in one inning too long against the Yankees in game seven of the ALCS. Come on, he had thrown a hundred pitches! Everyone knows Pedro is useless after a hundred pitches! You just never hear anything like that about hockey or basketball, which both boil down to great athletes pretty much just playing run and gun.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Baseball never needed tinkering, though tinker they did. The fundamental quality of the game first ensured its survival throught the hard times when fans strayed for the quick fix of non-stop hockey and basketball action. Now the richness, subtlety, and sophistication of the game has some stadiums selling out most games of the year of a very long season.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Moral for Lisp left as an exercise.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-94725993430236426?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/94725993430236426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=94725993430236426' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/94725993430236426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/94725993430236426'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/01/spring-cannot-come-soon-enough-for-bobi.html' title='Tinkering'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-4960005538372806404</id><published>2009-01-20T13:38:00.005-05:00</published><updated>2009-01-27T07:50:45.369-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tilton&apos;s Law software engineering'/><title type='text'>Tilton's Law: Solve the Failure First</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;The team was at my throat. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Just use the new search!," they bellowed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The mission critical, project saving, do or die demo to upper management was eight hours away and we had not even begun the always dicey process of moving the software from the development system to one within reach of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Demomeister&lt;/span&gt;, and I was trying to find out why the old search was so slow.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Soon," I replied.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We had a new search I was told was a screamer but I continued poking around putting in metrics trying to figure out why the old search was so slow. Had we not been a virtual remote telecommuting team I would not have lived to tell this tale but we were so they had no choice and I reassured then that "soon" meant ten minutes and they shut up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Why was I still trying to understand the perplexing sloth of the old when a whole new replacement module was available and working fine and pretty much the demo on which all our jobs and a cool project depended was coming on like freight train?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Tilton's&lt;/span&gt; Law: Solve the failure first.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Early on we learned the other side of that coin: &lt;a href="http://smuglispweeny.blogspot.com/2008/03/tiltons-law-solve-first-problem.html"&gt;Solve the first problem&lt;/a&gt;. The commonality is...no, let's do the war story first, war stories are more fun than preaching.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Back we go a quarter of a century to my first contract with a client who would become my sole recurring client for the next decade. I was being hired to take over maintenance of an application whose author had been one of the first to die of AIDS. I was reminded of the whole business by a conversation with another developer recently about the nature of working on OPC. Other People's Code. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my IT career I have worked always at the poles of software development, either writing new code or performing massive overhauls of OPC, never that relaxed zone between in which one simply maintains and extends in small ways a long-lived system. The second pole (OPC overhauls) always seemed to me an intimate one-way encounter with some anonymous predecessor, an encounter usually involving me roundly and steadily cursing them out. You can imagine then how eerie it was working on this system from this predecessor who was not so anonymous this time, especially when I learned that the poor guy was in bad shape during one stint but needed the money and so worked on the code I was now working on even as his fate rose up to meet him (this well before the days of the cocktails of today that make ones fate less certain). This guy I do not remember cursing out so much.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But I digress. Our lesson today is how to piss off your coworkers by insisting on solving a failure first, by which I mean even if you do decide to punt on X make sure you understand how X failed. I am not alone in this. In 2001 the movie when the crew determines that the unit Hal said was no good was fine he says fine let's put it back in and let it fail. Sure, he was really looking for a way to kill the crew but we learned in 2010 that Hal was just a computer system and I think the bit about putting the supposedly OK/not OK system back in to see if it failed was one of Hal's systems working nominally in accordance with Tilton's Law: we need to understand broken things.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[Aside: a good example of &lt;a href="http://sitereservation.com/xooglers/index.cfm?entryid=24"&gt;the Hell of Not Solving Failure&lt;/a&gt;.]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And now at long last, my unsolved failure. My predecessor's, actually. The application was a securities database with a nightly feed of data applied to the cumulative DB by a batch program. This is late 80s, primitive stuff. A security could have three IDs because three groups were tracking securities and each had their own ID system. We had tens of thousands of records in our VAX/VMS RMS file, and a separate RMS key for each of the three possible IDs. So far so yawn. Here comes the fun part.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Two of the IDs were populated all the time. The other one was populated five percent of the time. Big deal, right? Right, very big deal, the poster boy for Solve the Failure First. What happened was this quesswork reconstruction:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My predecessor Paul (I picked "Paul" because it easier to type than predecessor) had a problem. His program ran an initial test load of a hundred securities in a few seconds. Fine. Everything looked good. So then he ran it against a full daily feed, which would include news of every security traded that day so it would be -- OK, I confess I completely forget even the order of magnitude, let's say tens of thousands and declare up front that that is idiotic and I am sorry, but here is what happened: the damn thing ran forever. There probably was no immediate specific great mystery because Paul probably had the program printing something (a count, the last ID recorded, something) right to his VT-100 console as it went and he could see that the program had started out zooming along but then gradually got slower and slower until just adding one security to the database (and this is just good old ISAM, mind you) took... wait for it... twenty seconds. Oh. My. God. What on earth is happening?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Paul got a clue. Every once in a while two records were written out bang-bang, as fast as at the start. Dig dig dig puzzle puzzle...ah, there it is. Any record for which we have all three IDs is written out in nothing flat. Any record (you know, the ninety-five percent) with just two will (by the end of the run) be written out three per minute, 180/hour, or 1000/fuggedaboutit.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Paul realized what was going on. The ISAM file system had no problem storing data with duplicate keys, which was a good thing because Paul was storing a whole lot of data with one key 95% the same: spaces. Poor ISAM it seemed was chugging thru all the duplicates looking for the last one after which it would record the latest duplicate. And apparently it took twenty seconds back then to walk (effectively) the entire index of a hundred-thousand record file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now the good news is that we would never need to look something up using spaces as the key value sought, so....what can we do? Paul was no slouch. He popped open the RMS reference manual and to his delight discovered he was not the first to pass this way and gleefully added the option "NULL_VALUE=SPACES" (translated: "if the value is spaces, Just Don't Index this record on this key") to the key definitions in the file definition script he was using to initialize the file and recreated the file and re-ran the program from scratch.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The change did not help. At all. I think we all know that feeling, as visceral as a dropping elevator.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There it was, the option explicitly intended to solve the problem he had explicitly encountered,  and it did not change a thing. Impossible. But this happens to us programmers all the time.  We know what to do. Compile the damn code, because we made the edit change but forgot to compile. Or link. Or, in Lisp, to zap the faultily specialized method. Or something.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So Paul edited the definition again and checked that NULL_VALUE = SPACES was the right syntax and right spelling and on the right key -- to hell with that, he put it on all three damn keys -- and he saved it and checked the date and created the file again and ran his program again and you know it did not run any faster or I would not be telling this story.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OK, time to get serious. Or if he was good he did this without all the huffing and puffing of the preceding paragraph. He Just Typed In "rms/analyze sdb.dat". And RMS looked at the file itself (not the script used to create it) and confirmed that "NULL_VALUE = SPACES" was operative for all indexes.&lt;br /&gt;&lt;br /&gt;Momma don't let your kids grow up to be programmers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What comes next is hard to convey. I can tell you but if you have not worked on this code or (we will learn) run this batch application it is hard to convey how much blood, sweat, tears, CPU time, and delayed nightly batch closes for how many years resulted from Paul's not first solving the failure of NULL_VALUES=YES. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, maybe this is a fair glimpse of the enormity that followed: the problem got sorted out only because the head of operations and I got to talking one day and he pretty much ended up down on one knee begging me to find some way to eliminate the two-hour merge step that held up the nightly close every night. I had never heard this before, though I had been overhauling the system for months.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"It just sits there for two hours," he groaned. "It kills us every night. Please, if you can, please, do something to make this go away."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Whoa. I had inherited this system and been asked to enhance it but no one had said a word about this. The code was far and away the best OPC I had ever dealt with so everything got the benefit of the doubt, including the (soon-to-be explained) two hour merge. As in, if it is there, it must be there for a good reason. What was not there was The Story of the Unsolved Failure of NULL_VALUE=SPACES, but even if it had been I would have taken that at face value, too, because the NULL_VALUE option was unknown to me. But enough of this flash forward, let's get back to poor Paul.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;NULL_VALUE was not working as it should. Software is like that. Good programmers do not let bad software stop them. Plan B. A rule is born: Thou shalt not write new securities to the securities database where the massive duplicates will make each write take twenty seconds. Paul decides to write them to a second file initialized empty on each run. Since we only got dozens of new securities in one batch, that file would never have the massive count of duplicates and writes would be lightning fast. Then we just do a sort/merge at the end of the batch to combine the new securities in with the old. Oops. "Just."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The funny "you can run but you cannot hide" moral within the moral being that I did the calculations one day and worked out that twenty seconds times the usual number of new securities in a day was exactly as long as the sort/merge that was just killing the folks down in operations. And I bet Paul realized that but only after writing all the crazy code he had to write to work with two files at once as if there were only one file and at that point he just gave up and moved the thing into production. Speaking of crazy code...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You should have seen it. Looking back I cannot recall why it should have been so hard, but I did overhaul that code and I was forever tripping over it. The idea is simple. To look up a security to see if we already have it, first look in the real DB and if it is not there look in the daily "new stuff" DB and if it is not there, ah, it is new. If it is, update it. Just remember to update the right file, because we can get data from two sources about the same new security.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Piece of cake, right? A bottleneck function for all reads and updates... anyway, it seemed like the issue was always getting underfoot as I worked, and just looking at the code one saw again and again this check here/there code, and both Paul and I were the kind of engineers always on the lookout for ways to make code non-redundant. I would think my memory was faulty but I also remember eliminating Paul's Plan B after solving his failure first and &lt;span class="Apple-style-span" style="font-style: italic;"&gt;that &lt;/span&gt;was no picnic. It just permeated the application.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what was the first failure and how did it get solved? First, I had noticed the issue myself while using Datatrieve to add a record to the securities DB for test purposes. I hit enter and thought I had crashed the system because it went away and never came back and like every egomaniacal programmer out there I always assumed that whenever a system stopped responding the last thing I had done must have broken it so there I sat in dread for twenty seconds until the system finally responds. Wow. Twenty seconds? And then I guess I added a record specifying all three keys and it responded instantly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But this idea of null values not being recorded in an index was new to me, and we did not have the Internet back then where I could just ask the ether what was going on so it was only a coincidence that just after the guy in operations had begged me for a fix that I was visiting with the lads from a prior contract and I moaned that RMS sucked because it could not handle files with hundreds of thousands of records and they laughed at me and said they were handling millions with RMS. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I can actually remember the look on my face, a neat trick when you think on it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I haul ass back to work and pull out the RMS reference manual and I can tell you that dead trees aside there is one good thing about paper documentation: right above the entry for NULL_VALUES close enough to catch my eyes was the entry for NULL_KEYS.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Yep. You need to specify both. Paul had specifed NULL_VALUE=SPACES. He had not specified NULL_KEYS=YES. The default for NULL_KEYS? Guess.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I kinda wretch inside even now thinking about the astonishing amount of money, work, debugging, and delayed batches that followed from one simple failure to understand one broken thing. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The metalesson shared with "Solve the First Problem"? In programming, never deal with the unknown. This game is hard enough.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Epilogue&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The punchline is that I never solved the first failure from Scene I of this tragedy. As my father used to say, "Do as I say, not as I do." We &lt;span class="Apple-style-span" style="font-style: italic;"&gt;did &lt;/span&gt;have a deadline, and I &lt;span class="Apple-style-span" style="font-style: italic;"&gt;did &lt;/span&gt;narrow down the location of the problem in a way that reassured me somewhat that it would not jump up to bite the new code in the rear end. And even in its breech the law is confirmed: we &lt;span class="Apple-style-span" style="font-style: italic;"&gt;do &lt;/span&gt;need to address the underlying problem which I have some confidence I now understand because it still presents problems for the software but it will go away only when bigger problems are solved and they are much bigger so I am keeping my sights set on them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-4960005538372806404?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/4960005538372806404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=4960005538372806404' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/4960005538372806404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/4960005538372806404'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2009/01/tiltons-law-solve-failure-first.html' title='Tilton&apos;s Law: Solve the Failure First'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-2952451628360585841</id><published>2008-12-29T02:23:00.009-05:00</published><updated>2009-01-08T06:19:48.788-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript ajax frameworks qooxdoo RIA Web 2.0 Lisp jQuery Dojo YUI HTML CSS'/><title type='text'>The Road to qooxdoo Part III: Why It Rocks</title><content type='html'>In the episodes &lt;a href="http://smuglispweeny.blogspot.com/2008/12/road-to-qooxdoo.html"&gt;one&lt;/a&gt; and &lt;a href="http://smuglispweeny.blogspot.com/2008/12/road-to-qooxdoo-part-ii.html"&gt;two&lt;/a&gt; we learned all about how a Lisp God and Interwebby know-nothing found a way to support a client needing an enterprise Ajax Web application, said way turning out to be &lt;a href="http://qooxdoo.org/"&gt;qooxdoo&lt;/a&gt; after solid efforts to make jQuery, Dojo, and YUI fill the same bill. But we did not learn very much detail about qooxdoo, we just learned that it comes with lots of doc, lots of examples, a solid community, and that the engineering is first rate. I may not have mentioned this, but it also was dramatically faster/smoother than the others on my acid test: scrolling a datagrid. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Okay, that &lt;span class="Apple-style-span" style="font-style: italic;"&gt;is &lt;/span&gt;a lot as a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;general &lt;/span&gt;recommendation. I mean we did not learn much detail. Until now. Here are four Big Things that really stand out:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;1. HTML? CSS? Never heard of 'em.&lt;/span&gt;&lt;br /&gt;First comes a shocker. The qooxdoo user codes no HTML or CSS and needs know nothing about those two disappointments. Just as my Lisp compiler reads my Lisp code and spits out optimized native machine code, qooxdoo takes your qooxdoo/Javascript and produces the HTML and CSS to drive the browser. Upside: qooxdoo developers write less code and never have to worry about browser variability again.&lt;br /&gt;&lt;br /&gt;To a Web noob like me there is a second big win here: I do not have to &lt;span class="Apple-style-span" style="font-style: italic;"&gt;learn &lt;/span&gt;HTML, CSS, or the vagaries of the different Web browsers my client might want supported. I am a bit of a rarity in my ignorance of those things but soon I should have a lot of company now that qooxdoo has set the bar as high as it has on insulating the web app developer from lower level technology.&lt;br /&gt;&lt;br /&gt;By the way, in case you are wondering: yes, there is a widget (two, actually) that will accept classic HTML.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;2. I do declare. Not!&lt;/span&gt;&lt;br /&gt;The second thing that hits us is a consequence of the first: we are going to be writing a lot more Javascript than we would be with libraries such as Dojo where authors still write HTML/CSS. With declarative tools we sit in Lisp or Ruby or PHP on the server generating HTML. Not qooxdoo (but see next)  and not YUI.&lt;br /&gt;&lt;br /&gt;I am not at all happy about this but I will live and if it ever bothers me enough I will spend a weekend exploring the qooxdoo markup contrib called &lt;a href="http://qxtransformer.org/"&gt;QxTransformer&lt;/a&gt;. Right now I need to catch up on a backlog of functionality the client has had to do without because of the six weeks it took me to identify qooxdoo as The One.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;3. OO is not the Grail, but OO rocks&lt;/span&gt;&lt;br /&gt;Stendhal said it best in "On Love" in the chapter on Infatuation: (paraphrasing poorly) we do the object of our desire two injustices, first setting them on a pedestal unreasonably high and then, when they inevitably disappoint, setting them too low. OO is not the Grail, it is just a profound advance in serious application development. All by way of introduction of another stunner: qooxdoo's slightly more substantial object model layered atop the core Javascript OO capabilities. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To be honest this struck me as a bit of a yawn until I decided to start carving up my existing code into distinct qooxdoo classes. This is a very big application and I needed code re-use almost immediately and doing it in HTML with Javascript glue was...well, before qooxdoo I was pretty much starting to build my own abstraction layer atop the core tools--there was no way around it.&lt;br /&gt;&lt;br /&gt;But now that I have used qooxdoo's OO to partition my rapidly growing code base I have more than once had that wonderful sense of getting something for nothing after doing a major refactoring (you know, taking all the pieces and throwing them up in the air) and having it Just Work after two or three tweaks. Furthermore, I will not bore you with the details but I have not even started leveraging the full capabilities of qooxdoo's object layer: even more benefit will be reaped moving forward because of some nifty &lt;a href="http://en.wikipedia.org/wiki/Reactive_programming"&gt;reactive&lt;/a&gt; capabilities.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This came as a pleasant surprise. I do more OO in more ways than you can imagine in part because I normally program with Lisp's CLOS which is to normal OO what normal OO is to binary arithmetic but by the time I stumbled onto qooxdoo I had been doing Javascript, HTML, and CSS for a couple of months under a lot of pressure so I never had the time to build a sensible OO abstraction atop Javascripts primitive little OO pretensions. Thus Javascript had endowed me with a bit of &lt;a href="http://en.wikipedia.org/wiki/Shoshin"&gt;child mind&lt;/a&gt; and I was able to experience the mundane code structuring win of OO as if for the first time. It rocks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;3. Layout the Wazoo&lt;/span&gt;&lt;br /&gt;I may have lied. This may have been the first stunner I felt in my gut. The others I knew would be huge if they panned out, but this was the first one I saw in action working as beautifully as had the other frameworks left me hanging. With other frameworks I could find no way to get built-in layout schemes to use the full window real estate available. That cuts two ways: I either ended up with unused whitespace (and with our app we need all we can get) or my application panels grew so large that the browser itself put up scroll bars, meaning I had to window-scroll my scroll panes around. No, that was not a candidate for production release. Note that to a large degree this is the same as point #1: a framework is not hiding HTML/CSS from me if I am still victim to surprising browser decisions, such as oh gosh that is big let's use a scroll bar here.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How good is qooxdoo at layout? When I popped open the Firebug debugger in FireFox, where by default it begins by seizing application window real estate, the qooxdoo layout engine handled the downsizing impeccably, right down to adjusting scroll bars to accurately reflect the new dimensions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;4. Message In A Bottle&lt;/span&gt;&lt;/div&gt;&lt;div&gt;This feature is huge in a small way, by which I mean I could probably roll my own version of qooxdoo's Message mechanism in a an hour but--wait for it--I did not have to. They did. That is huge, the huge thing being that the qooxdoo team really has set out to create a compleat Web application development environment and with such a beast comes pleasant surprises such as their Message mechanism which allows a nice decoupling of widgets: one widget can dispatch "Make it so" and anyone responsible for "it" knows to roll up their sleeves simply by having subscribed to "Make it so".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Beyond the Message mechanism we have the Event mechanism. The documentation of every widget lists the events it might generate and what data the event will carry, and in toto we have an engine with an event model dozens of times richer than pure DOM.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;5. I know, I said "4"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Number five is an umbrella win, too detailed to list: as I whined above, this Lisp God is now writing an awful lot of Javascript leveraging more and more qooxdoo all the time. Again and again your highly critical correspondent is finding nothing but good news in qooxdoo. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Yes, I could make a bug report every other day if I had the time, but a long time ago I figured out that I am not looking for a perfect library, I am looking for a powerful library that is fundamentally sound (so anything broken can be readily fixed) and actively maintained (so things actually get fixed).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Summary&lt;/span&gt;&lt;/div&gt;&lt;div&gt;qooxdoo: fast, powerful, complete, rich, well-engineered, and it hides browsers, HTML, and CSS. Great doc, loads of examples, fine community. It's all good.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-2952451628360585841?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/2952451628360585841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=2952451628360585841' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/2952451628360585841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/2952451628360585841'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/12/road-to-qooxdoo-part-iii-why-it-rocks.html' title='The Road to qooxdoo Part III: Why It Rocks'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-1193706948969696207</id><published>2008-12-13T23:24:00.006-05:00</published><updated>2008-12-28T07:17:13.892-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp qooxdoo QxTransformer Dojo Yui Web 2.0 development Javascript framework PHP Python'/><title type='text'>The Road to qooxdoo - Part II</title><content type='html'>&lt;a href="http://smuglispweeny.blogspot.com/2008/12/road-to-qooxdoo.html"&gt;Last time&lt;/a&gt;, we learned how one self-appointed Lisp God with no knowledge of web programming ended up programming the web and then soon enough embarked on a six week grand tour of Javascript frameworks in search of a platform suitable for an enterprise web application and where his tour ended: qooxdoo. That episode ended with a promise of more information on qooxdoo, but first a note on the methodology: there was none.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My first experiment with web programming had thanks to the marvels of Lisp in general and AllegroCL's web tools in particular mushroomed into a full-blown web application aided here and there by jQuery widgets before we slowed down enough to think, Damn, we could benefit from a full-blown Web application framework.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; So I eyeballed the usual suspects and ran them through &lt;a href="http://googlefight.com/"&gt;googlefight&lt;/a&gt; and picked the most promising one and used that to redo what I had accomplished to date. Which was: tab controls, select boxes, data grids as views into server-side data stores, tree views, text input, tool tips, pushbuttons, pop-up windows, and probably one or two things I am forgetting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How did I assess the libraries? We needed a professional look, good performance, and maximum productivity. Sorry if that seems blindingly obvious. The productivity assessment has some beef: I looked for lots of documentation and tons of examples describing a rich set of widgets at once high-level, feature-rich, and yet highly authorable which may not be a word but it means I get to override stuff without resorting to back doors. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I considered also two metaqualities: on-line support and internals code quality. Having the &lt;a href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm"&gt;Lisp HyperSpec&lt;/a&gt; an F1 away is just a little faster than asking for the same information on comp.lang.lisp. ie, Community matters. As for code quality, the good thing about open source is not that it is free, it is that I can use the source to understand things at 3am when the community might be quiet; I can add print statements to debug my code; and maybe I can find and fix a bug in the library. But if the code is of low quality good luck with anything more than the print statement insertion.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It was a rough six weeks. Three times in six weeks I logged onto support groups and said, "Hi, this is my first day..." as I rebuilt a relatively feature-rich web app three times while staggering up to speed three times on three environments. All while the client is getting absolutely no new functionality. I feel bad all the while because they need this stuff &lt;span class="Apple-style-span" style="font-style: italic;"&gt;now.&lt;/span&gt; I am letting them down and there is the strong possibility they will be letting me go: I had been brought on to do the Web front-end. I like learning, but not so much with a gun to my head and a time bomb ticking.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Are we having fun yet? Well, yes. The last framework we tried was qooxdoo and it has worked out great. I can now give the client pretty much what they want fast and looking good once they pony up for a graphic artist because I just saw this &lt;a href="http://juhukinners.com/2008/12/23/qooxdoo-in-the-ct/"&gt;impressive example&lt;/a&gt; of what can be done with their "appearance" framework. But I ain't no designer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Funny thing, though: qooxdoo  like YUI and Dojo came up short during the evaluation. It had no example of the widget I needed most, a fairly standard widget at that: a datagrid backed by a remote store. Bad sign. Second, qooxdoo did no better on googlefight than does Lisp, and that is pretty bad. Finally, qooxdoo like YUI lacks a declarative programming model [though the declarative &lt;a href="http://qxtransformer.org/"&gt;QxTransformer&lt;/a&gt; has been revived since my original investigation] which means I cannot just sit in my Lisp IDE catching XHRs and tossing back HTML/CSS. This would put a non-trivial dent in my productivity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So how did qooxdoo prevail? What can I tell you? Bullet charts are useless, expert systems work great as long as expert humans interpret their output, and resumes tell us nothing about the work we will get out of people. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;qooxdoo &lt;span class="Apple-style-span" style="font-style: italic;"&gt;did &lt;/span&gt;have a contributed example of a remote data store which pretty much worked and when I looked at the qooxdoo internals to learn how to make it work better I found very good code and rather quickly had the datagrid I needed. Otherwise qooxdoo did have loads of examples and documentation and decent community (I say "decent", you'll say "great"--my standard is comp.lang.lisp) and then we get to the bottom line.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While resurrecting my app for the third time with qooxdoo, yes, I worked just as hard as I did using Dojo and YUI. But the effort was different. With qooxdoo I was struggling to learn a very nice framework that needs an index: I was slaving for six hours to find the simple six lines of code I had to write. With YUI I was struggling with a framework that did not work all that well and scared me more and more the more I looked inside it. With Dojo the struggle was with a good framework but the struggle was such that I suspected the struggle would never diminish and probably increase exponentially as the application grew in complexity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As for the declarative thing, hey, I am a programmer, I can write code. And Javascript has a lot of Lisp soul, I am not stuck with something daft like PHP or Python. Sure, having to spend more time in a JS IDE means a ten percent productivity hit but ten percent we can do. The terror we developers dread is the tool nightmare death by a thousand cuts two steps forward two steps back rope drag death. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will blog on rope drag sometime soon, but first let's get specific about qooxdoo. In Part III of my Road to qooxdoo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-1193706948969696207?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/1193706948969696207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=1193706948969696207' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1193706948969696207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1193706948969696207'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/12/road-to-qooxdoo-part-ii.html' title='The Road to qooxdoo - Part II'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-5609758665124194473</id><published>2008-12-12T20:19:00.010-05:00</published><updated>2008-12-29T02:15:29.853-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript ajax jquery dojo qooxdoo yui comparison'/><title type='text'>The Road to qooxdoo</title><content type='html'>&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;[The title of this rather boring entry derives from a fun little &lt;/span&gt;&lt;/span&gt;&lt;a href="http://64.233.169.132/search?q=cache:http://wiki.alu.org/RtL_Highlight_Film"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;survey&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; I kicked off years ago.]&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;OK, why should you listen to a Lisper on Javascript frameworks? Because we use Lisp so obviously we have better instincts when it comes to developing applications. In fact, this road would not have ended so well had not Lars, a fellow Lisper developing a killer new Lisp Web programming framework called &lt;/span&gt;&lt;/span&gt;&lt;a href="http://groups.google.com/group/symbolicweb?pli=1"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Symbolic Web&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; (SW) brushed aside my enthusiasm for &lt;/span&gt;&lt;/span&gt;&lt;a href="http://dojotoolkit.org/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Dojo&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; and mentioned he found &lt;/span&gt;&lt;/span&gt;&lt;a href="http://qooxdoo.org/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;qooxdoo&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; interesting, although for now SW uses a little &lt;/span&gt;&lt;/span&gt;&lt;a href="http://jquery.com/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;jQuery&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;. "A little" because the whole idea of Symbolic Web is to do most of your programming in Lisp which of course is the only way to go but SW is still emerging from the sea and I had a requirement &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;now&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; (well, six weeks ago, but there is major new release of SW just out I need to look into but as this Road will reveal I am not likely to change horses now because of what I found in qooxdoo (not that SW will not eventually catch up)). Gasp.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;The second question might be how a Lisp god and Interwebby know-nothing ended up doing heads-down intense Interweb development. Well, it was the Lisp credentials. A former client using mostly Lisp was having great luck with a Ruby/Rails front end but was looking for more speed and hoped having a Lisp image serve the pages directly would make for better response.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;What happened next was pretty neat, and again Lisp conquers all. I told the client I would look at what they had and what they needed for a few days to decide if even I could help them, because I can do a lot of things but one thing I cannot do is exaggerate how little I knew about Web programming and even static HTML eight weeks ago.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;A glance at the existing screens and Rails code had me thinking, "No way", but I was curious anyway about even getting an application to drive a web site so I fired up a tutorial on Web app development using &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.franz.com/support/tech_corner/ajax.lhtml"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;tools&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; from my Lisp vendor of choice, &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.franz.com/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Franz&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;How good are Lisp, Franz,  the tutorial, and the WebActions tool? In the three days I was supposed to be deciding whether I could help the client I managed to execute a respectable fraction of the first component they needed.  Sorry, no screenshots, NDA and all that.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;So now there I am with a contract and a browser toolbar sagging from the weight of bookmarks to sites on &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.w3schools.com/sitemap.asp"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;HTML, CSS&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;, and for the hell of it jQuery though I was not sure why but everyone was jumping up and down about it. And then I needed it.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Well, not jQuery. I needed a razzle-dazzle spreadsheet-like grid presenting data from an arbitrarily large table of data held on the server. Now at this point I had already rolled my own Ajax paging mechanism, but something superficial but nonetheless important for that this being an important application was holding me back: my HTML looked like crap. Meta-holding me back was my sense from surfing the Web that getting good results out of HTML/CSS was a black art requiring years of practice which certainly leaves me out. Enter &lt;/span&gt;&lt;/span&gt;&lt;a href="http://webplicity.net/flexigrid/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;FlexiGrid&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;. A URL which as I write responds "&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Please contact the billing/support department as soon as possible." &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;Which brings me to why I dumped jQuery. What I found was small, yes, and add-ons, yes, but a hodge-podge of add-ons does not a professional development environment make. By the time I punted I had contribs from three people and while each was lovely alone together they looked like, well, a great decorator on a multiple-personality binge. And beyond appearance there came a surprising result: FlexiGrid did not offer a "row selected" event. Meta-worse was the author's response. "Right, no row-selected event." Ooops. Next up was jqGrid and that was fine but I still had Crazed Decorator Syndrome going and now I am looking for the next widget I need and a light went on: we are building an application here, not a Web page/site. It is wonderful that jQuery is small, but small is exactly the wrong thing for developing a sophisticated application with a coherent look and feel never mind coherent engineering underneath so widgets can play well together. Enter Dojo. But first...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;In case you are wondering where the client went, they are encouraging my search for a pre-fab solution. Probably seeing the gorgeous FlexiGrid widget compared to my ugly efforts did not hurt, but the client has good instincts anyway (they use Lisp, right?) so they are leaning towards my original assessment that I am overmatched if I am going to try to turn out a hot application on short experience with HTML and CSS even though at this point I have wondered aloud to them how much HTML/CSS I might have mastered in the same time I was spending beating my head against pre-fab, this being the classic failed deal we make with the devil when we reach for 4GL: yeah, wow, a complete browser screen in five minutes. Gee, could we get the first sub-item appearing on the same row with the item? No. The client wants it. It cannot be done. That was Datatrieve on VAX/VMS twenty-five years ago, but nothing has changed. 4GLs get their apparent power by making decisions for me which works only if I (and my client) are not making any decisions.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;But no, the client says "find a framework" and I decide to try again with Dojo. Again?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;I had looked at Dojo before. The word on Dojo was incredibly good. Of course that word was from their Web site. When I tried to confirm by eyeballing the doc I could not find it. I mean, there were some great links, but all the pages they led to were blank. Next! But now I was back, encouraged by the news that &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.openlaszlo.org/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;OpenLaszlo&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; had just placed a bet on Dojo. IBM as well, but OpenLaszlo is more important because I know they are geniuses, they have a dataflow hack like &lt;/span&gt;&lt;/span&gt;&lt;a href="http://smuglispweeny.blogspot.com/2008/02/cells-manifesto.html"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;mine&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Oooh-ooh! Another reason Dojo looked good was a &lt;/span&gt;&lt;/span&gt;&lt;a href="http://blog.creonfx.com/javascript/dojo-vs-jquery-vs-mootools-vs-prototype-performance-comparison"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;benchmark&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; I had found showing the thing was fast. I have no idea if the benchmark is valid, but the pictures are gorgeous so I trust it. So why did I dump Dojo?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Well, OK, I did not really. It came in second. The question is why did I keep looking such that I found the eventual winner. Easy: too frickin hard to get to work. The documentation is awful. They know this and are addressing it but did I mention we need this &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;now?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; Overall Dojo fit the bill of being a Compleat Solution with solid backing and a great future, but after banging my head against the wall over something (ah, it was the six hours I spent trying to figure out the "build" mechanism for a compressed production release of my JS culminating in watching a blurry video that finally showed how to do it) I went for a better way surf (as in there's gotta be) and saw &lt;/span&gt;&lt;/span&gt;&lt;a href="http://developer.yahoo.com/yui/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;YUI&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; touted as a serious solution.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;A quick glance at the enormous volume of well-organized documentation and exhaustive examples and the client and I agreed at once to give it a try. And I will tell you right now YUI has the best graphic designers, because their stuff looks &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;hot&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;. Dojo is a close second there, too. YUI is a complete solution with a big backer, gorgeous style, and more doc than you can imagine. How did it get dumped?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Stuff was not working well. Even with all the doc and examples it was hard to get working. When I dug into the source to see why things were not working, I did not like what I saw. And the death knell: YUI abandons the declarative model. Why is this so bad? Hellooooo, Lisp? Remember?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Up thru Dojo I was programming in Lisp 90% of the time, doing just enough JS to get information back to the Lisp server application where HTML could be generated and sent back, even that Lispily thanks to HTML generating macros. And YUI was going to make me give that up and be as hard to figure out as Dojo and I suspect worse under the hood. So regretfully I informed the client my battles with Dojo would be resuming.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;So how does this road end up at qooxdoo? &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;The weekend was coming up. Weekends are mine, so I decide to follow-up on Lars's hint about qooxdoo. qooxdoo is the ultimate threat to YUI because qooxdoo also says Just Code Javascript, and if I am forced to do that by YUI I may as well do it in qooxdoo where the code is as good as YUI's is bad. (I looked at about fifty lines of it for five minutes, I should know.) Anyway....&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;qooxdoo is amazing. They need help on the graphic design (never look directly at their tab control, use a mirror) but other than that the engineering is terrific. [My bad: they simply leave anything more than the utilitarian look up to the developer, witness this &lt;a href="http://juhukinners.com/2008/12/23/qooxdoo-in-the-ct/"&gt;before/after&lt;/a&gt; case study.] The documentation and examples are also abundant here, and the support is great. They even do &lt;/span&gt;&lt;/span&gt;&lt;a href="http://qooxdoo.org/documentation/0.7/properties"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;dataflow&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;! Yes, I wish I could spend all my time in Lisp sending over HTML, but two things on that.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;One, there is a side-project that brings a declarative model back into qooxdoo.&lt;/span&gt;&lt;/span&gt;&lt;a href="http://qxtransformer.org/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; QxTransformer&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;. I have no idea where that stands, but I did see a note on-line where a developer spoke of it in the past tense. [Now &lt;a href="http://qxtransformer.org/"&gt;resurrected&lt;/a&gt;.]&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Two, hey, I can write some Javascript. I did ten years of C before I did fifteen years of Lisp, Javascript is not a problem. And it even has lambda, something &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.python.org/%7Eguido/"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;this guy&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; still does not understand. Lisp/markup would be better, but when dealing with mission-critical stuff (the client is doing valuable data crunching but does not win until they make it accessible) any team can roll up its sleeves and crank out the work even if they have to do without the brilliance of Lisp.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;This entry is getting long and I am getting tired and my bartenders are starting to worry about me so I will leave a detailed praise singing of qooxdoo to my next entry, but allow me a bit of a rant. What a mission-critical effort cannot stand is fundamentally flawed solutions that seem to offer a fast track but in fact bleed developers to death. This can be jQuery with an incomplete solution forcing me to try to build an application out of mom and pop contribs or YUI with fundamentally bad code or some other framework that might be just plain slow.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;As a developer I am not looking not to work, I am looking to have my work yield quality results predictably. I might spend four hours trying to figure out how to do something in qooxdoo but once I do it turns out to be insanely simple and work beautifully. Moral: their documentation needs an index! But I am keeping my big yap shut because documentation is a bitch and they have done a ton of it and I do not document &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;my&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt; stuff so...I keep my big yap shut. But the point is that my work now yields results reliably and predictably and this will accelerate as I learn the framework and even learn better how to navigate the documentation.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;qooxdoo not only fits the bill of being a complete solution well documented with many examples but it also has high-quality code under the hood, which both gives me confidence that I have found the right tool and not incidentally serves as useful further documentation. More next time.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-5609758665124194473?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/5609758665124194473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=5609758665124194473' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5609758665124194473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5609758665124194473'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/12/road-to-qooxdoo.html' title='The Road to qooxdoo'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-3854837146497331496</id><published>2008-12-07T12:38:00.001-05:00</published><updated>2008-12-07T12:41:35.167-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp packahes symbols interned uninterned case sensitivity noobs problems tutorials help'/><title type='text'>Why Lisp Packages are so Easy (Hard)</title><content type='html'>Slobodan Blazeski wrote:&lt;br /&gt;&gt; May somebody please explain me with simple words why cl packages are&lt;br /&gt;&gt; hard to use, 'couse I really don't get it?&lt;br /&gt;&gt; The best is probably to hear from somebody who just learned lisp or&lt;br /&gt;&gt; somebody who teaches lisp (do such people exist anymore?) and his/her&lt;br /&gt;&gt; students has problems with packages.&lt;br /&gt;&lt;br /&gt;...or a good teacher, defined as someone who remembers what it was like before they knew what they were teaching.&lt;br /&gt;&lt;br /&gt;The first problem is one of those immune system deals. Packages have a lot of the same proteins as, say, C dot aitch definition files so the recognition systems of programmers coming to Lisp from other languages (you know, everyone) does its damndest to parse them as dot aitches.&lt;br /&gt;&lt;br /&gt;In fact, packages have nothing to with anything but symbols, neither the functions nor global values they might name. More expansively: packages are about mapping string names to first class Lisp symbol objects and dividing this up into discrete mappings called packages so the same string "Hi, Mom!" can map to multiple |Hi, Mom!| symbols in multiple packages.&lt;br /&gt;&lt;br /&gt;The second problem is that symbols take us straight to black-belt Lisp in which one must understand the Lisp reader and fancy things like read-time and compile-time and all that. Example:&lt;br /&gt;&lt;br /&gt;I remember getting messed over because some symbol was mysteriously appearing the base CL-USER package. I could not for the life of me see where it was being introduced. I turned the problem over to a few trees worth of monkeys and one of them came up with this rule:&lt;br /&gt;&lt;br /&gt;"Never use a normal symbol like |Hi, Mom!| in a defpackage form coded in a source file with (in-package :cl-user) at the top which would likely be the default even without that."&lt;br /&gt;&lt;br /&gt;Instead, use a string like "Hi, Mom!" or an uninterned symbol like #:|Hi, Mom!|.&lt;br /&gt;&lt;br /&gt;Strings are dicey because you might want to export 'banana and be silly enough to code "banana". Lisp will take you seriously and create |banana| instead of BANANA, case sensitivity being what it is except when it is not when Lisp folds 'banana to 'BANANA which is what it does unless you are in Modern (case sensitive) mode.&lt;br /&gt;&lt;br /&gt;Did I mention "black-belt"? The fundamental idea is simple, but noobs get thrown off mostly by the non-simular simularity with C and then in the debugging stage by case sensitivity seeming to come and go at random and the whole read-time compile-time thang.&lt;br /&gt;&lt;br /&gt;hth, kxo&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-3854837146497331496?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/3854837146497331496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=3854837146497331496' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/3854837146497331496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/3854837146497331496'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/12/why-lisp-packages-are-so-easy-hard.html' title='Why Lisp Packages are so Easy (Hard)'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-1037639102832500046</id><published>2008-12-07T11:17:00.003-05:00</published><updated>2008-12-07T11:38:58.162-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp ASDF tutorial guide beginner help build make system defintion'/><title type='text'>A Beginners Guide to ASDF (Ha!)</title><content type='html'>&lt;div class="moz-text-flowed" style="font-family: -moz-fixed; font-size: 13px;" lang="x-western"&gt;OK, there is at least one thing about which Lispers are not so smug: ASDF (Another System Definition Facility), the de factor standard for the Lisp library equivalent of Makefiles, and my post today was prompted by ANFOBA (Another Noob Effed Over By ASDF) washing ashore on comp.lang.lisp, and how I almost responded there:&lt;br /&gt;&lt;br /&gt;Francogrex wrote:&lt;br /&gt;&lt;blockquote type="cite"&gt;Hi, I am struggling to understand how to work with asdf.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I have been using it for ten years and I am about 50-50 now on getting  it to work. I am assured it does a great job in working with a multitude  of Lisps/OSes, and I can assure you it is a disaster at working with  programmers.&lt;br /&gt;&lt;br /&gt;Come back here and post console output freely, you will need help,  especially because one of its great triumphs is useless error messages.&lt;br /&gt;&lt;br /&gt;Hints:&lt;br /&gt;&lt;br /&gt;(1) It will work. You will have to promise it your first-born, but it  will work.&lt;br /&gt;&lt;br /&gt;(2) No, PB was not joking: you have to separately push locations onto  some magical special variable. Leave off a slash (or add a slash, I  forget) and ASDF will take your head off, so don't do that.&lt;br /&gt;&lt;br /&gt;(3) No, PB was not joking, the syntax is:&lt;br /&gt;&lt;br /&gt;     (asdf:operate 'asdf:load-op :cl-pdf)&lt;br /&gt;&lt;br /&gt;Why is it not (asdf:load-system :cl-pdf)? In my experience, extremely  smart programmers think it astoundingly brilliant when "one function  does everything!!!!", remembering the ridiculous op-code first parameter  left as an exercise.&lt;br /&gt;&lt;br /&gt;Since you asked, this is because extremely smart programmers are tone  deaf to programmer productivity; they are so smart they do not even notice when they have created something unuseable, they just brain through it.&lt;br /&gt;&lt;br /&gt;(4) ASDF has a featurebug: it loads in the wrong order in order to make  McCLIM work. Don't ask. If the author of the .ASD file retreated to the  desert for forty days to slave over the dependencies this will not be  a problem. Otherwise do what I do: take a sledgehammer to the beast:&lt;br /&gt;&lt;br /&gt;     (asdf:operate 'asdf:load-op :cl-pdf :force t)&lt;br /&gt;&lt;br /&gt;That abandons the whole point of having a build system, but it gets ASDF  to work. When for the love of god I am just trying to build this frickin  thing!!! that is a nice tradeoff of compile-time vs tracking down and short-sheeting the author of ASDF.&lt;br /&gt;&lt;br /&gt;(5) On success ASDF emits more messages than an IBM OS/360 core dump.  This is so any errors will scroll well out of view and anyway stand out  like a healthy thumb from the surrounding...um, other healthy thumbs.  Anyway, do what I do: ignore all messages other than a backtrace and Just Try the Hello World(tm).&lt;br /&gt;&lt;br /&gt;If you get a backtrace, Just Post It to c.l.lisp.&lt;br /&gt;&lt;br /&gt;(6) If hello world fails, f*ck! But at least now you are a Real Lisp  Programmer(tm), this is what we live with.&lt;br /&gt;&lt;br /&gt;(7) Help Is On the Way(tm): &lt;a class="moz-txt-link-freetext" href="http://mudballs.com/"&gt;http://mudballs.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;hth, kenny&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-1037639102832500046?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/1037639102832500046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=1037639102832500046' title='45 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1037639102832500046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1037639102832500046'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/12/beginners-guide-to-asdf-ha.html' title='A Beginners Guide to ASDF (Ha!)'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>45</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-18209943361666309</id><published>2008-11-18T21:08:00.005-05:00</published><updated>2008-11-19T05:57:17.359-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Finite state machine software engineering'/><title type='text'>The Foisting of An Infinite State Machine</title><content type='html'>"I will not allow you to foist this convoluted scheme on the bank!", Sam yelled.&lt;br /&gt;&lt;br /&gt;This was fun in a lot of ways. First of all come on this is a bank, three or four full floors of programmers all enthralled by nothing more technical than getting through the day unfired and back on the train home to their families and here is  this aging cardpunch nutjob throwback not only noticing Someone Else's Code but caring?!&lt;br /&gt;&lt;br /&gt;Second, I did not make that up. Sam actually used the word "foist" without trying. I use SAT words all the time but I am usually trying, you can see my eyebrows arch a little as my language organ reaches for the thesaurus. Nothing shabby about "convoluted", but "to foist"? And Sam tossed that off in earnest in anger in the heat of diatribe sans affectation and it is not clear to me I have ever before or since heard the word used in vitro. Which brings me to the third fun bit.&lt;br /&gt;&lt;br /&gt;Sam was Jewish. Classic Orthodox home-by-sundown-on-Friday Brooklyn Jewish and of course he would be good with words. Right, get all PC on me and denounce me but what can you say?, he used "foist" in a sentence on the fly and I think I win on this. So there he is with this classic Billy Crystal Princess Bride accent yelling at me for foisting convoluted code on the bank.&lt;br /&gt;&lt;br /&gt;"I will not allow this!" he cried. "I will stop you!"&lt;br /&gt;&lt;br /&gt;Oh, please, tho Sam was a sweetheart. Yeah, "was". I heard he passed, Lord keep him, a beautiful soul. I could have choked him in that moment but at least he was attacking me for Code Quality. What was my sin?&lt;br /&gt;&lt;br /&gt;I had been tossed a throw-away job of persuading two applications to exchange information reliably when either app was free to collapse in a heap at any time and I was not to lose any information. Nowadays we just pull packages off the shelf for that but this was a while ago. Oddly enough in my first IT job ever I had had to do the same and it was fun because there was nothing theoretical about it, the two applications did even during development reliably disappear left and right allllll the time. Decnet, PDP-11, RSTS/E, 1981... you understand.&lt;br /&gt;&lt;br /&gt;What was different was that somewhere in the intervening ten years I had gotten this crazy idea of creating a domain-specific language to make it easier to develop a &lt;a href="http://www.theoryyalgebra.com/"&gt;software Algebra tutor&lt;/a&gt; so I had gotten a book on compiler design because I did not realize I could Just Use Lisp. I do not like reading so I did not get very far but fortunately one of the earliest chapters was on parsing  so I ended up learning about finite state machines. Oh, sorry.&lt;br /&gt;&lt;br /&gt;This post came up because I am doing some Web2.0 programming these days from Lisp and I wanted to send over Lisp sexprs and since Javascript for some reason lacks a Lisp reader I was going to have to parse it myself and after  ten minutes of trying to do it without a finite state machine I realize, damn, I should code up a finite state machine.&lt;br /&gt;&lt;br /&gt;I will not in this space try to explain what is a finte state machine but it is really simple and powerful and no matter what level programmer you are you need to have it in your, well, toolbox. I think the example I learned on was a pocket calculater when folks still had those. Your initial state is "initial". Duh. Then what happens? Oh, I got "/". Bzzt! Or just ignore it and my next state is still "initial". Now I get a "1". Great! Save that, my new state is...I dunno..."got a digit". We're on a roll. But wait, what other inputs could I get? A "+". Ummm...well, it seems no different, but we'll say "got a plus sign", and indeed when we are done one of the cool things that can happen is that as we fill in the table we may well discover that the row for the state (did I mention that rows were for states and columns were for inputs? Sorry) ..the row for the state "got a plus sign" might be no different from the row "initial" and we first go "whoa, enlightenment" and then collapse the two rows into one. I digress.&lt;br /&gt;&lt;br /&gt;But the idea is that we just break it down into cases. A fun example is that we now know whether a "+" is addition or a plus sign (or an error) without really trying, because we have aggrssively exploded the analysis into all these different states like "just got a digit" or "just got a left parens" or...yeah, it goes on, but guess what? Here comes the name! "Finite State Machine"! There are only so many!!! You may think there are a kabillion but after ten you are done, maybe after twenty. And you can collapse inputs (1-9 become "positive digit") and so you have a finite number there. Do you now have 150 cases to handle? Yeah, and each one you can code in your sleep. The alternative is one hyperglutionous mass of conditionals, tests, and branches that will fail on the one millionth execution because of a first time path execution.&lt;br /&gt;&lt;br /&gt;Back to Sam.&lt;br /&gt;&lt;br /&gt;I have realized that the reliable exchange between two autonomous systems permitted to fail at any point will best be solved using my old friend the finite state machine and I have enthusiastically shared this with Sam. Somehow I am now being denounced for using an algorithm learned from the top book in compiler design. Specifically, I am being denounced for foisting. I will be stopped. The bank will be saved from my convoluted scheme.&lt;br /&gt;&lt;br /&gt;Ooooookayyyyyyy.&lt;br /&gt;&lt;br /&gt;Well, what can one anachronistic lost in the Torah yamaha wearing card punching goto coding nut job do? Would you believe he could force a code review? Nay, a &lt;span style="font-style: italic;"&gt;defense&lt;/span&gt;. Sam forced a frickin &lt;span style="font-style: italic;"&gt;defense&lt;/span&gt; of about thirty lines of the best simplest most powerful correct code that bank had ever seen. Mind you Sam is also the man who produced my favorite line of code ever, using the Vax Basic statement modifier mechanism:&lt;br /&gt;&lt;blockquote&gt;return if flag&lt;/blockquote&gt;That's right, an action at a distance code teleportation straight out of the middle of seventy line for loop using a flag he had named.... flag. You can imagine my &lt;a href="http://smuglispweeny.blogspot.com/2008/07/aa-bb-cc-and-dd.html"&gt;reaction&lt;/a&gt;. And this guy is challenging &lt;span style="font-style: italic;"&gt;my &lt;/span&gt;code?&lt;br /&gt;&lt;br /&gt;If you are not yet suitably horrified, understand that novice programmers were regularly crashing production runs because no one anywhere was looking at their code and they were going to call a meeting of like twelve programmers to review my foistation of convolution upon the bank? Sorry, my ire is showing. Chase cut to.&lt;br /&gt;&lt;br /&gt;Code review/defense: twenty minutes, here it is, any fucking questions?&lt;br /&gt;&lt;br /&gt;Yes that was pretty much the tone of my presentation -- I like to consider people skills one of my strengths. And then Sam spoke and you will see why I loved him. At pain of repetition, probably no one else on those four floors would have even listened to me as I bragged on my FSM, but go to the mattresses to stop what he thought was bad code? One in a million. And one in ten million in my experience would have said what he said.&lt;br /&gt;&lt;br /&gt;"OK," Sam he said. "That looks fine."&lt;br /&gt;&lt;br /&gt;Of course now I am pissed off because I am just getting my turbines spun up for a full bore antler to antler knock down drag out kickin and a gougin in the mud and the blood and the beer round fifteen thrilla in manila finish and Sam is saying...fine?&lt;br /&gt;&lt;br /&gt;"That is simple," Sam continued, gesturing towards my whiteboard diagram. "This infinite state machine idea is complicated, but the way it works is simple."&lt;br /&gt;&lt;br /&gt;The beauty of that being......no. I would only ruin it.&lt;br /&gt;&lt;br /&gt;RIP, Sam. RIP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-18209943361666309?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/18209943361666309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=18209943361666309' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/18209943361666309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/18209943361666309'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/11/foisting-of-infinite-state-machine.html' title='The Foisting of An Infinite State Machine'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-8359206713983307951</id><published>2008-09-09T14:17:00.006-04:00</published><updated>2008-09-09T15:14:10.064-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='baseball Larry Ritter book review'/><title type='text'>URBBR #2: How Bad Is This Book?</title><content type='html'>[The following has been... well, only the names have been changed to protect the endangered toads.]&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We have a One-Paragraph Test for fiction. Not a complicated test, it involves reading the first paragraph and then deciding. If We are &lt;span class="Apple-style-span" style="font-style: italic;"&gt;really&lt;/span&gt; undecided We can read a second paragraph, but that is a Bad Sign.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For non-fiction We look at the blurbs the author managed to suck out of unwilling blurbers. Well, OK, We do not really want the blurbs to be from blurbers, We want them to be reviews and We know they have cherry-picked the review sentences so everything gets discounted about an order of magnitude. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And there are two such reductions applied, the second for the source of the review. Kirkus Review of Books... well, just quoting them gets a book back onto the shelf. In the wrong section, upside-down, binder in.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is the Gold Standard for non-fiction back covers (hmm, the URL goes to the whole book, be clever and click "Back Cover"): &lt;a href="http://www.amazon.com/gp/reader/0688112730/ref=sib_dp_ptu#reader-link"&gt;The Glory of Their Times&lt;/a&gt;. Yes, you need to read this book, and no I do not give a rat's ass if you like baseball just read it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We turn now to a book I have been asked to review, which will go unmentioned for the same reason I restacked it binder-in:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:verdana;font-size:13px;"&gt;&lt;blockquote&gt;"This work strikes a balance between the pure functional aspects of Blub and the object-oriented and imperative features that make it so useful in practice, enable .NET integration, and make large-scale data processing possible."&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:Georgia;font-size:16px;"&gt;&lt;div&gt;The clever unwilling blurber always manages to say something nice by talking about something else, in this case the language .... instead of the book for 90% of the blurb. What does he say about the book? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It strikes a balance. Wow. How big a put-down is that? Note that the reviewer did not say "a perfect balance" or even "a good balance". And what the Hell does balance buy me anyway?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The good news is that We cannot discount that 90%, Our micrometer does not go that low. But We better check the author of the blurb.&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;—John Doe, PhD, Researcher, Blubber Ltd.&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Oh. The people selling Blub.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The neat thing is that We now know the book is awful and that John was slowest to hide under his desk when the marketing people came around looking for a recommendation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-8359206713983307951?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/8359206713983307951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=8359206713983307951' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/8359206713983307951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/8359206713983307951'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/09/urbbr-2-how-bad-is-this-book.html' title='URBBR #2: How Bad Is This Book?'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-3023480239322239042</id><published>2008-09-09T06:19:00.006-04:00</published><updated>2008-09-09T07:24:59.866-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZenLisp Scheme Nils Holm McCarthy Hopper Knuth'/><title type='text'>Unread Book Review: Zen Style Programming, Nils Holm</title><content type='html'>&lt;div&gt;On comp.lang.lisp, Nils M Holm wrote:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&gt; I am happy to announce that free pre-release copies of my latest book&lt;/div&gt;&lt;div&gt;&gt; &lt;/div&gt;&lt;div&gt;&gt;           "zen style programming"&lt;/div&gt;&lt;div&gt;&gt; &lt;/div&gt;&lt;div&gt;&gt; are now available.&lt;/div&gt;&lt;div&gt;&gt; &lt;/div&gt;&lt;div&gt;&gt; Blurb&lt;/div&gt;&lt;div&gt;&gt; &lt;/div&gt;&lt;div&gt;&gt; The primary purpose of programs is to be understood by fellow human &lt;/div&gt;&lt;div&gt;&gt; beings,&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nonsense! Nils has been reading &lt;a href="http://www-cs-staff.stanford.edu/~uno/lp.html"&gt;Knuth&lt;/a&gt; or something. The purpose of programs is to model other processes so the most important virtue of a language is the ease of building programs with it. Yes, those programs should tend to be clear but that just requires powerful constructs, long names, and support for the functional paradigm. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Besides, "revise"  means "rewrite from scratch anyway because the way this was done is all cocked up" so we do not generally have to understand programs to work on them.&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&gt; hence programming languages should have certain properties:&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Bzzt!  The source of obfuscation is the programmer, not the programming language.&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&gt;     * Small size and uniformity&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Hand-waving! Nils has been reading Graham or something. Small size as a requirement does not follow even if one were to exalt human readability to Prime Directiveness. You could just have good names for functions, like pathname-sans-file. And an editor that knows how to get to a hyperspec.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;     * Unambiguousness&lt;/div&gt;&lt;div&gt;     * A high degree of abstraction&lt;/div&gt;&lt;div&gt;     * Achitecture neutrality&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt; The first part of this book introduces the concept of functional  programming and describes a purely symbolic language that fulfills these requirements. This language is a minimalisti variant of Scheme whose only data types are symbols and ordered pairs. Nothing else is required to describe algorithms for solving a variety of different problems.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second part of the book shows how to apply the techniques of  symbolic programming to some problems of varying complexity. Topics discussed in this part range from simple functions for sorting or permuting lists to ``lazy'' data structures, regular expression matching, formal language translation, and declarative programming.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The third part, finally, shows how to implement the abstraction layer that is necessary for solving problems in an abstract way on a concrete computer. It reproduces the complete and heavily annotated source code for an interpreter of symbolic LISP and provides an example of clear and readable C code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This book contains the full source code to a source-to-source compiler, a meta-circular interpreter, a logic programming system, and to the language that is used to implement all of these. &lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Damn, that was a lot of work. I should be nicer to Nils. Here's the &lt;a href="http://www.t3x.org/books/zen.html"&gt;book&lt;/a&gt;, anyway. Let us see what it says:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;"The first points are no-brainers."&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Come on, Nils, we talked about the hand-waving. &lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;"If a language is too complex..."&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Well, by the meaning of the word "too" I think you are on safe ground for the rest of that sentence, but it begs the question of how too is too? Nils needs to make his case or judge someone else's case, not both.&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;"...programmers will have to look up things in the manual perpetually instead of concentrating on the actual problem."&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;So now we need programs to be understandable by people who do not know the programming language? I think that &lt;span class="Apple-style-span" style="font-style: italic;"&gt;was&lt;/span&gt; a design goal for COBOL. Anyway, that does not give you a language with a small instruction set, it gives you a language with long, well-chosen names. Like COBOL.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As for looking things up, I want to meet the guy who looks up delete-duplicates when the status bar is saying:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    delete-duplicates sequence &amp;amp;key from-end test test-not start end key&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's see if there are any more self-serving rationalizations....&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;"The class of problems that can be solved by programs is much smaller. It typically involves very clearly defined tasks like&lt;/div&gt;&lt;div&gt;-- find permutations of a set;&lt;/div&gt;&lt;div&gt;-- find factors of an integer;&lt;/div&gt;&lt;div&gt;-- represent an infinite sequence;&lt;/div&gt;&lt;div&gt;-- translate formal language A to language B;&lt;/div&gt;&lt;div&gt;-- find a pattern in a sequence of characters;&lt;/div&gt;&lt;div&gt;-- solve a system of assertions.&lt;/div&gt;&lt;div&gt;Of course these tasks have to be defined"&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nils must be a professor of computer science. Programs exist to model real-world entities of arbitrary complexity, tho good luck with the human mind. OTOH, simulations of car crashes are admitted into evidence by finicky courts and some people even model human &lt;a href="http://www.theoryyalgebra.com/"&gt;private Algebra tutors.&lt;/a&gt; Unfortunately those things are a ton of work which is why you will not see academics doing that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now about the title. Zen zen zen, what an affectation! Zen this, zen that. I am going to write a book on The Zen of Ordering Take-Out Pizza.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What is zen about zenlisp? Never justified, never even addressed. Does the author think zen means small because it is a small word? I like that, actually. I tried googling for synonyms: &lt;a href="http://www.merriam-webster.com/thesaurus/Zen"&gt;oops&lt;/a&gt;. I think they would be pleased down at the monastery. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So much for the name. How about the language itself? Raison d'etre? &lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;Zenlisp is similar to Scheme, but simpler.&lt;/blockquote&gt;That sounds like being rescued from a desert island and then dropped off in the middle of the Sahara. No, the only reason ZenLisp exists is because Lisp is a venus flytrap of a blackhole delivered by John McCarthy an alien from outer space sent to stop good programmers from Actually Programming. Apparently Grace Hopper was just a few lines of code away from anti-gravity and time travel so They sent John down with Lisp so any good programmer would get so excited about the language itself they would stop programming time-travel applications, take out their CodeWarrior CDs, and start &lt;span class="Apple-style-span" style="font-style: italic; "&gt;implementing&lt;/span&gt; a Lisp using (wait for it) C.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The ones who &lt;span class="Apple-style-span" style="font-style: italic;"&gt;really&lt;/span&gt; want to avoid programming will then write a book about their language. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I wonder what Nils will do now.&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-3023480239322239042?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/3023480239322239042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=3023480239322239042' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/3023480239322239042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/3023480239322239042'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/09/unread-book-review-zen-style.html' title='Unread Book Review: Zen Style Programming, Nils Holm'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-5555583444410903746</id><published>2008-07-25T03:00:00.004-04:00</published><updated>2008-07-25T05:13:40.673-04:00</updated><title type='text'>AA, BB, CC, and DD</title><content type='html'>I am not making it up. Those were the datanames in the code I had inherited from the Wunderkind. So this will be the most boring stating the obvious war story I ever write but that is not why I am writing it. I am writing it because the Lisp subset of the human race is at it again running factual red lights with their prior conviction feet to the pedal.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Yes, kiddies, we revisit today &lt;a href="http://smuglispweeny.blogspot.com/2008/02/maybe-i-was-too-hard-on-sohail.html"&gt;The Unbearable Impenetrability of the Lisper&lt;/a&gt;. The cool thing being that Arc is again involved albeit peripherally in this latest train wreck of human comprehension.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Back then the Maddening Crowd was utterly fascinated that I liked Arc which I did not but they were not to be denied, the best part being those people who responded to my objection to the crowd's misperception by saying yeah I saw you were flabbergasted by everyone thinking you liked Arc so tell me, you like Arc? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No I am not making that up. Twice. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This time it was my scrimshaw-ready datanames, sample below. Some months after my exploration of Arc I had a laugh as I whipped up a DSL for my &lt;a href="http://www.theoryyalgebra.com/"&gt;Algebra software&lt;/a&gt; and found myself approaching Arcitude in the brevity of my names.  I posted something to comp.lang.lisp inadvertently loosing The Hounds of Lisp Density. A sample:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;(hard&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;    (dsb (b x) (rp 2 (rv))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;      (m/ (m^ b (m* (r2 7) x))(m^ (xqv b) (xqv x))))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;    (dsb (b x) (rp 2 (rv))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;      (m* (m^ b (ms* (r+ 7) x))(m^ (xqv b) (ms* (r+ 3) (xqv x)))))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;    (dsb (b x) (rp 2 (rv))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;      (m*eo (ms^ b (r+ 7))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;        (m^ (xqv b) (ms* (r+ 3) (xqv x)))))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;    (dsb (b x) (rp 2 (rv))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;      (m/eo (ms^ b (r+ 7))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;        (m^ (xqv b) (ms* (r+ 3) (xqv x)))))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;    (dsb (n d) (rv 2)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;      (w (k (r+ 12))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;        (m/ (m^ k n) (m^ k d))))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;dsb is short for the Lisp destructuring-bind.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;m/ is short for make-fraction.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;m*eo is short for make-product reordering the factors randomly (either-order)&lt;/li&gt;&lt;li&gt;etc etc&lt;/li&gt;&lt;/ul&gt;I gave a tip of the hat to Arc and explained that I had done this before (in C) and that this code (to generate randomly many varieties of Algebra problems) was a known PITA and even in C I had used the C preprocessor to likewise make the coding manageable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enter the Savages of Comp.lang.lisp.To a geek they lectured me on the importance of nice long meaningful names, or as His Sulzberbergerness edified me a ways back what Confucius called The Rectification of Names which is not quite the same thing but I can never resist name-dropping either Jay or Confucius. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I responded to the jackals nipping at my heels that yeah I know but in this case with vast incessant repetition of a small collection of opcodes that recognition would not be an issue and that it was much better to diminish the low information content (cue Shannon) of long names (what exactly does make-product add to m* in a context where a leading m is used only for makers?)  and learn a dozen opcodes which were mnemonically and predictably built anyway from atoms such as M and * and EO.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The universal response was that longer names were better. My universal response was that these special circumstances flipped the arrow on that otherwise sage rule.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The universal response was that longer names were better.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Trying again, my universal response was that I agreed, but would anyone like to address the salience of the special circumstances I had suggested were germaine, perhaps explaining how they were not special enough or too special or the wrong damn color?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;They all responded that longer names were better and I really started to enjoy things at that point. I was reminded of this desert spider that had a routine for burying any captured wasp and it involved positoning the wasp up just so and then going to dig a hole and then dragging in the dead wasp and these researchers would move the wasp a little while the spider was digging so the spider would be thrown off and start again by repositioning the wasp and no matter how many times they moved the wasp while the spider was digging the spider would just start right over readjusting the wasp and then digging the hole. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The topper was I myself was a staunch proponent of good long names. Tilton's Law of Programming:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt; Spend more time on the names you choose than on the algorithm.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt; As for the specific quality of length, we have Tilton's Rule of Abbreviation:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;Abbreviate no name less than seven characters long and then only if a good abbreviation is no more than half as long. Rounding down.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Which brings us to AA, BB, CC, and DD. I was working as a body shop consultant in easily my most &lt;a href="http://www.hickorywind.org/000068.php"&gt;Tall Building&lt;/a&gt; job ever. One day this new guy came on board, totally not GQ, scrawny, smart, energetic. I had no idea he was a first round draft pick, destined for greatness. An employee, by the way. Tom. He dives in and starts churning out a front-end application, learning the HLL and OS and tools all at once, a man after my heart. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At one point he mentions to me a problem. He wants users to be able to make discontinuous menu jumps, say, go sideways without backing up to the menu above (yeah, this was the good old days of modal interfaces) and the programming language would not go sideways. ie, He was using HLL recursion to handle nested menus.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I suggested the obvious: no, you cannot call sideways in a structured language, you have to return from the called function with a "message" always checked by the caller to see if the user should be taken somewhere else. Tom yelled Great! and tore off to code it up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A couple of weeks later I have inherited the system. Tom was smarter than I: as soon as he had chalked up the win he told his boss to "get some consultant" to maintain it. Moi. So there I am working on the first RFE and I am perusing the code trying to figure out how the hell it works and I find myself slowed a bit by the data names that pretty much controlled everything: AA, BB, CC, and DD.  Come on, you think I could make up names that bad?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So over I wander to Tom's desk, clear my throat, Tom looks up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Tom," I said. "I was looking at the code. AA? BB? CC? DD?"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tom burst out laughing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Those are just temporary variables!" he protested, laughing even more.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Un-hunh," I replied. "And they control the entire program flow."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"Well, change them if you like."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As I said, Tom was a smart cookie, he was wiping his hands of the whole deal.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now it turns out that one of the things I like to do when working on OPC (Other People's Code) is to stare at it and stare at it and when I see some crucial variable playing a big part in things and its name is getting in my way I pick a better name and do a global change, rinse, repeat until the damn code makes sense. The only reason I had gone to talk to Tom was the same reason we pay to see a two-headed sheep at the carnival.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Two hours into the renaming I had come up with decent names for AA, BB, CC, and DD (that last  one turned out to be three different variables) and I was making the global changes eyeballing each as I stepped through the source and after one such change forgive me I will never in my life remember the specifics but imagine you have just made the substitution and are now looking at a line of code that says:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  total-weight = total-weight + this-length&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I did not feel completely comfortable with that edit so I called Tom over. Did I mention he was a smart guy? Two seconds into explaining how I had gotten to that point he yells out, "Great! I gave up on finding that bug!"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Smart guy. Tough bug? He just moved on and chalked up the win. Let some consultant take over the code and run into the bug and think they introduced it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But there you have it. A bug so hard to find that a very smart programmer &lt;span class="Apple-style-span" style="font-style: italic;"&gt;gave up on finding it&lt;/span&gt; and someone who did not even know the bug &lt;span class="Apple-style-span" style="font-style: italic;"&gt;existed&lt;/span&gt; changed a few datanames and the bug positively jumped off the page. Explaining the corollary to Tilton's Law: &lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;If the names are right the algorithm will write itself.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Now if only some walking fencepost from c.l.l will post a comment saying... well, that would ruin it, would it not?&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-5555583444410903746?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/5555583444410903746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=5555583444410903746' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5555583444410903746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5555583444410903746'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/07/aa-bb-cc-and-dd.html' title='AA, BB, CC, and DD'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-2614478629150288518</id><published>2008-07-18T15:16:00.004-04:00</published><updated>2008-07-18T19:14:57.315-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consing Mariano Rivera Lisp mastery'/><title type='text'>Now Batting, Dave. Why is Mariano Rivera not worried?</title><content type='html'>&lt;span class="Apple-style-span"   style="  white-space: pre-wrap; font-family:'Lucida Grande';font-size:11px;"&gt;The venerable Mr. Roberts draws on his profound mastery of things algorithmic as he intones:&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap; font-family:'Lucida Grande';font-size:11px;"&gt;&lt;span class="Apple-style-span"   style="color: rgb(51, 51, 51);   line-height: 18px; white-space: normal; font-family:'Trebuchet MS';font-size:13px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap; font-family:'Lucida Grande';font-size:11px;"&gt;&lt;span class="Apple-style-span"   style="color: rgb(51, 51, 51);   line-height: 18px; white-space: normal; font-family:'Trebuchet MS';font-size:13px;"&gt;I'm actually quite conscious of cons-ing, but I also believe that obsessing about cons-ing leads to premature optimization and far greater numbers of bugs. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap; font-family:'Lucida Grande';font-size:11px;"&gt;We are fortunate to have the benefit of his wisdom and it occurs to me that we can keep talking past each other enjoyably for weeks like this so i will not suggest we try to establish a concrete example where he would code append and I would code nconc and ruin all the fun. But it &lt;span class="Apple-style-span" style="font-style: italic;"&gt;is&lt;/span&gt; a good question especially if we agree (we do) that as a rule the functional paradigm utterly Rocks the Casbah so how on earth am I going to get a list back from some function I call and not be free to nconc it? The moral being I am right (will it never end?): if we try to find a point of Actual Disagreement(tm) we will fail so let us not.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap; font-family:'Lucida Grande';font-size:11px;"&gt;Getting back to the fun abstract theoretical conflict, the problem is a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;policy&lt;/span&gt; of copying which leads straight to the solar power objection aka death by a thousand cuts which in turn leads us back to the simple question of why we do not just code the right operator at every turn? Genius is in the details which means we are &lt;span class="Apple-style-span" style="font-style: italic;"&gt;always&lt;/span&gt; on our game bringing me to Mariano Rivera.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;For those who do not know Mariano plays baseball and is starting to be called the best ever at his position, namely "closer" which means we won the first eight innings and do not want to lose the game please do the rest and he does. Even in the seventh game of the World Series that he lost every hitter broke their bat but the three balls involved known in the game rather morbidly as "dying quails" found their way to the grass. Hard to feel bad about shattering three bats. I digress, Mo is good.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;Genius. Details. The great Nconc vs Append War, Roberts-Tilton III, nothing like this since Ali-Frazier, Affirmed and Alydar.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;It was Just Another Game. The Yanks had won, Mo had saved. They always collar some poor sod and keep him from his shower and car service home to make those of us who pay to watch baseball on cable TV feel better and tonight poor Mariano's number (42!) came up and by the grace of God I pulled my face out of a carton of cold noodles with seame sauce just in time to witness a perfect moment in sports broadcasting and as well a master class in excellence any time any where.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;The announcer on the field for the interview went for a home run question, something way more astute than the usual "How did it feel getting the big out?" and he came up with a beaut: &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;"Billy Bob is a rookie and you have never faced him before, there must not be much of a book on him," the announcer observed. "Was it tougher facing an unknown quantity?". &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;"No," Mariano replied. "I went out during batting practice to watch him hit."&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap; font-family:'Lucida Grande';font-size:11px;"&gt;Mariano's disclosure that as a Hall of Fame shoe-in and multi-millionaire perennial All-Star participant he had looked down at the lineup and seen an unfamiliar name and broken off his clubhouse routine to go watch some ridiculous kid take batting practice had no small effect on our seasoned, professional, expert baseball announcer:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;"You did that?!!!!!!". He blurted out, hopping a little in the air, lurching towards Mariano. "You went out to watch him take batting practice?!!"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;Now it was Mariano's turn to be amazed, leaning back a little to create a margin of safety. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;"Of course," he replied. "I get paid a lot of money."&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;Doodleoodleoodleoodleoodleoooo.  Game over. The announcer (and I, I confess) had been seriously schooled. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;We sit at home and watch these athletes precisely because what they do is so wonderful to us and we endow them in our minds with magical and wonderful qualities because at an early age we were robbed of angels and dragons and Santa Claus and even monsters in the closet and trolls beneath the bridge and then every once in a while we learn that the miracle strikeout we saw with the bases loaded happened because a multi-millionaire punched the time clock, checked his glove for broken laces, sharpened his spikes, and checked the opposing team's roster for any names he did not know.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;I say learn the damn language.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  white-space: pre-wrap;font-family:'Lucida Grande';font-size:11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-2614478629150288518?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/2614478629150288518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=2614478629150288518' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/2614478629150288518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/2614478629150288518'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/07/now-batting-dave-roberts-why-is-mariano.html' title='Now Batting, Dave. Why is Mariano Rivera not worried?'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-1876652932622299754</id><published>2008-07-18T02:55:00.004-04:00</published><updated>2008-07-18T03:41:26.392-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lisp consing solar power torpedos molasses tuning'/><title type='text'>Fear No Evil II, or Why Solar Power Sucks</title><content type='html'>Just a quick note cuz I remembered something that answers Dave's well-reasoned comment:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color: rgb(51, 51, 51);  line-height: 18px;  font-family:'Trebuchet MS';"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;My own personal rule on this is to use functional programming whenever possible and let the GC deal with it. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Not much of an excerpt, but it says it all: modern Lisp GCs truly Rock the Casbah, and I myself am on record as denouncing the flipside of this blogcoin, consophobia. Actually, there may be a problem, Dave says "whenever" possible and perhaps then we agree! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But "whenever possible" has a ring to it like "oh, you know, all the time" and I actually had a good reason for not doing &lt;span class="Apple-style-span" style="font-style: italic;"&gt;that&lt;/span&gt;, I just forgot it. Has to do with solar power. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The reason solar power sucks even though there is an overwhelming amount of it is that it is diffuse. Yes, enough sunlight falls on Kansas in a month (I am making this up) to power Earth for a year, but just try to find a solar panel as big as Kansas, never mind deal with the Kansans or the inefficiency of the transmission to Australia. I digress.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem with a "Damn the consing! Full molasses ahead!" policy is that when ones application drags to a halt there will not be a bottleneck to fix. There will just be hundreds of places one was too lazy to think about whether one could use the right construct. And correcting them all will be as painful, tedious, dreary, mind-numbing (sound like fun yet?) and thus as bug prone as it would be easy and fun whenever reaching for a list manipulation tool to challenge oneself with, gee, can I cut in the afterburner? Stand back, GC! Captain Destructo is in da house!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That is a practical objection. My ethical objection (viz, hey, learn the language) is not all that far behind: jeez, I am building this list right here in front of my eyes, why am I not using a destructive operation for the next step? Do these same folks all have a copy-n-sort function in their personal toolkits that begins with a copy-list on the sequence to be sorted? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No, they do not. Why not? Hello.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My apps periodically get bogged down. I wait until they do and then dive in for what I like to call Speed Week after a regular TV extravaganza on vehicular racing. Normally this turns up interesting algorithmic gaffes I do not feel too bad about but one time the smoking gun was the most innocuous little needlessly copying statement you can imagine write at the center of the heaviest hitter bit of code you can imagine. This is pretty much the opposite of the solar power argument -- there &lt;span class="Apple-style-span" style="font-style: italic;"&gt;was&lt;/span&gt; just one little guy to track down -- but without the code profiler offered by AllegroC I am not sure how long it would have taken to find that. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And now I come back to the main point: er, exactly how hard is it to know when one can use destructive list operations?  So why not use them? Only one excuse comes to mind (fear) but always copying is not even a clear win (ie, it can totally suck at times) so.... learn the language?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If I was going to cut the Copying Cowards some slack I would say, shucks, not everybody writes insanely intense tight loops. But then I remember a point I made in FNO/1: we get noobs all the time struggling with slow code because of excess copying. Perhaps complex applications and tight loops are orthogonal?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I say learn the damn language.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-1876652932622299754?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/1876652932622299754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=1876652932622299754' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1876652932622299754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1876652932622299754'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/07/fear-no-evil-ii-or-why-solar-power.html' title='Fear No Evil II, or Why Solar Power Sucks'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-3712749671353841083</id><published>2008-07-14T02:25:00.005-04:00</published><updated>2008-07-14T03:56:15.645-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Chomsky Pinker skateboards drinking'/><title type='text'>Chomsky! Pinker! Get In Here!</title><content type='html'>[OK, OK, it is a Lisp blog but if I can refute Chomsky's entire body of work on language acquisition in one post, why not?]&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These academic PhD geniuses have a problem. They are geniuses. They think they can figure everything out by thinking, like Feynman fixing the neighbor's radio at the age of three or something close to that by thinking. Great story, buy the book. Forget which.&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Chomsky and Pinker merely repeat the error of the AI crowd who sniffed at NI (I just made that up, it means "natural intelligence") and said, "NI?! NI?! We don't need no stinkin NI!". They said that because they were geniuses they knew that what NI did with pretty much organic chemistry they could stomp with (drum roll, please) &lt;i&gt;reason&lt;/i&gt;.  Ooooohhhh, excuuuuse me!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I guess I can leave Pinker out of this, he did not add anything to Chomsky, he got drugged in only because a correspondent mentioned his "work" on blank slates. I love that "work": Oh, let me lean back and draw on my pipe and I have a PhD so if I think babies learn something too fast they learn them too fast, dammit! As if. And believe it or not I am coming to my point. But first a science trick, a prelude to my witnessing of the refutation of Chomsky. It has no bearing on anything else but it involves a cute girl and something I could not believe when I saw.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There I am in a sports bar/shore bar celebrating a great week almost delivering my world-changing &lt;a href="http://www.theoryyalgebra.com/"&gt;Algebra software&lt;/a&gt; when I see a lovely lass drop her drink. Three or four feet, to the floor. It was a plastic cup, which helped a lot come to think of it, because a glass glass being more rigid would not have absorbed the energy and there would have been a wicked rebound preventing what happened from happening: the drink landed upside down and just stood there, trapping half the drink inside. The bad news being there was no elegant way of finishing said drink, but that is not my point. Did I have a point?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, if I had to have a point, it would be that no one else was all that impressed. Clearly I need to spend more time in bars late at night watching drinks being dropped and I do not think it is possible to spend more time in bars late at night than do I so I guess I need to find bars with clumsier people, good luck on that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh, and the other useless and irrelevant to the demolition of Chomsky/Pinker thing I learned is that it takes just &lt;i&gt;one&lt;/i&gt; unauthorized speech on world affairs (well, he was mumbling pretty badly, I am not sure it was on world affairs) over the unattended band microphone to get escorted unceremoniously out the front door at the sports bar in question. Right, Chomsky.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I look up and I see a skateboard competition, lucky enough to be watching the winner's winning run, and lucky enough for my brain to clear long enough to understand what I am seeing, a Johnsonian kicking of the rock I refute you thus Dr Berkeley of Chomsky/Pinker by some sixteen year-old if that. What did he do, and why did my brain have to clear? Two good questions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What he did was give himself a push across a flat floor in a reasonably small room (no gigantic ramps and concomitant acceleration/stored momentum) and upon reaching a ramp at the same time push off in such a way that the skateboard (unattached to his feet for those who do not know) elevated with him to a height just above a rail (er, just an elevated horizontal pipe mebbe a foot off the floor) such that he could land on the skateboard in midair just as the tip of the skateboard landed on the rail and using his/their forward momentum proceed to slide along the rail for a couple of yards before again levitating off to land somewhere else to commence another trick. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And before the anti-blank-slate morons can scream "Oh that is easy, I have the algorithm right here" allow me to break their hearts and add that as he did the initial elevation springing the board into the air with him (a yawner in these competitons) he took the trouble to pop his deck into a barrel roll (or two, who knows at that speed?) before regaining it to land the rail toe-slide. If the MIT geniuses think that is easy lemme just say that I have spent &lt;span class="Apple-style-span" style="font-style: italic;"&gt;years&lt;/span&gt; in Central Park watching the same people practice on skateboards for &lt;span class="Apple-style-span" style="font-style: italic;"&gt;years&lt;/span&gt; and they still cannot jump over a small backback and land on the skateboard on the other side.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So... these people have skateboard organs? Or do you think learning to barrel-roll a jump into a rail toe-slide is more important to them than is mastering language to an infant so their motivation is stronger? This would be a reasonable belief if one has never been in the presence of an infant who will join in any conversation it hears when it neither understands nor can generate one intelligible syllable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh, and why did my brain have to clear? Because what I saw was a commonplace: inconceivable performance easily explained by sufficient practice. If a recent blog had not been on my mind I would not have given the skateboard performance a second thought, nor the motorcycle-flipping organ &lt;sigh&gt; manifested in the next story on ESPN.&lt;/sigh&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Come to think of it, this &lt;span class="Apple-style-span" style="font-style: italic;"&gt;is&lt;/span&gt; about why Lisp wins: we simply are not as smart as we think we are. I like to say that I cannot write good code but I do know when I have written crappy code. Recognizing is easier than generating. Hell, crappy is just one bit, right? But how do we produce a huge stream of uncrappy bits? Good luck.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What we want then is an agile language that lets us create awful code really fast and fix it as fast as we identify the problems. Pretty soon our software organs &lt;sigh&gt; cut in and we are creating not-so-awful code up front. Even better.&lt;/sigh&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now I just have to figure out an elegant way to finish a drink upside down on a barroom floor.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-3712749671353841083?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/3712749671353841083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=3712749671353841083' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/3712749671353841083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/3712749671353841083'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/07/chomsky-pinker-get-in-here.html' title='Chomsky! Pinker! Get In Here!'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-1523095351455178553</id><published>2008-07-09T02:39:00.003-04:00</published><updated>2008-07-09T03:19:19.593-04:00</updated><title type='text'>Buzz off, Charlotte</title><content type='html'>Omigod. I just made up that title because of the subject of this post and not five minutes ago I ended up daydreaming about a girlfriend I had back in college named Charlotte and as you will see there is no connection. Scary.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, it is 2:38 am and I am in the middle of a trivial but unwelcome re-de-refactoring with a scant few days to go before a self-imposed but jeez I gotta get this frickin thing out the door it is the middle of July deadline and it is an &lt;a href="http://www.theoryyalgebra.com/"&gt;educational app&lt;/a&gt; &lt;span class="Apple-style-span"  style="  white-space: pre; font-family:'Lucida Grande';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="  white-space: normal; font-family:Georgia;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;and how far is it from the middle of July to frickin September?!!!!!!! I digress. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is 2:38 am and a spider I swear to god no more than 2mm across is dangling in front of my flat planel trying to figure out this code (the last bit of the last line, to be precise):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;(defun alert (s oks)&lt;/div&gt;&lt;div&gt;      (tk-format-now (conc$ "tk_dialog .oops {&lt;cough&gt;} {"&lt;/cough&gt;&lt;/div&gt;&lt;div&gt;                   (format nil "I thought you were solving for \"~c\"? I do not see it."&lt;/div&gt;&lt;div&gt;                            (key-char sfvar))&lt;/div&gt;&lt;div&gt;                   (format nil "} {} {~s} {~s}" oks oks))))&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Charlotte (look it up furriners, E B White) is freaking out over the double occurrence of the variable OKS. I know because the little hussy has lowered herself I swear to God ten feet from the A-frame ceiling of my ranch rental all the way down to within a foot of my desktop and stopped. How still is the air in here? She was swaying no more than another 2mm.  I digress. But how does a 2mm spider pack ten feet of gossamer into its, well, gossamer pack?! I don't care how thin it is, it is stll ten feet!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Charlotte was both deeply concerned and a sufferer of tunnel vision. She ascended to the top of the flat panel (I have it angled down to my slouched position a few inches above desktop), gained a foothold or five, and then inched...no, mmed over and redescended to get a better look at the first occurrence of OKS, just to be sure. It is possible she then pirouetted on her thread to ask why I did not check the CLHS on FORMAT to find out how to back up one argument and re-use it, but I cannot be sure. If my eyes were better, I could tell you. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, I am in a hurry dammit and you know what I think I have the strength to type oks a second time and no I do not think the redundancy will lead to the loss of a satellite but if a damn spider complains I know enough to listen... ah, there it is ~:*, back up one arg.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now buzz off, Ch... hey, where'd she go?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-1523095351455178553?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/1523095351455178553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=1523095351455178553' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1523095351455178553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/1523095351455178553'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/07/buzz-off-charlotte.html' title='Buzz off, Charlotte'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-5640318785057335551</id><published>2008-07-03T02:07:00.004-04:00</published><updated>2008-07-03T03:38:52.715-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nike Spike Lee Michael Jordam shoes Lisp'/><title type='text'>It's the shoes, Jeff! It's the shoes!</title><content type='html'>My buddy Jeff wondered aloud on comp.lang.lisp why We Lisp Gods were so much better than the rest of you at adapting to alien environments, aka other languages. Without coming down in favor of any, he offered several possible explanations:&lt;div&gt;&lt;ol&gt;&lt;li&gt;We are just smarter than you un-Lisping dopes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We are accustomed to learning other languages because the food is OK in soup kitchens but the decor? Omigod!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We are older and you can't teach an old dog new... hang on.&lt;/li&gt;&lt;/ol&gt;Based on recent copious experience, you can safely forget #1. Lispers are precisely as dense as other programmers, and if anything more so: as the title suggests, we are being carried by the shoes. Anyone both smart &lt;span class="Apple-style-span" style="font-style: italic;"&gt;and&lt;/span&gt; using Lisp is named Graham or Morris and either has or split over forty big ones, and no, a thousand smackolas is not "big".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;#2 is a fine answer but is boring and knocks the legs out the upcoming argument so let us declare it false. That was easy&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;#3 is part #2 and part what I joked: old may be wise but it sure ain't adaptable, it already knows The Right Way, it aint listenin.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That leaves the title of this entry, a reference to one (or more?) humorous Spike Lee ads for Nike sneakers in which he insists the sneakers explain Michael Jordan's Unbearable Lightness, to which we see his Airness reacting with feet-on-ground dubiosity. IIRC, but I think I do.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But in this case, I think for once Chomsky might find a home. Chomsky decided that because he Chomsky could not understand how infants picked up language that there must be a magical device at play, a language organ in the brain dedicated to language acquisiton just as the spleen is dedicated to damn I wish I had not slept through biology.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Chomsky had a tiny little problem with his nonsense in that when one looks at human languages -- any of which can be picked up by any infant raised in its midst, whatever that infant's genetic tree -- well, the structural variation is infinite. I remember one universality they found: adjectives tend to appear very close to the nouns modified. Well, shazaam!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So the Chomsker has a problem: this super-duper language organ has to be hardwired not to learn any particular syntax, it has to be hardwired to learn every syntax. Ok, that makes no sense, shall we try again?........... um............. er....................... I got it! It is hard wired to learn an abstract syntax! If only we could find one!!! Chomsky failed except for that bit about modifiers miraculously always appearing close in sentences to the thing being modified.  Yeah, how come no language ever came up with "The little giant slowly balloon over drifted the mansion red white."? Because the language organ rejected all those! &lt;sigh&gt; Where was I?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ah, flexible language acquisition, computer or otherwise. No, it is not the brain, it is the shoes. Basketball no, programming yes. No, Michael did not reach new heights because his sneakers opened new doors for him, but yes: expose someone to Lisp and (as many before me have observed) they become a better programmer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Chomsky saw the infinite variability of actual syntaxes as a severe objection to his hypothesis, and he was right to do so. Indeed, look at it from the other direction and we see the light: forget infants' ease of language acquisition, look at the difference between those who know one language and those who know five. Something happens after one has learned a bunch of languages -- acquisition of the next becomes a snap. No, I do not have that backwards. There is a small effect of "hey, anyone who has learned five just digs languages and does because they are easy for them", but I learn natural languages insanely easy and get a huge kick out of stumbling thru a conversation in French or Mandarin and learning a new language is &lt;span class="Apple-style-span" style="font-style: italic;"&gt;still&lt;/span&gt; hard for me because circumstances never led me to learn more than what I needed to get out of high school. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No, what is going on is the same as any learning process: the more we do the more the brain wires up metaskill at that activity. Babies are not born with a language organ, they just happen to have nice blank slates and speech is to them obviously something utterly compelling to master, it seems to control these big creatures moving about before them. Nothing like insane motivation for apt learning, eh Dr. Chomsky? But later on in life when a second language is an amusement? Acquisition is brutal. Where's the language organ now? Withered? Why does it come back after I have learned four the hard way? Ooops.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Was I supposed to be answering Jeff's question? My bad. Chomsky was wrong, McCarthy was right: a language in which code can be data and verse visa is one in which the programmer is stripped of structure and stricture and as Sartre warned us is not free to be not free. In mastering any art true freedom comes only within the constraints of the form, but Lisp offers us no such handholding. Some brilliant wag once observed that Lisp gives us a million ways to do anything but (1- million) of them are wrong -- a working Lisper like one who has learned the hard way five natural languages learns a metalanguage of programming that would delight and disappoint Chomsky, because the learned metalanguage is just one more demonstration of the brain's ability to find patterns in whatever it is immersed in long enough. ie, Organ, schmorgan, neural nets simply rock.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lispers are not smarter, they just fell into a pool and learned to swim -- ah, good analogy, nothing to hold them up, had to make do in a medium that would not support them, they had to add energy to the system to stay afloat, something like that. Lisp not only supports every paradigm, worse, it even allows any paradigm you can invent one as I thought I did with Cells until I looked up the prior art, but that does not change the fact that while working on a little GUI geometry problem a new paradigm jumped into my code... deal with this kind of language and... well, imagine sneakers that really did have wings. Wear those for a year and then climb back into ordinary sneakers...I'll give you a minute to think. What happens?&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;.&lt;/div&gt;&lt;div&gt;Disappointment? Some. Depression? No. End of flying? Never. You have tasted flight, you know what is possible, and you want to be there again. Now the analogy breaks down, because guess what? Lisp is just another language. When you do not have it, you can Greenspun it. When subjected to a toad of a language you grouse for fun but you also have code to write and you shrug off the downgrade and fly with the sneakers you have. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my first programming job I astounded the team so badly they kinda fired me, gave me only the maximum raise and blew me off when I asked for more because in nine months I had finished every system they had in development. At my going away they said they did not go out on a limb for me to exceed the maximum because they knew I would be leaving anyway. They did not know how much I loved the company bowling league or softball beer league. What was my secret in this Cobol shop? I had been programming in Basic on an Apple II. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One day I came upon a senior guy (OK,they were all senior, I had been there three months at the time) staring at my code as he tried cloning it to his assigned, well, clone. Concerned, I paused and asked if there was a problem. He waved me away, saying, No, I just have never seen Cobol like this. I understood. I knew even as I did it that I had been programming Cobol in Basic. I think I have that backwards. I remember asking them -- I was just learning Cobol at the time -- if a subscripted variable could be a subscript and I remember a very nice twenty-year Cobol veteran asking me very gently if I might not be making things a little too complicated. Nah, just trying to do Basic in these Cobol sneakers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lisp then is a substitute in itself for learning five natural languages, because it itself is not Chomsky's language organ, it is the universal syntax Chomsky had to identify for his imagined language organ to have been hardwired to learn. Lisp is the programming language embodiment of Sartre's curse: we are not free to be not free. Program this language and one will first use the wrong language feature at the wrong time (hang out on comp.lang.lisp to witness the hijinx of Lisp noobs trying to do things "The Lisp Way") and eventually get to the point where one can look at problems and see the paradigms they bring with them aided always by your language which is being utterly useless at telling you what paradigm to use, it could care less. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ie, It's the shoes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-5640318785057335551?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/5640318785057335551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=5640318785057335551' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5640318785057335551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5640318785057335551'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/07/its-shoes-jeff-its-shoes.html' title='It&apos;s the shoes, Jeff! It&apos;s the shoes!'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-5714570011002078729</id><published>2008-05-30T16:52:00.005-04:00</published><updated>2008-05-30T18:47:57.608-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='30day'/><title type='text'>30Day Death March: If They Can't Take a Joke, F**k 'Em</title><content type='html'>The title? Part one is &lt;a href="http://kalzumeus.com/2008/05/25/more-talking-and-more-doing/"&gt;someone's idea&lt;/a&gt; on how to distract programmers from working so as to make it even less likely we will get anything done in thirty days but at least we'll have company. Part two is how we pull it off and is what we used to say about the customer on my summer job in the automobile brake repair shop when we felt our work was a little sketchy. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I poked around on the feed and can confirm what someone said: I totally killed myself over the years by thinking certain edge features were indispensible. In my head an imagined reviewer was  going batsh*t over something that could be better, like a Consumer's Report automobile editor knocking off two stars from a sport sedan review because their test football linebackers found access to the rear seat problematic. Did you notice it was a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;sports sedan?!&lt;/span&gt; The linebackers can take the frickin &lt;span class="Apple-style-span" style="font-style: italic;"&gt;bus&lt;/span&gt;, OK?!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Even knowing this I did it again this time around (this is version two of something I did in the last century) and I blame Lisp because it made it so damn easy. At first. I failed to notice quickly enough the ensuing death by a thousand cuts for which I thus had signed up. That sentence reminds me of diagramming sentences in the ninth grade when I should have known I would be a social failure when the English teacher and I were doing high fives over the corner cases while the other kids in the class were silently writing me off as... I digress, just watch out for Lisp, it is a two-edged sword.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The crazy thing is that I also know damn well and will tell anyone who asks that this is one of those 80-20 or 90-10 deals, pick yer own damn ratio, OK?: almost all of the value is in the first feature. [kick kick kick] &lt;kick-kick-kick&gt; That was for me, not you. Who are you, anyway?&lt;/kick-kick-kick&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One caveat: sitting in my cubicle above cloud level one day on one of five floors dedicated to IT drones I was stunned to overhear an intelligent abstract discussion of technology. Someone had a theory. I &lt;span class="Apple-style-span" style="font-style: italic;"&gt;love&lt;/span&gt; a good theory. This one said, Don't ship too soon. The point was and my experience had already confirmed that shipping costs. Period. Suddenly one is working on all sorts of crap that does not move the product forward. Once one ships being live costs. This microISV stuff is about one-person operations so guess who is dealing with the cost/burden of being live? And guess another thing: how completely ineradicable are first impressions? Can I write a survey question guaranteed to elicit unbiased responder input or not?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oops, what am I? The Anti-30day-Christ? OK, let me finish on a positive note. True story.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"These drawings are wonderful," marvelled aloud the pre-school parent to the children's teacher. "You have a great gift for art instruction."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"No," the teacher demurred. "I just know when to take their drawings away from them."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We few, we happy few Actually Writing Applications have as our mission should we choose to accept to take from ourselves our own applications. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-5714570011002078729?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/5714570011002078729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=5714570011002078729' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5714570011002078729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/5714570011002078729'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/05/30day-death-march-if-they-cant-take.html' title='30Day Death March: If They Can&apos;t Take a Joke, F**k &apos;Em'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-4553396327363092058</id><published>2008-03-22T17:45:00.006-04:00</published><updated>2008-03-24T22:19:41.095-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming design Taoism'/><title type='text'>"We Can Live With the Way You Handled That"</title><content type='html'>Tilton's Lemma had come under attack and the title of this entry was the happy result. You forgot Tilton's Lemma? Here ya go:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Refinements to requirements cannot vary fundamentally from the original.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;The point is that careful design is worth the effort so that software can be successfully rolled out even though users naturally produce RFE after RFE during user acceptance testing. No matter what they come up with the software will adapt to it with a minimum of refurbishing.&lt;br /&gt;&lt;br /&gt;So what was the attack? We must begin with the launch meeting of the relevant project, where my conduct was such I rarely again got asked to meetings, but as a tease I will share that this was one of the most profound God is speaking to you experiences I have had in software development, one of those moments where one senses forces unknown at play.&lt;br /&gt;&lt;br /&gt;I was being given a nice new standalone task perfect for a cowboy contractor such as myself who was good with code but not with teams. My manager Frank would be perfect for such a loose cannon, one who cared not about how loud I snored when I catnapped or at what hour I showed up or how badly my lunch reeked as I ate it over the keyboard but only if the code worked so he could sleep at night.&lt;br /&gt;&lt;br /&gt;Just one problem. I walk into the launch meeting and sit down having no idea what is happening. After thirty minutes of sitting quietly at one corner of the table having nothing to do with any of the discussion I have deduced that a foreign branch of the bank has accounting software that will be shut down and covered by the software at our central location and that I will be writing the interface to take the feed from an off-the-shelf humongoid accounting package and feed it into the central system in such a way that it replicates their existing system.&lt;br /&gt;&lt;br /&gt;I have grown increasingly intrigued at this prospect as the meeting drags on because our group has more than a few people assigned to supporting the massive off-the-shelf system (shall we call it Isis?) and it seemed worthy of months of apprenticeship. On top of that I certainly had no knowledge of the foreign branch's system. Best of all I knew less than nothing about accounting. Okay, no, best of all was that no one was talking to me at the meeting so I developed this crazy idea that they were just going to turn to me at the end and say, Need anything else, Ken?&lt;br /&gt;&lt;br /&gt;Then Tony the Senior AVP turned to me.&lt;br /&gt;&lt;br /&gt;"Need anything else, Ken?"&lt;br /&gt;&lt;br /&gt;Left to my own devices for the first 99% of the meeting I had had time not only to deduce its ending but also prepare an answer. My fans from comp.lang.lisp can tell you His Kennyness likes nothing better than a good analogy and it had occurred to Himself that the developing situation resonated strongly with an image that formed spontaneously in his mind of a couple with a dog on a leash standing on some corner in the middle of Manhattan deciding how best to get to the Botanical Gardens in Brooklyn and after considerable discussion and perhaps even a consultation with maps street, bus, and subway settling on a means and path of transveyance and turning to the dog and saying, "Lead on, Fido!"&lt;br /&gt;&lt;br /&gt;Hence my prepared answer, before not one but two AVPs and the users on conference call from Canada:&lt;br /&gt;&lt;br /&gt;"Woof! Woof!", I offered, and looking back I regret only not having thought to wiggle my ass in my chair to signify enthusiastic tail wagging.&lt;br /&gt;&lt;br /&gt;When it became clear that the import of my barking had eluded those present and had at least stunned Canada into silence I expanded on it by observing that I knew neither the sending application nor the application I was meant to replicate nor the entire subject of accounting and concluded by wondering aloud if the guy outside tending the falafel cart might not be a better fit since he at least knew how to make change.&lt;br /&gt;&lt;br /&gt;The Canadians had heretofore been utterly thrilled at the idea of having their accounting taken over by our central gang that could not shoot straight (I'll wait while those of you who missed the irony go back for a look) and now they had White Fang as the contractor assigned to the task, confirming their worst nightmares.&lt;br /&gt;&lt;br /&gt;They agreed to provide a thorough specification and the AVP and I ever after when meeting in the hallway would bark at each other in greeting and at his going away dinner -- well, after the second round of shots it was pretty much non-stop howling, thank god for private rooms, we should have had one. I digress.&lt;br /&gt;&lt;br /&gt;Remember: this is about users not being able to change requirements discontinuously. So now we know how I ended up with the most beautiful requirements from which I have ever worked. Requirements? Bah, this was pseudo code. Just brilliant. They identified a dozen kind of transactions/situations/circumstances I could expect from Isis and they specified exactly how each should be handled.&lt;br /&gt;&lt;br /&gt;And this "exactly" was not just exact. There was this tremendous regularity in how they specified the handing of each case. Each was expressed cleanly as so many debit this, credit that, debit this subtransactions. These subtransactions just begged to be viewed as microcode for the larger instructions specifying how each case was to be handled.&lt;br /&gt;&lt;br /&gt;So that is the code I wrote, after effusively praising Team Canada to themselves and anyone else I could find. The high-level code read Isis transactions, identified the high-level case, and invoked its handler, each handler dispatching one or more microcode subtask handlers. We are talking easy work and soon we sail into user acceptance done thoroughly for a couple of months because I mentioned they did not trust us. I also know it was a long time because by the time the call came through with the title of this entry I had forgotten about the entire issue to which they referred, which was this:&lt;br /&gt;&lt;br /&gt;After a week my bugs had been rooted out and IRs were being handled by letting them know how they had screwed up the test. Frank was happy, I was snoring, life was good, we had time to buzz about this new write once run anywhere language called Java that would let browsers run applets.&lt;br /&gt;&lt;br /&gt;Then well into the test when the IRs had slowed to a drip I got a call from Canada. I had blown a transaction. Lemme see it... OK, sorry, that is what the spec says. No, these have to be handled this way, the debit goes over here and credit goes over there when X is Y.&lt;br /&gt;&lt;br /&gt;Now as usually happens in these deals I still did not know anything about accounting but some of the words had taken on glimmers of meaning and I asked, But isn't this the same as whatever? And then I threw around some terms and said that from my poor understanding what they were suggesting seemed wrong. Nope, that is how we do it. OK. Bye. Bye.&lt;br /&gt;&lt;br /&gt;And now comes the good part. I invoked Tilton's Lemma -- not because Kenny could not see the legitimacy of their accounting, though that encouraged me, but because of something else I found to be strangely compelling: my code would not do what they wanted.&lt;br /&gt;&lt;br /&gt;I tried to see how I could patch in the exception and there was no way. I would have needed action at a distance and Einstein had already spoken on that. What was needed was for the microcode to behave differently based on information (X and Y) available only at the top level in which the higher level transactions were being identified and their handlers invoked. The only way to give Canada what they wanted was either to add a parameter to everything in the call chain (which I would have called woof-woof, I think) or even more elegantly to set a global variable at the higher level that this one microcode handler could watch out for. Ewwww.&lt;br /&gt;&lt;br /&gt;Now please do not think I am posing as a person of integrity or principle or anything because I am the most miserably pragmatic soul you can hope to meet, but I got back on the phone to Canada.&lt;br /&gt;&lt;br /&gt;"Marcia, Kenny. My code does not want to do what you want, eh? Your spec is pretty clear on all these things and just from the sound of it it seems the way I am handling it now is right anyway. I can kludge things up to get what you want, but I will hate myself in the morning."&lt;br /&gt;&lt;br /&gt;Marcia said she would talk to Bernie, her VP, and get back to me. She did not do so for so long that I forgot about it and to her credit she did not even have to make the call but she did.&lt;br /&gt;&lt;br /&gt;"Kenny, Marcia. I spoke to Bernie. The way you are handling that transaction will be OK. We can live with the way you are doing it."&lt;br /&gt;&lt;br /&gt;Tilton's Lemma lived on. Somehow clean design (starting I freely acknowledge with a great spec) had flushed out a faulty business practice. The users had indeed offered an RFE discontinuous with all their other stated requirements, but it turned out to be such an egregious error that they agreed to fix it. (To their credit again!)&lt;br /&gt;&lt;br /&gt;Why does this war story give me goose bumps? Yes, I need to get out more. And OK, maybe it is not such a big deal. The careful architecture forced on us by having to program these godawful machines makes it easy for programmers to see inconsistencies the business experts miss.&lt;br /&gt;&lt;br /&gt;I just get a kick out of it -- a sense of God or Plato or the Tao throwing their weight around as long as we take design seriously and hop on the phone over such things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-4553396327363092058?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/4553396327363092058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=4553396327363092058' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/4553396327363092058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/4553396327363092058'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/03/we-can-live-with-way-you-handled-that.html' title='&quot;We Can Live With the Way You Handled That&quot;'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6508797467947601724.post-2475597964318051331</id><published>2008-03-22T12:11:00.006-04:00</published><updated>2008-03-22T15:01:37.673-04:00</updated><title type='text'>TLOP: The Worst Thing You Can Say About Software Is That It Works</title><content type='html'>I walked out of my cubicle, turned left, went up one maze turn, turned into the next cubicle. This was clearly a while ago, before email and even before I had reached the point where I would phone a guy ten feet away in case they were not there so I could leave voice mail.&lt;br /&gt;&lt;br /&gt;I wanted to tell Mike that I had enhanced the julian date function he had shared with me so he could replace his with mine instead of the system growing a multiplicity of julian date functions.&lt;br /&gt;&lt;br /&gt;Mike was another contractor on some godforsakenly dreary application being developed at cruising altitude in some megabank, a great guy always joking well and laughing about everything including his obsession with the real estate scheme infomercials he apparently watched non-stop in his free time.&lt;br /&gt;&lt;br /&gt;I told Mike I had snazzed his function up nicely, generalizing it or adding some whiz-bang feature or something, and mentioned he could now modify his program to use the new version.&lt;br /&gt;&lt;br /&gt;Something I need to get across to My Cherished Reader is the utter and profound honesty of Mike's reaction. Indeed, sufficient googling may well surface Mike's blog entry detailing in turn his astonishment and horror at what I had proposed. For when I finished there was a brief moment of incomprehension and then a dawning and his eyes grew wide and his jaw dropped and then a huge smile of wonder spread across his face, his palms rose in supplication for any possible justification of my madness and at last words came to him.&lt;br /&gt;&lt;br /&gt;"But...but...," he stammered for effect. "My code already works!"&lt;br /&gt;&lt;br /&gt;It was a grand moment, two solid technologists sincere in their craft standing face to face with not one scintilla of common ground on the simplest of questions.&lt;br /&gt;&lt;br /&gt;Mike was reeling at the idea that a working module should be touched. He repeated his encomium ("It works!") and then with no offense intended and with solid good-feeling camaraderie just started laughing at me.&lt;br /&gt;&lt;br /&gt;Meanwhile I knew without doubt that swapping in my version would likely take one minute (what's that? about sixty seconds?) and that application systems should be kept as simple as possible (and so not have two julian date functions (can you say Y2K?)).&lt;br /&gt;&lt;br /&gt;I shrugged -- it was a small matter -- and retraced my path back to my cubicle before the pheromone trail could grow cold. Well, this is my blog, so Mike was wrong. Tilton's Law:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;The worst thing you can say about software is that it works. &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;I think I can prove that with geometry: if a pile of code does not work it is not software, we'll talk about its merit when it works, OK? Therefore to say software works is to say nothing. Therefore anything substantive one can say about software is better than to say it works. QED. (That last bit is the geometry.)&lt;br /&gt;&lt;br /&gt;So what else besides that it works can you say about software, especially about applications written in tall buildings? Well, unless one is banking on the relatively high probability that the project will get canceled before ever it sees light of day, the software will eventually be asked to do new things or to do old things differently.&lt;br /&gt;&lt;br /&gt;So the software must not be brittle and must not have any more built-in assumptions than necessary and where one builds in the assumptions it would be nice if they were abstracted out of the core so that new requirements can be handled as gracefully as possible.&lt;br /&gt;&lt;br /&gt;Note that new and changed requirements come along not just after a successful deployment but also during development, perhaps even more so because only when users see software do they realize what they wanted. They should do a study: I bet requirements change more just implementing the software than they do ever after. Brittle, inflexible software can be so hard to change during development that projects never make it out the door no matter how well the software "works" on the original requirements.&lt;br /&gt;&lt;br /&gt;Reminds me of another war story. Schedule "B".&lt;br /&gt;&lt;br /&gt;The law on tax shelters had just been changed eliminating the bogus write-offs those things produced and some financial establishment needed some contractor to write the software to generate statements for clients detailing exactly how badly they would be hosed by the new law. Apparently they had tried it in-house and the guy assigned to it had quit after working on it for a couple of months to no avail. Jobs were everywhere back then in the Eighties, why not?&lt;br /&gt;&lt;br /&gt;God forbid I should digress: it was a fun interview, really nice group and nice manager. The best point was when he asked His Kennyness what was His greatest weakness. Neat question!&lt;br /&gt;&lt;br /&gt;Lemme see...no...no...no... I was looking at the floor going through coding, debugging, DB design, and it was taking a while which I thought was pretty funny and I am sure they were all enjoying it but I &lt;span style="font-style: italic;"&gt;really &lt;/span&gt;wanted to come up with something and then it came to me.&lt;br /&gt;&lt;br /&gt;"Testing!" I almost yelled. "I am terrible at testing!"&lt;br /&gt;&lt;br /&gt;Whew! Reminds me of the time I had a little team (this was before people realized I should just be chained to an out-of-the-way workstation and hosed down and thrown food as needed on big projects) and was assigned a junior nooby who asked me the same question about three times and who hated me because apparently Hell hath no fury like a woman gently suggested she might take notes,  which was great (that she hated me) because she was so useless we just had her testing my code and believe me no software has ever been subjected to such merciless, sustained, and deliberate abuse as was mine. Every twenty or thirty minutes we would hear this triumphant rejoicing "Ha!" explode from her cubicle as she found another bug and imagined another dagger plunged between my ribs when in fact I was loving the whole thing because to me testing is just God and Abraham and Isaac all over again. Where was I? Schedule "B".&lt;br /&gt;&lt;br /&gt;Anyway, the task went very well. The manager (another Mike) gave me a very clear spec and I did my usual structured architectural blah-blah-blah and the users were very nice and called me every once and a while with RFEs. Bringing me to my point.&lt;br /&gt;&lt;br /&gt;Mike was a great guy but also button-downed and into process and told me not to listen to the users, make them ask him and he would tell them, No.  So I was always very nice with the users and said I welcomed their thoughtful consideration and input and could barely restrain myself from just dashing it off right now if I could just put them on hold for a second and I will indeed start looking at the matter while it would help very much if they could just run this great idea past Mike, he's a bit of a stickler for protocol, terrible bother I know, hate to ask this of you.&lt;br /&gt;&lt;br /&gt;OK, they would say.&lt;br /&gt;&lt;br /&gt;Then I would put down the phone and look at the code to see what was needed. Oh. Scratch, scratch, poke. Done.&lt;br /&gt;&lt;br /&gt;Then I would go into Mike's office and tell him the users had asked for X and he would make a face and I would say I had already made the change if that would affect his decision.&lt;br /&gt;&lt;br /&gt;Mind you this did not happen because I consciously planned for change, I just worried about things besides whether the code worked. Simple architectural tidiness went straight to the business bottom line: the users got exactly what they needed at no extra cost to the enterprise. How does simple clean design make RFEs easy to handle? Tilton's Lemma:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Refinements to requirements cannot vary fundamentally from the original.&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;It is possible for users to say, Oh my, you have the runners running the bases clockwise? We wanted them going &lt;span style="font-style: italic;"&gt;counterclockwise&lt;/span&gt;. It is &lt;span style="font-style: italic;"&gt;not &lt;/span&gt;possible for the users to come back and say, We wanted them going first to second base, then over to first, then to third, and then home. Some fundamental force of nature constrains how we can screw up and keeps it within a metalevel such that refinements to requirements will never break code all that badly.&lt;br /&gt;&lt;br /&gt;[Keep your eyes open for the "We Can Live With the Way You Handled That" mind-bending illustration of the power of clean design.]&lt;br /&gt;&lt;br /&gt;The flipside war story was in a different tall building working on a system so badly designed that after a certain point it pretty much stopped evolving at all.&lt;br /&gt;&lt;br /&gt;I walked up to my manager and said I had an idea on how to improve something I was working on for her so that it could be used for other things.&lt;br /&gt;&lt;br /&gt;"No, no, no," she said. "I just need this one thing working before Thursday's meeting so I can score one on the users. They are out to get us."&lt;br /&gt;&lt;br /&gt;Ah, systems development as an act of war. The system they had developed was such a horror that the only thing that ever moved it forward was a team of very well-paid outside contractors who managed against all odds to add new functionality, pausing from their toils every several days when one of them would take a design two-by-four across his skull from said system and lean back and poll the others on how badly each felt the system hindered them, an order of magnitude generally being settled on as no exaggeration however often it usually is.&lt;br /&gt;&lt;br /&gt;The IT department ended up with a bunker mentality lobbing back hand grenade code releases to suppress fire from users strafing us with gratuitous RFEs as the organization staggered towards collapse and acquisition, and it being a financial institution to no small degree dependent on how well it processed information I cannot help thinking this system was to blame.&lt;br /&gt;&lt;br /&gt;But it &lt;span style="font-style: italic;"&gt;did &lt;/span&gt;work.&lt;span style="font-style: italic;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Oh, sorry. Lisp? Well, the more powerful the language the more time one has for that much easier a job of designing an application as opposed to banging out whatever source code passes the unit tests. And when it comes to separating specifics out into a configuration area that drives a more universal engine... can you say DSL? Sher ya can.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6508797467947601724-2475597964318051331?l=smuglispweeny.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smuglispweeny.blogspot.com/feeds/2475597964318051331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=6508797467947601724&amp;postID=2475597964318051331' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/2475597964318051331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6508797467947601724/posts/default/2475597964318051331'/><link rel='alternate' type='text/html' href='http://smuglispweeny.blogspot.com/2008/03/tlop-worst-thing-you-can-say-about.html' title='TLOP: The Worst Thing You Can Say About Software Is That It Works'/><author><name>Kenny Tilton</name><uri>http://www.blogger.com/profile/17430816457662806163</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08529321509689979662'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry></feed>