Re: Python Design Principles

2005-09-10 Thread Fredrik Lundh
"[EMAIL PROTECTED]" wrote:

> After all, the fact that Python is not strongly typed and is
> interpreted rather than compiled

if you think those are facts, you don't understand how Python
works.

(hint: Python's both strongly typed *and* compiled)

> sacrificing programmer producitivity

the ability to save a newline here and there doesn't affect the
programmer productivity in any way whatsoever.

 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python Design Principles

2005-09-09 Thread Neal Norwitz
[EMAIL PROTECTED] wrote:
>
> But I am still puzzled by the argument that has been given for why
> methods that operate on mutable types should return None, namely, that
> the designers of python didn't want the users to shoot themselves in
> the foot by thinking a method simply returned a result and left the
> data structure unchanged.

Let me try to answer your question with a question.  Given this code:

  >>> d = {}
  >>> e = d.update([(1, 2)])

If .update() returned a dictionary, does d == e?

I'm not sure what you would guess. I am pretty sure that everyone
wouldn't agree whether d should equal e or not.  If they are not equal,
that would mean a new copy would be made on each update which could be
incredibly expensive in speed and memory.  It is also different from
how Python works today, since the update() method mutates the
dictionary.

> In the context of fundamental design principles, if you asked a random
> sample of Python gurus what is more Pythonesque: preventing users from
> shooting themselves in the foot or making things easier to accomplish,
> my impression is that people would overwhelmingly choose the latter.

Probably true, but ...

> After all, the fact that Python is not strongly typed and is
> interpreted rather than compiled gives plenty of ways for people to
> shoot themselves in the foot but what is gained is the abilitity to do
> more with less code.

I think most people programming Python are pretty pragmatic.  There is
no single language that is ideal in all circumstances.  There are
necessarily some trade-offs.  Many believe that tools can help bridge
this gap.  There are at least 2 tools for finding bugs (or gotchas) of
this sort:  pychecker and pylint.

> But in this instance, by not allowing operations on mutable types to
> return the mutated objects, it seems that the other side is being
> taken, sacrificing programmer producitivity for concerns about
> producing possible side effects. It is somewhat ironic, I think, that
> Java, a language whose design principles clearly side on preventing
> users from shooting themselves in the foot, much more so thatn Python,
> generally allows you to get back the mutated object.

I think Python has attempted to create an internal consistency.  I
believe Java has tried to do the same.  However, these aren't the same
sets of consistency.  People are always going to have assumptions.
Python strives to be as intuitive as possible.  However, it can't be
right 100% of the time for all people.

HTH,
n

-- 
http://mail.python.org/mailman/listinfo/python-list


Python Design Principles

2005-09-09 Thread lechequier
In a previous post, I asked about the inconsistency in usage patterns
in operating on mutable and immutable types. Thanks Dave and everyone
else for answering my question so thoughtfully and helping me to
understand the reasoning about why the different usage patterns are not
deemed to be inconsistent.

But I am still puzzled by the argument that has been given for why
methods that operate on mutable types should return None, namely, that
the designers of python didn't want the users to shoot themselves in
the foot by thinking a method simply returned a result and left the
data structure unchanged.

In the context of fundamental design principles, if you asked a random
sample of Python gurus what is more Pythonesque: preventing users from
shooting themselves in the foot or making things easier to accomplish,
my impression is that people would overwhelmingly choose the latter.
After all, the fact that Python is not strongly typed and is
interpreted rather than compiled gives plenty of ways for people to
shoot themselves in the foot but what is gained is the abilitity to do
more with less code.

But in this instance, by not allowing operations on mutable types to
return the mutated objects, it seems that the other side is being
taken, sacrificing programmer producitivity for concerns about
producing possible side effects. It is somewhat ironic, I think, that
Java, a language whose design principles clearly side on preventing
users from shooting themselves in the foot, much more so thatn Python,
generally allows you to get back the mutated object.

I'm not trying to change minds here but just to understand better how
this particular design decision fits into Python's overall design
principles.

thanks,
Scott

Dave Benjamin wrote:
> [EMAIL PROTECTED] wrote:
> > Let's say I define a list of pairs as follows:
> >
> >>>l = [('d', 3), ('a', 2), ('b', 1)]
> >
> >
> > Can anyone explain why this does not work?
> >
> >>>h = {}.update(l)
> >
> >
> > and instead I have to go:
> >
> >>>h = {}
> >>>h.update(l)
> >
> > to initialize a dictionary with the given list of pairs?
> >
> > when an analagous operation on strings works fine:
> >
> >>>s = "".join(["d","o","g"])
> >
> >
> > Seems inconsistent.
>
> Python is actually quite consistent in this regard: methods that modify
> an object in-place return None; methods that do not modify an object
> in-place return a new object instead. Since strings are immutable, they
> cannot be modified in-place, so it makes sense for the "join" method to
> return a new string. On the other hand, Python's dictionaries are
> imperative-style and so most operations on a dictionary modify an
> existing dictionary.
>
> I was initially bothered by the phenomenon of so many methods returning
> None because they could not be chained. But I have come to deeply
> appreciate this style for a couple of reasons. First, it makes it clear
> which methods are side-effecting (like "update") and which are not (like
> "sort").
>
> Second, it is not always clear what a good return value is for a
> mutator. Perhaps {}.update() should return the dictionary, making
> chaining convenient. Perhaps it should return the total number of items
> after updating. Or maybe it should return the number of new keys that
> were added, or a list of those keys. All of these are plausible
> behaviors; the problem is that "update" is not a function. Its job is to
> change something, not return something. Any possible return value would
> be a convenience for certain tasks and useless for other tasks.
>
> It's also hard to remember, in my opinion. For example, JavaScript has a
> "push" method on the Array object which behaves like Python's "append"
> method on lists:
>
> js> var a = [];
> js> a.push(5);
> 1
> js> a.push(6);
> 2
>
> I bet you that almost nobody knows that "push" returns the new length of
> the Array. It could just as easily have returned "a" here. I could
> always write "a.length", if I really needed to know the new length. This
> sort of thing becomes language trivia, and when I write in JavaScript I
> always ignore the result of "push" because, even if *I* know what it
> returns, chances are that my readers don't.
>
> Another reason that Python adopts the convention of returning None for
> mutators is that it discourages the use of side-effecting code in
> expressions. Mixing side-effects with expressions can lead to code that
> is hard to read and understand. This is often debated by those who know
> better and wish to write things like "h.update(a).update(b)" (method
> chaining) or "while (line = file.readline()): ...". Python's decision is
> pretty clear, and it's also evident in the division between statements
> and expressions.
>
> Regardless of whether you like Python's style decision or not, if you
> dig deeper I think you will find that it is pretty consistent, and that
> there are useful benefits to Python's way of handling side effects.
>
> Dave
>
> PS. If mutators had to return a value, I'd have the