A critic of Guido's blog on Python's lambda

Bill Atkins NOatkinwSPAM at rpi.edu
Sat May 6 21:43:03 EDT 2006


aleaxit at yahoo.com (Alex Martelli) writes:

> Yes, we are, because the debate about why it's better for Python (as a
> language used in real-world production systems, *SCALABLE* to extremely
> large-scale ones) to *NOT* be insanely extensible and mutable is a
> separate one -- Python's uniformity of style allows SCALABILITY of
> teams, and teams-of-teams, which is as crucial in the real world as
> obviously not understood by you (the law you misquoted was about adding
> personnel to a LATE project making it later -- nothing to do with how
> desirable it can be to add personnel to a large and growing collection
> of projects, scaling and growing in an agile, iterative way to meet
> equally growing needs and market opportunities).
>
> This specific debate grew from your misuse of "scalable" to mean or
> imply "a bazillion feechurz can [[and, implicitly, should]] be added to
> a language, and therefore anything that stands in the way of feechuritis
> is somehow holding the language back".  That's bad enough, even though
> in its contextual misuse of "scalable" it breaks new ground, and I don't
> want to waste even more time re-treading *old* ground as to whether the
> "*insane* extensibility" afforded by macros is a good or a bad thing in
> a language to be used for real-world software production (as opposed to
> prototyping and research).

It's interesting how much people who don't have macros like to put
them down and treat them as some arcane art that are too "*insane*"ly
powerful to be used well.

They're actually very straightforward and can often (shock of shocks!)
make your code more readable, without your efficiency taking a hit.

For example, at work I recently had to generate PDF reports in PHP.
Certain sections would need to be indented, and then once they were
done, I wanted to move back out to the previous level of indentation.
I ended up with stuff like this (totally made up on the spot, but
conveys the general idea):

function out_main_text( ) {
  $old_indent = $pdf->indentation;
  $pdf->indent_to( $pdf->indentation + 4 );

  out_header();
  out_facts();

  $pdf->set_indentation( $old_indent );
}

function out_header() {
  $old_indent = $pdf->indentation;
  $pdf->indent_to( $pdf->indentation + 4 );

  $pdf->write( "some text" );

  $pdf->set_indentation( $old_indent );
}

function out_facts() {
  $old_indent = $pdf->indentation;
  $pdf->indent_to( $pdf->indentation + 4 );

  out_some_subsection();
  out_another_subsection();

  $pdf->set_indentation( $old_indent );
}


Obviously, this is very much pseudocode.  The point is that managing
indentation was a hassle, because each of these subfunctions indents
to a new position.  This can pretty clearly get tedious, and is
definitely error-prone, especially when you consider that different
groups of functions are called depending upon the input and that some
of the functions might return early.

But why should I have to worry about any of this?  Why can't I do:

  (with-indentation (pdf (+ (indentation pdf) 4))
     (out-header)
     (out-facts))

and then within, say out-facts:

  (with-indentation (pdf (+ (indentation pdf) 4))
    (write pdf "some text"))

More readable, and no bookkeeping to worry about.  This is great!  And
here's the macro:

  (defmacro with-indentation (pdf new-value &body body)
    (let ((old-indent (gensym)))
      `(let ((,old-indent (indentation pdf)))
        (unwind-protect (progn , at body)
          (setf (indentation pdf) ,old-indent)))))

Bam, all of that bookkeeping, all of those potential errors have taken
care of themselves.  WITH-INDENTATION will expand into code that uses
UNWIND-PROTECT to ensure that the indentation always gets returned to
its previous value, even if an exception occurs or the code within
calls RETURN.  The WITH-INDENTATION call sets up an environment where
there is a new indentation level in effect, and then cleans it up when
it's done.  I can nest these to my heart's content.

Obviously, to someone totally unfamiliar with Lisp, the contents of
that macro are pretty daunting.  But you're crazy if you argue that
having WITH-INDENTATION around isn't an improvement over manually
ensuring that indentation gets saved and restored for every function
call.

I could even generalize this (as CLISP does) to this:

  (letf (((indentation pdf) (+ 4 (indentation pdf))))
    (write "some text"))

Now I can use LETF to temporarily set any value at all for as long as
the code inside is running, and to restore it when it's done.

Macros rock.

-- 
This is a song that took me ten years to live and two years to write.
 - Bob Dylan



More information about the Python-list mailing list