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

S

Steven D'Aprano

No one ever gave that justification. The justification is that they are
*good*.

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?

One criticism of operator overloading is that when you see X + Y you have
no real idea of whether it is adding X and Y together, or doing something
bizarre.

Now allow syntax to be over-ridden as well, and not only can't you tell
what X + Y does, but you can't even tell what it *means*. Maybe its a for-
loop, calling the function Y X times.

The usual response is "That's insane, no sane programmer would do that!",
and that's true as far as it goes (except for the programmers who are
just too clever for their own good). Nevertheless there is a real issue
there. When I program in Python, I always know what the syntax means,
because there is no possible way it can be changed. That's one less thing
I have to keep in my head, one less thing to worry about.

Sometimes, more freedom is not better. If you had a language that let you
redefine the literal 1 to mean the integer zero, wouldn't that make it
much harder to understand what even basic arithmetic meant?

If I wanted a bondage-and-discipline language, I'd use something with
static typing and declared variables and a compiler that made sure my
shoelaces were tied correctly before I did anything. But I don't, I use
Python, and I appreciate the dynamic typing and runtime errors and the
relatively few compiler checks.

But that doesn't mean I want a language where anything goes -- there's a
balance between too little freedom and too much. If Python became the
sort of language where I had to think about every module imported, every
function called, just to be sure that 1+1 would equal 2, I'd have to
reconsider whether Python was the language for me. There would have to be
some serious advantages before I'd be comfortable.
 
D

Douglas Alan

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. 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.

The fact that CLOS could be developed in a modular way allowed for a
number of different groups to work on competing object systems. After
some experience with the pros and cons of the various object systems,
the developers of CLOS were able to incorporate most of the best ideas
from the entire field and then get it adopted as a defacto standard.

This allowed, for instance, the inclusion of multimethods, which are
an extremely nice feature for modular code development. In prior Lisp
dialects I had used, the object systems were more like the
single-object dispatching OO system in Python, which is substantially
inferior. The fact that the entire OO system in Common Lisp could be
loaded as a module that is coded entirely within Common Lisp allowed
for a large jump in the quality of its OO subsystem.
One criticism of operator overloading is that when you see X + Y you
have no real idea of whether it is adding X and Y together, or doing
something bizarre.

Yes, and despite this, operator overloading is an essential feature
for a modern language. (Java's lack of it notwithstanding.)
Now allow syntax to be over-ridden as well, and not only can't you tell
what X + Y does, but you can't even tell what it *means*. Maybe its a for-
loop, calling the function Y X times.

(1) With operator overloading you have no idea what X + Y *means*. It
could be feeding the cat, for all you know. If that turns out to
be the case, you fire the programmer in question. Just because a
language feature *can* be abused is no reason to leave it out of a
language. Power always comes with responsibility, but we still
need powerful programming languages.

(2) In Lisp, you cannot redefine existing syntax (without modifying
the standard library, which would be considered very rude), so the
problem that you are talking about is moot. You can only add
*new* syntactic constructs. I would suggest that any proposed
syntax extension mechanisms for other languages behave like Lisp
in this regard.
Sometimes, more freedom is not better. If you had a language that
let you redefine the literal 1 to mean the integer zero, wouldn't
that make it much harder to understand what even basic arithmetic
meant?

But we're not talking about anything like this. E.g., in some
dialects of Lisp it used to be possible to set the variable that
contained the value for *true* to the value for *false*. If you
actually did this, however, just imagine the havoc that it would
wreak. So ultimately, this capability was removed.

Alas, in Python, you can still do such a crazy thing!
But that doesn't mean I want a language where anything goes

You are imagining something very different from what is proposed.
Lisp-like macros don't allow "anything goes".

|>oug
 
N

Neil Cerutti

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.
 
D

Douglas Alan

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.
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
 
T

Terry Reedy

|
| > 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
 
T

Terry Reedy

| 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
 
T

Terry Reedy

| > 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
 
R

Robert Brown

Neil Cerutti said:
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/Publications/urls/LapalmeLispComp.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-tools/screamer-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/
 
D

Douglas Alan

Terry Reedy said:
| 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
 
S

Steven D'Aprano

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.)
 
N

Neil Cerutti

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. ;)
 
D

Douglas Alan

Neil Cerutti said:
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
 
N

Neil Cerutti

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/default.asp?ttype=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.
 
D

Douglas Alan

Terry Reedy said:
"Douglas Alan" <[email protected]> wrote 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
 
D

Douglas Alan

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
 
D

Douglas Alan

Terry Reedy said:
| 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
 
T

Terry Reedy

| > 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.
 
D

Douglas Alan

Terry Reedy said:
"Douglas Alan" <[email protected]> wrote in message
| "Terry Reedy" <[email protected]> writes:
| > 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
 
P

Paul Rubin

Douglas Alan said:
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.
 
S

Steven D'Aprano

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.)
 

Members online

No members online now.

Forum statistics

Threads
473,801
Messages
2,569,658
Members
45,421
Latest member
DoreenCorn

Latest Threads

Top