Flat-schmat! [was Re: Python syntax in Lisp and Scheme]
Kenny Tilton
ktilton at nyc.rr.com
Sun Oct 5 08:27:47 EDT 2003
Andrew Dalke wrote:
> Still have only made slight headway into learning Lisp since the
> last discussion, so I've been staying out of this one. But
>
> Kenny Tilton:
>
>>Take a look at the quadratic formula. Is that flat? Not. Of course
>>Python allows nested math (hey, how come!), but non-mathematical
>>computations are usually trees, too.
>
>
> Since the quadratic formula yields two results, ...
I started this analogy, didn't I? <g>
I expect most
> people write it more like
>
> droot = sqrt(b*b-4*a*c) # square root of the discriminate
> x_plus = (-b + droot) / (4*a*c)
> x_minus = (-b - droot) / (4*a*c)
Not?:
(defun quadratic (a b c)
(let ((rad (sqrt (- (* b b) (* 4 a c)))))
(mapcar (lambda (plus-or-minus)
(/ (funcall plus-or-minus (- b) rad) (+ a a)))
'(+ -))))
:)
>
> possibly using a temp variable for the 4*a*c term, for a
> slight bit better performance.
Well it was a bad example because it does require two similar
calculations which can be done /faster/ by pre-computing shared
components. But then the flattening is about performance, and the
subject is whether deeply nested forms are in fact simpler than
flattened sequences where the algorithm itself would be drawn as a tree.
So the example (or those who stared at it too hard looking for
objections <g>) distracted us from that issue.
> But isn't that flattening *exactly* what occurs in math. Let me pull
> out my absolute favorite math textbook - Bartle's "The Elements
> of Real Analysis", 2nd ed.
Oh, god. I tapped out after three semesters of calculus. I am in deep
trouble. :)
>
> I opened to page 213, which is in the middle of the book.
>
> 29.1 Definition. If P is a partition of J, then a Riemann-Stieltjes sum
> of f with respect to g and corresponding to P = (x_0, x_1, ..., x_n) is a
> real
> number S(P; f, g) of the form
>
> n
> S(P; f, g) = SIGMA f(eta_k){g(x_k) - g(x_{k-1})}
> k = 1
>
> Here we have selected number eta_k satisying
>
> x_{k-1} <= eta_k <= x_k for k = 1, 2, ..., n
>
> There's quite a bit going on here behind the scenes which are
> the same flattening you talk about. For examples: the definiton
> of "partition" is given elsewhere, the notations of what f and g
> mean, and the nomenclature "SIGMA"
<snip another good example>
> In both cases, the equations are flattened. They aren't pure trees
> nor are they absolutely flat. Instead, names are used to represent
> certain ideas -- that is, flatten them.
No! Those are like subroutines; they do not flatten, they create call
trees, hiding and encapsulating the details of subcomputations.
We do precisely the same in programming, which is part of why flattening
can be avoided. When any local computation gets too long, there is
probably a subroutine to be carved out, or at least I can take 10 lines
and give it a nice readable name so I can avoid confronting too much
detail at any one time. But I don't throw away the structure of the
problem to get to simplicity.
> .. You judge the Zen of Python
> using the Zen of Lisp.
Hmmm, Zen constrained by the details of a computing language. Some
philosophy! :) What I see in "flat is better" is the mind imposing
preferred structure on an algorithm which has its own structure
independent of any particular observer/mind.
I am getting excellent results lately by always striving to conform my
code to the structure of the problem as it exists independently of me.
How can I know the structure independently of my knowing? I cannot, but
the problem will tell me if I screw up and maybe even suggest how I went
wrong. I make my code look like my best guess at the problem, then if I
have trouble, I try a different shape. I do not add bandaids and patches
to force my first (apparently mistaken) ideas on the problem. When the
problem stops resisting me, I know I have at least approximated its
shape. Often there is a "pieces falling into place" sensation that gives
me some confidence.
Lisp has both SETF and "all forms return a value", so it does not
interfere in the process. In rare cases where the functional paradigm is
inappropriate, I can run thru a sequence of steps to achieve some end.
Lisp stays out of the way.
Python (I gather from what I read here) /deliberately/ interferes in my
attempts to conform my code to the problem at hand, because the
designers have decreed "flat is better". Python rips a tool from my
hands without asking if, in some cases (I would say most) it might be
the right tool (where an algorithm has a tree-like structure).
I do not think that heavy-handedness can be defended by saying "Oh, but
this is not Lisp." It is just plain heavy-handed.
kenny
"Be the ball."
- Caddy Shack
More information about the Python-list
mailing list