Re: Question about consistency in python language

2005-09-11 Thread James
 Also, you shouldn't use 1, I mean l, as a variable name. It gets confusing
 because l, I mean 1, looks a lot like 1, I mean l.

I have seen the same warnning above significantly several times.
Is this problem originally came from the similarities between 'l' and
'1'
or from bad looking news-browser?
Forgive me if it is out of your interests.

-James GOLD

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


Re: Question about consistency in python language

2005-09-11 Thread Kay Schluehr

Steve Holden wrote:
 Kay Schluehr wrote:
  Mike Meyer wrote:
 
 
 Yes, but the function sorted is more useful than a list method
 sorted in a duck typing language.
 
 
  I don't see what this has to do with duck typing? sorted() is simply
  a generic function accepting different types. I'm not aware that
  sorted() requires a specific interface of those types it accepts.
 
 Just because you aren't aware of something doesn't stop it being true.
 The argument must be iterable, and there's a specific protocol for that.
 
 The function sorted works on all iterators. I can do:
 
 Ah, so you *were* aware of it.

I already responded to it two days ago in the reply to Terry. No need
to rehash that.

 
 def t(n):
   for i in range(n):
 yield i
 ...
 print sorted(t(5))
 
 and have it work.
 
 If sorted were a method of a class - the it'd have to be implemented
 again for every class iterable class. Either that, or you'd have to
 create an abstract parent of all iterable classes to add it to - which
 seems more appropriate for a BD language than Python.
 
 
  Instead of extending a class hierarchy it might even be possible to
  hook a trait into the class by means of a __traits__ attribute.
 
  http://fsl.cs.uiuc.edu/~mhills/presentations/TraitsPresentation.pdf
 
  Generators as well as lists and tuples would provide a sortable trait.
  The sorted() function could remain available for convenience.
 
 The advantage being ... ? Perhaps you have just discovered a really
 interesting hammer, and are seeing this problem as a nail?

I also responded to traits as nice-to-have but not essential. And
please don't aggressively consider me as childish as you might be
yourself.

Adding a __traits__ attribute should enable the user adding methods to
builtins in a safe manner. This has the advantage that one can apply
methods to string or integer literals or even replace methods without
touching the C sources. A very typical use case is integer
representation. In 95% of all my business applications I don't have
much use for decimal integer representation but want a hex rep in
different variants:

 0x0F  # current rep
15

 int.__traits__.append(HexRepTrait)  # used for delegation of
# __repr__ to the Trait
 int.configure_format(HexRepTrait.HEXFORM_STD) # configure_format is a
  # hooked trait method
 0x0F
0F
 2*0x800
10 00
 print 700
02 BC

I know I can write wrapper classes, because I do this all the time, but
that's not the point: Python is essentially not about boiler-plate. And
no, I also don't want to fight for each method and keyword with Guido.

 
 And even if you do add the abstract class, how do you make my example
 work without explictly converting the iterator to a list type?
 
 
  I don't know how sorted() is implemented? A naive implementation would
  in fact be nothing else then:
 
  def sorted(iter):
  l = list(iter)
  l.sort()
  return l
 
  Kay
 
 That would indeed be a naïve implementation.

And that's the real implementation:

static PyObject *
builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs;
PyObject *callable;
static char *kwlist[] = {iterable, cmp, key, reverse, 0};
long reverse;

if (args != NULL) {
if (!PyArg_ParseTupleAndKeywords(args, kwds, O|OOi:sorted,
kwlist, seq, compare, keyfunc, reverse))
return NULL;
}

newlist = PySequence_List(seq);
if (newlist == NULL)
return NULL;

callable = PyObject_GetAttrString(newlist, sort);
if (callable == NULL) {
Py_DECREF(newlist);
return NULL;
}

newargs = PyTuple_GetSlice(args, 1, 4);
if (newargs == NULL) {
Py_DECREF(newlist);
Py_DECREF(callable);
return NULL;
}

v = PyObject_Call(callable, newargs, kwds);
Py_DECREF(newargs);
Py_DECREF(callable);
if (v == NULL) {
Py_DECREF(newlist);
return NULL;
}
Py_DECREF(v);
return newlist;
}


The crucial steps are the conversion from args to seq, the conversion
from seq to newlist and finally calling PyObject_Call(callable, ...)
where callable stores the sort method of newlist. By the way I don't
see much use in implementing this trivial wrapper function in C except
for the joy of refcounting ;)

And now we take a look on how the PyPythonistas implemented sorted():

def sorted(lst, cmp=None, key=None, reverse=None):
sorted(iterable, cmp=None, key=None, reverse=False) -- new sorted
list
sorted_lst = list(lst)
sorted_lst.sort(cmp, key, reverse)
return sorted_lst

Surprise, surprise!

 The implementation is, of
 course, an implementation detail ;-) In this case it requires 

Re: Question about consistency in python language

2005-09-11 Thread Robert Kern
James wrote:

[James Stroud wrote:]
Also, you shouldn't use 1, I mean l, as a variable name. It gets confusing
because l, I mean 1, looks a lot like 1, I mean l.
 
 I have seen the same warnning above significantly several times.
 Is this problem originally came from the similarities between 'l' and
 '1'
 or from bad looking news-browser?
 Forgive me if it is out of your interests.

In many, many fonts 'l' and '1' look close enough to be easily mistaken
for one another, especially for people whose vision isn't perfect. The
problem exists in the fonts people view and edit code with, not just
newsreaders.

-- 
Robert Kern
[EMAIL PROTECTED]

In the fields of hell where the grass grows high
 Are the graves of dreams allowed to die.
  -- Richard Harter

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


Re: Question about consistency in python language

2005-09-11 Thread Terry Reedy

Robert Kern [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 In many, many fonts 'l' and '1' look close enough to be easily mistaken
 for one another

In the default font used by Outlook Express, displayed on my 1078x786 
screen, the only difference I can see, using a magnifying glass on 
side-by-side characters (l1 = el-onel), is that 'el' is one pixel taller 
than the 'one'.  The serifs appear the same, down to the anti-alias gray 
pixels.  (To my surprise, this makes 'lbdk' a pixel taller than uppercase 
chars!)  Now I know ;-).  But 1 isolated from l is still difficult to 
distinguish.

Terry J. Reedy




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


Re: Question about consistency in python language

2005-09-10 Thread Steve Holden
Kay Schluehr wrote:
 Mike Meyer wrote:
 
 
Yes, but the function sorted is more useful than a list method
sorted in a duck typing language.
 
 
 I don't see what this has to do with duck typing? sorted() is simply
 a generic function accepting different types. I'm not aware that
 sorted() requires a specific interface of those types it accepts.
 
Just because you aren't aware of something doesn't stop it being true. 
The argument must be iterable, and there's a specific protocol for that.
 
The function sorted works on all iterators. I can do:

Ah, so you *were* aware of it.

def t(n):
  for i in range(n):
yield i
...
print sorted(t(5))

and have it work.

If sorted were a method of a class - the it'd have to be implemented
again for every class iterable class. Either that, or you'd have to
create an abstract parent of all iterable classes to add it to - which
seems more appropriate for a BD language than Python.
 
 
 Instead of extending a class hierarchy it might even be possible to
 hook a trait into the class by means of a __traits__ attribute.
 
 http://fsl.cs.uiuc.edu/~mhills/presentations/TraitsPresentation.pdf
 
 Generators as well as lists and tuples would provide a sortable trait.
 The sorted() function could remain available for convenience.
 
The advantage being ... ? Perhaps you have just discovered a really 
interesting hammer, and are seeing this problem as a nail?
 
And even if you do add the abstract class, how do you make my example
work without explictly converting the iterator to a list type?
 
 
 I don't know how sorted() is implemented? A naive implementation would
 in fact be nothing else then:
 
 def sorted(iter):
 l = list(iter)
 l.sort()
 return l
 
 Kay
 
That would indeed be a naïve implementation. The implementation is, of 
course, an implementation detail ;-) In this case it requires that 
sort() then provides all the magic - the need for magic doesn't go away!

regards
  Steve
-- 
Steve Holden   +44 150 684 7255  +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

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


Re: Question about consistency in python language

2005-09-09 Thread Kay Schluehr
[EMAIL PROTECTED] wrote:

 Let's say I define a list of pairs as follows:
 l = [('d', 3), ('a', 2), ('b', 1)]

 Can anyone explain why this does not work?
 h = {}.update(l)

 and instead I have to go:
 h = {}
 h.update(l)
 to initialize a dictionary with the given list of pairs?

 when an analagous operation on strings works fine:
 s = .join([d,o,g])

 Seems inconsistent.

If you define

 sep = 
 sep.join([d,o,g])
dog
 sep
''

sep is preserved and a new dog string is generated. Since sep is
immutable there is no way to manipulate it inplace.

On the other hand there exists no sorted() method for tuples or lists
like join() for strings but it is implemented as a function in Python24
that returns a new sorted container. I consider this as an
inconsistency across builtin types. Consistent would be following usage
pattern:

 l = [1,3,2]
 l.sorted()
[1,2,3] # new sorted list
 l.sort()# sort list inplace
 l.appended(4)   # new extended list
[1,2,3,4]
 l.append(4) # appends an element to the same list
 l
[1,2,3,4]

Preserving the naming convention we would have

 .joined([d,o,g])
dog

Kay

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


Re: Question about consistency in python language

2005-09-09 Thread Mike Meyer
Dave Benjamin [EMAIL PROTECTED] writes:
 Mike Meyer wrote:
 Dave Benjamin [EMAIL PROTECTED] writes:
Python is actually quite consistent in this regard: methods that
modify an object in-place return None;
 Um, no. list.pop comes to mind as an immediate counterexample. It may
 be the only one...
 I've never had to look up the return type of pop though. The only
 thing even remotely ambigious about that term (at least, if you've
 learned what a stack is) is whether it mutates the object, but I don't
 think I've ever seen a pop that didn't (aside from toy examples in
 formal methods / ADT related classes).

Eiffel STACK class has a pop that dosn't return a value - at least in
SmartEiffel. On the other hand, Eiffel makes a *big* deal about the
difference between command features - which change the state - and
query features - which report on the state. That distinction even
shows up in the threading model for Eiffel.

 os.system might be a better example, since the return value could be
 one of two obvious things: the status code, or the program's output.

To me, os.system obviously returns the status code. Then again, I know
it's just the unix system() routine, which I've know *much* longer
than there's been a Python.

The point is that what's obvious depends on where you're coming
from. If your background is as a Unix developer, the result of
os.system is obvious. If your background is Eiffel or some other
strong ADT area, that pop has a result at all may surprise you.

 mike
-- 
Mike Meyer [EMAIL PROTECTED]  http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about consistency in python language

2005-09-09 Thread Mike Meyer
Kay Schluehr [EMAIL PROTECTED] writes:
 If you define

 sep = 
 sep.join([d,o,g])
 dog
 sep
 ''

 sep is preserved and a new dog string is generated. Since sep is
 immutable there is no way to manipulate it inplace.

 On the other hand there exists no sorted() method for tuples or lists
 like join() for strings but it is implemented as a function in Python24
 that returns a new sorted container. I consider this as an
 inconsistency across builtin types. Consistent would be following usage
 pattern:

 l = [1,3,2]
 l.sorted()
 [1,2,3] # new sorted list
 l.sort()# sort list inplace
 l.appended(4)   # new extended list
 [1,2,3,4]
 l.append(4) # appends an element to the same list
 l
 [1,2,3,4]


Yes, but the function sorted is more useful than a list method
sorted in a duck typing language.

The function sorted works on all iterators. I can do:

 def t(n):
   for i in range(n):
 yield i
 ...
 print sorted(t(5))

and have it work.

If sorted were a method of a class - the it'd have to be implemented
again for every class iterable class. Either that, or you'd have to
create an abstract parent of all iterable classes to add it to - which
seems more appropriate for a BD language than Python.

And even if you do add the abstract class, how do you make my example
work without explictly converting the iterator to a list type?

 mike
-- 
Mike Meyer [EMAIL PROTECTED]  http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about consistency in python language

2005-09-09 Thread Terry Reedy

Kay Schluehr [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 On the other hand there exists no sorted() method for tuples or lists
 like join() for strings but it is implemented as a function in Python24
 that returns a new sorted container. I consider this as an
 inconsistency across builtin types.

The sorted function is not a list method because it is not only a list 
function or even only a tuple and list function or even only a string, 
tuple, list, array, or dict function.  Its input is **any** iterable.  The 
only way to have it both be general and a method would be to have an 
iterable type and to require that all iterables inherit from that type to 
reap the benefit of being an iterable.  All the itertools functions are 
also functions and not methods of a hypothetical iterable type.  'Iterable' 
is a duck type and hence functions thereof must be functions and not 
methods.

Terry J. Reedy



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


Re: Question about consistency in python language

2005-09-09 Thread Kay Schluehr
Mike Meyer wrote:

 Yes, but the function sorted is more useful than a list method
 sorted in a duck typing language.

I don't see what this has to do with duck typing? sorted() is simply
a generic function accepting different types. I'm not aware that
sorted() requires a specific interface of those types it accepts.


 The function sorted works on all iterators. I can do:

  def t(n):
for i in range(n):
  yield i
  ...
  print sorted(t(5))

 and have it work.

 If sorted were a method of a class - the it'd have to be implemented
 again for every class iterable class. Either that, or you'd have to
 create an abstract parent of all iterable classes to add it to - which
 seems more appropriate for a BD language than Python.

Instead of extending a class hierarchy it might even be possible to
hook a trait into the class by means of a __traits__ attribute.

http://fsl.cs.uiuc.edu/~mhills/presentations/TraitsPresentation.pdf

Generators as well as lists and tuples would provide a sortable trait.
The sorted() function could remain available for convenience.

 And even if you do add the abstract class, how do you make my example
 work without explictly converting the iterator to a list type?

I don't know how sorted() is implemented? A naive implementation would
in fact be nothing else then:

def sorted(iter):
l = list(iter)
l.sort()
return l

Kay

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


Re: Question about consistency in python language

2005-09-09 Thread Kay Schluehr
Terry Reedy wrote:
 Kay Schluehr [EMAIL PROTECTED] wrote in message
 news:[EMAIL PROTECTED]
  On the other hand there exists no sorted() method for tuples or lists
  like join() for strings but it is implemented as a function in Python24
  that returns a new sorted container. I consider this as an
  inconsistency across builtin types.

 The sorted function is not a list method because it is not only a list
 function or even only a tuple and list function or even only a string,
 tuple, list, array, or dict function.  Its input is **any** iterable.  The
 only way to have it both be general and a method would be to have an
 iterable type and to require that all iterables inherit from that type to
 reap the benefit of being an iterable.  All the itertools functions are
 also functions and not methods of a hypothetical iterable type.  'Iterable'
 is a duck type and hence functions thereof must be functions and not
 methods.

 Terry J. Reedy

So what? Then an iterable class providing the __iter__ method may be
factored out as Mike reasonably suggested ( I was wrong with my remark
about duck-typing. The __iter__ method may be the interface I claimed
not being aware of ). Or a sortable trait gets used as I would slightly
prefer - but it's not necassary. To be honest I'm not sure what all the
BDFLs Javaesque interfaces and optional static typing blabla for Py3K
should matter if it's not even possible to create obvious inheritance
hierarchies in favour for accidental generic functions?

Kay

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


Question about consistency in python language

2005-09-08 Thread lechequier
Let's say I define a list of pairs as follows:
l = [('d', 3), ('a', 2), ('b', 1)]

Can anyone explain why this does not work?
h = {}.update(l)

and instead I have to go:
h = {}
h.update(l)
to initialize a dictionary with the given list of pairs?

when an analagous operation on strings works fine:
s = .join([d,o,g])

Seems inconsistent. 

thanks,
Scott

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


Re: Question about consistency in python language

2005-09-08 Thread James Stroud
This is the difference between mutable and immutable types. In this sense it 
is consistent.

If you want to do the former in one shot:

   h = dict(l)

Also, you shouldn't use 1, I mean l, as a variable name. It gets confusing 
because l, I mean 1, looks a lot like 1, I mean l.

James

On Thursday 08 September 2005 16:03, [EMAIL PROTECTED] wrote:
 Let's say I define a list of pairs as follows:
 l = [('d', 3), ('a', 2), ('b', 1)]

 Can anyone explain why this does not work?

 h = {}.update(l)

 and instead I have to go:
 h = {}
 h.update(l)

 to initialize a dictionary with the given list of pairs?

 when an analagous operation on strings works fine:
 s = .join([d,o,g])

 Seems inconsistent.

 thanks,
 Scott

-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about consistency in python language

2005-09-08 Thread Sam Pointon
update updates the dictionary in place - it actually returns None, not
the updated dict. However, you can construct a dictionary from a list
of (key, value) pairs using dict(list). Example:

l = [('foo', 'bar'), ('baz', 'qig')]
d = dict(l)
print d
{'foo': 'bar', 'baz': 'qig'}

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


Re: Question about consistency in python language

2005-09-08 Thread Bengt Richter
On 8 Sep 2005 16:03:12 -0700, [EMAIL PROTECTED] wrote:

Let's say I define a list of pairs as follows:
l = [('d', 3), ('a', 2), ('b', 1)]

Can anyone explain why this does not work?
h = {}.update(l)

and instead I have to go:
h = {}
h.update(l)
to initialize a dictionary with the given list of pairs?

when an analagous operation on strings works fine:
s = .join([d,o,g])

Seems inconsistent. 

Join isn't that good an analogy, because the inputs and outputs are immutable.
list.sort is more comparable to dict.update. There is now a builtin sorted 
function
that will take a list and return a sorted one. Perhaps there will come an 
updated
function analogously for dictionaries, but I don't think the use is that common,
and you can make your own. Several ways. If you want to start with an empty dict
anyway, the dict constructor will accept a sequence of pairs (so long as the 
first
of every pair is hashable, which is also required for update). E.g.,

  dict([('d', 3), ('a', 2), ('b', 1)])
 {'a': 2, 'b': 1, 'd': 3}

or the sequence of pairs as a tuple expression
  dict((('d', 3), ('a', 2), ('b', 1)))
 {'a': 2, 'b': 1, 'd': 3}

or sometimes it's handy to start with the keys and values as separate sequences
and zip them together for the dict constructor

  dict(zip('dab', [3,2,1]))
 {'a': 2, 'b': 1, 'd': 3}

or a generator expression

  dict((k,3-i) for i,k in enumerate('dab'))
 {'a': 2, 'b': 1, 'd': 3}


though note that dict wants the sequence as a single argument:
  dict( ('d', 3), ('a', 2), ('b', 1) )
 Traceback (most recent call last):
   File stdin, line 1, in ?
 TypeError: dict expected at most 1 arguments, got 3

  def updated(d, seq): d=d.copy(); d.update(seq); return d
 ...
  updated({}, [('d', 3), ('a', 2), ('b', 1)])
 {'a': 2, 'b': 1, 'd': 3}

One rationale for not returning a reference to the mutated value
from a mutating method is that it is too easy to think of it
as a pure expression, and forget the persistent side effect of
mutating the object. I think that was thought too bug-prone.

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about consistency in python language

2005-09-08 Thread Dave Benjamin
[EMAIL PROTECTED] wrote:
 Let's say I define a list of pairs as follows:
 
l = [('d', 3), ('a', 2), ('b', 1)]
 
 
 Can anyone explain why this does not work?
 
h = {}.update(l)
 
 
 and instead I have to go:
 
h = {}
h.update(l)
 
 to initialize a dictionary with the given list of pairs?
 
 when an analagous operation on strings works fine:
 
s = .join([d,o,g])
 
 
 Seems inconsistent. 

Python is actually quite consistent in this regard: methods that modify 
an object in-place return None; methods that do not modify an object 
in-place return a new object instead. Since strings are immutable, they 
cannot be modified in-place, so it makes sense for the join method to 
return a new string. On the other hand, Python's dictionaries are 
imperative-style and so most operations on a dictionary modify an 
existing dictionary.

I was initially bothered by the phenomenon of so many methods returning 
None because they could not be chained. But I have come to deeply 
appreciate this style for a couple of reasons. First, it makes it clear 
which methods are side-effecting (like update) and which are not (like 
sort).

Second, it is not always clear what a good return value is for a 
mutator. Perhaps {}.update() should return the dictionary, making 
chaining convenient. Perhaps it should return the total number of items 
after updating. Or maybe it should return the number of new keys that 
were added, or a list of those keys. All of these are plausible 
behaviors; the problem is that update is not a function. Its job is to 
change something, not return something. Any possible return value would 
be a convenience for certain tasks and useless for other tasks.

It's also hard to remember, in my opinion. For example, JavaScript has a 
push method on the Array object which behaves like Python's append 
method on lists:

js var a = [];
js a.push(5);
1
js a.push(6);
2

I bet you that almost nobody knows that push returns the new length of 
the Array. It could just as easily have returned a here. I could 
always write a.length, if I really needed to know the new length. This 
sort of thing becomes language trivia, and when I write in JavaScript I 
always ignore the result of push because, even if *I* know what it 
returns, chances are that my readers don't.

Another reason that Python adopts the convention of returning None for 
mutators is that it discourages the use of side-effecting code in 
expressions. Mixing side-effects with expressions can lead to code that 
is hard to read and understand. This is often debated by those who know 
better and wish to write things like h.update(a).update(b) (method 
chaining) or while (line = file.readline()):  Python's decision is 
pretty clear, and it's also evident in the division between statements 
and expressions.

Regardless of whether you like Python's style decision or not, if you 
dig deeper I think you will find that it is pretty consistent, and that 
there are useful benefits to Python's way of handling side effects.

Dave

PS. If mutators had to return a value, I'd have them return self, 
probably 95% of the time. But then, it wouldn't be Python anymore. It'd 
be Ruby, maybe.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Question about consistency in python language

2005-09-08 Thread Mike Meyer
Dave Benjamin [EMAIL PROTECTED] writes:
 Python is actually quite consistent in this regard: methods that
 modify an object in-place return None;

Um, no. list.pop comes to mind as an immediate counterexample. It may
be the only one...

   mike
-- 
Mike Meyer [EMAIL PROTECTED]  http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
-- 
http://mail.python.org/mailman/listinfo/python-list