473,575 Members | 3,448 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 8237
Steven D'Aprano <st***@REMOVE.T HIS.cybersource .com.auwrites:
On Mon, 11 Jun 2007 01:28:09 +0100, Alexander Schmolck wrote:
>Steven D'Aprano <st***@REMOVE.T HIS.cybersource .com.auwrites:
>>On Sat, 09 Jun 2007 22:42:17 +0100, Alexander Schmolck wrote:

As for why tail calls are not optimized out, it was decided that being able
to have the stack traces (with variable information, etc.) was more useful
than offering tail call optimization

I don't buy this.

Do you mean you don't believe the decision was made, or you don't agree
with the decision?

Neither. I don't believe the rationale stated in this thread to be the true
reason.


Don't keep us in suspense. What do you believe is the true reason?
It's easier to spot that some rationalization is bogus than to unconver the
true underlying causes; I'm pretty sure it's more a Gestalt thing than a
compelling technical reason (I guess Guido's distaste for scheme also plays a
role). Not that I discount that out of hand -- maybe all that's great about
python is due to Guido being exceptionally good at making such judgements.
>>Are you volunteering? If you are, I'm sure your suggestion will be welcomed
gratefully.

I rather doubt it. Guido has stated quite clearly that his not
interested in incorporating this feature.

He's not the only one who gets to make these decisions.
This is news to me. Who else does?
But even if he uses his veto to prevent tail-recursion optimization from
being put into the main branch, there are other options.
That don't involve abducting his kids?
>>>>(do what I say).

Where did you say run out of memory and fail? More importantly how do
you say "don't run out of memory and fail"?

If we can live with a certain amount of "arbitrary failures" in simple
arithmetic,

I prefer not too, and thus when possible avoid to use languages where
``a + b`` is liable to fail arbitrarily (such as C, where the behavior
will often be undefined).

That's not the sort of arbitrary failure I was discussing, but for that
matter Python is one of those languages.
Apart from floating point arithmetic, simple arithmetic doesn't tend to fail
arbitrarily in python, as far as I'm aware. You can of course create your very
own classes specifically to get broken arithmetic but that doesn't strike me
as "simple" arithmetic anymore.
Perhaps Python is not the language for you?
Do you also happen to know what would be?
Correct me if I'm wrong, but surely it is C++ that can have arbitrary
behaviour for "a + b", not C?
``INT_MAX + 1`` can do precisely anything in C.
>>You can always hand-optimize it yourself.

Not tail calls, in general, no.

Sorry, how does that work? You're suggesting that there is an algorithm
which the compiler could follow to optimize away tail-recursion, but human
beings can't follow the same algorithm? Now I'm confused.
Does it also confuse you that if I give you a 500x500 matrix A you won't be
able to figure out a single element in A^-1 by doing mental arithmetic (or
using pen and paper), although my computer manages just fine and I'm happy to
give you the algorithm it uses?

'as
Jun 13 '07 #41
"Anders J. Munch" <20**@jmunch.dk writes:
Like Steven said, tail-call optimisation is not necessary as you can always
hand-optimise it yourself.
Care to demonstrate on some code written in CPS (a compiler or parser, say)?

'as
Jun 13 '07 #42
Alexander Schmolck wrote:
Steven D'Aprano <st***@REMOVE.T HIS.cybersource .com.auwrites:
>>On Mon, 11 Jun 2007 01:28:09 +0100, Alexander Schmolck wrote:
>>>Steven D'Aprano <st***@REMOVE.T HIS.cybersource .com.auwrites:
>>Don't keep us in suspense. What do you believe is the true reason?


It's easier to spot that some rationalization is bogus than to unconver the
true underlying causes; I'm pretty sure it's more a Gestalt thing than a
compelling technical reason.
There's a real reason. Remember, functions are dynamically
replaceable. The compiler would have to detect that the function
doesn't modify or replace itself while recursing for this optimization
to be valid. Worst case, another thread could replace the function
while it was recursing, invalidating the tail recursion optimization.

John Nagle
Jun 13 '07 #43
On 2007-06-12, Anders J. Munch <20**@jmunch.dk wrote:
Paul Rubin wrote:
>Steven D'Aprano <st***@REMOVE.T HIS.cybersource .com.auwrites:
>>>Not tail calls, in general, no.
Sorry, how does that work? You're suggesting that there is an
algorithm which the compiler could follow to optimize away
tail-recursion, but human beings can't follow the same
algorithm?

Now I'm confused.

The usual compiler method is to translate the code into
continuation-passing style and thereby gain tail-recursion
optimization automagically.

There's no need to go into CPS just to optimise tail-recursion.
After all, compilers were optimising tail-calls decades before
Appel's work on SML/NJ.

Converting tail-recursion to iteration is trivial, and
perfectly reasonable for a human to do by hand.
For simple recursive tail calls, yeah, it can be. Translating a
tail-recursive Factorial function into a while loop is easy. But
tail-call optimization technically works for any tail-call,
including mutual recursion, and non-recursive tail-calls. You
can't reasonably hand-optimize away the stack frame for all
tail-calls.

def foo(x)
bar(x)

The only way to hand-optimize the call to bar is to inline it
yourself.

--
Neil Cerutti
Will the highways on the Internet become more few? --George W. Bush
Jun 13 '07 #44
On 2007-06-13, Steve Howell <sh*******@yaho o.comwrote:
You would just change the language definition to say that once
you enter f(), any call to f() from within f() behaves as if
the recursively called f() still points to the originally bound
version of f. To want any other behavior would be absurd,
anyhow.
There's a reason it's generally refered to as "tail-call"
optimization and not "tail-recursive" optimization. The former is
more general, and, I believe, easier to implement than the
latter.

--
Neil Cerutti
The peace-making meeting scheduled for today has been cancelled due to a
conflict. --Church Bulletin Blooper
Jun 13 '07 #45
Neil Cerutti wrote:
On 2007-06-12, Anders J. Munch <20**@jmunch.dk wrote:
>Converting tail-recursion to iteration is trivial, and
perfectly reasonable for a human to do by hand.

For simple recursive tail calls, yeah, it can be. Translating a
tail-recursive Factorial function into a while loop is easy. But
tail-call optimization technically works for any tail-call,
including mutual recursion, and non-recursive tail-calls. You
can't reasonably hand-optimize away the stack frame for all
tail-calls.
I may have misunderstood, I thought we were talking about tail recursion only.
The general tail-call optimisation, where all leaf calls become jumps and the
called function usurps the current stack frame, is a different ballgame
entirely. There's no pure-Python transformation for that, but that still
doesn't mean you need CPS.

General tail-call optimisation is of course completely out-of-bounds for Python,
because it ruins tracebacks. Unlike tail recursion, which could use recursion
counters.

- Anders

Jun 13 '07 #46
Alexander Schmolck wrote:
"Anders J. Munch" <20**@jmunch.dk writes:
>Like Steven said, tail-call optimisation is not necessary as you can always
hand-optimise it yourself.

Care to demonstrate on some code written in CPS (a compiler or parser, say)?
I meant tail recursion, not tail-call, sorry, that was just my fingers trying to
save typing.

- Anders
Jun 13 '07 #47
On 2007-06-13, Anders J. Munch <20**@jmunch.dk wrote:
General tail-call optimisation is of course completely
out-of-bounds for Python, because it ruins tracebacks. Unlike
tail recursion, which could use recursion counters.
Is it really ruined? To use a similar example:

def foo(x):
bar(x+1)

def bar(x):
if x 10:
raise ValueError
else:
foo(x+2)

Today, when I call foo(4), I get something like:

C:\WINNT\system 32\cmd.exe /c python temp.py
Traceback (most recent call last):
File "temp.py", line 529, in <module>
foo(4)
File "temp.py", line 521, in foo
bar(x+1)
File "temp.py", line 527, in bar
foo(x+2)
File "temp.py", line 521, in foo
bar(x+1)
File "temp.py", line 527, in bar
foo(x+2)
File "temp.py", line 521, in foo
bar(x+1)
File "temp.py", line 525, in bar
raise ValueError
ValueError
shell returned 1

With tail-call optimization you'd get something like:

C:\WINNT\system 32\cmd.exe /c python temp.py
Traceback (most recent call last):
File "temp.py", line 529, in <module>
foo(4)
File "temp.py", line 525, in bar
raise ValueError
ValueError
shell returned 1

What makes the latter harder to work with?

--
Neil Cerutti
Jun 13 '07 #48
On Wed, 2007-06-13 at 18:22 +0000, Neil Cerutti wrote:
On 2007-06-13, Anders J. Munch <20**@jmunch.dk wrote:
General tail-call optimisation is of course completely
out-of-bounds for Python, because it ruins tracebacks. Unlike
tail recursion, which could use recursion counters.

Is it really ruined? To use a similar example:

def foo(x):
bar(x+1)

def bar(x):
if x 10:
raise ValueError
else:
foo(x+2)

Today, when I call foo(4), I get something like:

C:\WINNT\system 32\cmd.exe /c python temp.py
Traceback (most recent call last):
File "temp.py", line 529, in <module>
foo(4)
File "temp.py", line 521, in foo
bar(x+1)
File "temp.py", line 527, in bar
foo(x+2)
File "temp.py", line 521, in foo
bar(x+1)
File "temp.py", line 527, in bar
foo(x+2)
File "temp.py", line 521, in foo
bar(x+1)
File "temp.py", line 525, in bar
raise ValueError
ValueError
shell returned 1

With tail-call optimization you'd get something like:

C:\WINNT\system 32\cmd.exe /c python temp.py
Traceback (most recent call last):
File "temp.py", line 529, in <module>
foo(4)
File "temp.py", line 525, in bar
raise ValueError
ValueError
shell returned 1

What makes the latter harder to work with?
The fact that you don't see how many call levels down your algorithm got
before throwing an exception. This may be an important clue in debugging
a recursive algorithm.

--
Carsten Haese
http://informixdb.sourceforge.net
Jun 13 '07 #49
On 2007-06-13, Neil Cerutti <ho*****@yahoo. comwrote:
On 2007-06-13, Anders J. Munch <20**@jmunch.dk wrote:
>General tail-call optimisation is of course completely
out-of-bounds for Python, because it ruins tracebacks. Unlike
tail recursion, which could use recursion counters.

Is it really ruined? To use a similar example:
I found some interesting notes by Alex Martelli pertaining to
tail-call optimisation, and my assumption that tail-call
optimization is easier to implement than tail-recursive
optimization may have been naive. ;)

http://groups.google.com/group/comp....3c1bd70?hl=en&

Moreover, there are (or were) technical reasons that you can't do
tail-call optimization in Python, which can't even recognize
tail-calls at compile time. According to Tim Peters:

http://groups.google.com/group/comp....aefb828?hl=en&

--
Neil Cerutti
Jun 13 '07 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

226
12411
by: Stephen C. Waterbury | last post by:
This seems like it ought to work, according to the description of reduce(), but it doesn't. Is this a bug, or am I missing something? Python 2.3.2 (#1, Oct 20 2003, 01:04:35) on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> d1 = {'a':1} >>> d2 = {'b':2} >>> d3 = {'c':3}
22
3408
by: Tuang | last post by:
I'm checking out Python as a candidate for replacing Perl as my "Swiss Army knife" tool. The longer I can remember the syntax for performing a task, the more likely I am to use it on the spot if the need arises. If I have to go off and look it up, as I increasingly have to do with Perl's ever hairier syntax, I'm more likely to just skip it,...
7
3551
by: Michele Simionato | last post by:
So far, I have not installed Prothon, nor I have experience with Io, Self or other prototype-based languages. Still, from the discussion on the mailing list, I have got the strong impression that you do not actually need to fork Python in order to implement prototypes. It seems to me that Python metaclasses + descriptors are more than powerful...
25
2801
by: John Morgan | last post by:
Though I have designed and implemented a number of large reasonably well received web sites I do not consider myself a graphics designer I am now for the first time going to work with a graphics designer. I notice that in the draft design the idea will be that many 'pages' will in fact be pdf files. I suppose I exaggerate slightly but the...
7
10596
by: Russell Mangel | last post by:
I have been doing some C++ Interop using the new VS2005 (June Beta). I am exposing these methods to .NET clients. I ran into some WinAPI methods which use LPVOID types, and I don't understand the philosophy behind this type. What I don't get is why doesn't a person pass in a pointer to the datatype they need, instead of LPVOID. Can you...
150
6480
by: tony | last post by:
If you have any PHP scripts which will not work in the current releases due to breaks in backwards compatibility then take a look at http://www.tonymarston.net/php-mysql/bc-is-everything.html and see if you agree with my opinion or not. Tony Marston http://www.tonymarston.net
191
7803
by: Xah Lee | last post by:
Software Needs Philosophers by Steve Yegge, 2006-04-15. Software needs philosophers. This thought has been nagging at me for a year now, and recently it's been growing like a tumor. One that plenty of folks on the 'net would love to see kill me.
22
3646
by: Xah Lee | last post by:
The Nature of the “Unix Philosophy” Xah Lee, 2006-05 In the computing industry, especially among unix community, we often hear that there's a “Unix Philosophy”. In this essay, i dissect the nature and characterization of such “unix philosophy”, as have been described by Brian Kernighan, Rob Pike, Dennis Ritchie, Ken Thompson,...
5
2170
by: Mathias Panzenboeck | last post by:
Hi. I wrote a small hashlib for C. Because I'm new to hashes I looked at pythons implementation and reused *some* of the code... or more the mathematical "hash-function", not really the code. In particular I looked at pythons hash and lookup functions, so I came up with this (see the code underneath). So, can this code be considered as...
0
7845
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main...
0
8143
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6515
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5664
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5338
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3778
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3797
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1382
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1107
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.