Re: Is isinstance always considered harmful?

2005-05-16 Thread Jordan Rastrick

Leif K-Brooks wrote:

 Regardless of the various issues surrounding isinstance(), you have a
 difference in functionality. Since you're just storing a reference in
 the case of another LinkedList instead of copying it, mutating the
 LinkedList will be different from mutating another iterable type
which
 has been passed to extend:

Oops, didn't think of that. Good point.

  linkedlist1 = LinkedList()
  list1 = [1, 2, 3]
  linkedlist2 = LinkedList([4, 5, 6])
  linkedlist1.extend(list1)
  linkedlist1.extend(linkedlist2)
  linkedlist1
 LinkedList([1, 2, 3, 4, 5, 6])
  list1.append(4)
  linkedlist1 # Notice how there's still only one 4
 LinkedList([1, 2, 3, 4, 5, 6])
  linkedlist2.append(7)
  linkedlist1 # Notice how there's now a 7
 LinkedList([1, 2, 3, 4, 5, 6, 7])

Out of curiousity, is this code real? Where does the LinkedList() class
come from?

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


Re: Is isinstance always considered harmful?

2005-05-16 Thread Jordan Rastrick
Thanks for the replies, everyone. As is usual when reading
comp.lang.python, I got some invaluable exposure to new ideas (multiple
dispatching in particular seems to fill a gap I've felt in OO
programming in the past.)

I'm starting to think this newsgroup is in its own right an excellent
reason to get into Python - the fact its an awesome language is just an
added bouns ;-)

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


Re: Is isinstance always considered harmful?

2005-05-15 Thread Terry Reedy

Jordan Rastrick [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]

 I've read arguments, here and elsewhere, to the effect that in Python
 isinstance should be avoided like the plague, except in a few very
 specific and narrow circumstances.

Putting it like this is rather extreme.

 Roughly speaking, due in part to
 Python's dynamic nature its better to concern yourself only with the
 interface an object provides, and not whether it happens to inherit
 from a given base class.

To my mind, your example of using isinstance to select a better (such as 
speedier) subalgorithm for a special case is not just fine, but good 
programming.  (Selecting a subalgorithm that works more robustly is also a 
good reason for special casing.)  It is an internal matter whose externally 
visible effect is to improve performance.

Using isinstance to unnecessarily narrow the domain is quite different.  It 
has the externally visible effect of degrading performance (to a nullity) 
for arguments that the user might reasonably want to work.

Terry J. Reedy



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


Re: Is isinstance always considered harmful?

2005-05-15 Thread Leif K-Brooks
Jordan Rastrick wrote:
 Say you're writing, in Python, the extend() method for a Linked List
 version of python's builtin list. Its really important to know what
 kind of iterable youre being passed in - because if its another
 Linked list, and you know it, you can connect the two in 0(1) time;
 whereas any other arbitrary iterable is going to take 0(n), as you're
 just going to have to append the items one by one. Is this a case
 where use of isinstance, to see exactly what kind of Iterable you
 have, can be justified?

 def extend(self, elems):
if isinstance(elems, LinkedList):
   # Point last to first
else:
   for elem in elems: self.append(elem)

Regardless of the various issues surrounding isinstance(), you have a
difference in functionality. Since you're just storing a reference in
the case of another LinkedList instead of copying it, mutating the
LinkedList will be different from mutating another iterable type which
has been passed to extend:

 linkedlist1 = LinkedList()
 list1 = [1, 2, 3]
 linkedlist2 = LinkedList([4, 5, 6])
 linkedlist1.extend(list1)
 linkedlist1.extend(linkedlist2)
 linkedlist1
LinkedList([1, 2, 3, 4, 5, 6])
 list1.append(4)
 linkedlist1 # Notice how there's still only one 4
LinkedList([1, 2, 3, 4, 5, 6])
 linkedlist2.append(7)
 linkedlist1 # Notice how there's now a 7
LinkedList([1, 2, 3, 4, 5, 6, 7])
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Is isinstance always considered harmful?

2005-05-15 Thread Robert Brewer
Jordan Rastrick wrote:
 Subject: Is isinstance always considered harmful?
 
 Say you're writing,
 in Python, the extend() method for a Linked List version of python's
 builtin list. Its really important to know what kind of iterable youre
 being passed in - because if its another Linked list, and you know it,
 you can connect the two in 0(1) time; whereas any other arbitrary
 iterable is going to take 0(n), as you're just going to have to append
 the items one by one. Is this a case where use of isinstance, to see
 exactly what kind of Iterable you have, can be justified?

I'd say so, definitely.

 There are other solutions I can think of - perhaps the least 
 hideous is factoring out the 0(1), point last to first code
 in a separated method, __linkedExtend() or something, and then
 do something similar to the above by using an exception,
 like this:
 
 def extend(self, elems):
try:
   self.__linkedExtend(elems)
catch NotALinkedListError:
   for elem in elems: self.append(elem)
 
 I dont know, I don't really like this (although it is more BAFP than
 the first version, so maybe that makes it more Pythonic?).

You've decided to special-case a binary operation based on the type of
*both* objects. Whether you use isinstance or __linkedExtend, you're
still providing a single-dispatch mechanism, which gets uglier in
proportion to the number of types involved. Meh. I'd go with isinstance
for now. Your use case is exactly why it's in the language, IMO.

If the number of types you're special-casing becomes unwieldy, you might
be interested in multiple-dispatch approaches (cf
http://gnosis.cx/publish/programming/charming_python_b12.html) and
generic functions (cf
http://dirtsimple.org/2004/11/generic-functions-have-landed.html).


Robert Brewer
System Architect
Amor Ministries
[EMAIL PROTECTED]

 To me,
 instanceof seems like the infimum of all possible evils in this case.
 
 It'd be nice if I'd seen the source code for Python's builtin list to
 see if any of these kind of considerations are taken into 
 account there
 (ultra fast array copying in C when extend is called on another list,
 perhaps)? Luckily, one of the great gifts of Python is I can indeed
 look at the source for the entire langauge at any time I want. So I'm
 going to go read it (my first time, how exciting!), and in the
 meantime, I'll let replies start accumulating froma  whole lot of
 people who are a lot smarter and more experience in Python than myself
 :)
 
 Several-weeks-in-and-still-liking-Python-better-than-any-other
 -previously-learned-language-ly
 yours,
 Jordan Rastrick
 
 -- 
 http://mail.python.org/mailman/listinfo/python-list
 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is isinstance always considered harmful?

2005-05-15 Thread Bengt Richter
On Sun, 15 May 2005 14:31:21 -0400, Terry Reedy [EMAIL PROTECTED] wrote:


Jordan Rastrick [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]

 I've read arguments, here and elsewhere, to the effect that in Python
 isinstance should be avoided like the plague, except in a few very
 specific and narrow circumstances.

Putting it like this is rather extreme.

 Roughly speaking, due in part to
 Python's dynamic nature its better to concern yourself only with the
 interface an object provides, and not whether it happens to inherit
 from a given base class.

To my mind, your example of using isinstance to select a better (such as 
speedier) subalgorithm for a special case is not just fine, but good 
programming.  (Selecting a subalgorithm that works more robustly is also a 
good reason for special casing.)  It is an internal matter whose externally 
visible effect is to improve performance.
I agree, but I am also a little uncomfortable about such performance tuning,
unless the assumptions it depends on are prominently documented or even
validated with an assert or explicit warning. Otherwise the next version
of the interpreter or a library module could change the optimal decision,
and a bad optimization decision could be locked in for the new version.

Maybe there should be another testable condition like __debug__ except for
testing (e.g. __testing__ ;-) which could be used to introduce temporary
alternative code (such as alternate optimization decisions) so that system
tests could be used to validate locking in one decision or another for a
new system version being tested.

For trivial personally maintained code, a one-line version check with a
reminder exception to re-visit the optimization or whatever decision
(and revise the version check for next time) could cheaply prevent hidden
lock-in of bad optimization etc.


Using isinstance to unnecessarily narrow the domain is quite different.  It 
has the externally visible effect of degrading performance (to a nullity) 
for arguments that the user might reasonably want to work.
Agreed, but the key thing there is to define unnecessarily ;-)

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