Zope 3.0, and why I won't use it

Josiah Carlson jcarlson at uci.edu
Tue Nov 16 12:59:01 EST 2004


aleaxit at yahoo.com (Alex Martelli) wrote:
> 
> Josiah Carlson <jcarlson at uci.edu> wrote:
> 
> > > but the point is whether, if and when 'optional static typing' _syntax_
> > > gets it, it will have this semantics or that of inserting a lot of
> > > typechecks... people can do typecheks or adaptation now, and neither
> > > will go away -- but which, if either, should syntax facilitate?  That,
> > > as I see it, is key.
> > 
> > I guess it all depends.
> > "In the face of ambiguity, refuse the temptation to guess."
> > "Explicit is better than implicit."
> > 
> > With the requisite zens quoted, I'd say that there should be an explicit
> > way to do both, because guessing which one (but not both) is necessarily
> > the wrong thing to do.
> 
> Since the actual need for type-checking is extremely rare, I contend it
> should not _at all_ be a candidate for a syntax to facilitate it.  Since
> the actual need for adaptation is much wider, I contend it's the one
> obvious choice for the "nice syntax" if any.

Sounds reasonable, but there will be a group of people who will beg and
plead for type checking, because they want "static type checking on
function call and return".


> > With that said, type-based dispatch, checking and adaptation are
> > provided by decorators, which are explicit.  They are not a syntax
> > per-se, but they will get the job done in the mean time (if placing type
> > checking and adaptations in the function body is not sufficient).
> 
> Type checking is ugly, so it's quite fitting that it be implemented in
> ugly ways -- by boilerplate or user-coded splats.  Adaptation is
> beautiful, and beautiful is better than ugly (see, I can quote the zen
> of Python too...), so it should have nice syntax (<var> 'as' <itf>).

Adaptation is quite nifty, but being that I am a rare user of either, it
probably isn't worth the effort to attempt to convince me that
adaptation is the one true way, especially considering that I've got
little to no pull in python-dev.


> Type-based dispatch is a little bit of a mess to implement with
> decorators, IMHO.  Consider the hypothetical code...:
> 
> class A(object):
>   @ dispatch(int)
>   def foo(x): ...
> 
>   @ dispatch(float)
>   def foo(x): ...
> 
> class B(object):
>   @ dispatch(int)
>   def foo(x): ...
> 
>   @ dispatch(str)
>   def foo(x): ...
> 
> Sure, dispatch can be a H**2OF which returns a dispatching-foo and
> stashes somewhere a (say) foo__int, foo__float or whatever, but the
> problem is, _WHAT_ 'somewhere'.  dispatch isn't told what class body
> it's being called from, so it can't easily stash stuff in the obvious
> place, the class dictionary being built.  Attributes of the
> dispatching-foo don't seem good, because of the problem of getting at
> the right previously-returned dispatching-foo object on successive calls
> of dispatch from within the same class body (but not from separate class
> bodies).   Maybe some peek-into-the-stack black magic or custom
> metaclass can help, but it does seem a little bit of a mess, unless I'm
> overlooking something obvious.  If the implementation is hard to
> explain, it's a bad idea...

It can be a mess, which is one reason why I haven't been using it, and
generally don't use it.  But you know those C/C++ guys who are all like
"hey, where's my polymorphism?"

I agree that it would be best of one could place everything into the
class dict without frame hacks, but for simplicity in implementation's
sake, I would stick with a dispatch-factory and jam all of the requisite
dispatch information into the closure (or instance) that is generated.
Sure, you need to say 'hey, I'm going to do type-based dispatch here'
at the beginning of your desired non-overlapping namespaces, but it is
explicit what one would want in such a case.  Heck, with a properly
defined metaclass or class decorator, a post-decoration pass could be
done to extract all of the dispatches and place them into foo__int, etc.

@ multi_dispatch_to_methods
class A(object):
  dispatch = dispatch_factory()
  
  @ dispatch(int)
  def foo(x): ...

  @ dispatch(float)
  def foo(x): ...


It may have a couple warts, but it is implementable today.

 - Josiah




More information about the Python-list mailing list