D
Dave Benjamin
Guido gave a good, long interview, available at IT Conversations, as was
recently announced by Dr. Dobb's Python-URL! The audio clips are available
here:
http://www.itconversations.com/shows/detail545.html
http://www.itconversations.com/shows/detail559.html
I'd like to comment on a few parts of that interview.
One thing Guido mentions in his comparison of ABC (Python's predecessor) and
Python is how ABC was inextricably tied to its environment (a la Smalltalk),
where Python, though it supports an interactive mode, follows more of a
UNIX-style "do one thing well" philosophy, and was designed to integrate
with other tools rather than being a whole world to its own.
I find that a similar comparison can be made between Python and Java. Java's
startup time is so long that it is not practical for writing small tools for
use in command-line scripts, and the propensity toward application servers
and integrated development environments suggests a strong preference for a
monolithic, self-contained, single-language environments. On the other hand,
even though internally "there's only one way to do it" in Python, Python
itself is one of many ways to develop software, and does not insist on being
the one perfect way to do it. You can use whatever editor you like, and the
language doesn't go out of its way to make it difficult to use other
programs and processes, including the operating system if so desired.
It is a bit ironic that, according to Guido, the command-line interpreter
interface to Python was more of an afterthought, since my whole experience
with Python has very much centered around the interpreter. Like many, I
think, my first use for Python was as a calculator. =) In fact, since
discovering Python, I've been very resistant toward learning any language
that doesn't have an interpreter. Ruby, Scheme, OCaml and SML/NJ have been
fun to learn because I can tinker with them at the command line. "perl -de
42" is rather frustrating to use, as is Haskell's "hugs" due to the
inability to define new functions at the command line.
Command-line interfaces are a great way to get up to speed on new languages
and libraries. One of the advantages of Python is that it allows you to
graft a CLI onto environments that weren't designed with one. For instance,
Jython gives Java a command-line interface, and this makes working with Java
much more tolerable since you can interact with libraries in real-time and
learn how they behave at runtime. Likewise with PythonWin and COM scripting.
I am glad to see that IronPython is designed with a command-line interpreter
as well, should I ever need to learn my way around .NET in a hurry.
Guido makes a funny jab at Paul Graham about Graham's nine things that make
Lisp Lisp (available here: http://www.paulgraham.com/icad.html) - I had read
this essay many times but never saw the subtle irony behind claims of
"Greenspunning": in order to claim that a language is approaching Lisp, you
have to define what it is about Lisp that other languages are purportedly
emulating, and this begs the question of why you have the authority to
declare which 9 (or n) attributes of Lisp are most important. I like Paul
Graham and his essays a lot, but I must admit I had to laugh too when I
heard the way Guido framed this argument. I'm not so sure that Python has 8
out of 9, though: the statement/expression dichotomy rules out #6, and the
lack of macros rules out #9. These are arguable, depending on how you define
things, but I think the most obvious thing that Python lacks compared with
Lisp and Scheme (and also Ruby) is a symbol type (#7). I'm in the process of
trying to understand what symbols are good for, outside the context of Lisp
and its nested lists of symbols as executable code. Ruby seems to have come
up with some creative uses for symbols within Python-like syntax, though I
haven't seen anything terribly compelling so far.
Guido briefly summarizes language comparisons with other languages:
- Perl: similar niche, but Perl is for regexes and text processing, and
Python is for objects, data structures, and more general-purpose
programming. Obligatory TMTOWTDI argument.
- PHP: very successful at its niche, being a point-solution for adding
bits of script to web pages. Not very useful outside that context, and
lots of language-design gaffes.
- Java: the usual static vs. dynamic, static analysis vs. unit testing
arguments. Guido says that there's such a small amount of problems that
can be caught at compile time, and even the smallest amount of unit
testing would also catch these problems. "The blindness of that [static]
position... escapes me."
- C/C++: same arguments as Java, plus most programmers aren't up to the
task of manual memory-management.
- Lisp: even though there's no code-equals-data in Python, you still have
the compiler available at runtime, and there's a lot you can do to treat
code as data even though they're not syntactically idnentical.
- Smalltalk: very similar to Python, but Python is easier to integrate
into existing shops that use other languages, mainly (IMO) because
Smalltalk is a self-contained, integrated environment so the cost of
introducing it is much higher
There was also some discussion on why Java seems to be such a memory hog.
Guido chalks it up to Java's "fancy schmancy garbage collection technology"
with its heaps and threads and insistance on far-reaching low-level control
over all the poitners in the heap. It is a bit ironic that (C)Python with its
simple reference-counting plus cycle-detection seems much less
resource-hungry than Java's GC, even though most language experts consider
GC to be a vastly better technique. But I think this has more to do with
Java's particular implementaion of GC; OCaml, for instance, is
garbage-collected but has a very lean memory footprint.
I think Python's decision to use reference counting was an instance of
worse-is-better: at the time, reference counting was already known not to be
"the right thing", but it worked, and the implementation was simple.
Likewise with dynamic typing versus type inference. It seems that Guido
shares Alan Kay's viewpoint that type inference is really "the right thing",
but modern language technology is really not ready to make it mainstream,
whereas dynamic typing works today, and is arguably a better "worse"
solution than explicit/manifest static typing due to its verbosity.
From the perspective of writing C extensions, Guido claims that the amount
of pain (regarding memory management) is about the same whether you're
extending a reference-counted language like CPython or a garbage collected
language like Java. Anyone with experience writing C extensions want to
comment on this?
Type inferencing is especially difficult to add to a dynamically typed
language, and in general I think results are much better if you have type
inference from the very beginning (like ML and Haskell) rather than trying
to retrofit it later. Guido says that they've only been able to get it to
work reliably in Python with constants, which isn't very useful.
Regarding Ruby, Guido said that the community is much smaller than Python,
and that it's much more of a "better Perl" than a "better Python". I think
that, despite claims by both Guido and Matz, Ruby sits pretty much on the
fence betwee the two languages. Guido says he dislikes the code block syntax
in Ruby, but doesn't make it clear whether it's the syntax he dislikes or
the code blocks themselves. He does mention that if you like Smalltalk,
you'll probably like Ruby because of the code blocks...
Generators and iterators are, according to Guido, an "80% solution" for the
kinds of things people use code blocks for in Ruby. I think that the
newly-proposed PEP 343 offers adds another 5-10% to the solution, perhaps;
soon, Python will be able to do resource management in addition to iteration
patterns without the use of code blocks. I can still think of additional
uses for code blocks, and I have to wonder how many "point solutions" Python
is going to gain in attempt to avoid adding code blocks to the language.
This is not to say that I don't think generators or the newly proposed
"with" keyword are cool features to have.
(Upon review, I realize that Guido made the "80% solution" comment
regarding generators vs. continuations, not code blocks. Still, generators
are far more specific of a tool than either continuations or blocks.)
Someone in the audience mentioned that the CPython VM is so solid they're
surprised nobody's implemented a Java program on top of the Python VM (as
opposed to the other way around, as in Jython). Someone in the audience
surprised everyone by mentioning an actual project attempting this, called
javaclass:
http://www.boddie.org.uk/python/javaclass.html
In response to any question on how to create a language, a community, a
successful project, Guido's response tended to be the same: he doesn't
really know what he did that made it work, or made the community follow
Python so well and for so long. He says it's probably not a good idea to
start a new project by following in the footsteps of an old one. If only we
could tap a bit deeper into the mystique of successful software projects.
Cheers,
Dave
recently announced by Dr. Dobb's Python-URL! The audio clips are available
here:
http://www.itconversations.com/shows/detail545.html
http://www.itconversations.com/shows/detail559.html
I'd like to comment on a few parts of that interview.
One thing Guido mentions in his comparison of ABC (Python's predecessor) and
Python is how ABC was inextricably tied to its environment (a la Smalltalk),
where Python, though it supports an interactive mode, follows more of a
UNIX-style "do one thing well" philosophy, and was designed to integrate
with other tools rather than being a whole world to its own.
I find that a similar comparison can be made between Python and Java. Java's
startup time is so long that it is not practical for writing small tools for
use in command-line scripts, and the propensity toward application servers
and integrated development environments suggests a strong preference for a
monolithic, self-contained, single-language environments. On the other hand,
even though internally "there's only one way to do it" in Python, Python
itself is one of many ways to develop software, and does not insist on being
the one perfect way to do it. You can use whatever editor you like, and the
language doesn't go out of its way to make it difficult to use other
programs and processes, including the operating system if so desired.
It is a bit ironic that, according to Guido, the command-line interpreter
interface to Python was more of an afterthought, since my whole experience
with Python has very much centered around the interpreter. Like many, I
think, my first use for Python was as a calculator. =) In fact, since
discovering Python, I've been very resistant toward learning any language
that doesn't have an interpreter. Ruby, Scheme, OCaml and SML/NJ have been
fun to learn because I can tinker with them at the command line. "perl -de
42" is rather frustrating to use, as is Haskell's "hugs" due to the
inability to define new functions at the command line.
Command-line interfaces are a great way to get up to speed on new languages
and libraries. One of the advantages of Python is that it allows you to
graft a CLI onto environments that weren't designed with one. For instance,
Jython gives Java a command-line interface, and this makes working with Java
much more tolerable since you can interact with libraries in real-time and
learn how they behave at runtime. Likewise with PythonWin and COM scripting.
I am glad to see that IronPython is designed with a command-line interpreter
as well, should I ever need to learn my way around .NET in a hurry.
Guido makes a funny jab at Paul Graham about Graham's nine things that make
Lisp Lisp (available here: http://www.paulgraham.com/icad.html) - I had read
this essay many times but never saw the subtle irony behind claims of
"Greenspunning": in order to claim that a language is approaching Lisp, you
have to define what it is about Lisp that other languages are purportedly
emulating, and this begs the question of why you have the authority to
declare which 9 (or n) attributes of Lisp are most important. I like Paul
Graham and his essays a lot, but I must admit I had to laugh too when I
heard the way Guido framed this argument. I'm not so sure that Python has 8
out of 9, though: the statement/expression dichotomy rules out #6, and the
lack of macros rules out #9. These are arguable, depending on how you define
things, but I think the most obvious thing that Python lacks compared with
Lisp and Scheme (and also Ruby) is a symbol type (#7). I'm in the process of
trying to understand what symbols are good for, outside the context of Lisp
and its nested lists of symbols as executable code. Ruby seems to have come
up with some creative uses for symbols within Python-like syntax, though I
haven't seen anything terribly compelling so far.
Guido briefly summarizes language comparisons with other languages:
- Perl: similar niche, but Perl is for regexes and text processing, and
Python is for objects, data structures, and more general-purpose
programming. Obligatory TMTOWTDI argument.
- PHP: very successful at its niche, being a point-solution for adding
bits of script to web pages. Not very useful outside that context, and
lots of language-design gaffes.
- Java: the usual static vs. dynamic, static analysis vs. unit testing
arguments. Guido says that there's such a small amount of problems that
can be caught at compile time, and even the smallest amount of unit
testing would also catch these problems. "The blindness of that [static]
position... escapes me."
- C/C++: same arguments as Java, plus most programmers aren't up to the
task of manual memory-management.
- Lisp: even though there's no code-equals-data in Python, you still have
the compiler available at runtime, and there's a lot you can do to treat
code as data even though they're not syntactically idnentical.
- Smalltalk: very similar to Python, but Python is easier to integrate
into existing shops that use other languages, mainly (IMO) because
Smalltalk is a self-contained, integrated environment so the cost of
introducing it is much higher
There was also some discussion on why Java seems to be such a memory hog.
Guido chalks it up to Java's "fancy schmancy garbage collection technology"
with its heaps and threads and insistance on far-reaching low-level control
over all the poitners in the heap. It is a bit ironic that (C)Python with its
simple reference-counting plus cycle-detection seems much less
resource-hungry than Java's GC, even though most language experts consider
GC to be a vastly better technique. But I think this has more to do with
Java's particular implementaion of GC; OCaml, for instance, is
garbage-collected but has a very lean memory footprint.
I think Python's decision to use reference counting was an instance of
worse-is-better: at the time, reference counting was already known not to be
"the right thing", but it worked, and the implementation was simple.
Likewise with dynamic typing versus type inference. It seems that Guido
shares Alan Kay's viewpoint that type inference is really "the right thing",
but modern language technology is really not ready to make it mainstream,
whereas dynamic typing works today, and is arguably a better "worse"
solution than explicit/manifest static typing due to its verbosity.
From the perspective of writing C extensions, Guido claims that the amount
of pain (regarding memory management) is about the same whether you're
extending a reference-counted language like CPython or a garbage collected
language like Java. Anyone with experience writing C extensions want to
comment on this?
Type inferencing is especially difficult to add to a dynamically typed
language, and in general I think results are much better if you have type
inference from the very beginning (like ML and Haskell) rather than trying
to retrofit it later. Guido says that they've only been able to get it to
work reliably in Python with constants, which isn't very useful.
Regarding Ruby, Guido said that the community is much smaller than Python,
and that it's much more of a "better Perl" than a "better Python". I think
that, despite claims by both Guido and Matz, Ruby sits pretty much on the
fence betwee the two languages. Guido says he dislikes the code block syntax
in Ruby, but doesn't make it clear whether it's the syntax he dislikes or
the code blocks themselves. He does mention that if you like Smalltalk,
you'll probably like Ruby because of the code blocks...
Generators and iterators are, according to Guido, an "80% solution" for the
kinds of things people use code blocks for in Ruby. I think that the
newly-proposed PEP 343 offers adds another 5-10% to the solution, perhaps;
soon, Python will be able to do resource management in addition to iteration
patterns without the use of code blocks. I can still think of additional
uses for code blocks, and I have to wonder how many "point solutions" Python
is going to gain in attempt to avoid adding code blocks to the language.
This is not to say that I don't think generators or the newly proposed
"with" keyword are cool features to have.
(Upon review, I realize that Guido made the "80% solution" comment
regarding generators vs. continuations, not code blocks. Still, generators
are far more specific of a tool than either continuations or blocks.)
Someone in the audience mentioned that the CPython VM is so solid they're
surprised nobody's implemented a Java program on top of the Python VM (as
opposed to the other way around, as in Jython). Someone in the audience
surprised everyone by mentioning an actual project attempting this, called
javaclass:
http://www.boddie.org.uk/python/javaclass.html
In response to any question on how to create a language, a community, a
successful project, Guido's response tended to be the same: he doesn't
really know what he did that made it work, or made the community follow
Python so well and for so long. He says it's probably not a good idea to
start a new project by following in the footsteps of an old one. If only we
could tap a bit deeper into the mystique of successful software projects.
Cheers,
Dave