469,281 Members | 2,486 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,281 developers. It's quick & easy.

Python's "only one way to do it" philosophy isn't good?

I've just read an article "Building Robust System" by Gerald Jay
Sussman. The article is here:
http://swiss.csail.mit.edu/classes/s...st-systems.pdf

In it there is a footprint which says:
"Indeed, one often hears arguments against building exibility into an
engineered sys-
tem. For example, in the philosophy of the computer language Python it
is claimed:
\There should be one|and preferably only one|obvious way to do
it."[25] Science does
not usually proceed this way: In classical mechanics, for example, one
can construct equa-
tions of motion using Newtonian vectoral mechanics, or using a
Lagrangian or Hamiltonian
variational formulation.[30] In the cases where all three approaches
are applicable they are
equivalent, but each has its advantages in particular contexts."

I'm not sure how reasonable this statement is and personally I like
Python's simplicity, power and elegance. So I put it here and hope to
see some inspiring comments.

Jun 9 '07
206 7111
On 2007-06-21, Douglas Alan <do**@alum.mit.eduwrote:
Steven D'Aprano <st****@REMOVE.THIS.cybersource.com.auwrites:
>On Wed, 20 Jun 2007 17:23:42 -0400, Douglas Alan wrote:
>>Macros are a way to abstract syntax the way that objects are
used to abstract data types and that iterators and generators
abstract control, etc.
>But why is the ability to abstract syntax good?

It allows the community to develop language features in a
modular way without having to sully the code base for the
language itself.
That's not an advantage exclusive to macros, though.

Some time last week I found myself writing the following thing in
Python:

def do_until(body, test):
body()
while not test():
body()

I don't remember why I thought I needed it; it had to do with
getting really annoyed with the code repetition needed for
certain kinds of while loops in Python.

I deleted it right after I tried to use it the first time. Using
it is more cumbersome than simply repeating myself, due to syntax
limitations of Python.

Until iterators came along there wasn't a good, Pythonic
solution. The lack of a syntax-extension facility in Python meant
everyone had to wait until iterators were finished.

But today there *are* a few syntax extension facilities in
Python, notably descriptors, upon which Python's object system is
based.

And other, more bizarre syntax extensions have been perpetrated.
mx.TextTools uses Python tuples to write a completely different
programming language.
A prime example of this is how CLOS, the Common Lisp Object
System was implemented completely as a loadable library (with
the help of many macros) into Common Lisp, which was not an OO
language prior to the adoption of CLOS.
Is there a second example? ;)

Seriously, maybe Python looks like 'blub' (thanks, Paul Graham),
to the skilled Lisp user, but it makes a lot of other languages
look like 'blub', too, including, sometimes, Lisp: Lisp has to
'blub' generators.

--
Neil Cerutti
Jun 21 '07 #101
Neil Cerutti <ho*****@yahoo.comwrites:
>>But why is the ability to abstract syntax good?
>It allows the community to develop language features in a
modular way without having to sully the code base for the
language itself.
That's not an advantage exclusive to macros, though.
No, but macros are often are necessary to be able to implement such
features in (1) an efficient-enough manner, and (2) in a manner that
is syntactically palatable. E.g., PEAK for Python implements multiple
predicate-based dispatch, but you have to define the predicates as
Python code within strings. That's not very pretty. And probably not
very fast either. Though Python, in general, is not very fast, so
perhaps that doesn't matter too much for Python.
Some time last week I found myself writing the following thing in
Python:
[...]
I deleted it right after I tried to use it the first time. Using it
is more cumbersome than simply repeating myself, due to syntax
limitations of Python.
See what I mean!
And other, more bizarre syntax extensions have been perpetrated.
mx.TextTools uses Python tuples to write a completely different
programming language.
Sounds like "the Loop macro" for Lisp, which implements a mini sort of
Cobol-like language just for coding gnarly loops within Lisp. It
turns out that when restricted to just coding gnarly loops, this is a
much better idea than it sounds.

Yes, you can do this sort of thing, sort of, without macros, but, as
we discussed above, the result is often ugly and slow.
>A prime example of this is how CLOS, the Common Lisp Object
System was implemented completely as a loadable library (with
the help of many macros) into Common Lisp, which was not an OO
language prior to the adoption of CLOS.
Is there a second example? ;)
Why yes, now that you mention it: the Loop macro. Also, in many
implementations of Lisp, much of the core language is actually
implemented using macros against an even smaller core. Keeping this
inside core as small as possible helps make the implementation easier
to construct, maintain, and optimize.

Also, way back when, when I used to code in Maclisp, I implemented my
own object system and exception handling system in macros, as Maclisp
had neither of these off the shelf. The object system took me a
couple of weeks to do, and the exception handing system a couple of
days. They worked well, looked good, and ran fast.
Seriously, maybe Python looks like 'blub' (thanks, Paul Graham), to
the skilled Lisp user, but it makes a lot of other languages look
like 'blub', too, including, sometimes, Lisp: Lisp has to 'blub'
generators.
Actually, Scheme has first class continuations, and with continuations
and macros you could easily implement generators, and I'm sure someone
has. Whether such a library has been widely adopted for Scheme,
though, I have no idea.

You're probably right about Common Lisp, which is probably missing
generators due to efficiency concerns. Lisp Machines had "stack
groups", which were basically the same thing as generators, but making
a call to a stack group was 100 times slower than a normal function
call. This meant that people generally didn't use them even when it
would make their code more elegant, due to the huge performance cost.

Now, since Python is like 100 times slower than Common Lisp anyway,
you don't notice this performance issue with Python's generators.
They just happen to be only as slow as the rest of Python.

|>oug

"Lisp is worth learning for the profound enlightenment experience you
will have when you finally get it; that experience will make you a
better programmer for the rest of your days, even if you never
actually use Lisp itself a lot." -- Eric Raymond
Jun 21 '07 #102

"Douglas Alan" <do**@alum.mit.eduwrote in message
news:lc************@gaffa.mit.edu...
| Steven D'Aprano <st****@REMOVE.THIS.cybersource.com.auwrites:
|
| On Wed, 20 Jun 2007 17:23:42 -0400, Douglas Alan wrote:
|
| >Macros are a way to abstract syntax the way that objects are used to
| >abstract data types and that iterators and generators abstract
control,
| >etc.
|
| But why is the ability to abstract syntax good?
|
| It allows the community to develop language features in a modular way
| without having to sully the code base for the language itself.
[etc]

Some of the strongest opposition to adding macros to Python comes from
people like Alex Martelli who have had experience with them in
*multi-person production* projects. He claimed in various posts that the
net effect was to reduce productivity. So convince us (and Guido!) that he
is wrong ;-)

But I would prefer you somehow try to help make usable multi-arg and
predicate dispatch a reality.

tjr

Jun 21 '07 #103

"Steven D'Aprano" <st****@REMOVE.THIS.cybersource.com.auwrote in message
news:pa*********************@REMOVE.THIS.cybersour ce.com.au...
| On Wed, 20 Jun 2007 17:23:42 -0400, Douglas Alan wrote:
| Macros are a way to abstract syntax the way that objects are used to
| abstract data types and that iterators and generators abstract control,
| etc.
|
| But why is the ability to abstract syntax good?

I think this points to where Sussman went wrong in his footnote and Alan in
his defense thereof. Flexibility of function -- being able to do many
different things -- is quite different from flexibility of syntax -- being
to say 'do this' many different ways. An system with a limited repetoire
of actions could have multiple ways to invoke each. But it would still be
limited and inflexible in respect to what it can do.

Sussman's essay advocates functional flexibility. So when he claims that
some advocate against 'flexibility', I think it entirely reasonable to read
that as 'operational flexibility'. But when he present Peters (and Python)
as being against [operational] flexibility, he is wrong. Tim's main
sentence is "There should be one obvious way to do it" where 'it' is
anything one might sensibly want to do in real-life code. That to me is
advocacy of flexibility and not the opposite. The parenthetical insertion
'-- and preferably only one --' is advocacy against needless# *semantic*
duplication and is in no way a statement against *functional* flexibility.
(In particular, the clause is, I believe, meant to differentiate Python
from a certain other language which purportedly has a 'many ways is good'
philosophy ;-)

The followup line is 'Although that way may not be obvious at first unless
you're Dutch'. It marks the piece as something other than a serious
academic philosophical dissertation. Tim Peters is also Mr. [fractional]
Wink.

Terry Jan Reedy


Jun 22 '07 #104

"Douglas Alan" <do**@alum.mit.eduwrote in message
news:lc************@gaffa.mit.edu...
| But why is the ability to abstract syntax good?
|
| It allows the community to develop language features in a modular way
| without having to sully the code base for the language itself.

Anyone can write modules, experimental or otherwise, without touching the
code base for any particular implementation.

For those whose know one of the implementation languages, source code
control systems allow one to do experiments on branches without 'sullying'
the trunk or impeding the development thereof. There are a least a few
experimental branches, and branches of branches, in the main CPython
repository and an unknown number of independent branches out in the
community for either production use or for developing features aimed back
at the core.

One of the goals of the PyPy project was to allow people to experiment with
syntax extensions in Python itself. (But I don't know how easy that is
yet.)

But I think that overall the problem of designing new syntax is more in the
design than the implementation. Anything new has to be usable, readable,
not clash too much with existing style, not introduce ambiguities, and not
move the extended language outside the LL(1) [I believe that is right]
subset of CFLs.

tjr

Jun 22 '07 #105
Neil Cerutti <ho*****@yahoo.comwrites:
On 2007-06-21, Douglas Alan <do**@alum.mit.eduwrote:
>A prime example of this is how CLOS, the Common Lisp Object System was
implemented completely as a loadable library (with the help of many
macros) into Common Lisp, which was not an OO language prior to the
adoption of CLOS.

Is there a second example? ;)
There are many useful macro packages that syntactically extend Common Lisp.
Here are a few representative examples.
comp an implementation of list comprehensions
http://rali.iro.umontreal.ca/Publica...meLispComp.pdf

iterate a domain specific language for expressing complex iteration
http://common-lisp.net/project/iterate/

screamer support for nondeterministic programming
http://www.cis.upenn.edu/~screamer-t...mer-intro.html

cl-who a domain specific language for HTML generation
http://weitz.de/cl-who/

parenscript a domain specific language for JavaScript generation
http://common-lisp.net/project/parenscript/
Jun 22 '07 #106
"Terry Reedy" <tj*****@udel.eduwrites:
| It allows the community to develop language features in a modular way
| without having to sully the code base for the language itself.
[etc]
Some of the strongest opposition to adding macros to Python comes
from people like Alex Martelli who have had experience with them in
*multi-person production* projects. He claimed in various posts
that the net effect was to reduce productivity. So convince us (and
Guido!) that he is wrong ;-)
I'm not convinced that Guido is wrong because I know that he has at
least occasionally mused that he might someday consider a macro
facility for Python.

Alex Martelli, on the other hand, although an extremely smart guy,
seems to me to often be over-opinionated and dismissive.

Regarding being on a project where people used macros poorly, I've
also been on projects where people did a poor job of OO design, and a
non-OO design would have been better than the crappy OO design that
was ultimately used. Does that mean that we should remove the OO
features from Python?

Paul Graham made it rich implementing Yahoo Stores in Lisp, and claims
that heavy use of macros is one of the reasons that he was able to
stay well-ahead of all the competition. So, maybe Paul and Alex can
duke it out. Personally, I like Paul's style better. And he's made a
lot more money using his theory of software design.
But I would prefer you somehow try to help make usable multi-arg and
predicate dispatch a reality.
Alas, I can't stand programming in C, so there's no way I'm going to
dive that deeply into the CPython code base. If I could help
implement it in Python itself, using a good macro facility, sign me up!

|>oug
Jun 22 '07 #107
On Thu, 21 Jun 2007 15:25:37 -0400, Douglas Alan wrote:
You are imagining something very different from what is proposed.
Lisp-like macros don't allow "anything goes".
Provided people avoid doing anything "which would be considered very
rude" (your own words).

Python already allows me to shoot myself in the foot, if I wish. I'm
comfortable with that level of freedom. I'm not necessarily comfortable
with extensions to the language that would allow me the freedom to shoot
myself in the head. I would need to be convinced of the advantages, as
would many other people, including the BDFL.

It isn't clear exactly what functionality a hypothetical Python macro
system would include, let alone whether the benefits would outweigh the
costs, so I think it is very important for proponents of such a macro
system to justify precisely why it is valuable before expecting others to
go off and spend potentially thousands of man-hours turning Python into a
shadow of Lisp/Scheme. (It took Lisp half a century and millions of
dollars of corporate funding to reach where it is now. Anyone who thinks
it is a trivial task to turn Python into Lisp "only better" is deluded --
one can't merely bolt on macros onto the existing Python compiler.)
--
Steven.
Jun 22 '07 #108
On 2007-06-21, Douglas Alan <do**@alum.mit.eduwrote:
Neil Cerutti <ho*****@yahoo.comwrites:
>Seriously, maybe Python looks like 'blub' (thanks, Paul
Graham), to the skilled Lisp user, but it makes a lot of other
languages look like 'blub', too, including, sometimes, Lisp:
Lisp has to 'blub' generators.

Actually, Scheme has first class continuations, and with
continuations and macros you could easily implement generators,
and I'm sure someone has. Whether such a library has been
widely adopted for Scheme, though, I have no idea.
A strength of Lisp is the ability to cherry-pick features from
different Lisp implementations, as seen here.

Common Lisp has powerful macro facilities and generates fast
code, but hasn't got continuations.

Scheme has continuations, but is *not* fast, and has simpler,
more complicated macro facilities. ;)
"Lisp is worth learning for the profound enlightenment
experience you will have when you finally get it; that
experience will make you a better programmer for the rest of
your days, even if you never actually use Lisp itself a lot."
-- Eric Raymond
You don't need to learn Lisp to get the ephiphany, though.
Haskell, Ocaml or ML would likely be more enlightening to a
Python programmer, who will see much of Lisp as old hat.

That said, I wouldn't give up the summer I spent studying _Simply
Scheme_. Writing recursive code seemed totally alien to me before
that. On the other hand, _Simply Scheme_ uses a logo-like
adaptation of Scheme for 90% of the course, wisely disguising the
total weird unintuitiveness of list manipulation until the
student has been fully brainwashed. ;)

--
Neil Cerutti
Jun 22 '07 #109
Neil Cerutti <ho*****@yahoo.comwrites:
That said, I wouldn't give up the summer I spent studying _Simply
Scheme_.
Sounds like fun. Is this like a kinder, gentler version of SICP?

I'm not sure, though, that I could have learned computer science
properly without the immortal characters of Ben Bittwiddler and Harry
Reasoner intruding into every problem set.

|>oug
Jun 22 '07 #110
On 2007-06-22, Douglas Alan <do**@alum.mit.eduwrote:
Neil Cerutti <ho*****@yahoo.comwrites:
>That said, I wouldn't give up the summer I spent studying _Simply
Scheme_.

Sounds like fun. Is this like a kinder, gentler version of SICP?
No, it is a prequel. Along with "How to Design Programs" it is
meant specifically as a primer for SICP, and an introduction to
computer science.
I'm not sure, though, that I could have learned computer
science properly without the immortal characters of Ben
Bittwiddler and Harry Reasoner intruding into every problem
set.
http://mitpress.mit.edu/catalog/item...ype=2&tid=3662

_Simply Scheme_ has the cute Little Computer People, and amusing
cartoons. If you aren't a Rolling Stones, Beatles, or Monty
Python fan then the examples may seem arbitrary. The authors
chose to make most of their exercises and examples about
manipulating sentences, rather than computing math functions.

It won't much other than a nice diversion if you've already
mastered the material in SICP.

--
Neil Cerutti
Low Self-Esteem Support Group will meet Thursday at 7 to 8:30 p.m. Please use
the back door. --Church Bulletin Blooper
Jun 22 '07 #111
"Terry Reedy" <tj*****@udel.eduwrites:
"Douglas Alan" <do**@alum.mit.eduwrote in message
| But why is the ability to abstract syntax good?
| It allows the community to develop language features in a modular way
| without having to sully the code base for the language itself.
Anyone can write modules, experimental or otherwise, without touching the
code base for any particular implementation.
For those whose know one of the implementation languages, source code
control systems allow one to do experiments on branches without 'sullying'
the trunk or impeding the development thereof.
When I said "without having to sully the code base", I meant that one
can implement a language feature for the target language as a loadable
module written entirely within the language itself, and without having
to understand anything particularly deep or specific about the language
implementation details.

I.e., I could write a new object system for Lisp faster than I could
even begin to fathom the internal of CPython. Not only that, I have
absolutely no desire to spend my valuable free time writing C code.
I'd much rather be hacking in Python, thank you very much.
One of the goals of the PyPy project was to allow people to experiment with
syntax extensions in Python itself. (But I don't know how easy that is
yet.)
PyPy sounds like a very interesting project indeed!
But I think that overall the problem of designing new syntax is more
in the design than the implementation. Anything new has to be
usable, readable, not clash too much with existing style, not
introduce ambiguities, and not move the extended language outside
the LL(1) [I believe that is right] subset of CFLs.
People (myself included) haven't had much trouble implementing nice
and useful macro packages for Lisp. Admittedly, it's a harder problem
for a language that doesn't have a Lisp-like syntax. I believe that
Dylan has macros without having a Lisp-like syntax, but Dylan is
really a dialect of Lisp, only with a more traditional Algol-like
syntax veneered onto it. My guess is that a macro developer for Dylan
would have to be familiar with an underlying hidden intermediate Lisp
syntax. (Though I'm just really just spouting that guess out of my
butt.)

A few years back, I designed a somewhat Python-like language with a
macro facility for a class on dynamic languages and their
implementations. I didn't implement it, however, and I doubt that
I'll have time to get around to it in this lifetime.

|>oug
Jun 22 '07 #112
Steven D'Aprano <st****@REMOVE.THIS.cybersource.com.auwrites:
On Thu, 21 Jun 2007 15:25:37 -0400, Douglas Alan wrote:
>You are imagining something very different from what is proposed.
Lisp-like macros don't allow "anything goes".
Provided people avoid doing anything "which would be considered very
rude" (your own words).
No, Lisp macros are entirely contained within a begin and end
delimiter, which is introduced by the name of the macro. E.g., here
is a real example of some Lisp code that I wrote aeons ago using the
loop macro:

(loop for index from 0 below size
for element in contents
do (store (arraycall t array index)
element)
finally (return (make-htable BUCKETS size
ARRAY array
KEY-PRINTER key-printer
ITEM-PRINTER item-printer)))))

The syntactical extensions supported by the loop macro can only begin
starting immediately after "(loop " and they end with the matching
closing parenthesis. There's no way in Lisp to write a macro whose
syntactical extensions can extend outside of this very explicitly
delimited scope. Nor can they mess with Lisp's tokenization.
Python already allows me to shoot myself in the foot, if I wish. I'm
comfortable with that level of freedom. I'm not necessarily comfortable
with extensions to the language that would allow me the freedom to shoot
myself in the head.
Lisp macros don't let you shoot yourself in the head -- only in the
foot. Being able to do

True = False

is being able to shoot yourself in the head. And Python certainly
lets you do that.
I would need to be convinced of the advantages, as would many other
people, including the BDFL.
The proof is in the pudding for anyone who has seen the advantages it
brings to Lisp. As Paul Graham points out, it's hard to look up and
see the advantages of what is up there in a more powerful language.
It's only easy to look down and see the disadvantages of what is
missing from a less powerful language. To understand the advantages,
one has to be willing to climb the hill and take in the view.
It isn't clear exactly what functionality a hypothetical Python macro
system would include,
It should be largely equivalent to what is provided by Lisp.
Admittedly this is a bit more difficult for Python, as Lisp's syntax
is eminently suited for macros, while Python's is not. One would
probably want to take a look at how Dylan solved this problem, as
Dylan implements Lisp-like macros even though it has an Algol-like
syntax. Or you could look at the paper I wrote (for a class) on the
design of Python-like language that would support macros. My paper is
only a rough sketch, however.
let alone whether the benefits would outweigh the costs,
They pay off in boatloads in the Lisp community.
(It took Lisp half a century and millions of dollars of corporate
funding to reach where it is now.
Ummm, not really. Lisp hasn't really changed very much since the late
'70s, and prior to that, most of the work on Lisp was just done in a
few university labs (e.g., MIT) and at Xerox Parc. Any work and money
that has been spent on Lisp since then has just been in trying to
market it, or standardize it, or design hardware suited to running it
faster, or build better development environments for it, or optimizing
compilers, etc.

Lisp, itself, is rather easily to implement. (Getting it to run as
fast as C is more of a challenge, what with good garbage collectors
and all being non-trivial to implement, but performance doesn't seem
to be much of an issue for the Python community.) I made my own Lisp
implementation in C++ in two weeks. (Not really a production dialect,
but it worked.) Kyoto Common Lisp, which was definitely a production
implementation, was implemented by two people in a couple of years.
(It compiled Common Lisp into C.)

|>oug
Jun 22 '07 #113
"Terry Reedy" <tj*****@udel.eduwrites:
| But why is the ability to abstract syntax good?
I think this points to where Sussman went wrong in his footnote and
Alan in his defense thereof. Flexibility of function -- being able
to do many different things -- is quite different from flexibility
of syntax
I think you are setting up a false dichotomy. One that is related to
the false unification that annoying people used to always make when
they would perpetually argue that it wasn't important which
programming language you programmed in, as they are all Turing
equivalent anyway. Well, I sure as hell don't want to write all my
programs for a Turning machine, and a Turing machine is certainly
Turing equivalent!

Functionality is no good if it's too cumbersome to use. For instance,
Scheme gives you first class continuations, which Python doesn't.
Continuations let you do *all sorts* of interesting things that you
just cannot do in Python. Like backtracking, for instance. (Well
maybe you could do backtracking in Python with lots of putting code
into strings and liberal use of eval, for all I know, but the results
would almost certainly be too much of a bear to actually use.)

Now, continuations, by themselves, in Scheme actually don't buy you
very much, because although they let you do some crazy powerful
things, making use of them to do so, is too confusing and verbose. In
order to actually use this very cool functionality, you need macros so
that you can wrap a pretty and easy-to-use face on top of all the
delicious continuation goodness.

You'll, just have to trust me on this one. I've written code with
continuations, and I just couldn't make heads or tails out of the code
a few hours later. But when prettied-up with a nice macro layer, they
can be a joy to behold.

|>oug
Jun 22 '07 #114

"Douglas Alan" <do**@alum.mit.eduwrote in message
news:lc************@gaffa.mit.edu...
| "Terry Reedy" <tj*****@udel.eduwrites:
| I think this points to where Sussman went wrong in his footnote and
| Alan in his defense thereof. Flexibility of function -- being able
| to do many different things -- is quite different from flexibility
| of syntax
|
| I think you are setting up a false dichotomy.

I think this denial of reality is your way of avoiding admitting, perhaps
to yourself, that your god Sussman made a mistake.

| One that is related to
| the false unification that annoying people used to always make when
| they would perpetually argue that it wasn't important which
| programming language you programmed in, as they are all Turing
| equivalent anyway. Well, I sure as hell don't want to write all my
| programs for a Turning machine, and a Turing machine is certainly
| Turing equivalent!

Diversionary crap unrelated to the previous discussion.

Bye.

Jun 22 '07 #115
"Terry Reedy" <tj*****@udel.eduwrites:
"Douglas Alan" <do**@alum.mit.eduwrote in message
| "Terry Reedy" <tj*****@udel.eduwrites:
| I think this points to where Sussman went wrong in his footnote
| and Alan in his defense thereof. Flexibility of function --
| being able to do many different things -- is quite different
| from flexibility of syntax
| I think you are setting up a false dichotomy.
I think this denial of reality is your way of avoiding admitting, perhaps
to yourself, that your god Sussman made a mistake.
Sussman isn't my god -- Kate Bush is.

Just because I'm right and you're wrong, doesn't mean that I'm in
denial. It is you who are in denial if you believe that syntax is
unimportant, as long as one is provided the required functionality.
In fact, that's stereotypical Computer Science denial. Computer
Science academics will typically state as a truism that semantics are
what is important and syntax is just a boring trifle in comparison.
But time and time again, you'll see programming languages succeed or
fail more on their syntax than on their semantics. And issues of
syntax is often where you see the most inflamed debates. Just look at
all the flames one used to hear about Python using whitespace
significantly. Or all the flames that one will still hear about Lisp
using a lot of parentheses.

You seem oblivious to the fact that one of the huge benefits of Python
is its elegant and readable syntax. The problem with not having a
"flexible syntax", is that a programming language can't provide
off-the-shelf an elegant syntax for all functionality that will ever
be needed. Eventually programmers find themselves in need of new
elegant functionality, but without a corresponding elegant syntax to
go along with the new functionality, the result is code that does not
look elegant and is therefore difficult to read and thus maintain.

Consequently, "flexibility of function" is often moot without
"flexibility of syntax". I don't know how I can make it any clearer
than this. I'm sorry if you don't understand what I am saying, but
just because you don't understand, or if you do, that you don't agree,
doesn't mean that I don't have a reasoned and reasonable point of
view.
| One that is related to the false unification that annoying people
| used to always make when they would perpetually argue that it
| wasn't important which programming language you programmed in, as
| they are all Turing equivalent anyway. Well, I sure as hell don't
| want to write all my programs for a Turning machine, and a Turing
| machine is certainly Turing equivalent!
Diversionary crap unrelated to the previous discussion.
Take the issue up with Paul Graham. Since making a fortune developing
software in Lisp (making heavy use of macros), he now has much more
free time to write essays defending the truth than I do:

http://www.paulgraham.com/avg.html

|>oug
Jun 22 '07 #116
Douglas Alan <do**@alum.mit.eduwrites:
People (myself included) haven't had much trouble implementing nice
and useful macro packages for Lisp. Admittedly, it's a harder problem
for a language that doesn't have a Lisp-like syntax.
One very simple hack would be to define a syntax extension like

f.(arg1,arg2,arg3)

to compile f's args into unevaluated thunks passed into f, instead of
evaluating them as expressions before calling f. That could replace
macros and syntax extensions in some circumstances. For example the
famous ternary operator would just be

def ternary(cond, a, b):
if cond(): return a()
else: return b()

Then you'd write, e.g.

selection = ternary.(x y, exp1, exp2)

without worrying about side effects of exp1 and exp2 both getting
evaluated.

Jun 23 '07 #117
On Fri, 22 Jun 2007 13:21:14 -0400, Douglas Alan wrote:
I.e., I could write a new object system for Lisp faster than I could
even begin to fathom the internal of CPython. Not only that, I have
absolutely no desire to spend my valuable free time writing C code.
I'd much rather be hacking in Python, thank you very much.
Which is very valuable... IF you care about writing a new object system. I
don't, and I think most developers don't, which is why Lisp-like macros
haven't taken off. I simply don't want to think about object syntax, I
just want it to work. I'm happy that Guido and the other Python-dev
people have thought about it, and come up with a good syntax, and are
conservative with their syntax changes. When I use somebody else's
library, I don't want to have to learn their syntax, no matter how cunning
they think it is.

The cost is that if I do have a brilliant new idea for syntax to Python,
it is hard for me to implement it. Nobody sensible denies that Python's
model is cost-free. But I think the cost is worth it, in the same way that
building houses out of bricks and mortar instead of plastic Lego blocks
makes it really hard to redesign the layout of rooms in the house, but has
other advantages.

(Don't over-analyze the analogy. I'm not suggesting Lisp code is
necessarily as fragile and easy to break as a house made of Lego would be,
or that Python code is safe as houses.)
--
Steven.

Jun 23 '07 #118
On Fri, 22 Jun 2007 13:54:35 -0400, Douglas Alan wrote:
>Python already allows me to shoot myself in the foot, if I wish. I'm
comfortable with that level of freedom. I'm not necessarily comfortable
with extensions to the language that would allow me the freedom to shoot
myself in the head.

Lisp macros don't let you shoot yourself in the head -- only in the
foot. Being able to do

True = False

is being able to shoot yourself in the head. And Python certainly
lets you do that.
True, that is a current piece of badness. There are arguments for and
against making True and False reserved words, like None.

Nevertheless, in Python 1+2 always equals 3. You can't say the same thing
about Lisp.

>I would need to be convinced of the advantages, as would many other
people, including the BDFL.

The proof is in the pudding for anyone who has seen the advantages it
brings to Lisp. As Paul Graham points out, it's hard to look up and
see the advantages of what is up there in a more powerful language.
It's only easy to look down and see the disadvantages of what is missing
from a less powerful language. To understand the advantages, one has to
be willing to climb the hill and take in the view.
I don't accept Graham's reasoning.

I think that it is true that people's *values* change, as they get more
familiar with a more powerful language. For instance, I used to write
Pascal code on a Mac, and I avoided object-oriented techniques because
they were too inefficient and slow. (E.g. when Apple released System
7, which used OO code extensively, even the most one-eyed Mac fan boys
had to admit that the Finder ran like a dog compared to System 6.) But the
advantages were obvious, even before I had experience with OO design.

Now, I use Python, which is all object-oriented -- but the hardware I run
it on is so much faster that I care more about the programmer productivity
(my time) than about the efficiency of the executed code (the computer's
time). But if I were still running on a 1988-vintage Mac, you better believe I
wouldn't be making the same trade-offs I am now.

So, quite frankly, the things which you and Graham value in Lisp *simply
don't interest me*. It isn't that I can't see the advantages. They just
don't matter to me, in fact in some ways they are disadvantages.

Could my opinion ever change? Of course it could. I might, for example,
suddenly have a burning passion about language design, or find some
problem that is really painful under Python, and then I might go searching
for "a more powerful language". One doesn't need to be familiar with more
powerful languages to be aware that they offer benefits that less powerful
languages don't.

Or some really smart people might come up with a macro system that reduces
the disadvantages while keeping the advantages, and then dealing with
some random module developer's syntax extensions no more frightening than
dealing with some random module developer's functions.

(Considering the poor design and shoddy code of some modules I've had to
deal with, I really worry about giving developers the ability to redefine
syntax too.)

[snip]

>let alone whether the benefits would outweigh the costs,

They pay off in boatloads in the Lisp community.
But do they? Where is the standard library containing all these
magnificent macros? Forcing people to implement basic things from scratch
doesn't sound like a pay-off to me.

It seems that one of the major costs of having an extremely minimalist,
but easily extensible, syntax is that it encourages massive re-invention
of the wheel. Things get moved into the language slowly, because it is so
easy to work around the lack -- but the cost is a proliferation of
different macros all doing the same thing.

I think Python has the better philosophy. Python has one really good
syntax, minimalistic but not _overly_ minimalistic, not an easily
extensible syntax. The cost is that there are some things which could be
easier, if the syntax were different, but the benefit is that I don't have
to write syntax-extending macros, or debug them, or learn somebody else's.
Once every few years, Python introduces a new syntax, e.g. list
comprehensions, after much thought. That's better than every time I use a
different library or module.
--
Steven.

Jun 23 '07 #119
Douglas Alan wrote:
"Terry Reedy" <tj*****@udel.eduwrites:
>"Douglas Alan" <do**@alum.mit.eduwrote in message
>| But why is the ability to abstract syntax good?
>| It allows the community to develop language features in a modular way
| without having to sully the code base for the language itself.
>Anyone can write modules, experimental or otherwise, without touching the
code base for any particular implementation.
>For those whose know one of the implementation languages, source code
control systems allow one to do experiments on branches without 'sullying'
the trunk or impeding the development thereof.

When I said "without having to sully the code base", I meant that one
can implement a language feature for the target language as a loadable
module written entirely within the language itself, and without having
to understand anything particularly deep or specific about the language
implementation details.

I.e., I could write a new object system for Lisp faster than I could
even begin to fathom the internal of CPython. Not only that, I have
absolutely no desire to spend my valuable free time writing C code.
I'd much rather be hacking in Python, thank you very much.
CPython's class system is independent of the interpreter proper. That is
how two class systems, classic and new-style, can exist in the same
language. Both class types implement hooks into attribute lookup. By
providing __getattr__/__getattribute__, __setattr__, and __delattr__
methods one can effectively alter object behavior, such as method
resolution. And metaclasses change the nature of class statements. Novel
objects systems, such as prototypes, are possible. So the Python
language provides more of a framework for handling objects rather than
defining an actual object model. Python is the syntax; objects define
the behavior.

Finally, with the advent of Python 2.2, built-in types like int and list
became far more class like. Subclassing became possible. The object
types were reworking at the interpreter level. No amount of macro
wizardry could have done it.
>One of the goals of the PyPy project was to allow people to experiment with
syntax extensions in Python itself. (But I don't know how easy that is
yet.)

PyPy sounds like a very interesting project indeed!
PyPy uses aspects without needing macros.
>But I think that overall the problem of designing new syntax is more
in the design than the implementation. Anything new has to be
usable, readable, not clash too much with existing style, not
introduce ambiguities, and not move the extended language outside
the LL(1) [I believe that is right] subset of CFLs.

People (myself included) haven't had much trouble implementing nice
and useful macro packages for Lisp. Admittedly, it's a harder problem
for a language that doesn't have a Lisp-like syntax. I believe that
Dylan has macros without having a Lisp-like syntax, but Dylan is
really a dialect of Lisp, only with a more traditional Algol-like
syntax veneered onto it. My guess is that a macro developer for Dylan
would have to be familiar with an underlying hidden intermediate Lisp
syntax. (Though I'm just really just spouting that guess out of my
butt.)
Dylan macros do not use an "underlying hidden intermediate Lisp syntax".
They are language-based, doing pattern matching on Dylan language
elements ( http://www.opendylan.org/books/dpg/db_329.html ).
A few years back, I designed a somewhat Python-like language with a
macro facility for a class on dynamic languages and their
implementations. I didn't implement it, however, and I doubt that
I'll have time to get around to it in this lifetime.
It's easy to say Python would benefit from macros. Macros have solved
problems in Common Lisp and Scheme and so it is assumed they can do the
same for Python. But no concrete suggestions are made in this thread. No
specific macro mechanism is put forward for Python. No example is given
on how to implement some Python feature with it. No point has been
identified in the Python compiler chain for macro expansion.

When this thread turned to the topic of macros I did an Internet search
for information on macros relevant to Python. Dylan's macros look
promising. The Python-inspired language Converge has macros (
http://convergepl.org/ ). Michael Hudson's Bytecodehacks package
supports limited Python macros (
http://bytecodehacks.sourceforge.net...cks.macro.html
). There is also the __macro__ package, which I still have on my
computer, but I cannot find its home page.

The __macro__ package simply allows text substitution of source code at
module import time. The bytecodehack.macro module lets one define what
amounts to inlined functions. IMO neither package represents a
productive macro system. And I could find no other attempts to take
Python macros beyond wishful thinking. So until some solid proposal for
Python macros is put on the table any discussion of their merits is
unproductive. I can suggest though that procedural macros are a natural
starting point given the runtime nature of class and function creation.

--
Lenard Lindstrom
<le***@telus.net>

Jun 23 '07 #120
On Fri, 22 Jun 2007 19:51:28 -0400, Douglas Alan wrote:
You seem oblivious to the fact that one of the huge benefits of Python
is its elegant and readable syntax. The problem with not having a
"flexible syntax", is that a programming language can't provide
off-the-shelf an elegant syntax for all functionality that will ever
be needed.
It is hardly "off-the-shelf" if somebody has to create new syntax for it.
Eventually programmers find themselves in need of new
elegant functionality, but without a corresponding elegant syntax to
go along with the new functionality, the result is code that does not
look elegant and is therefore difficult to read and thus maintain.
That's true, as far as it goes, but I think you over-state your
case. The syntax included in Python is excellent for most things, and even
at its weakest, is still good. I can't think of any part of Python's
syntax that is out-and-out bad.

The reality is, one can go a long, long, long distance with Python's
syntax. Most requests for "new syntax" I've seen fall into a few
categories:

* optimization, e.g. case, repeat, multi-line lambda
* "language Foo looks like this, it is kewl"
* the usual braces/whitespace flamewars
* trying to get static type checking into the language
So let's be specific -- what do you think Python's syntax is missing? If
Python did have a macro facility, what would you change?

It is easy to point to functional features Python is missing, but are they
functions that can't be elegantly written without new syntax? Given
that not everybody is convinced that Python needs static type checking,
the only obvious hole I can see is the lack of syntax for
repeat-at-least-once.
[snip]
Take the issue up with Paul Graham. Since making a fortune developing
software in Lisp (making heavy use of macros), he now has much more
free time to write essays defending the truth than I do:

http://www.paulgraham.com/avg.html

I think the #1 advantage to using Lisp in a commercial enterprise is only
indirectly related to the language. Lisp coders are a self-selecting
above-average bunch -- no VB drones or C code monkeys need apply.

Graham talks about 25% of the Viaweb code base being macros. Imagine how
productive his coders would have been if the language was not quite
so minimalistic, so that they could do what they wanted without the
_lack_ of syntax getting in the way.

--
Steven.

Jun 23 '07 #121
On Jun 22, 8:09 pm, Douglas Alan <d...@alum.mit.eduwrote:
Functionality is no good if it's too cumbersome to use. For instance,
Scheme gives you first class continuations, which Python doesn't.
Continuations let you do *all sorts* of interesting things that you
just cannot do in Python. Like backtracking, for instance. (Well
maybe you could do backtracking in Python with lots of putting code
into strings and liberal use of eval, for all I know, but the results
would almost certainly be too much of a bear to actually use.)

Now, continuations, by themselves, in Scheme actually don't buy you
very much, because although they let you do some crazy powerful
things, making use of them to do so, is too confusing and verbose. In
order to actually use this very cool functionality, you need macros so
that you can wrap a pretty and easy-to-use face on top of all the
delicious continuation goodness.

You'll, just have to trust me on this one. I've written code with
continuations, and I just couldn't make heads or tails out of the code
a few hours later. But when prettied-up with a nice macro layer, they
can be a joy to behold.

Been there, done that. So what? Your example will not convince any
Pythonista.
The Pythonista expects Guido to do the language job and the
application developer
to do the application job. Consider for instance generators. In Python
they are
already implemented in the core language and the application developer
does not
care at all about implementing them. In Scheme I am supposed to
implement them myself with
continuations, but why should I do that, except as a learning
exercise? It is
much better if competent people are in charge of the very low level
stuff and
give me just the high level tools. I essentially view macros are low-
level performance
hacks, useful for language developers more than for application
developers.
BTW, there are already Python-like languages with macros (i.e. logix)
and still
nobody use them, including people with a Scheme/Lisp background. That
should be
telling you something.
Michele Simionato

Jun 23 '07 #122
On Jun 22, 7:54 pm, Douglas Alan <d...@alum.mit.eduwrote:
The proof is in the pudding for anyone who has seen the advantages it
brings to Lisp. As Paul Graham points out, it's hard to look up and
see the advantages of what is up there in a more powerful language.
It's only easy to look down and see the disadvantages of what is
missing from a less powerful language. To understand the advantages,
one has to be willing to climb the hill and take in the view.
Right. However you fail to recognize that there are people here with a
good
understanding of Lisp and its macrology that still prefer Python over
Lisp.
I will go even further and say that the utility of macros is inversely
proportional
to the power of a language: the more the language is powerful, the
less macros
are useful. Really powerful languages (say Haskell, just not to be too
Python-centric)
do not need macros.

Provocative-but-with-a-grain-of-salt-in-it-yours,

Michele Simionato

Jun 23 '07 #123
On Jun 23, 6:11 am, Lenard Lindstrom <l...@telus.netwrote:
When this thread turned to the topic of macros I did an Internet search
for information on macros relevant to Python. Dylan's macros look
promising. The Python-inspired language Converge has macros (http://convergepl.org/). Michael Hudson's Bytecodehacks package
supports limited Python macros (http://bytecodehacks.sourceforge.net...e-bytecodehack...
). There is also the __macro__ package, which I still have on my
computer, but I cannot find its home page.

The __macro__ package simply allows text substitution of source code at
module import time. The bytecodehack.macro module lets one define what
amounts to inlined functions. IMO neither package represents a
productive macro system. And I could find no other attempts to take
Python macros beyond wishful thinking. So until some solid proposal for
Python macros is put on the table any discussion of their merits is
unproductive. I can suggest though that procedural macros are a natural
starting point given the runtime nature of class and function creation.

--
Lenard Lindstrom
<l...@telus.net>
I would add to your list http://livelogix.net/logix/
and
http://www.fiber-space.de/EasyExtend...asyExtend.html

Michele Simionato

Jun 23 '07 #124
Michele Simionato <mi***************@gmail.comwrites:
BTW, there are already Python-like languages with macros
(i.e. logix) and still nobody use them, including people with a
Scheme/Lisp background. That should be telling you something.
What about Dylan?
Jun 23 '07 #125
Michele Simionato <mi***************@gmail.comwrites:
Really powerful languages (say Haskell, just not to be too
Python-centric) do not need macros.
http://www.haskell.org/th/
Jun 23 '07 #126
Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrites:
Nevertheless, in Python 1+2 always equals 3. You can't say the same thing
about Lisp.
Well, I can't say much of *anything* about "1 + 2" in Lisp, since
that's not the syntax for adding numbers in Lisp. In Lisp, numbers
are typically added using the "+" function, which might be invoked
like so:

(+ 1 2 3)

This would return 6.

It's true that some dialects of Lisp will let you redefine the "+"
function, which would typically be a bad idea. Other dialects would
give you an error or a warning if you tried to redefine "+". I would
fall more into the latter camp. (Though sometimes you might want a
way to escape such restrictions with some sort of "yes, I really want
to shoot myself in the head" declaration, as you may want to
experiment, not with changing the meaning of "(+ 1 2"), but rather
with adding some additional useful capability to the "+" function that
it doesn't already have.

Back on the Python front, although "1 + 2" might always equal 3 in
Python, this is really rather cold comfort, since no useful code would
ever do that. Useful code might include "a + 1", but since you can
overload operators in Python, you can say little about what "a + 1"
might do or mean on the basis of the syntax alone.

Furthermore, in Python you can redefine the "int" data type so that
int.__add__ does a subtraction instead. Then you end up with such
weirdness as
>>int(1.0) + int(2.0)
-1

Also, you can redefine the sum() function in Python.

So, we see that Python offers you a multitude of ways to shoot
yourself in the head.

One of the things that annoys me when coding in Python (and this is a
flaw that even lowly Perl has a good solution for), is that if you do
something like

longVarableName = foo(longVariableName)

You end up with a bug that can be very hard to track down. So one use
for macros would be so that I can define "let" and "set" statements so
that I might code like this:

let longVariableName = 0
set longVarableName = foo(longVariableName)

Then if longVarableName didn't already exist, an error would be
raised, rather than a new variable being automatically created for me.

The last time I mentioned this, Alex Martelli basically accused me of
being an idiot for having such trivial concerns. But, ya know -- it
isn't really a trivial concern, despite Martelli's obviously high
intellect. A woman I work with who is bringing up a CMS using Drupal
was complaining to me bitterly that this very same issue in PHP was
causing her bugs that were hard to track down. Unfortunately, I could
not gloat over her with my Python superiority, because if Drupal were
written in Python, rather than PHP, she'd have the very same problem
-- at least in this regard.

|>oug
Jun 23 '07 #127
Michele Simionato <mi***************@gmail.comwrites:
Been there, done that. So what? Your example will not convince any
Pythonista.
I'm a Pythonista, and it convinces me.
The Pythonista expects Guido to do the language job and the
application developer to do the application job.
I'm happy to hear that there is a brain washing device built into
Python that provides all Python programmers with exactly the same
mindset, as that will certainly aid in having a consistent look and
feel to all Python code.
Consider for instance generators.
Yes, consider them! If Python had first class continuations (like
Ruby does) and macros in 1991, it could have had generators in 1992,
rather than in 2002. (I implemented generators using macros and stack
groups for Lisp Machines in 1983, and it took me all of a few hours.)
In Python they are already implemented in the core language and the
application developer does not care at all about implementing them.
And if they were implemented as macros in a library, then the
application developer doesn't have to care about implementing them
either.
In Scheme I am supposed to implement them myself with continuations,
but why should I do that, except as a learning exercise?
Well, when I get around to giving my sage advice to the Scheme
community, I'll let them know that generators need to be in the
standard library, not a roll-your-own exercise.
It is much better if competent people are in charge of the very low
level stuff and give me just the high level tools.
Even many competent people don't want to hack in the implementation
language and have to understand the language implementation internals
to design and implement language features. By your argument,
Pythonistas might as well insist that the entire standard library be
coded in C.
BTW, there are already Python-like languages with macros
(i.e. logix) and still nobody use them, including people with a
Scheme/Lisp background. That /should be telling you something.
It only tells me what I've known for at least a couple decades now --
that languages live and die on issues that often have little to do
with the language's intrinsic merits.

|>oug
Jun 23 '07 #128
On Sat, 23 Jun 2007 12:39:51 -0400, Douglas Alan wrote:
One of the things that annoys me when coding in Python (and this is a
flaw that even lowly Perl has a good solution for), is that if you do
something like

longVarableName = foo(longVariableName)

You end up with a bug that can be very hard to track down. So one use
for macros would be so that I can define "let" and "set" statements so
that I might code like this:

let longVariableName = 0
set longVarableName = foo(longVariableName)

Then if longVarableName didn't already exist, an error would be
raised, rather than a new variable being automatically created for me.
So "let" is the initial declaration, and "set" modifies the existing
variable?

What happens is you declare a variable twice?

let longVariableName = 0
let longVariableName = foo(longVariableName) # oops I meant set

How long did it take you to write the macros, and use them, compared to
running Pylint or Pychecker or equivalent?
But if you really want declarations, you can have them.
>>import variables
variables.declare(x=1, y=2.5, z=[1, 2, 4])
variables.x = None
variables.w = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "variables.py", line 15, in __setattr__
raise self.DeclarationError("Variable '%s' not declared" % name)
variables.DeclarationError: Variable 'w' not declared

The variables module isn't part of the standard library. Here's the code
for it:

import sys

class _variable:
class DeclarationError(TypeError): pass
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
self.__dict__[name] = value
else:
raise self.DeclarationError("Variable '%s' not declared" % name)
self.__dict__[name]=value
def declare(self, **args):
for name, value in args.items():
self.__dict__[name] = value

sys.modules[__name__]=_variable()
It took me less than five minutes starting from Alex Martelli's code here
http://aspn.activestate.com/ASPN/Coo...n/Recipe/65207

No special syntax or macros or magic powers were needed. I could extend
the variables functionality to (say) make sure the same variable isn't
declared twice, or be case-insensitive, or have multiple namespaces, none
of which need special syntax.
--
Steven.

Jun 23 '07 #129
Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrites:
>So one use for macros would be so that I can define "let" and "set"
statements so that I might code like this:

let longVariableName = 0
set longVarableName = foo(longVariableName)

Then if longVarableName didn't already exist, an error would be
raised, rather than a new variable being automatically created for me.
So "let" is the initial declaration, and "set" modifies the existing
variable?
Yes.
What happens is you declare a variable twice?
The same thing that would happen in Perl or any other language that
supports this type of variable declaration and setting: it would raise
an error.

The big debate you get next, is then whether you should be allowed to
shadow variables in nested scopes with new variables of the same
name. Given that Python already allows this, my guess is that the
answer should be yes.
How long did it take you to write the macros, and use them, compared
to running Pylint or Pychecker or equivalent?
An hour? Who cares? You write it once and then you have it for the
rest of your life. You put it in a widely available library, and then
*every* programmer also has it for the rest of their lives. The
amortized cost: $0.00. The value: priceless.
But if you really want declarations, you can have them.
>>>import variables
variables.declare(x=1, y=2.5, z=[1, 2, 4])
variables.x = None
variables.w = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "variables.py", line 15, in __setattr__
raise self.DeclarationError("Variable '%s' not declared" % name)
variables.DeclarationError: Variable 'w' not declared
Thanks, but that's just too syntactically ugly and verbose for me to
use. Not only that, but my fellow Python programmers would be sure to
come and shoot me if I were to code that way.

One of the reasons that I want to use Python is because I like reading
and writing code that is easy to read and looks good. I don't want to
bend it to my will at the expense of ugly looking code.

|>oug
Jun 23 '07 #130
Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrites:
But if you really want declarations, you can have them.
>>>import variables
variables.declare(x=1, y=2.5, z=[1, 2, 4])
variables.x = None
variables.w = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "variables.py", line 15, in __setattr__
raise self.DeclarationError("Variable '%s' not declared" % name)
variables.DeclarationError: Variable 'w' not declared
Oh, I forgot to mention that I work a lot on preexisting code, which I
am surely not going to go to all the effort to retype and then retest.
With the "let" and "set" macros I can use "set" without a matching
"let". "set" just checks to make sure that a variable already exists
before assigning to it, and "let" just prevents against
double-declarations. They can be used independently or together.
With your "variables" class, they have to be used together.

|>oug
Jun 23 '07 #131
On Sat, 23 Jun 2007 14:56:35 -0400, Douglas Alan wrote:
>How long did it take you to write the macros, and use them, compared
to running Pylint or Pychecker or equivalent?

An hour? Who cares? You write it once and then you have it for the
rest of your life. You put it in a widely available library, and then
*every* programmer also has it for the rest of their lives. The
amortized cost: $0.00. The value: priceless.
Really? Where do I download this macro? How do I find out about it? How
many Lisp programmers are using it now?

How does your glib response jib with your earlier claims that the
weakness of Lisp/Scheme is the lack of good libraries?

Googling for ' "Douglas Allen" download lisp OR scheme ' wasn't very
promising. If you have made your macros available to others, they don't
seem to be very well-known.

In fairness, the various Python lints/checkers aren't part of the standard
library either, but they are well-know "standards".
>But if you really want declarations, you can have them.
>>>>import variables
variables.declare(x=1, y=2.5, z=[1, 2, 4])
variables.x = None
variables.w = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "variables.py", line 15, in __setattr__
raise self.DeclarationError("Variable '%s' not declared" % name)
variables.DeclarationError: Variable 'w' not declared

Thanks, but that's just too syntactically ugly and verbose for me to
use.

"Syntactically ugly"? "Verbose"?

Compare yours with mine:

let x = 0
let y = 1
let z = 2
set x = 99

(Looks like BASIC, circa 1979.)

variables.declare(x=0, y=1, z=2)
variables.x = 99

(Standard Python syntax.)

I don't think having two easily confused names, let and set, is an
advantage, but if you don't like the word "declare" you could change it to
"let", or change the name of the module to "set" (although that runs the
risk of confusing it with sets).

Because this uses perfectly stock-standard Python syntax, you could even
do this, so you type fewer characters:

v = variables
v.x = 99

and it would Just Work.

Not only that, but my fellow Python programmers would be sure to
come and shoot me if I were to code that way.
*shrug* They'd shoot you if you used "let x = 0" too.

One of the reasons that I want to use Python is because I like reading
and writing code that is easy to read and looks good. I don't want to
bend it to my will at the expense of ugly looking code.
But the "ugly looking code" is stock-standard Python syntax.

module.function(keyword=value)
module.attribute = value

is precisely the standard Python syntax you describe as "easy to read and
looks good" one moment. I don't believe you that you find it "ugly looking
code" -- if you did, you wouldn't be using Python.
--
Steven.

Jun 24 '07 #132
Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrites:
On Sat, 23 Jun 2007 14:56:35 -0400, Douglas Alan wrote:
>>How long did it take you to write the macros, and use them, compared
to running Pylint or Pychecker or equivalent?
>An hour? Who cares? You write it once and then you have it for the
rest of your life. You put it in a widely available library, and then
*every* programmer also has it for the rest of their lives. The
amortized cost: $0.00. The value: priceless.
Really? Where do I download this macro? How do I find out about it? How
many Lisp programmers are using it now?
(1) I didn't have to write such a macro for Lisp, as Lisp works
differently. For one thing, Lisp already has let and set special
forms. (Lisp uses the term "special form" for what Python would call
a "statement", but Lisp doesn't call them statements since they return
values.)

(2) You act as if I have no heavy criticisms of Lisp or the Lisp
community. I critique everything with equal vigor, and keep an eye
out for the good aspects and ideas of everything with equal vigor.
How does your glib response jib with your earlier claims that the
weakness of Lisp/Scheme is the lack of good libraries?
(1) See above. (2) My response wasn't glib.
Googling for ' "Douglas Allen" download lisp OR scheme ' wasn't very
promising.
(1) You spelled my name wrong. (2) I haven't written any libraries
for any mainstream dialects of Lisp since there was a web. I did
write a multiple dispatch lookup cacher for a research dialect of
Lisp, but it was just an exercise for a version of Lisp that few
people have ever used.
In fairness, the various Python lints/checkers aren't part of the standard
library either, but they are well-know "standards".
In general I don't like such checkers, as I tend to find them more
annoying than useful.
>Thanks, but that's just too syntactically ugly and verbose for me to
use.
"Syntactically ugly"? "Verbose"?
Compare yours with mine:
let x = 0
let y = 1
let z = 2
set x = 99
(Looks like BASIC, circa 1979.)
It looks like a lot of languages. And there's a reason for that -- it
was a good idea.
variables.declare(x=0, y=1, z=2)
variables.x = 99
(Standard Python syntax.)
I don't think having two easily confused names, let and set is an
advantage,
Let and set are not easily confused. Lisp programmers have had
absolutely no problem keeping the distinction separate for the last 47
years now.
but if you don't like the word "declare" you could change it to
"let", or change the name of the module to "set" (although that runs the
risk of confusing it with sets).
Because this uses perfectly stock-standard Python syntax, you could even
do this, so you type fewer characters:
v = variables
v.x = 99
and it would Just Work.
I wouldn't program that way, and no one that I know would either.

In this regard you sound exactly like all the C++ folks, who when you
point out that something in C++ is inadequate for one's needs, they
point you at some cumbersome and ugly solution and then tell you that
since C++ can already deal with the complaint, that there's no good
reason to consider changing C++. Consequently, C++ still doesn't have
a "finally" statement, and it requires either making instance
variables public or forcing the programmer to write lots of
boilerplate code writing setter and getter functions. Fortunately,
the Python developers finally saw the errors of their ways in this
regard and fixed the situation. But, it seems to me that you would
have been one of those people saying that there's no need to have a
way of overriding attribute assignment and fetching, as you can always
just write all that extra boilerplate code, or instead add an extra
layer of indirection (proxy objects) in your instance data to have
things done the way you want, at the expense of ugly code.
>Not only that, but my fellow Python programmers would be sure to
come and shoot me if I were to code that way.
*shrug* They'd shoot you if you used "let x = 0" too.
Clearly you are not familiar with the programmers that I work with.
As I mentioned previously, at least one of them is quite upset about
the auto-declaration feature of most scripting languages, and your
suggestion would not make her any happier.
>One of the reasons that I want to use Python is because I like reading
and writing code that is easy to read and looks good. I don't want to
bend it to my will at the expense of ugly looking code.
But the "ugly looking code" is stock-standard Python syntax.
There many things that cannot be done in stock Python syntax elegantly
(e.g. multiple predicate dispatch), which is why, when programming in
Python, one often sticks to doing things the way that *can* be done
elegantly. (This can often result in programs that are structured
less elegantly in the large, however.) If you don't recognize this,
then you must be livid over the addition to Python of decorators, list
and generator comprehension, etc. After, all, Python is Turing
complete, and any problem that can be solved in Python now could have
been solved in Python before. The solution might just have looked a
little (or a lot) different.
module.function(keyword=value)
module.attribute = value
is precisely the standard Python syntax you describe as "easy to read and
looks good" one moment. I don't believe you that you find it "ugly looking
code" -- if you did, you wouldn't be using Python.
It's ugly for the purpose of local variable assignment, as it doesn't
*look* like local variable assignment. If I wanted to program in a
language that didn't understand the idea that different sorts of
things ought to look different, I'd program in Java, rather than Python.

|>oug
Jun 24 '07 #133

Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrites:
Graham talks about 25% of the Viaweb code base being macros. Imagine how
productive his coders would have been if the language was not quite
so minimalistic, so that they could do what they wanted without the
_lack_ of syntax getting in the way.
Paul Graham's Viaweb code was written in Common Lisp, which is the least
minimalistic dialect of Lisp that I know. Even though they were using this
powerful tool, they still found it useful to create new syntactic
abstractions. How much less productive would they have been had they not
had this opportunity?
Jun 24 '07 #134
Steven D'Aprano <st***@REMOVE.THIS.cybersource.com.auwrites:
>You seem oblivious to the fact that one of the huge benefits of Python
is its elegant and readable syntax. The problem with not having a
"flexible syntax", is that a programming language can't provide
off-the-shelf an elegant syntax for all functionality that will ever
be needed.
It is hardly "off-the-shelf" if somebody has to create new syntax
for it.
Ummm. that's my point. No language can provide all the syntax that
will ever be needed to write elegant code. If module authors can
provide the syntax needed to use their module elegantly, then problem
solved.
>Eventually programmers find themselves in need of new
elegant functionality, but without a corresponding elegant syntax to
go along with the new functionality, the result is code that does not
look elegant and is therefore difficult to read and thus maintain.
That's true, as far as it goes, but I think you over-state your
case.
I do not.

It is so easy for you, without *any* experience with a language (i.e.,
Lisp) or its community to completely dismiss the knowledge and wisdom
acquired by that community. Doesn't that disturb you a bit?
The syntax included in Python is excellent for most things, and even
at its weakest, is still good. I can't think of any part of Python's
syntax that is out-and-out bad.
The proposed syntax for using the proposed predicate-based multimethod
library is ungainly.

Until decorators were added to the language, the way to do things that
decorators are good for was ugly. Decorators patch up one ugliness,
but who wants Python to become an old boat with lots of patches?

Nearly every addition made to Python since 1.5 could have been done in
the standard library, rather than being made to the core language, if
Python had a good macro system. The exceptions, I think, being
objects all the way down, and generators. Though generators could
have been done in the standard library too, if Python had first class
continuations, like Scheme and Ruby do.

Over time, an infinite number of examples will turn up like this, and
I claim (1) that it is better to modify the standard library than to
modify the language implementation, and that (2) it is better to allow
people to experiment with language features without having to modify
the implementation, and (3) that it is better to allow people to
distribute new language features for experimentation or production in
a loadable modular fashion, and (4) that it is better to allow
application developers to develope new language features for their
application frameworks than to not.
The reality is, one can go a long, long, long distance with Python's
syntax.
And you can go a long, long way with Basic, or Fortran, or C, or C++,
or Haskell, or Lisp. None of this implies that there aren't
deficiencies in all of these languages. Python is no exception.
Python just happens to be better than most in a number of significant
regards.
Most requests for "new syntax" I've seen fall into a few
categories:
* optimization, e.g. case, repeat, multi-line lambda
I don't give a hoot about case or repeat, though a Lisp-like "loop
macro" might be nice. (The loop macro is a little mini language
optimized for coding complicated loops.) A multi-line lambda would
be very nice.
* "language Foo looks like this, it is kewl"
Sometimes language Foo has features that are actually important to for
a specific application or problem domain. It's no accident, for
instance, that Lisp is still the preferred language for doing AI
research. It's better for Python if Python can accommodate these
applications and domains than for Python to give up these markets to
Foo.
* the usual braces/whitespace flamewars
* trying to get static type checking into the language
So let's be specific -- what do you think Python's syntax is missing? If
Python did have a macro facility, what would you change?
In addition to the examples given above, symbols would be nice. Lisp
has 'em, Ruby has 'em, Python doesn't. They are very useful.

An elegant multimethod based object system will be essential
for every language someday, when the time is right for people to
understand the advantages.

Manifest typing will be essential.

A backtracking system is important for some applications. Perhaps all
applications, someday.

The ability to make mini-languages for specific domains, like fields
of math and science, is very useful, so the mathematicians and
scientists can denote things in a notation that is closer to the
notation that they actually work in.

Etc., etc., etc. The future is long, and our ability to peer into it
is blurry, and languages that can adapt to the unforeseen needs of that
blurry future are the ones that will survive.

For instance, I can state with almost 100% certainty that one hundred
years from now, some dialect of Lisp will still be around and in
common usage. I can't say the same thing about Python. I can't say
that about Python ten years from now with Ruby popularity now hot on
the heels of Python's.
>Take the issue up with Paul Graham. Since making a fortune developing
software in Lisp (making heavy use of macros), he now has much more
free time to write essays defending the truth than I do:
> http://www.paulgraham.com/avg.html
I think the #1 advantage to using Lisp in a commercial enterprise is
only indirectly related to the language. Lisp coders are a
self-selecting above-average bunch -- no VB drones or C code monkeys
need apply.
And it's self-selecting because the people don't want to live within
the limits of VB or C or perhaps even Python. Why should Python want
to alienate these uber-hackers rather than attract them?
Graham talks about 25% of the Viaweb code base being macros. Imagine how
productive his coders would have been if the language was not quite
so minimalistic, so that they could do what they wanted without the
_lack_ of syntax getting in the way.
You just prove Graham's point--that one is not qualified to judge the
features of a more powerful language without actually learning and
using the language--when you say things like this. Viaweb almost
certainly used Common Lisp, not Scheme, and Common Lisp is anything
but a minimalistic language. Python looks like a minimalistic
language compared to Common Lisp.

*Scheme* is the most well-known minimalistic Lisp, and was created, in
part, as a response to the the feature-creep of Common Lisp. (Or
actually to the immediate precursors of Common Lisp.) But few people
use Scheme for real work (as opposed to academic work). Common Lisp
is the production Lisp work horse.

(The reasons for Common Lisp being dominant for production are as
complex as the reasons that other languages win or lose in market
place, but they have something to do with there being very efficient
implementations of Common Lisp, people actually wanting all those
creeping features, and the Scheme standardizing committees operating
so slowly.)

|>oug
Jun 25 '07 #135
Steven D'Aprano wote:
But if you really want declarations, you can have them.
>import variables
variables.declare(x=1, y=2.5, z=[1, 2, 4])
variables.x = None
variables.w = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "variables.py", line 15, in __setattr__
raise self.DeclarationError("Variable '%s' not declared" % name)
variables.DeclarationError: Variable 'w' not declared
Another way is to decorate functions with their local variables:
>>from strict import my
@my("item")
.... def f(x=1, y=2.5, z=[1,2,4]):
.... x = float(x)
.... w = float(y)
.... return [item+x-y for item in z]
....
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "strict.py", line 11, in dec
raise DeclarationError("No slot for %s"%varname)
strict.DeclarationError: No slot for w

and the implementation

import re

class DeclarationError(TypeError): pass

def my(slots=""):
tokens = slots.split()
def dec(func):
code = func.func_code
for varname in code.co_varnames[code.co_argcount:]:
if re.match('\w+$', varname) and varname not in tokens:
raise DeclarationError("No slot for %s"%varname)
return func
return dec
The best way to catch false rebindings is to stick a comment with the
word "rebound" after every statement where you think you're rebinding
a variable. Then you can search your code for cases where there's a
"rebound" comment but no rebinding. Assuming you're the kind of
person who knows that false rebindings can lead to perplexing bugs,
but doesn't check apparent rebindings in a paranoid way every time a
perplexing bug comes up, anyway. (They aren't that common in modern
python code, after all.) And that you remembered to add the comments
(like you would have remembered the let and set). And you're also the
kind of person who's troubled by perplexing bugs but doesn't run a
fully fledged lint. Maybe that's the kind of person who wouldn't put
up with anything short of a macro as in the original proposal. All I
know is that it's the kind of person I don't want to second guess.
Graham

Jun 25 '07 #136
Graham Breed <x3*********@gmail.comwrites:
Another way is to decorate functions with their local variables:
>>>from strict import my
@my("item")
... def f(x=1, y=2.5, z=[1,2,4]):
... x = float(x)
... w = float(y)
... return [item+x-y for item in z]
Well, I suppose that's a bit better than the previous suggestion, but
(1) it breaks the style rule of not declaring variables until you need
them, and (2) it doesn't catch double initialization.
The best way to catch false rebindings is to stick a comment with
the word "rebound" after every statement where you think you're
rebinding a variable.
No, the best way to catch false rebindings is to have the computers
catch such errors for you. That's what you pay them for.
Then you can search your code for cases where there's a "rebound"
comment but no rebinding.
And how do I easily do that? And how do I know if I even need to in
the face of sometimes subtle bugs?
Assuming you're the kind of person who knows that false rebindings
can lead to perplexing bugs, but doesn't check apparent rebindings
in a paranoid way every time a perplexing bug comes up, anyway.
(They aren't that common in modern python code, after all.)
They're not that uncommon, either.

I've certainly had it happen to me on several occasions, and sometimes
they've been hard to find as I might not even see the mispeling even
if I read the code 20 times.

(Like the time I spent all day trying to figure out why my assembly
code wasn't working when I was a student and finally I decided to ask
the TA for help, and while talking him through my code so that he
could tell me what I was doing wrong, I finally noticed the "rO" where
there was supposed to be an "r0". It's amazing how useful a TA can
be, while doing nothing at all!)
And you're also the kind of person who's troubled by perplexing bugs
but doesn't run a fully fledged lint.
Maybe PyLint is better than Lint for C was (hated it!), but my idea of
RAD does not include wading through piles of useless warning messages
looking for the needle warning in the warning haystack. Or running
any other programs in the midst of my code, run, code, run, ..., loop.
Maybe that's the kind of person who wouldn't put up with anything
short of a macro as in the original proposal. All I know is that
it's the kind of person I don't want to second guess.
As it is, I code in Python the way that a normal Python programmer
would, and when I have a bug, I track it down through sometimes
painstaking debugging as a normal Python programmer would. Just as
any other normal Python programmer, I would not use the alternatives
suggested so far, as I'd find them cumbersome and inelegant. I'd
prefer not to have been bit by the bugs to begin with. Consequently,
I'd use let and set statements, if they were provided (or if I could
implement them), just as I have the equivalents to let and set in
every other programming language that I commonly program in other than
Python.

|>oug
Jun 25 '07 #137
On Jun 23, 6:39 pm, Douglas Alan <d...@alum.mit.eduwrote:
>
One of the things that annoys me when coding in Python (and this is a
flaw that even lowly Perl has a good solution for), is that if you do
something like

longVarableName = foo(longVariableName)

You end up with a bug that can be very hard to track down.
You should really be using pychecker (as well as Emacs autocompletion
feature ...):

~$ cat x.py
def foo(x): return x

longVariableName = 1
longVarableName = foo(longVariableName)

~$ pychecker -v x.py
Processing x...

Warnings...

x.py:4: Variable (longVarableName) not used

[I know you will not be satisfied with this, but pychecker is really
useful,
since it catches many other errors that no amount of macroprogramming
would
evere remove].

Michele Simionato

Jun 25 '07 #138
Michele Simionato <mi***************@gmail.comwrites:
You should really be using pychecker (as well as Emacs autocompletion
feature ...):
I *do* use Emacs's autocompletion, but sometimes these sorts of bugs
creep in anyway. (E.g., sometimes I autocomplete in the wrong variable!)
~$ pychecker -v x.py
Processing x...

Warnings...

x.py:4: Variable (longVarableName) not used

[I know you will not be satisfied with this, but pychecker is really
useful,
Okay, I'll check out PyChecker and PyLint, though I'm sure they will
annoy the hell out of me. They're probably less annoying than
spending all day tracking down some stupid bug.
since it catches many other errors that no amount of
macroprogramming would evere remove].
And likewise, good macro programming can solve some problems that no
amount of linting could ever solve.

|>oug
Jun 25 '07 #139
Douglas Alan <do**@alum.mit.eduwrites:
And likewise, good macro programming can solve some problems that no
amount of linting could ever solve.
I think Lisp is more needful of macros than other languages, because
its underlying primitives are too, well, primitive. You have to write
all the abstractions yourself. Python has built-in abstractions for a
few container types like lists and dicts, and now a new and more
general one (iterators), so it's the next level up. Haskell abstracts
the concept of containers to something called monads, so operations
like loops and list comprehensions fall out automatically (it took me
a while to realize that--Haskell listcomps weren't a bright new idea
someone thought of adding to an otherwise complete language: they were
already inherently present in the list monad operations and their
current syntax is just minor sugaring and is actually restricted on
purpose to make the error messages less confusing).

So, a bunch of stuff one needs macros to do conveniently in Lisp, can
be done with Python's built-in syntax. And a bunch of stuff that
Python could use macros for, are easily done in Haskell using delayed
evaluation and monads. And Haskell is starting to grow its own macro
system (templates) but that's probably a sign that an even higher
level language (maybe with dependent types or something) would make
the templates unnecessary.
Jun 25 '07 #140
Paul Rubin <http://ph****@NOSPAM.invalidwrites:
Douglas Alan <do**@alum.mit.eduwrites:
>And likewise, good macro programming can solve some problems that no
amount of linting could ever solve.
I think Lisp is more needful of macros than other languages, because
its underlying primitives are too, well, primitive. You have to write
all the abstractions yourself.
Well, not really beause you typically use Common Lisp with CLOS and a
class library. If you ask me, the more things that can (elegantly) be
moved out of the core language and into a standard library, the
better.
Python has built-in abstractions for a few container types like
lists and dicts, and now a new and more general one (iterators), so
it's the next level up.
Common Lisp has had all these things for ages.
And a bunch of stuff that Python could use macros for, are easily
done in Haskell using delayed evaluation and monads. And Haskell is
starting to grow its own macro system (templates) but that's
probably a sign that an even higher level language (maybe with
dependent types or something) would make the templates unnecessary.
Alas, I can't comment too much on Haskell, as, although I am familiar
with it to some extent, I am far from proficient in it. Don't worry
-- it's on my to-do list.

I think that first I'd like to take Gerry Sussman's new graduate
class, first, though, and I'll find out how it can all be done in
Scheme.

|>oug
Jun 25 '07 #141
Douglas Alan <do**@alum.mit.eduwrites:
>Python has built-in abstractions for a few container types like
lists and dicts, and now a new and more general one (iterators), so
it's the next level up.

Common Lisp has had all these things for ages.
Rubbish. Do you actually know any common lisp?

There is precisely no way to express

for x in xs:
blah(x)

or
x = xs[key]

in either scheme or CL, which is a major defect of both language (although
there has been a recent and limited proposal for sequence iteration by c.
rhodes which is implemented as an experimental extension in sbcl). This is
stuff even C++, which is about the lowest-level language anyone uses for
general purpose programming these days has been able to express for decades
(modulo foreach syntax).

In a decent scheme it's easy enough to define your own collection
class/iteration protocol, which does allow you to do something like the above,
but of course only for container abstractions that you have some control over
yourself. Even in this limited sense you can forget about doing this in CL in
a way that meshes nicely with the existing primitives (inter alia because of
spurious inconsistencies between e.g. sequence and hash-access and
under-specification of the exception hierachy) and anything as expressive as
generators/coroutines in CL with reasonable effort and performance which won't
even allow you to write LOOPs over custom container types (the nonstandard
ITERATE package has limited support for this).

'as
Jun 25 '07 #142
Alexander Schmolck <a.********@gmail.comwrites:
Douglas Alan <do**@alum.mit.eduwrites:
>>Python has built-in abstractions for a few container types like
lists and dicts, and now a new and more general one (iterators), so
it's the next level up.
>Common Lisp has had all these things for ages.
Rubbish. Do you actually know any common lisp?
Yes, though it's been quite a while, and it was mostly on Lisp
Machines, which, at the time, Common Lisp was still being
standardized, and so Lisp Machine "Chine Nual" Lisp wasn't quite
Common Lisp compliant at the time. Also, Lisp Machine Lisp had a lot
of features, such as stack groups, that weren't put into Common Lisp.
Also, my experience predates CLOS, as at the time Lisp Machines used
Flavors.

Most of my Lisp experience is actually in MacLisp (and Ulisp and
Proto, neither of which you've likely heard of). MacLisp was an
immediate precursor of Common Lisp, and didn't have a standard object
system at all (I rolled one myself for my applications), but it had
the Loop macro and if I recall correctly, the MacLisp Loop macro
(which was nearly identical to the Chine Nual Loop macro, which I
thought was ported rather unsullied for Common Lisp). In any case,
IIRC, there were hooks in the Loop macro for dealing with iterators
and I actually used this for providing an iterator-like interface to
generators (for Lisp Machines) that I coded up with macros and stack
groups.

It may be that these hooks didn't make it into the Common Lisp Loop
macro, or that my memory of what was provided by the macro is a little
off. What's not off, is that it was really easy to implement these
things, and it wasn't like I was some sort of Lisp guru -- I was just
an undergraduate student.

I will certainly admit that Lisp programmers at the time were (and
likely still are) much more enamored of mapping functions than of
iterators. Mapping functions certainly get the job done as elegantly
as iterators most of the time, although I would agree that they are
not quite so general. Of course, using generators, I was easily able
to make a converter that would take a mapping function and return a
corresponding iterator.

Scheme, on, the other hand, at least by idiom, has computation
"streams", and streams are equivalent to iterators.
There is precisely no way to express

for x in xs:
blah(x)
The canonical way to do this in Lisp would be something like:

(mapcar (lambda (x) (blah x))
xs)

Though there would (at least in MacLisp) be a differently named
mapping function for each sequence type, which makes things a bit less
convenient, as you have to know the name of the mapping function
for each type.
or
x = xs[key]
I'm not sure what you are asserting? That Common Lisp doesn't have
hash tables? That's certainly not the case. Or that it doesn't
provide standard generic functions for accessing them, so you can
provide your own dictionaries that are implemented differently and
then use exactly the same interface? The latter I would believe, as
that would be one of my criticisms of Lisp -- although it's pretty
cool that you can load whatever object system you would like (CLOS
being by far the most common), it also means that the core language
itself is a bit deficient in OO terms.

This problem would be significantly mitigated by defining new
standards for such things in terms of CLOS, but unfortunately
standards change unbearably slowly. There are certainly many
implementations of Lisp that solve these issues, but they have a hard
time achieving wide adoption. A language like Python, which is
defined by its implementation, rather than by a standard, can move
much more quickly. This debate though is really one more of
what is the best model for language definition, rather than one on
what the ideal language is like.

|>oug
Jun 25 '07 #143
On Jun 26, 8:49 am, Andy Freeman <ana...@earthlink.netwrote:
Map doesn't work on generators or iterators because they're not part
of the common lisp spec, but if someone implemented them as a library,
said library could easily include a map that handled them as well.
Note that this is is a consequence of something that Python does
better than lisp. Far more parts of python are defined in terms of
named operations which are data-type independent. As a result, they
work on things that the implementor (or spec) never considered.

That said, it's no big deal for a lisp program that needed an enhanced
map that also understands iterators and generators to use it.

Compare that with what a programmer using Python 2.4 has to do if
she'd like the functionality provided by 2.5's with statement. Yes,
with is "just syntax", but it's extremely useful syntax, syntax that
can be easily implemented with lisp-style macros.

Jun 26 '07 #144
Andy Freeman <an****@earthlink.netwrites:
Compare that with what a programmer using Python 2.4 has to do if
she'd like the functionality provided by 2.5's with statement. Yes,
with is "just syntax", but it's extremely useful syntax, syntax that
can be easily implemented with lisp-style macros.
Not really. The with statement's binding targets all have to support
the protocol, which means a lot of different libraries need redesign.
You can't do that with macros. Macros can handle some narrow special
cases such as file-like objects, handled in Python with
contextlib.closing.

That said, the with statement was missing from Python for much too
long, since users were happy to rely on reference counting.
Jun 26 '07 #145
On Jun 26, 10:10 am, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
Andy Freeman <ana...@earthlink.netwrites:
Compare that with what a programmer using Python 2.4 has to do if
she'd like the functionality provided by 2.5's with statement. Yes,
with is "just syntax", but it's extremely useful syntax, syntax that
can be easily implemented with lisp-style macros.

Not really.
Yes really, as the relevant PEP shows. The "it works like" pseudo-
code is very close to how it would be defined with lisp-style macros.
The with statement's binding targets all have to support
the protocol, which means a lot of different libraries need redesign.
That's a different problem, and it's reasonably solvable for anyone
who wants to use the roll-your-own with while writing an application
running under 2.4. (You just add the relevant methods to the
appropriate classes.)

The big obstacle is the syntax of the with-statement. There's no way
to define it in python with user-code.

Jun 26 '07 #146
Paul Rubin <http://ph****@NOSPAM.invalidwrites:
Andy Freeman <an****@earthlink.netwrites:
>Compare that with what a programmer using Python 2.4 has to do if
she'd like the functionality provided by 2.5's with statement. Yes,
with is "just syntax", but it's extremely useful syntax, syntax that
can be easily implemented with lisp-style macros.
Not really. The with statement's binding targets all have to support
the protocol, which means a lot of different libraries need redesign.
You can't do that with macros.
But that's a library issue, not a language issue. The technology
exists completely within Lisp to accomplish these things, and most
Lisp programmers even know how to do this, as application frameworks
in Lisp often do this kind. The problem is getting anything put into
the standard. Standardizing committees just suck.

I just saw a presentation today on the Boost library for C++. This
project started because the standard library for C++ is woefully
inadequate for today's programming needs, but any chance of getting
big additions into the standard library will take 5-10 years.
Apparently this is true for all computer language standards. And even
then, the new standard will be seriously lacking, because it is
usually based on armchair thinking rather than real-world usage.

So the Boost guys are making a defacto standard (or so they hope)
library for C++ that has more of the stuff you want, and then when the
standardizing committees get around to revising the actual standard,
the new standard will already be in wide use, meaning they just have
to sign off on it (and perhaps suggest a few tweaks).

Alas, the Lisp standards are stuck in this sort of morass, even while
many implementations do all the right things.

Python doesn't have this problem because it operates like Boost to
begin with, rather than having a zillion implementations tracking some
slow moving standard that then mandates things that might be nearly
impossible to implement, while leaving out much of what people need.

But then again, neither do many dialects of Lisp, which are developed
more or less like Python is. But then they aren't standards
compliant, and so they don't receive wide adoption.
Macros can handle some narrow special cases such as file-like
objects, handled in Python with contextlib.closing.
Macros handle the language part of things in Lisp perfectly well in
this regard. But you are right -- they certainly can't make
standardizing committees do the right thing.

|>oug
Jun 27 '07 #147
On Wed, 27 Jun 2007 01:45:44, Douglas Alan <do**@alum.mit.eduwrote
>A chaque son gout
I apologise for this irrelevant interruption to the conversation, but
this isn't the first time you've written that.

The word "chaque" is not a pronoun.

http://grammaire.reverso.net/index_a...s/Fiche220.htm
--
Doug Woodrow

Jun 27 '07 #148
Dennis Lee Bieber <wl*****@ix.netcom.comwrites:
What happens when two individuals release "libraries" using these
proposed macros -- and have implement conflicting macros using the same
identifiers -- and you try to use both libraries in one application?
Something like the current situation with Python web frameworks ;)
Jun 27 '07 #149
On Jun 27, 1:15 am, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
Dennis Lee Bieber <wlfr...@ix.netcom.comwrites:
What happens when two individuals release "libraries" using these
proposed macros -- and have implement conflicting macros using the same
identifiers -- and you try to use both libraries in one application?

Something like the current situation with Python web frameworks ;)
Actually, no. For python, the most reasonable macro scope would be
the file, so different files in the same application could easily use
conflicting macros without any problems.
Jun 27 '07 #150

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

226 posts views Thread by Stephen C. Waterbury | last post: by
22 posts views Thread by Tuang | last post: by
7 posts views Thread by Michele Simionato | last post: by
25 posts views Thread by John Morgan | last post: by
191 posts views Thread by Xah Lee | last post: by
22 posts views Thread by Xah Lee | last post: by
5 posts views Thread by Mathias Panzenboeck | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.