[Python-3000] Adaptation and type declarations

Jim Jewett jimjjewett at gmail.com
Mon Apr 10 23:37:56 CEST 2006


On 4/10/06, Guido van Rossum <guido at python.org> wrote:
> On 4/10/06, Jim Jewett <jimjjewett at gmail.com> wrote:
> > On 4/10/06, Guido van Rossum <guido at python.org> wrote:

> > > A completely separate issue is what kind of objects
> > > Seq, Index and Text would be

> > What do you mean?  The only question that leaps
> > out at me is whether they should be predicates or
> > constructors.  In other words, should

> >     def f(a:Seq): ...

> > mean something closer to

> >     def f(a):  assert Seq(a) ...

> > or

> >     def f(a):  a=Seq(a) ...

> It should mean neither. As I tried to say, the *only*
> semantics is that the value of the expression is
> accessible through the __signature__ attribute of
> the function. It is then up to the decorator to decide
> what it means.

So type annotation is only for use with decorators, not for general
documentation or compiler speedups?

> > If adaptation is light enough to be useful, then I
> > can't see any reason to prefer the first.

> >     def f(a:0<a<10): ...

> > isn't *that* much cleaner than whichever of

> >     def f(a:clip_to_int_range(0,10)): ...
> >     def f(a:int_in_range(0,10)): ...
> >     def f(a:clip_to_number_range(0,10)): ...
> >     def f(a:number_in_range(0,10)): ...

> > was actually intended.

> That's not something I had considered. It would have to
> turn the expression into an implicit lambda (or an AST),
> which isn't something we should do lightly, and which
> conflicts with other proposed uses, where the value of
> the expression is made available to the decorator
> -- the value of '0<a<10' is not available until f is *called*.

I suppose I should have supplied definitions, just to be explicit.  For example:

    def number_in_range(min, max):
        def checker(val):
            if min < val < max:
                return val
            raise ValueError("%s not between %s and %s",
                             (val, min, max))
        return checker

Then checker (the actual predicate) is available at compile time; the
only thing waiting for run time is the result of checker(a) for that
particular call.

Or were you just saying that even the predicate-only simple expression
version should really have been written as

    def f(a:lambda a:(0<a<10)): ...

so that there would be a complete predicate available independent of
the function itself?

If so, then I can't see any reason not to require that the type
markers be callables whose return value is used in place of the
argument.

There is nothing to prevent the type markers from returning the
original object (possibly with extra annotations).  For efficiency,
that should be the normal case.  Nor is there anything preventing a
decorator (if you assume there will always be one) from changing the
signature anyhow.  The only downside is an additional call per
annotated argument *if* neither the decorator nor the compiler has
used the information to optimize something away.

-jJ


More information about the Python-3000 mailing list