Re: [Python-Dev] UserString

2005-02-21 Thread Guido van Rossum
  Anyway, can you explain why LBYL is bad?
 
 In the general case, it's bad because of a combination of issues.  It
 may violate once, and only once! -- the operations one needs to check
 may basicaly duplicate the operations one then wants to perform.  Apart
 from wasted effort, it may happen that the situation changes between
 the look and the leap (on an external file, or due perhaps to threading
 or other reentrancy).  It's often hard in the look to cover exactly the
 set of prereq's you need for the leap -- e.g. I've often seen code such
 as
  if i  len(foo):
  foo[i] = 24
 which breaks for i-len(foo); the first time this happens the guard's
 changed to 0=ilen(foo) which then stops the code from working
 w/negative index; finally it stabilizes to the correct check,
 -len(foo)=ilen(foo), but even then it's just duplicating the same
 check that Python performs again when you then use foo[i]... just
 cluttering code.  The intermediate Pythonista's who's learned to code
 try: foo[i]=24 // except IndexError: pass is much better off than the
 one who's still striving to LBYL as he had (e.g.) when using C.
 
 Etc -- this is all very general and generic.

Right. There are plenty of examples where LBYL is better, e.g. because
there are too many different exceptions to catch, or they occur in too
many places. One of my favorites is creating a directory if it doesn't
already exist; I always use this LBYL-ish pattern:

 if not os.path.exists(dn):
try:
   os.makedirs(dn)
except os.error, err:
   ...log the error...

because the specific exception for it already exists is quite subtle
to pull out of the os.error structure.

Taken to th extreme, the LBYL is bad meme would be an argument
against my optional type checking proposal, which I doubt is what you
want.

So, I'd like to take a much more balanced view on LBYL.

 I had convinced myself that strings were a special case worth singling
 out, via isinstance and basestring, just as (say) dictionaries are
 singled out quite differently by metods such as get... I may well have
 been too superficial in this conclusion.

I think there are lots of situations where the desire to special-case
strings is legitimate.

  Then you would be able to test whether something is sequence-like
  by the presence of __getitem__ or __iter__ methods, without
  getting tripped up by strings.
 
  There would be other ways to get out of this dilemma; we could
  introduce a char type, for example. Also, strings might be
  recognizable by other means, e.g. the presence of a lower() method or
  some other characteristic method that doesn't apply to sequence in
  general.
 
 Sure, there would many possibilities.
 
  (To Alex: leaving transform() out of the string interface seems to me
  the simplest solution.)
 
 I guess you mean translate.  Yes, that would probably be simplest.

Right.

BTW, there's *still* no sign from a PEP 246 rewrite. Maybe someone
could offer Clark a hand? (Last time I inquired he was recovering from
a week of illness.)

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] Store x Load x -- DupStore

2005-02-21 Thread Raymond Hettinger
 Where are the attempts to speed up function/method calls? That's an
 area where we could *really* use a breakthrough...

At one time you had entertained treating some of the builtin calls as
fixed.  Is that something you want to go forward with?  It would entail
a from __future__ and transition period.

It would not be hard to take code like return len(alist) and transform
it from:

  2   0 LOAD_GLOBAL  0 (len)
  3 LOAD_FAST0 (alist)
  6 CALL_FUNCTION1
  9 RETURN_VALUE  

to:

  2   0 LOAD_FAST0 (alist)
  3 OBJECT_LEN
  4 RETURN_VALUE  

Some functions already have a custom opcode that cannot be used unless
we freeze the meaning of the function name:  

repr --  UNARY_CONVERT -- PyObject_Repr
iter --  GET_ITER  -- PyObject_GetIter

Alternately, functions could be served by a table of known, fixed
functions:

  2   0 LOAD_FAST0 (alist)
  3 CALL_DEDICATED   0 (PyObject_Len)
  6 RETURN_VALUE  

where the dispatch table is something like:  [PyObject_Len,
PyObject_Repr, PyObject_IsInstance, PyObject_IsTrue, PyObject_GetIter,
...].

Of course, none of these offer a big boost and there is some loss of
dynamic behavior.



Raymond
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com