merits of Lisp vs Python

xscottg at gmail.com xscottg at gmail.com
Sat Dec 16 14:18:34 EST 2006


Ken Tilton wrote:
> xscottg at gmail.com wrote:
> >
> > Code is data is code
>
> I was hoping no one would make that mistake. :) macros are all about
> code is data, but code is not data in Python* so the two words code and
> data serve to differentiate them for Pythonistas.
>

I disagree.  I frequently write data-driven algorithms in C and Python
(data is code).  I occasionally write code-generators too (code is
data).  Just because the representation is different between code and
data in those languages doesn't mean that you can't use data as code
(interpreter style) or generate code as data (compiler style).  (I
won't bother boring you with the Python bytecode hacks or the parser
module, because I think those are not terribly practical.)

It's very elegant that Lisp makes the representations between code and
data so similar, but it looks like you know the mantra and not the
meaning if you can't apply that principle in other languages.

BTW...  Even in Scheme, I have to use syntax-object->datum and it's
inverse to switch between the two.  I suspect this has something to do
with the other context that must be associated with the data to turn it
into code.  Probably at least the enclosing environment for lexical
scoping and the line numbers for debugging or exception handling.  Does
Common Lisp maintain this information with it's macro expansions?  If
so, you have a slight difference between code and data too.  If not,
how do you get the line number when a problem happens in a nested
macro?

Moreover, if you really want to be pedantic about what "is" means in
"code is data", then you have to acknowledge that data is a superset of
code, since all code is obviously data, but there are plenty of types
of data that aren't used as code.  Or are they?  :-)


> *  Taking questions after a keynote to ILC200? where he reiterated that
> Python was the same as Lisp for all intents and purposes:
>
> Norvig: "Yes, John?"
> McCarthy: "Is code also data in Python?"
> Norvig: "No."
>
> End of exchange. :)
>

Really?  You're relying on an appeal to authority?  Ok, I'm going to
start arguing by analogy then...



> >    def reverse(cls, *args):
> >      # I didn't understand what your code was doing
>
> yeah, and god forbid you should ask. :) this is the crux of the matter!
>
> Actually, it is kinda cool that you and Greg are semi-identifying the
> crux by saying "this is the only bit I do not get, I'll skip this, move
> on, nothing to see here".
>

Ok, I'll bite.  What does it do?  I read through it, and it looks the
code you're passing to the macro does some things like calculating the
number of decimal digits and generating a 2 + a random number of that
many digits to find a divisor or something.  It also looks like you
have some "string interpolation" to substitute names in your text, but
as a whole, I really don't have any clue what it's all about.

It looks like the macro itself is building some names on the fly and
defining methods (new specializations for multimethods?) with those
names.

So I'm sure I'm missing something, but there is almost certainly a
readable equivalent in Python (and even C).  If you really want to
generate dynamic names for functions, you can do that in Python by
modifying the class or globals hash or whatever.  A more standard way
might be to be have members in the base class.

There is even a multi-methods module in Python, but I've never used it.
 I'd guess you could add to that dynamically too.


> >
> > That would be a reasonable place for a "pie decorator" on a class, but
> > I guess that's not allowed.
>
> Hmmm. Actually, that is the whole point, all of Python is allowed.
> decorators were used in PyCells, but I never got much of an idea what
> they did. Is there a moral equivalent of a macroexpansion for decorators
> so you can show the before and after?
>

It's Python that doesn't allow you to decorate classes.  (You can
decorate functions, but not classes...)  I made this comment as a
criticism of Python since it seems like a non-orthogonal corner...  It
would have fit in this case.

Decorators are pretty simple:

    @foo
    def bar(): pass

is equivalent to:

    def bar(): pass
    bar = foo(bar)

The callable foo can use whatever it wants to inspect, modify, or wrap
the function bar.

but:

    @foo
    class bar: pass

is not currently allowed, so you have to do

    class bar: pass
    bar = foo(bar)



>
> exactly what we are looking for in this cultural exchange: how would
> Python handle what I am doing with macros in the reverse functions? Make
> it as slick and programmer-friendly (cuz I may get to a hundred of these
> before I am done with Algebra I) as possible. When all the Pythonistas
> proclaim it optimal, then we compare and contrast.
>
> This, btw, is the Tilton Test for language comparison: Not measurements
> of programmer effort, rather examination of perfect equivalent code.
> PyCells vs Cells would be an amazing case, because that is some hairy
> functionality.
>

That seems like a fine strategy.  I fall more on the programmer effort
side.  I want to write as little code as possible in a readable way
such that it meets the requirements.

I'm not a particularly good ambassador for Python.  I know Python much
better than Lisp (Scheme), but I already think Scheme is a better
language.  Macros are part of that.  I'm mostly playing devil's
advocate here because I don't think your example really brings it home.
 I've got limited time that I'm willing to invest in learning your
algebra system, but I haven't seen (understood, if you insist) anything
yet that couldn't be done readably in Python.  If you want Common Lisp
to win in your language battle against the Pythonistas, you're going to
need to break out with something stronger.  Then again, you're probably
pissing into the wind anyway.


Cheers,
    -Scott




More information about the Python-list mailing list