[Types-sig] Proposed Goals PEP

Paul Prescod paulp@ActiveState.com
Tue, 13 Mar 2001 04:10:50 -0800

Tim Peters wrote:
> ...
> 3. The .check() method is the proper place to raise an exception.

I disagree. foo.check() should be something that you could call anywhere
in Python code and it should return a boolean. It should also probably
be called __check__ or __typecheck__ or __implementedby__ or something
similar. It is invoked magically under the covers like all of the other
__ methods.

if String.check(a):

> 4. But the calling code is the proper place to construct part of the
>    error message, because it has easy access to useful symbolic info
>    about the function (like the names of the arguments).

Another good reason to have check return a boolean.

> return expr
> needs to change into (in general)
>     _unique_temp = expr
>     if __typecheck__:
>         Tr.check(_unique_temp, msgr)
>     return _unique_temp
> which is less trivial to implement via a source-to-source translator, but
> still easy.

I was thinking of implementing it as a byte-code transformation which
might be easier.

  0 SET_LINENO               1

  3 SET_LINENO               2
  6 LOAD_FAST                0 (a)

 11 SET_LINENO               3
 14 LOAD_FAST                1 (b)

 19 SET_LINENO               4
 22 LOAD_FAST                1 (b)
 25 LOAD_FAST                0 (a)
 28 BUILD_TUPLE              2
    (typecheck goes HERE!)
 32 LOAD_CONST               0 (None)

> Subtlety:  the "t" argument above has to be a check object itself.  That
> means AnyType.check(t) has to be able to determine whether t *is* a check
> object.  This would be a great time to insist that all check objects be
> instances of subclasses of a base TypeCheck class, so that isinstance(t,
> TypeCheck) is sufficient.  I don't see that anything would be gained by
> continuing the usual dance of saying "well, if it has a .check() attribute,
> then I can't prove it's *not* a typecheck object, so I'll just assume that it
> is".

The reason to do the dance is to allow a C-type to implement .check. The
middle ground is to require an __implements__ that contains TypeCheck
(or a subtype).

> >
> > This idea looks like a good starting point to me. It's simple, it can
> > express complex types, it helps both err and doc. On the downside, it's
> > unlikely to help opt, and I don't know about glue.
> Take heart:  the same people who believe Python can magically infer types
> can't deny that it could just as magically track down the defns of the check
> objects and infer everything useful about them too <wink>.

Those are the wrong people to worry about. They say any type
declarations as cruft anyhow. But there are some people who want to use
this information in static ways. I had hoped not to get in their way!

On the other hand, the thing that the speed-demons REALLY need is a way
to freeze namespaces -- instance, class and module namespaces. If they
"freeze" the types module namespace then they can be assured that the
Integer type is the REAL integer type and they can optimize integer
inputs as real integers.

Furthermore, there is a natural upgrade path from this model to the
scarecrow interfaces model. That's more of a static-y type of thing for
those who want that.

    Programming the way
    indented it.
       - (originated with Skip Montanaro?)