Thoughts about Python

M

Marco Aschwanden

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

Michael Hudson

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
 
D

Duncan Booth

(e-mail address removed) (Marco Aschwanden) wrote in
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.
 
M

Matthias

Duncan Booth said:
(e-mail address removed) (Marco Aschwanden) wrote in
*** 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.
 
D

Duncan Booth

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

Aahz

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

Terry Reedy

Marco Aschwanden said:
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 said:
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
 
T

Terry Reedy

Matthias said:
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
 
P

Paul Prescod

Terry said:
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]]]
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
 
O

OKB (not okblacke)

Duncan said:
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
 
O

OKB (not okblacke)

Terry said:
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
 
J

John Roth

Marco Aschwanden said:
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
 
N

nnes

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?
 
M

Marco Aschwanden

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)

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

Marco Aschwanden

*** Problem: clumsy static class methods
See PEP 318 (and current discussion on python-dev).

Thanks for the hint.
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.
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)
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).
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
 
M

Mike C. Fletcher

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

David H Wild

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

Sean Ross

----- Original Message -----
From: "Duncan Booth said:
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 ...
 
A

Andres Rosado-Sepulveda

Marco said:
*** 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: (e-mail address removed)
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
 
D

David M. Cooke

At said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top