By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,610 Members | 2,155 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,610 IT Pros & Developers. It's quick & easy.

Thoughts about Python

P: n/a
Hi

I don't have to talk about the beauty of Python and its clear and
readable syntax... but there are a few things that striked me while
learning Python.

I have collected those thoughts. I am sure there are many discussions
on the "problems" mentioned here. But I had this thoughts without
looking into any forums or anything... it is kind of feedback.

Thanks for this marvellous language,
Marco

*** Problem: clumsy static class methods

In order to create a static method we have to use a the builtin
staticmethod(function):

class C (object):
def f(arg1, arg2, ...): ...
f = staticmethod(f)

Why? The speciality of a "static" method is: It has no access to any
instance vars. The following class is easier to read and understand
what a static method is about... as a positive side-effect: self is
not available and it can't be used!

class c (object):
def staticMethod(arg1, arg2, ...):
# self is not handed in... hence I can't use the instance vars
pass
def normalMethod(self, arg1, arg2, ...):
pass

There is no need for the builtin... as I understand it: the builtin is
a workaround...

*** Problem: clumsy properties for classes

property( [fget[, fset[, fdel[, doc]]]])

class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")
I don't like this one either. It is not necessary because it describes
something that should be clear by looking at the class/code. A
convention would make the syntax clearer and more intuitive and by
looking at the definition of a method you would know: This is a
getter, setter or deleter. My proposal:

all getters start with __get__
all setters start with __set__
all deleters start with __del__

If someone uses:

prop.x = 5

Python checks whether the var 'x' exists on prop. If it does - it is
set. If it doesn't exist Python checks for '__set__x' if it doesn't
exist either... a AttributeError is raised:
class PropertyExample(object):
"""A demonstration class for the property idea.

This class is used afterwards as follows:
prop = PropertyExample()
prop.x = 5 # __set__x(self, 5) is called behind the scenes
print prop.x # __get__x(self) is called behind the scenes
del prop.x # __del__x(self) is called behind the scenes"""

def __init__(self):
self.__x = None

def __del__x(self):
del self.__x
def __get__x(self):
return self.__x
def __set__x(self, value):
self.__x = value

*** Problem: Many builtins are not necessary

Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:

["I", "like", "Python"].len()
"I".len()
{1:"I", "2":"like", 3:"Python"}.len()
(1,2,3,4).len()

"Throwing away" this builtins would flatten the alreay flat learning
curve once more (you don't have to learn that many builtins) ... these
functions belong to the class and they are naturally expected there.
One weakness of a language as (Visual)Basic, PHP, ... is its payload
of available functions... Python's OO helps here to diminish the need
for lots of functions.
*** Problem: tuples are not necessary

Throw them away in the long run - for now make them depracted. It is
hard to argue in favour of tuples. There might to 2 reason:

1. It is MUCH faster than a list
2. We can't live without an immutable list

Cons:

1. I don't think that tuples deliver a big performance gain.
2. Python makes so many "soft" conventions (eg.: don't use
vars/methods with 2 leading underscores) but when it comes to tuples
the immutable issue is very important... why? I hope the tuples will
disappear in P3K.
*** Problem: builtins list() dict() ...

A list, a dictionary, a str, an int, a float are builtin functions...

myList = list()
myDict = dict()
myString = str(45)

The list-function instantiates a new list... it is actually nothing
but an overloaded List class. Why are the handed in as functions? In a
OO environment it should be more the instatiation of a class rather
than a function and classes start with an uppercase letter:

myList = List()
myDict = Dict()
myString = String(45)
Jul 18 '05 #1
Share this Question
Share on Google+
39 Replies


P: n/a
PP**********@spammotel.com (Marco Aschwanden) writes:
Hi

I don't have to talk about the beauty of Python and its clear and
readable syntax... but there are a few things that striked me while
learning Python.

I have collected those thoughts. I am sure there are many discussions
on the "problems" mentioned here. But I had this thoughts without
looking into any forums or anything... it is kind of feedback.

Thanks for this marvellous language,
Marco

*** Problem: clumsy static class methods

In order to create a static method we have to use a the builtin
staticmethod(function):

class C (object):
def f(arg1, arg2, ...): ...
f = staticmethod(f)
See PEP 318 (and current discussion on python-dev).
Why? The speciality of a "static" method is: It has no access to any
instance vars. The following class is easier to read and understand
what a static method is about... as a positive side-effect: self is
not available and it can't be used!

class c (object):
def staticMethod(arg1, arg2, ...):
# self is not handed in... hence I can't use the instance vars
pass
def normalMethod(self, arg1, arg2, ...):
pass

There is no need for the builtin... as I understand it: the builtin is
a workaround...
What's so special about self? I really don't like the idea of
argument names keying this kind of change in behaviour.
*** Problem: clumsy properties for classes

property( [fget[, fset[, fdel[, doc]]]])

class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")
I don't like this one either. It is not necessary because it describes
something that should be clear by looking at the class/code. A
convention would make the syntax clearer and more intuitive and by
looking at the definition of a method you would know: This is a
getter, setter or deleter. My proposal:

all getters start with __get__
all setters start with __set__
all deleters start with __del__

If someone uses:

prop.x = 5

Python checks whether the var 'x' exists on prop. If it does - it is
set. If it doesn't exist Python checks for '__set__x' if it doesn't
exist either... a AttributeError is raised:
class PropertyExample(object):
"""A demonstration class for the property idea.

This class is used afterwards as follows:
prop = PropertyExample()
prop.x = 5 # __set__x(self, 5) is called behind the scenes
print prop.x # __get__x(self) is called behind the scenes
del prop.x # __del__x(self) is called behind the scenes"""

def __init__(self):
self.__x = None

def __del__x(self):
del self.__x
def __get__x(self):
return self.__x
def __set__x(self, value):
self.__x = value
You seem really fond of magic names...

By the way, Python 2.2 introduced the capacity for staticmethods and
properties and consciously decided not to add syntax for the same
until there was some experience in using these things. So it's known
that there is some discomfort here, but it's not yet clear (to me, at
least) what a good syntax *is*. I hope you're not too offended if I
say that your suggestion doesn't seem instantly wonderful.
*** Problem: Many builtins are not necessary
Pah. So what? If you want minimailty scheme is over there ====>
Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:
Says you!

[...]
*** Problem: tuples are not necessary
Says you! Here's a hint: hash([]).

[...] *** Problem: builtins list() dict() ...

A list, a dictionary, a str, an int, a float are builtin functions...

myList = list()
myDict = dict()
myString = str(45)


Pedantry: no they're not, they're builtin types.

I think you might be expecting something other of Python than what it
is. Nothing you suggest is completely ridiculous, just, well,
slightly un-Pythonic. I suggest you continue using Python for a few
more weeks and read your list again.

Cheers,
mwh

--
MARVIN: Oh dear, I think you'll find reality's on the blink again.
-- The Hitch-Hikers Guide to the Galaxy, Episode 12
Jul 18 '05 #2

P: n/a
PP**********@spammotel.com (Marco Aschwanden) wrote in
news:15**************************@posting.google.c om:
I have collected those thoughts. I am sure there are many discussions
on the "problems" mentioned here. But I had this thoughts without
looking into any forums or anything... it is kind of feedback.
I think you should spend a bit of time reading the PEPs and the python-dev
mailing list archives. A lot of what you say has been discussed previously,
and it would be good if you could take the earlier discussion on board and
then see where your thoughts lead you.

*** Problem: clumsy static class methods
This has been widely discussed elsewhere and various solutions have been
proposed.

*** Problem: clumsy properties for classes
As for static methods various ways to improve this have been suggested. You
should read the discussions on python-dev to see the various viewpoints.

*** Problem: Many builtins are not necessary

Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:

["I", "like", "Python"].len()
"I".len()
{1:"I", "2":"like", 3:"Python"}.len()
(1,2,3,4).len()
The advantage of min and max as builtins are that they work on any
sequence. In particular they work on iterators. Having functions that apply
to an arbitrary sequence avoids a lot of potential code duplication.
"Throwing away" this builtins would flatten the alreay flat learning
curve once more (you don't have to learn that many builtins) ... these
functions belong to the class and they are naturally expected there.
One weakness of a language as (Visual)Basic, PHP, ... is its payload
of available functions... Python's OO helps here to diminish the need
for lots of functions.
There are other builtins I would throw away first. Note that you can't
actually throw any of these builtins away: one of Pythons great strengths
are the lengths it goes to to maintain backward compatibility. Some of the
less useful builtins are being relegated to backwaters of the
documentation, but they will remain as builtins for the foreseeable future.


*** Problem: tuples are not necessary

Throw them away in the long run - for now make them depracted. It is
hard to argue in favour of tuples. There might to 2 reason:

1. It is MUCH faster than a list
2. We can't live without an immutable list
Forget the speed and memory difference. The main argument for tuples as a
separate type are to use as dictionary keys. How do you propose to handle
dictionary keys without tuples?

*** Problem: builtins list() dict() ...

A list, a dictionary, a str, an int, a float are builtin functions...
No they aren't. They are types, not functions.

myList = list()
myDict = dict()
myString = str(45)

The list-function instantiates a new list... it is actually nothing
but an overloaded List class. Why are the handed in as functions? In a
OO environment it should be more the instatiation of a class rather
than a function and classes start with an uppercase letter:

myList = List()
myDict = Dict()
myString = String(45)


So they don't follow your naming convention. If this is a big problem for
you, then add some new globals in your own programs. The type 'file' is
already aliased as 'open'. You can't remove the existing builtins (since
that would break the library), but there is nothing to stop you adding your
own either in the __builtin__ module, or as a separate module containing
your aliases.

FWIW, I agree that the builtins that exist aren't the best choice for type
names --- too often they collide with the 'obvious' variable names that
python newcomers choose and then they wonder why their call to 'str' blow
up when they used a variable 'str' a few lines earlier.
Jul 18 '05 #3

P: n/a
Duncan Booth <me@privacy.net> writes:
PP**********@spammotel.com (Marco Aschwanden) wrote in
news:15**************************@posting.google.c om:
*** Problem: Many builtins are not necessary

Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:

["I", "like", "Python"].len()
"I".len()
{1:"I", "2":"like", 3:"Python"}.len()
(1,2,3,4).len()


The advantage of min and max as builtins are that they work on any
sequence. In particular they work on iterators. Having functions that apply
to an arbitrary sequence avoids a lot of potential code duplication.


Do you mean code duplication on the user side? Or code duplication in
Python's implementations? In the latter case, it seems strange to
force inconsistent method/function usage on thousands of developers
just in order to save a couple of lines in Python's source code.

To me, Python's builtins are by far not a "problem", but I admit that
I never understood why astring.len() doesn't work.
Jul 18 '05 #4

P: n/a
Matthias <no@spam.pls> wrote in
news:36*************@goya03.ti.uni-mannheim.de:
The advantage of min and max as builtins are that they work on any
sequence. In particular they work on iterators. Having functions that
apply to an arbitrary sequence avoids a lot of potential code
duplication.
Do you mean code duplication on the user side? Or code duplication in
Python's implementations? In the latter case, it seems strange to
force inconsistent method/function usage on thousands of developers
just in order to save a couple of lines in Python's source code.


I mean code duplication on the user side. A function that operates on every
iterator or sequence type is far more useful than a protocol that more
often than not wouldn't be implemented.

To me, Python's builtins are by far not a "problem", but I admit that
I never understood why astring.len() doesn't work.

Because it would have to begin and end with two underscores (thats the
naming convention for special methods), and astring.__len__() already does
what you want. But I think it is mostly for historical reasons.
Jul 18 '05 #5

P: n/a
In article <15**************************@posting.google.com >,
Marco Aschwanden <PP**********@spammotel.com> wrote:

*** Problem: Many builtins are not necessary

Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:

["I", "like", "Python"].len()
"I".len()
{1:"I", "2":"like", 3:"Python"}.len()
(1,2,3,4).len()

"Throwing away" this builtins would flatten the alreay flat learning
curve once more (you don't have to learn that many builtins) ... these
functions belong to the class and they are naturally expected there.
One weakness of a language as (Visual)Basic, PHP, ... is its payload
of available functions... Python's OO helps here to diminish the need
for lots of functions.


"Practicality beats purity"; if you're not familiar with that, start up
an interactive Python session and type "import this".

In this case, this means that Guido thinks that len() is such a common
usage that it works better as a function than a method.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"Do not taunt happy fun for loops. Do not change lists you are looping over."
--Remco Gerlich, comp.lang.python
Jul 18 '05 #6

P: n/a

"Marco Aschwanden" <PP**********@spammotel.com> wrote in message
news:15**************************@posting.google.c om...
I have collected those thoughts. I am sure there are many discussions
on the "problems" mentioned here.
Yes, there have been. Do read some if you are really interested.
*** Problem: clumsy properties for classes
The problem is currently under discussion. Your fix is based on thinking
'self' to be a keyword, which it is not, instead of a usage convention for
English language programmers. Python is not <language x>.
class c (object):
def staticMethod(arg1, arg2, ...): pass
# self is not handed in... hence I can't use the instance vars
Yes it is and yes you can if this method called on an instance. You have
simply called the instance 'arg1' instead of 'self'.
def normalMethod(self, arg1, arg2, ...):
pass
If you follow this by normalMethod = staticmethod(normalMethod), then
'self' is *not* an instance.
Static methods are very rare. You left out a proposal for the more common
and more useful classmethod.

.... Many builtins are not necessary.
Many people agree.
To name a few: min / max / len
But people wildly disagree on which should be axed.
This functions should be defined on the class:
This syntax uniformatizing suggestion comes up about once a year. It
overlooks the fact that uniformity is lost as soon as a user writes a
sequence function (for instance, variance()). I know, we could abolish
functions and only have methods. But if you want that, choose a different
language.

Even more, It also overlooks the tremendous advantages of generic
programming with Python. If I write an iterable type, it can be used with
any sequence function, current or future. Conversely, if I write a
sequence (iterable) function, it can be used with any iterable object,
current or future -- without subclassing or access to source code. Your
proposed handcuff of requiring a specifc method for each type - function
combinatin leads to an M*N explosion of code and coding work.

Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if len()
were a method?
classes start with an uppercase letter:
myList = List()


This appears to be a convention or rule you learned from another language.
Though some Python programmers follow it, tt is not part of Python.

Terry J. Reedy


Jul 18 '05 #7

P: n/a

"Matthias" <no@spam.pls> wrote in message
news:36*************@goya03.ti.uni-mannheim.de...
Duncan Booth <me@privacy.net> writes:
The advantage of min and max as builtins are that they work on any
sequence. In particular they work on iterators. Having functions that apply to an arbitrary sequence avoids a lot of potential code duplication.
Do you mean code duplication on the user side? Or code duplication in
Python's implementations?


Python's generic programming saves user code.

Write a function taking an iterable argument and it can be used with any of
the countable infinity of possible iterable types, current and future. For
free, without having to subclass or otherwise attach the function as a
method to each.

Write an iterable type and it can be fed to any of the countable infinity
of possible sequence functions, written and yet to be written. For free,
without adding them all as methods, which is impossible anyway for future
functions.
In the latter case,
But it is both cases, so your consequent does not follow.
To me, Python's builtins are by far not a "problem", but I admit that
I never understood why astring.len() doesn't work.


Because there is currently no process to make generic functions accessible
(aliased) as specific methods. Possible (but not-serious) proposal: Add
interface objects with attribute __takes__ being a set of functions which
takes objects implementing that interface as a single argument. Give types
a set of interfaces called __implements__. If attribute look-up fails,
search __takes__ for interfaces in __implements__. But you now you have
to explicitly register objects with the sets, and you still have problems
with interfaces (virtual types) often being too narrow, too broad, and/or
too numerous and what to do with multiparameter functions. Isn't
len(astring) easier, as well as one char shorter?

Terry J. Reedy


Jul 18 '05 #8

P: n/a
Duncan Booth wrote:
The advantage of min and max as builtins are that they work on any
sequence. In particular they work on iterators. Having functions
that apply to an arbitrary sequence avoids a lot of potential code
duplication.


Wouldn't subclassing be an appropriate solution? The most general
sequence class/type could define a len method and the others would
inherit it and override it if they have different length semantics. In
fact, Python already does this with the __len__ magic method. Having a
builtin function whose implementation is defined with a magically named
method seems an awkward design. Why not have just the method and do
away with the function?

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #9

P: n/a
Terry Reedy wrote:
Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if
len() were a method?


[ a.len() for a in ['abc', (1,2,3,4), [5,6]] ]

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #10

P: n/a

"Marco Aschwanden" <PP**********@spammotel.com> wrote in message
news:15**************************@posting.google.c om...
Hi

I don't have to talk about the beauty of Python and its clear and
readable syntax... but there are a few things that striked me while
learning Python.

I have collected those thoughts. I am sure there are many discussions
on the "problems" mentioned here. But I had this thoughts without
looking into any forums or anything... it is kind of feedback.

Thanks for this marvellous language,
Marco

*** Problem: clumsy static class methods

In order to create a static method we have to use a the builtin
staticmethod(function):

class C (object):
def f(arg1, arg2, ...): ...
f = staticmethod(f)

Why? The speciality of a "static" method is: It has no access to any
instance vars. The following class is easier to read and understand
what a static method is about... as a positive side-effect: self is
not available and it can't be used!
Since several people have already mentioned that the syntax
is a temporary expedient until such time as a better idea can
be agreed upon, I'll just add one thing. "self" is not a built-in.
There is no requirement that the first parameter of a method
be called "self", although it's easy enough to get that impression.
So it's not possible to distinguish static methods by not having
"self" as the first parameter.
*** Problem: clumsy properties for classes

property( [fget[, fset[, fdel[, doc]]]])

class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")
[blah...]

There's nothing standing in your way of writing a
metaclass to do this, you know.
*** Problem: Many builtins are not necessary

Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:

["I", "like", "Python"].len()
"I".len()
{1:"I", "2":"like", 3:"Python"}.len()
(1,2,3,4).len()

"Throwing away" this builtins would flatten the alreay flat learning
curve once more (you don't have to learn that many builtins) ... these
functions belong to the class and they are naturally expected there.
One weakness of a language as (Visual)Basic, PHP, ... is its payload
of available functions... Python's OO helps here to diminish the need
for lots of functions.
That's a common complaint of OO purists about Python. Most
of them miss one rather obvious point: single inheritance languages
that have a root object tend to load that object with lots of utility
functions as methods, and then expect that all derived classes will
kowtow to them and not change their meaning. That makes it very
difficult to add new universal methods: you'll run into existing
classes that use them for something else.

Python's method of doing it takes universal method names
out of a different name space.
*** Problem: tuples are not necessary
Frankly, there is very little in any programming language that is
necessary. Back when I brushed up against computability theory,
I found that all programs can be written in a language with one operation:
a combination of subtract and conditional branch. That's hardly
practical, though. The question is whether a feature serves a useful
purpose.

Tuples serve two distinct purposes. One is as a cheap version
of a C struct: that is, a data structure in which each element
serves a conceptually different purpose.

The other is as a structure that is immutable so it can be used
as a key in a dict.

One thing to understand about this is that immutability is key:
dicts depend on having a hash key that is somehow derived
from the content of the object, and if the content of a key
changes that key will probably simply be unlocatable: it will be
filed in the dict under the old rather than the new hash code.

Ruby, for instance, does not have that restriction on hash
keys, but it's got other restrictions that are much easier
to trip over.

*** Problem: builtins list() dict() ...

A list, a dictionary, a str, an int, a float are builtin functions...

myList = list()
myDict = dict()
myString = str(45)

The list-function instantiates a new list... it is actually nothing
but an overloaded List class. Why are the handed in as functions? In a
OO environment it should be more the instatiation of a class rather
than a function and classes start with an uppercase letter:

myList = List()
myDict = Dict()
myString = String(45)


I think we've discussed the built-in function versus object
attribute issue before.

John Roth
Jul 18 '05 #11

P: n/a
Terry Reedy wrote:

Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if len()
were a method?


map(lambda x: x.len(), ['abc', (1,2,3,4), [5,6]])

or

[x.len() for x in ['abc', (1,2,3,4), [5,6]]]
classes start with an uppercase letter:
myList = List()


This appears to be a convention or rule you learned from another language.
Though some Python programmers follow it, tt is not part of Python.
...


It actually is a pretty good convention. There really is a pretty big
distinction between functions and types (isa, inheritance etc.) so it is
good to distinguish them. Also, many classes in the standard library use
upper-case classes. (e.g. UserList, Pickler, etc.)

Paul Prescod

Jul 18 '05 #12

P: n/a
PP**********@spammotel.com (Marco Aschwanden) wrote in message news:<15**************************@posting.google. com>...
Hi

I don't have to talk about the beauty of Python and its clear and
readable syntax... but there are a few things that striked me while
learning Python.

I have collected those thoughts. I am sure there are many discussions
on the "problems" mentioned here. But I had this thoughts without
looking into any forums or anything... it is kind of feedback.

Thanks for this marvellous language,
Marco

*** Problem: clumsy static class methods

In order to create a static method we have to use a the builtin
staticmethod(function):

class C (object):
def f(arg1, arg2, ...): ...
f = staticmethod(f)

Why? The speciality of a "static" method is: It has no access to any
instance vars. The following class is easier to read and understand
what a static method is about... as a positive side-effect: self is
not available and it can't be used!

class c (object):
def staticMethod(arg1, arg2, ...):
# self is not handed in... hence I can't use the instance vars
pass
def normalMethod(self, arg1, arg2, ...):
pass

There is no need for the builtin... as I understand it: the builtin is
a workaround...

*** Problem: clumsy properties for classes

property( [fget[, fset[, fdel[, doc]]]])

class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")
I don't like this one either. It is not necessary because it describes
something that should be clear by looking at the class/code. A
convention would make the syntax clearer and more intuitive and by
looking at the definition of a method you would know: This is a
getter, setter or deleter. My proposal:

all getters start with __get__
all setters start with __set__
all deleters start with __del__

If someone uses:

prop.x = 5

Python checks whether the var 'x' exists on prop. If it does - it is
set. If it doesn't exist Python checks for '__set__x' if it doesn't
exist either... a AttributeError is raised:
class PropertyExample(object):
"""A demonstration class for the property idea.

This class is used afterwards as follows:
prop = PropertyExample()
prop.x = 5 # __set__x(self, 5) is called behind the scenes
print prop.x # __get__x(self) is called behind the scenes
del prop.x # __del__x(self) is called behind the scenes"""

def __init__(self):
self.__x = None

def __del__x(self):
del self.__x
def __get__x(self):
return self.__x
def __set__x(self, value):
self.__x = value

*** Problem: Many builtins are not necessary

Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:

["I", "like", "Python"].len()
"I".len()
{1:"I", "2":"like", 3:"Python"}.len()
(1,2,3,4).len()

"Throwing away" this builtins would flatten the alreay flat learning
curve once more (you don't have to learn that many builtins) ... these
functions belong to the class and they are naturally expected there.
One weakness of a language as (Visual)Basic, PHP, ... is its payload
of available functions... Python's OO helps here to diminish the need
for lots of functions.
*** Problem: tuples are not necessary

Throw them away in the long run - for now make them depracted. It is
hard to argue in favour of tuples. There might to 2 reason:

1. It is MUCH faster than a list
2. We can't live without an immutable list

Cons:

1. I don't think that tuples deliver a big performance gain.
2. Python makes so many "soft" conventions (eg.: don't use
vars/methods with 2 leading underscores) but when it comes to tuples
the immutable issue is very important... why? I hope the tuples will
disappear in P3K.
*** Problem: builtins list() dict() ...

A list, a dictionary, a str, an int, a float are builtin functions...

myList = list()
myDict = dict()
myString = str(45)

The list-function instantiates a new list... it is actually nothing
but an overloaded List class. Why are the handed in as functions? In a
OO environment it should be more the instatiation of a class rather
than a function and classes start with an uppercase letter:

myList = List()
myDict = Dict()
myString = String(45)


I agree with you in all but that tuples are not
necessary. Lists are the ones that are actually a
hack for speed! :-)

In fully functional languages you would operate on your
list with something like:

lst=[1,2]
lst=lst.append(3)
lst=lst.sort()
lst=lst.reverse()
lst=lst.insert(2,3)

count=lst.append(3).sort().reverse().len()

1_ Do not try this at home kids, it will not work :)

2_ Hmm, tuples could grow these methods. Would be
confusing as hell though. >:-}

3_ I prefer reading from left to right instead from right
to left (it makes the parenthesis less confusing too).
Compare to:

count=len(reversed(sorted(appended(lst,3)))).

Maybe I should learn Hebrew :-)
Or we could always change it to

$ lst|append -3|sort|reverse|len

(in the end all are just filter patterns :))

4_ If the python interpreter was smart enough sort()
could return a new list or sort in place depending on the
context: i.e.
lst=lst.sort() eq. lst.sort()
newlst=lst.sort() where lst is never used again eq.
lst.sort();newlst=lst;del lst, etc
but that would be against the pythons philosophy of
keeping the interpreter small, lean and simple.

Inmutable types are usually less "magical" than their
mutable counterpart.

For instance:
lst1=[1,2]
lst2=lst1
lst2.append(3)
lst1 [1, 2, 3] lst2 [1, 2, 3] tup1=(1,2)
tup2=tup1
tup2=tup2+(3,)
tup1 (1, 2) tup2 (1, 2, 3)


Do you think a newbie would expect that a modification
on one variable would have a effect on another?
Jul 18 '05 #13

P: n/a
> I think you should spend a bit of time reading the PEPs...
what you say has been discussed previously,
then see where your thoughts lead you.
I will do that.
Forget the speed and memory difference. The main argument for tuples as a
separate type are to use as dictionary keys. How do you propose to handle
dictionary keys without tuples?


Maybe I don't get the point here: Why do dictionaries need tuples to
work? I know that tuples can be used as keys... but how many times do
you need tuples as dictionary keys (it would be simple to turn a list
into an immutable string if really needed ("::".join(["a","b"]). But
maybe tuples are used within dictionary in a way I don't know. If you
could clarify on this point I will never ever say anything about
"useless" tuples... instead I will start asking for "immutable
dictionaries" 8o)

A list, a dictionary, a str, an int, a float are builtin functions...


No they aren't. They are types, not functions.


functions... types... classes... simplicity at its best. But then it
was stated I am a very un-pythonic thinker.
The list-function instantiates a new list... it is actually nothing
but an overloaded List class. Why are the handed in as functions? In a
OO environment it should be more the instatiation of a class rather
than a function and classes start with an uppercase letter:

myList = List()
myDict = Dict()
myString = String(45)


So they don't follow your naming convention.


Well, yeah, this is true and isn't. It is true that there is no rule
how to name a class. To me a list / dict / string is a (basic) class
(you take about types - the manuals does also) but why introduce new
words, when the class-idiom is enough to explain everything. You want
a list, well instantiate a list class --> list = List().
What is easier to explain: If you want to create an object some kind,
you need a class which starts with an uppercase letter. Or do you
rather like to explain: well, if you want a list or dictionary you use
list() or dict() but if you want an attribute error object you use:
AttributeError(). Whenever you want an object, you check the manuals
to see, whether you need upper- or lower-class instantiation. 8o)
It is true, no one tells you that class names have to start with
uppercase letter (and I could create an alias). But look into the
standard library and you will find that my naming scheme for classes
prevails. Intuition tells me hence: I want a list instance therefore I
need to call the _L_ist-Class. And yes, talking about the
_f_ile-function/class/type... that returns a "file-object": I would
write it with a leading uppercase letter: I want to instantiate a
file-object hence I need to new a _F_ile-class.
I am well aware that it wasn't possible to derive a List / Dict / ...
until lately. Most probably the distinction between types and classes
stems from this time.
Anyway, I see that my "feedback" was very unreflected. These were
thoughts I had while learning and it was wrong to mention them so
unprocessed. Without consulting the PEP, reading comp.lang.python
discussions...

Sorry,
Marco
Jul 18 '05 #14

P: n/a
> > *** Problem: clumsy static class methods
See PEP 318 (and current discussion on python-dev).
Thanks for the hint.
class c (object):
def staticMethod(arg1, arg2, ...):
# self is not handed in... hence I can't use the instance vars
pass
def normalMethod(self, arg1, arg2, ...):
pass
What's so special about self? I really don't like the idea of
argument names keying this kind of change in behaviour.
One gets to get used to passing in self into class member functions.
It is there and I learned to live with it (self). What separates a
static method from a non-static-method is its (var) context. A static
method is not allowed to use instance vars. This can be easily
achieved by dropping the self-arg in the method definition... but as I
can see by browsing through PEP 318: A lot of "decorators" are wished
and this proposal only "solves" the static method case. Forget about
it - it was just a thought.
*** Problem: clumsy properties for classes My proposal:

all getters start with __get__
all setters start with __set__
all deleters start with __del__


You seem really fond of magic names...

No, it uses an idea that Python uses in many places: __len__ is used
with the len-function, __init__ is used when a class is instantiated,
__getitem__ is used with [], etc. etc. so why not use the same scheme
for class properties. But I can live with you saying:
I hope you're not too offended if I
say that your suggestion doesn't seem instantly wonderful.
No problem. 8o)
*** Problem: Many builtins are not necessary


Pah. So what? If you want minimailty scheme is over there ====>


No, I am not asking for minimality. I am asking for a clean design - a
string has a length therefore a string has the method len(). How many
"object oriented" languages do you know that give you the size/length
of an object by calling an external function? Except for Python I know
no other... and I know: Java, C++, Ruby (and others but not so object
oriented ones).
Many builtins are not necessary. To name a few: min / max / len

This functions should be defined on the class:


Says you!


Yeah, thanks for the convincing arguments against it. 8o)
*** Problem: tuples are not necessary
Says you! Here's a hint: hash([]).

[...]


I suppose this is the argument: list are not immutable that is why
they cannot be used a dict key... I wonder how many people use a tuple
as dict key. This seems to be a common practice to justify its own
"type". I admit, I can think of simple workarounds when there wouldn't
be tuples (eg. Instead of transforming a list into tuple why not
transforming it into a string).
I think you might be expecting something other of Python than what it
is. Nothing you suggest is completely ridiculous, just, well,
slightly un-Pythonic.


un-Pythonic... this bytes ... hmm... why? Reading your comments it
does not justify such a hard judgment - or does it?

Thanks anyway for your response and the hint for PEP 318,
Greetings,
Marco
Jul 18 '05 #15

P: n/a
Marco Aschwanden wrote:
*** Problem: tuples are not necessary
Says you! Here's a hint: hash([]).

[...]

I suppose this is the argument: list are not immutable that is why
they cannot be used a dict key... I wonder how many people use a tuple
as dict key. This seems to be a common practice to justify its own
"type". I admit, I can think of simple workarounds when there wouldn't
be tuples (eg. Instead of transforming a list into tuple why not
transforming it into a string).


I sometimes I use it. Especially if I use dates, where it makes sorting
so much easier. But it does have its usefulness.

Transforming a list to a string is not very good, because tuples may
contain user-defined classes that overwrite __lt__ and not __str__.

--
Andres Rosado
Email: an*****@despammed.com
ICQ: 66750646
AIM: pantear
Homepage: http://andres980.tripod.com/

Random Thought:

I'm just as sad as sad can be!
I've missed your special date.
Please say that you're not mad at me
My tax return is late.
-- Modern Lines for Modern Greeting Cards
Jul 18 '05 #16

P: n/a
Marco Aschwanden wrote:
....
Maybe I don't get the point here: Why do dictionaries need tuples to
work? I know that tuples can be used as keys... but how many times do
you need tuples as dictionary keys (it would be simple to turn a list
into an immutable string if really needed ("::".join(["a","b"]). But
maybe tuples are used within dictionary in a way I don't know. If you
could clarify on this point I will never ever say anything about
"useless" tuples... instead I will start asking for "immutable
dictionaries" 8o)

x = [1,2]
d = { x : 32 }
x.append( 3 )
d[ [1,2] ]

Does that last line raise a key-error, or return 32? Tuples are useful
as keys precisely because they are immutable, and hash based on their
contents/value. Mutable keys in dictionaries either need to be
"identity" based (which is far less useful that "value" based, (as then
you can only test whether a particular list is used as a key, not any
list with the same value)), or have some funky book-keeping rules
regarding what happens when the key changes (for example, convert the
key to a tuple under the covers so that all further changes to the key
are ignored in the dictionary).

To clarify regarding identity:

x = (1,2)
d = { x : 32 }
d[ x ]
d[ (1,2) ]

because they hash and compare based on value, tuples here can
unambiguously be used as value-based keys. With a list, were we to use
identity-based comparisons:

x = [1,2]
d = { x : 32 }
d[ x ] # would return a value
d[ [1,2] ] # would raise a key-error,
# defeating one of the most common usage patterns for
tuples-in-dictionaries

while if we were to use value-based comparisons set at key-specification
time:

x = [1,2]
d = { x: 32 }
x.append( 3 ) # possibly done in another thread...
del d[ x ] # would raise a key-error

to do lots of common operations (such as iterating through the keys of a
dictionary and deleting those which meet a particular test) in this
scenario you'd need to be able to return a static key in order to be
sure not to have it mutate while you're working, so you'd need an
exposed list-like immutable data-type (sound familiar).

Now, as shown above, we could do an explicit cast on setting a
dictionary value to make a list a tuple "under the covers" and thus get
back... but this is another "explicit is better than implicit" things.
The magic would up and bite in debugging weird corner cases more times
than it saved you a few seconds of thinking in the design stage. We
still have the static type, it would need to be dealt with in code, and
it would be surprising to see it show up instead of the lists we
originally used as the keys.

Using lists forced to strings would be a difficult sell even without the
problems described above, particularly as you can quite readily have
strings as keys already, so you get difficult-to-debug collisions where
a string just happens to equal the string-ified list representation of
some other value. The "explicit is better than implicit" axiom of
"import this" would then suggest that having an explicitly defined
immutable type (tuple) that hashes by value and is used to set keys in a
dictionary is a better choice than automagically coercing the lists to a
hidden type (or a string).

Don't worry about asking questions like this, by the way, it's good for
the perceptions of the community to be stirred every once in a while.
Enjoy yourself,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
Jul 18 '05 #17

P: n/a
In article <15**************************@posting.google.com >, Marco
Aschwanden <PP**********@spammotel.com> wrote:
Forget the speed and memory difference. The main argument for tuples
as a separate type are to use as dictionary keys. How do you propose
to handle dictionary keys without tuples?
Maybe I don't get the point here: Why do dictionaries need tuples to
work? I know that tuples can be used as keys... but how many times do
you need tuples as dictionary keys (it would be simple to turn a list
into an immutable string if really needed ("::".join(["a","b"]). But
maybe tuples are used within dictionary in a way I don't know.


One of the reasons for doing this is that you can use a dictionary to
represent points with coordinates in a space of two or more dimensions. In
this case you need an immutable type, and you may need to get at its
elements.

--
__ __ __ __ __ ___ _____________________________________________
|__||__)/ __/ \|\ ||_ | / Acorn StrongArm Risc_PC
| || \\__/\__/| \||__ | /...Internet access for all Acorn RISC machines
___________________________/ dh****@argonet.co.uk
Jul 18 '05 #18

P: n/a
----- Original Message -----
From: "Duncan Booth" <me@privacy.net>
*** Problem: tuples are not necessary

Throw them away in the long run - for now make them depracted. It is
hard to argue in favour of tuples. There might to 2 reason:

1. It is MUCH faster than a list
2. We can't live without an immutable list


Forget the speed and memory difference. The main argument for tuples as a
separate type are to use as dictionary keys. How do you propose to handle
dictionary keys without tuples?


Well, you _could_ (you won't, but you could ;) take some ideas from Ruby:

"""
obj.freeze -> obj

Prevents further modifications to obj. A TypeError will be raised if
modification is attempted. There is no way to unfreeze a frozen object. See
also Object#frozen? .
"""

I would think that myList.freeze() should allow myList to be used as a
dictionary key. Of course, now you'd have to freeze your lists before using
them in a dictionary ... I don't know why I bother ...

Jul 18 '05 #19

P: n/a
At some point, PP**********@spammotel.com (Marco Aschwanden) wrote:
Forget the speed and memory difference. The main argument for tuples as a
separate type are to use as dictionary keys. How do you propose to handle
dictionary keys without tuples?


Maybe I don't get the point here: Why do dictionaries need tuples to
work? I know that tuples can be used as keys... but how many times do
you need tuples as dictionary keys (it would be simple to turn a list
into an immutable string if really needed ("::".join(["a","b"]).


Simple, yes. Practicable, no. Wrong, certainly. For instance, I have a
lot of use cases where I use tuples of numbers -- (3, 4, 20.0101), eg.
It'd be a *hack* to convert that into a string, and the representation
would not be unique. This ain't Perl.

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca
Jul 18 '05 #20

P: n/a
Marco Aschwanden wrote:
I know that tuples can be used as keys... but how many times do
you need tuples as dictionary keys (it would be simple to turn a list
into an immutable string if really needed ("::".join(["a","b"]).


Having used other languages where dictionary keys have to
be strings, I very much like the fact that I *don't* have to
do this in Python. Uniquely deriving a string from a non-flat
data structure is fraught with difficulties (e.g. in your example,
what if one of the list elements contains "::"? Or what if you
wanted to stringify [42, "elephant", myFunkyClassInstance]?) You
end up having to carefully design a stringifying scheme for each
particular case. It's a big can of hassles that I can do without.

And using a tuple as a dict key is a more common thing to do than
you might think. It synergises with another feature of the Python
syntax, that commas (and not parentheses) are what generate tuples,
to give a very nice way of using a dict as a multi-dimensional table:

my_sparse_matrix = {}
my_sparse_matrix[17, 42] = 88

This works because '17, 42' is an expression yielding a
tuple, and tuples can be used as dict keys.

I hope you can see now that expecting Python programmers to
"simply" turn their lists into strings for use as dict
keys would *not* go down well in the Python community. :-)

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #21

P: n/a
Marco Aschwanden wrote:
Well, yeah, this is true and isn't. It is true that there is no rule
how to name a class. To me a list / dict / string is a (basic) class
(you take about types - the manuals does also) but why introduce new
words, when the class-idiom is enough to explain everything.


Types and classes used to be very different things, but somewhere
around Python 2.1 or 2.2 a project was begun to unify the two
concepts, and nowadays the terms "type" and "class" are very
nearly synonymous. (There still exist what are now called "old-style
classes", but these are expected to disappear eventually, at which
time we will be able to stop talking about types at all and just
speak of classes.)

Before the type/class unification, builtins such as list and str
were functions. After the unification, it made sense to re-define
them as types/classes for compatibility, and for consistency the
new ones such as dict were named in the same style.

You're right that naming conventions (or lack thereof) in Python
leave something to be desired, but we're stuck with many of them
for historical reasons. Personally, I *like* that the most
fundamental built-in functions and classes have the shortest
and simplest names.

Your suggested convention (classes start with uppercase, functions
with lowercase) has its uses, and I tend to follow it in most of
the code that I write, but it has its drawbacks as well. A
counterargument often put forward is that users of a class usually
don't care whether something is really a class or whether it's
a factory function, and often you would like to be free to change
the implementation from one to the other without affecting client
code. With a naming convention that distinguishes classes from
functions, you can't do that.

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #22

P: n/a
Greg Ewing (using news.cis.dfn.de) wrote:
....
You're right that naming conventions (or lack thereof) in Python
leave something to be desired, but we're stuck with many of them
for historical reasons.
Not really. If "open" can be renamed "file" it could also have been
renamed File. To be honest I think that the real problem is that Guido
is allergic to caps. I don't know how None snuck in. ;)
Your suggested convention (classes start with uppercase, functions
with lowercase) has its uses, and I tend to follow it in most of
the code that I write, but it has its drawbacks as well. A
counterargument often put forward is that users of a class usually
don't care whether something is really a class or whether it's
a factory function, and often you would like to be free to change
the implementation from one to the other without affecting client
code. With a naming convention that distinguishes classes from
functions, you can't do that.


Changing from a function to a class is _always_ easy.

def open(filename, flags):
return File(filename, flags)

The trickier issue is having the class itself export the interface the
client code is used to.

Changing from a class to a function is never really very safe:

class myobject(File):
...

if isinstance(myobject, File):
....

How can you change File to be just a function safely? But anyhow, why
would you want to?

Paul Prescod

Jul 18 '05 #23

P: n/a
Paul Prescod wrote:
Changing from a class to a function is never really very safe:

class myobject(File):
...

if isinstance(myobject, File):
....

How can you change File to be just a function safely?


You can't, obviously. This demonstrates that there *is*
an important distinction to be made between classes and
functions -- you can subclass one and not the other!

Arguments like this (and others, such as the capability-based
security model problems) are making me re-consider whether
having classes also be factory functions is really such
a good idea. There are two distinct ways of using classes
in Python:

1. As a base class
2. As a factory function

and these have different degrees of coupling to the
implementation. Use (1) requires it to really be a
class, whereas (2) only requires it to be a callable
object.

For use (1), there is an advantage in having classes
named differently from functions -- if it's named like
a class, you know it's a class and can therefore
subclass it.

But for use (2), it's a disadvantage, since if something
starts out as a factory function and later changes into
a (published) class, all code using it has to change.

The only way I can see of reconciling these is to adopt
the convention that whenever you publish a class Foo,
you also publish a factory function foo() that instantiates
Foo. Users of it are expected to use Foo when subclassing
and foo() when instantiating.

Now, if you change the implementation so that Foo is
no longer a class, code which subclasses Foo will break --
there's no avoiding that. But code which only instantiates,
using foo(), will keep working.

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #24

P: n/a
Sean Ross wrote:
"""
obj.freeze -> obj

Prevents further modifications to obj. A TypeError will be raised if
modification is attempted. There is no way to unfreeze a frozen
object. See also Object#frozen? .
"""


An interesting idea. This would also allow other mutable types such as
dictionaries to be used as dictionary keys. I'm not sure if I like it, but
I am sure that I am not happy with the current list/tuple situation.

An alternate approach would be for the dictionary to lock the key objects
when they are inserted and unlock them when they are removed. Another would
be for dictionaries to keep a private copy of their keys.
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #25

P: n/a
In article <c1*************@ID-169208.news.uni-berlin.de>, Greg Ewing (using news.cis.dfn.de) wrote:
Having used other languages where dictionary keys have to
be strings, I very much like the fact that I *don't* have to
do this in Python. Uniquely deriving a string from a non-flat
data structure is fraught with difficulties (e.g. in your example,
what if one of the list elements contains "::"? Or what if you
wanted to stringify [42, "elephant", myFunkyClassInstance]?) You
end up having to carefully design a stringifying scheme for each
particular case. It's a big can of hassles that I can do without.


TCL-style strings provice a good universal escaping mechanism for this,
as long as you're consistent.

Joe
Jul 18 '05 #26

P: n/a
"Mike C. Fletcher" <mc******@rogers.com> wrote in message news:<ma************************************@pytho n.org>...

I can see that tuples have their utility as a dict key. And from other
postings as well, I conclude: Tuples as dictionary keys are common
practice and are therefore here to stay.

Thanks,
Cheers,
Marco
Jul 18 '05 #27

P: n/a
co**********@physics.mcmaster.ca (David M. Cooke) wrote in message news:<qn*************@arbutus.physics.mcmaster.ca> ...
At some point, PP**********@spammotel.com (Marco Aschwanden) wrote:
Forget the speed and memory difference. The main argument for tuples as a
separate type are to use as dictionary keys. How do you propose to handle
dictionary keys without tuples?


Maybe I don't get the point here: Why do dictionaries need tuples to
work? I know that tuples can be used as keys... but how many times do
you need tuples as dictionary keys (it would be simple to turn a list
into an immutable string if really needed ("::".join(["a","b"]).


Simple, yes. Practicable, no. Wrong, certainly. For instance, I have a
lot of use cases where I use tuples of numbers -- (3, 4, 20.0101), eg.
It'd be a *hack* to convert that into a string, and the representation
would not be unique. This ain't Perl.

tup = (3, 4, 20.0101)
stringified = str(tup)
stringified

'(3, 4, 20.010100000000001)' # 8o)
What is not unique about this string?
Okay, I can think of cases where this approach is problematic -
foremost when sorting is involved.
It is also a bit complicated to retrieve the values from the string
(it has to be "split"ted or "eval"ed back to a tuple or list).
If this pattern would be seldom used... but it seems, that everybody
except me uses this dicts as keys.

And yes, luckily this is not Perl.

Cheers,
Marco
Jul 18 '05 #28

P: n/a
> >*** Problem: clumsy properties for classes

The problem is currently under discussion. Your fix is based on thinking
'self' to be a keyword, which it is not, instead of a usage convention for
English language programmers.
Thanks! Now I know where my thinking went wrong... self is "another"
soft Python contract. This was now a real enlightment! I intermingled
Java's <this> with Python's <self>. They are not the same and <self>
is not "automatic".
Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if len()
were a method?


The quiz is already (and very elegantly and better readable) solved
with a comprehension list. The OO-technique used is called
polymorphism... 8o).

Thanks for the hint on <self> is not "system var".
Cheers,
Marco
Jul 18 '05 #29

P: n/a
> > *** Problem: tuples are not necessary

Frankly, there is very little in any programming language that is
necessary. Back when I brushed up against computability theory,
I found that all programs can be written in a language with one operation:
a combination of subtract and conditional branch. That's hardly
practical, though. The question is whether a feature serves a useful
purpose.
I once read an interesting article that a programming language can be
reduced to 4 instructions: (1) input (2) output (3) if-then (4) goto.
All other commands / functions are built upon those 4 "basic ideas".

I would say: Python struggles for a maximum functionalty by preserving
optimal "simplicity". And it does a good job at that! That's why I
like it so much.

I am not a reductionist. And I am not asking to create a reduced
Python. I had just the feeling that to learn about all specialities of
tuples is not worth the hassle... obviously I was wrong and you bring
some more aspects in favour tuples further down below:
Tuples serve two distinct purposes. One is as a cheap version
of a C struct: that is, a data structure in which each element
serves a conceptually different purpose.

The other is as a structure that is immutable so it can be used
as a key in a dict.

One thing to understand about this is that immutability is key:
dicts depend on having a hash key that is somehow derived
from the content of the object, and if the content of a key
changes that key will probably simply be unlocatable: it will be
filed in the dict under the old rather than the new hash code.


Cheers,
Marco
Jul 18 '05 #30

P: n/a
> I agree with you in all but that tuples are not
necessary. Lists are the ones that are actually a
hack for speed! :-)
Did you do some time profiling? I would be interested in the results.

3_ I prefer reading from left to right instead from right
to left (it makes the parenthesis less confusing too).
Compare to:

count=len(reversed(sorted(appended(lst,3)))).

Maybe I should learn Hebrew :-)
Or we could always change it to

$ lst|append -3|sort|reverse|len

(in the end all are just filter patterns :))
This is an excellent example!
count = lst.append(3).sort().reverse().len()
is extremly readable but chaining of method calls is not supported in
Python. And I can live with it... Python has a more "expressive" path:
lst = []
lst.append(3)
lst.sort()
lst.reverse()
count = len(lst)

The last line looks a bit odd after all the dot-notations to see a
function-call in the last line.

4_ If the python interpreter was smart enough sort()
[...]
Inmutable types are usually less "magical" than their
mutable counterpart.

For instance:
lst1=[1,2]
lst2=lst1
lst2.append(3)
lst1 [1, 2, 3] lst2 [1, 2, 3] tup1=(1,2)
tup2=tup1
tup2=tup2+(3,)
tup1 (1, 2) tup2 (1, 2, 3)


Do you think a newbie would expect that a modification
on one variable would have a effect on another?


Good point.

Thanx,
Marco
Jul 18 '05 #31

P: n/a
Marco Aschwanden wrote:
....
'(3, 4, 20.010100000000001)' # 8o)
What is not unique about this string?
Okay, I can think of cases where this approach is problematic -
foremost when sorting is involved.

Actually, this is the classic problem of data-escaping. It's *possible*
to guarantee unique values when encoding as a string, but it's a *lot*
harder than just doing str( data ). You need to make sure that
different things are going to show up with different values:

d = {}
myWorkingList = (3,4,20.010100000000001)
somePieceOfDataFromSomewhere = '(3, 4, 20.010100000000001)'
d[ myWorkingList ] = 32
d[ somePieceOfDataFromSomewhere ] = 34

That is, you'd need to encode into your string information regarding the
*type* and internal structure of the object to avoid collisions where
something just happens to look the same as another object, so something
like:

'(I3\nI4\nF20.010100000000001\nt.' # for the tuple and
"S'(3,4,20.010100000000001)'\np1\n." # for the string

Thing is, creating those static string representations is a major PITA
(in case you're wondering, the above are pickles of the values), and
would waste a lot of memory and processing cycles (to build the safe
string representation, (a task which is somewhat involved)) compared to
just using a pointer to the object and the object's built-in __hash__
and comparison methods.
It is also a bit complicated to retrieve the values from the string
(it has to be "split"ted or "eval"ed back to a tuple or list).
If this pattern would be seldom used... but it seems, that everybody
except me uses this dicts as keys.

Round-trip-eval-capable objects are considered good style, but are not
by any means universal even among the built-in objects:
x = object()
x

<object object at 0x00C7D3B8>

pickle/cPickle is closer to the idea of a robust mechanism for coercion
to/from string values, but even it has its limits, particularly with
respect to older built-in types that assumed they'd never be pickled.

wrt sorting, it's not really a huge issue, dictionaries are not ordered,
so to produce a sorted set you'd need to produce the keys as a
list/sequence of reconstituted objects anyway.

Have fun, and enjoy yourself,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/

Jul 18 '05 #32

P: n/a
PP**********@spammotel.com (Marco Aschwanden) writes:
*** Problem: tuples are not necessary
Says you! Here's a hint: hash([]).

[...]


I suppose this is the argument: list are not immutable that is why
they cannot be used a dict key... I wonder how many people use a tuple
as dict key.


I do, on occasion.
This seems to be a common practice to justify its own "type". I
admit, I can think of simple workarounds when there wouldn't be
tuples (eg. Instead of transforming a list into tuple why not
transforming it into a string).


Oh yeah, transforming it into a string is really clean.
I think you might be expecting something other of Python than what it
is. Nothing you suggest is completely ridiculous, just, well,
slightly un-Pythonic.


un-Pythonic... this bytes ... hmm... why? Reading your comments it
does not justify such a hard judgment - or does it?


I was trying to be polite...

I've been reading this list for about six (eek!) years now. You kind
of get used to posts like yours, and also to their posters realizing
that there is perhaps more sense behind Python's existing form than
they first imagine.

Cheers,
mwh

--
(Unfortunately, while you get Tom Baker saying "then we
were attacked by monsters", he doesn't flash and make
"neeeeooww-sploot" noises.)
-- Gareth Marlow, ucam.chat, from Owen Dunn's review of the year
Jul 18 '05 #33

P: n/a
Marco Aschwanden schrieb:
...............
I once read an interesting article that a programming language can be
reduced to 4 instructions: (1) input (2) output (3) if-then (4) goto.
All other commands / functions are built upon those 4 "basic ideas".
.....................


I am absolutely horrified to find goto as a necessary instruction of
programming! Real (modern) programming languages dont have a goto
statement, since extensive use is considered bad programming practice
in every language. If there is a goto statement - ignore it. "jump" or
"goto" hides the difference between selection and repetition und
unclarifies the program structure.

Bohm C. and G. Jacopini "Flow Diagrams, Turing Machines, and Languages
with Only Two Formation Rules." Communications of the ACM, Vol 9, No.5,
May 1966, pp336-371.
In this article they have shown, that any progrm can be written without
any goto statement. Structured programming is common goal since about
1970. (See O. J. Dahl and C. A. R Hoare, Notes on Structured
Programming, 1972)

Bernhard

Jul 18 '05 #34

P: n/a

"b-blochl" <bb******@compuserve.de> wrote in message
news:ma************************************@python .org...
I am absolutely horrified to find goto as a necessary instruction of
programming! ..Bohm C. and G. Jacopini "Flow Diagrams, Turing Machines, and Languages
with Only Two Formation Rules."


You'll be sticking to the infinitely long tape then. ;)
Jul 18 '05 #35

P: n/a

"Marco Aschwanden" <PP**********@spammotel.com> wrote in message
news:15**************************@posting.google.c om...
co**********@physics.mcmaster.ca (David M. Cooke) wrote in message

news:<qn*************@arbutus.physics.mcmaster.ca> ...
tup = (3, 4, 20.0101)
stringified = str(tup)
stringified '(3, 4, 20.010100000000001)' # 8o)
What is not unique about this string?
Okay, I can think of cases where this approach is problematic -
foremost when sorting is involved.


Mike pointed out the problem of making sure that different things get
different strings. For dict keys, there is also the problem of making sure
that 'different' things that hash equal and which have the same value as a
key get the same string, and you cannot do that without inventing a new
*non-invertible* stringify function. In particular, numbers are hashed by
value, with 0 == 0L == 0.0 => hash(0) == hash(0L) == hash(0.0), whereas
these would give three different strings with either str() or repr().
Example:
d={1:'one'}
d[1.0]

'one'

So, you make newstr((1,2)) == newstr((1.0,2L)). Which means you must
eliminate the number type information and make newstr *not* invertible! Or
you could change the dict key rules;=).

Terry J. Reedy

Jul 18 '05 #36

P: n/a
Mike C. Fletcher wrote:
Actually, this is the classic problem of data-escaping. It's
*possible* to guarantee unique values when encoding as a string, but
it's a *lot* harder than just doing str( data ).


In Python it's one extra line of code.

from pickle import dumps
dumps(data)

--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #37

P: n/a
Rainer Deyke wrote:
Mike C. Fletcher wrote:

Actually, this is the classic problem of data-escaping. It's
*possible* to guarantee unique values when encoding as a string, but
it's a *lot* harder than just doing str( data ).


In Python it's one extra line of code.

from pickle import dumps
dumps(data)

Sure, even used that to create the examples :) , but it instantiates and
invokes a huge class (~500 lines of Python code) built using multiple
other dictionaries, each of which would need to be serviced themselves
without getting into weird recursion problems. Pickling machinery is
*really heavy* (i.e. a lot harder for the computer to do, and a lot more
hairy to program) than a few structure lookups to find functions
computing hashes and/or equalities and the inclusion of a static
sequence type.

Peace and lava lamps,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/

Jul 18 '05 #38

P: n/a
Greg Ewing (using news.cis.dfn.de) wrote:
...

Now, if you change the implementation so that Foo is
no longer a class, code which subclasses Foo will break --
there's no avoiding that. But code which only instantiates,
using foo(), will keep working.


Okay, but is this ever a serious problem? Is changing classes into
functions and vice versa actually a common enough problem to worry about?

Paul Prescod

Jul 18 '05 #39

P: n/a
On 2004-02-25 05:18:54 -0500, PP**********@spammotel.com (Marco
Aschwanden) said:
I agree with you in all but that tuples are not
necessary. Lists are the ones that are actually a
hack for speed! :-)


Did you do some time profiling? I would be interested in the results.

3_ I prefer reading from left to right instead from right
to left (it makes the parenthesis less confusing too).
Compare to:

count=len(reversed(sorted(appended(lst,3)))).

Maybe I should learn Hebrew :-)
Or we could always change it to

$ lst|append -3|sort|reverse|len

(in the end all are just filter patterns :))


This is an excellent example!
count = lst.append(3).sort().reverse().len()
is extremly readable but chaining of method calls is not supported in
Python. And I can live with it... Python has a more "expressive" path:


You can 'chain method calls' all you want.. what you're missing here is
a python idiom: methods that mutate an object shall not return the
same object.

If the above code were to actually work, then "lst" would contain an
extra element and be stored in reverse sorted order, while "count"
would be the number you were trying to extract. The intent probably
was not to modify "lst", so this particular idiom just saved you the
time of debugging your broken code by encouraging you to do it the
right way the first time.

-bob

Jul 18 '05 #40

This discussion thread is closed

Replies have been disabled for this discussion.