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 Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com