On 4/11/06, Jim Jewett <[EMAIL PROTECTED]> wrote:
> On 4/10/06, Guido van Rossum <[EMAIL PROTECTED]> wrote:
>
> > I don't want to assign *any* semantics to the type markers;
>
> > ... I'd like to be able to have a decorator that
> > requires the convention of using concrete types
> > (e.g. list, int, file) as type markers; calling these
> > would be a mistake, they should be used
> > in isinstance() calls for example.
>
> list is indeed a corner case, because of the copying.
>
> To me, the answer is to instead create a similar List that doesn't
> copy unless it has to.
>
> def List(val): return val if isinstance(val, list) else list(val)
>
> It would be nicer to use list directly, but I'm not sure it is worth
> having to also add a decorator every time I use a type marker. That
> starts to look too much like boilerplate.
Beware that this (which has been discussed many times in the context
of adaptation) is a very treacherous path. Saying it is a "List"
doesn't say what you intend to do to it; modifying a copy and
modifying the original have very different effects.
> Alternatively, if you're assuming a decorator anyhow, then a decorator
> for only-these-odd-cases could wrap the function with a different
> signature and its own isinstance check.
Every framework should probably decide for itself how it wants to
handle these things. Implicit adaptation isn't exactly a feature which
has been tried a lot before in Python.
> > You're thinking of the type markers as adapters
> > exclusively.
>
> No, but I am saying that they should be constrained to be callables
> which can be used as (possibly faulty) adapters.
And to the contrary I think they should be allowed to be whatever is
acceptable to the decorator you use. Argument annotations (I guess we
should drop the "type" part altogether :-) should be a matter of
agreement between the annotation and the decorator -- if any. Or
implied introspection, of course.
> > Several people (in a previous round of discussion)
> > have agreed that they'd be totally happy if
> > [the type annotations were ignored], so ...
>
> >>> def f(x: int):
> ... print x*2
> >>> f("abc")
> 'abcabc'
>
> I think "satisfied" is more accurate that "totally happy".
>
> That call is arguably an error, and there are certainly execution
> contexts where it isn't worthwhile checking for errors. I think the
> same people would be just as happy if the call raised a TypeError
> (particularly in debug mode). In optimized mode, they might even be
> willing to live with undefined results, to avoid the try-except
> overhead.
>
> What they don't want is for
>
> (a) Every type marker to be an annoyance to create,
>
> particularly if
>
> (b) Every parameter has to be marked up (in a likely useless
> fashion), because of style expectations imported from other languages.
I don't think anyone suggested that?
> So the fact that users might want any of:
>
> def MyType(val): return val # no run-time overhead
What do you mean by no run-time overhead? What about the call to
MyType(val) itself?
> class MyType(RealType): # copyless adapter
> def __new__(self, other):
> if isinstance(other, MyType):
> return other
> return RealType(other)
>
> def MyType(val): # checker
> if not isinstance(val, _MySecretType):
> raise TypeError("%s is not a MyType" % (val,))
> return val
>
> shouldn't mean that type providers have to write all of the above.
Well what's your proposed alternative? We seem to be going around in circles.
> Having to provide "a callable" isn't nearly so restrictive. Even
> meeting a full "type annotation API" isn't so bad, if inheritance lets
> them mostly not bother.
I'm lost.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
_______________________________________________
Python-3000 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com