[Edu-sig] quantum instance

Dethe Elza delza at livingcode.org
Wed Sep 14 06:19:22 CEST 2005


You may be happy to know that hard-core computer scientists cannot  
agree on the benefits of abstractions such as decorators.

Paul Graham attributes power and elegance to the tersest languages[1] 
[2], claiming that fewer lines of code means fewer bug, less time  
writing the code, and less time maintaining the code.

Meanwhile Richard Gabriel notes[2] that code can share with poetry  
the aspect of Compression, in which a few words can hold a great deal  
of meaning, but he is careful to note that this can easily be taken  
too far, resulting in incomprehensible gibberish (in poetry or in code).

Perhaps this comes down to the fact that both men are old hands at  
Lisp, but while Graham literally wrote the book on Common Lisp[3],  
Gabriel wrote "A Critique of Common Lisp."

Graham used a simplistic program to demonstrate succinctness, a straw  
man I could argue against, but it demonstrates what I'm talking  
about, using Python's standard foil: Perl.  The goal is to create a  
function which generates accumulators: Given a number n, it will  
return a new function which takes another number i, and returns n  
incremented by i, storing the accumulating result.

Graham's canonical example is in Common Lisp, and is indeed quite  

(defun foo (n)
   (lambda (i) (incf n i)))

And in Perl you have

sub foo {
   my ($n) = @_;
   sub {$n += shift}

Which is succinct and perhaps readable to someone thoroughly familiar  
with Perl, but does look like line noise to me.

Perhaps the most succinct you can get this in Python is the following:

def foo(n):
      def bar(i, l=[n]):
          l[0] += i
          return l[0]
      return bar

Although this is quite a bit longer than the Lisp version, it is  
nearly as unreadable as the Perl code.  In part this is because  
Python distinguishes between expressions and statements, so we cannot  
"return l[0] += i".  Also, Python does not allow us to assign to  
local integers, so we hack around this by putting the integer "n" in  
a mutable container "l = [n]".  And lambdas don't allow statements  
(or is it expressions?) so that keeps it from getting succinct as well.

But of course, this is not the canonical Python.  Canonical Python  
would create a class:

class foo:
     def __init__(self, n):
         self.n = n
     def __call__(self, i):
         self.n += i
         return self.n

As you can see, this is not much longer, and (in my eyes at least),  
vastly more readable.  No hacks with lists, it clearly shows that  
we're accumulating the value.  If I were to use this in any real  
system, I would change "self.n" to "self.accumulator" or some such,  
and make it even longer, because readability counts more than  
succinctness, despite what Graham claims[5].

If you're still reading this far you may have noted that I haven't  
actually talked about decorators at all.  In my code, I have come to  
places where there are aspects which cut across classes and methods  
in a way that's not always intuitive or easy to capture in standard  
object-oriented code.  In Java and some other languages they are  
implementing Aspect-Oriented Programming (AOP), where you create  
"cutpoints" where code will be injected for different "aspects" which  
are defined elsewhere.  Generating this code is called "code weaving"  
or "aspect weaving" and the result is not intended to be read or  
modified by humans.  Debugging this type of code must take the  
patience of a saint, since all your line numbers and references would  
have disappeared in the warp and weft.

With decorators I get an 80/20 solution to aspects which cover all of  
the most common (and dare I say, important) uses of AOP, without  
compile-time weaving, or losing line numbering or stack tracing or  
any of my standard editing, reading, or debugging toolkit.  For me,  
this is a big win, and I'm happy to have decorators in my toolbox.   
I'm also quite happy to have generators, list comprehensions,  
properties, and descriptors, because these all fill needs for times I  
have bumped up against a wall of complexity and my code has grown too  
big, too multi-branched to fit comfortably in my head.  Since I do a  
lot of "hobby coding" in my limited spare time, on a lot of different  
project, being able to fit the code in my head is essential.  I need  
to be able to come to a project I left off with months ago and  
quickly grok what it does and why.

That said, I don't make daily use of decorators, descriptors,  
properties, or even generators.  Just as a carpenter's toolbox may  
contain hammers and screwdrivers he uses everyday, and also more  
specialized planes or chisels he uses more rarely (but still values  
having the right tool for the job when he needs it), these are my  
more specialized tools.  I do use list comprehensions daily, they  
have become one of my favored hammers, but I do try to take care to  
use them in a way which enlightens the code rather than obfuscates  
it, which they can certainly do.

And while Lisp hackers like Graham cannot understand why anyone  
wouldn't want to use his all-powerful language, the Smalltalk  
community is equally amused when the concepts they cut their teeth on  
in the seventies are finally adopted by more mainstream languages 
[6].  Power quote: "Reinventing Smalltalk, one decade at a time."


[1] http://www.paulgraham.com/icad.html (especially see "Appendix:  
Power" at the end).

[2] http://www.dreamsongs.com/NewFiles/PatternsOfSoftware.pdf (Reuse  
vs. Piecemeal Growth chapter)

[4] http://www.paulgraham.com/acl.html (ANSI Common Lisp)

[3] http://dreamsongs.com/NewFiles/clcrit.pdf (A Critique of Common  

[5] http://www.paulgraham.com/power.html (Succinctness is Power, a  
direct attack on Python)

[6] http://www.intertwingly.net/blog/2005/09/09/The-Case-for-Dynamic- 
Languages (slides link)

"And you think you're so clever and classless and free"
— John Lennon on prototype-based programming

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2488 bytes
Desc: not available
Url : http://mail.python.org/pipermail/edu-sig/attachments/20050913/a4d8e99a/smime.bin

More information about the Edu-sig mailing list