[Types-sig] Re: [Doc-SIG] Sorry!

Edward Welbourne Edward Welbourne <eddyw@lsl.co.uk>
Thu, 16 Dec 1999 14:09:02 +0000

[Ooops - sent it to Paul but not the group, again]

> Who said anything about a separate file for every interface?
Dunno - I wasn't supposing anyone had.

You are asking for a separate file for each module, for the purpose of
saying which interfaces the things in the module support.  My
(admittedly poorly expressed) point was that any mechanism for doing
this depends on ways of saying what an interface is; which could as
readilly be stated in the source file as in a separate one.  If it's so
big and unweildy that it needs to go in a separate source file, then:

  * anything else I write that has the same interface has to include a
    copy of this big and unweildy thing, instead of just referencing the
    same interface-description object

  * it's big and unweildy, so its right out.

> The benefits of the shadow files have been documented ...
Hmm, I'm not sure I read Guido's
> I think that any proposal that requires you to keep two separate files
> "in sync" is bound to fail in the long term. I left that crap behind
> in C++. But in the short term...okay.
as anything but a `yes, we could use this as a temporary measure to let
us experiment with static typing within python 1'.  And it appears to be
typical of the comments to date.

I guess this means I should ask:
  do you consider the changes you're proposing to be
   * temporary measures or 
   * how python 2 will do this

If the former, then we have nothing to argue about - my sole concern is
how python 2 can do this (and, for context, I'm not particularly keen on
bothering - but if it's going to be done, I want to be *very* sure it
isn't going to foul some of the truly lovely things python 2 could be ...)

> You said that static type checking was ugly to start with so I would
> have thought that you would prefer a proposal that separated the type
> declarations from your code.

I also consider many kinds of large industrial plant to be ugly: and
whether I can see them or not doesn't enter into it (except that the
ones no-one can see can get away with uglier visual appearance than the
others): and the `ugliness' I'm sensing isn't a surface-thing.  What my
prejudices are pinging off is (something I can't properly express, or I
wouldn't call it a prejudice, but it's) about the fact that we're
*saying things about* what interfaces an object supports, rather than
just leaving exceptions to get raised when those interfaces of it get
exercised.  As with large industrial plant, I can see how it may serve a
useful purpose ... but I'd far sooner see that purpose served some other
way, or find some way of dodging the need to serve that purpose.

Besides, various of the proposals I've seen since being so horribly
judgemental have swayed me towards a more ... restrained ... view of
type-checking.  I'm not keen on it, but maybe it's not as bad as my
first impressions.  However, trying to hide it so that I'll forget it's
there is *much* less welcome than confronting me with something I find

> This is one of the reasons I like this strategy: to comfort those that
> didn't want static types in Python code.
Don't bother.  I don't want comforted.  (Although, I confess, I
sometimes wish I had my teddy-bear, but don't tell the shrinks ...)

If there's going to be a mechanism for saying, in the source, which
variables have (and/or which expressions hold) which kinds of value:
    let it be
        * straightforward
        * general (or, in the first instance, straightforwardly
          extensible to full generality)
        * part of the source code

I'm *much* happier with Tim Peters' scheme, using typedecls, than with
any scheme involving my source living in a separate place from something
that will make a difference to how it gets compiled.

(Tim: the type Boolean is a (useful) synonym for PyObject.  It probably
includes some added semantics about how you should be trying to use it.)

(I'd even be happy with the typedecl incorporating the docstring, which
is part of the interface spec after all: and would make the run-time
thing actually called be lighter-weight in some probably-irrelevant
sense.)  Actually, there are two doc-strings in two places: one is the
doc-string of (say) the function object - it says what the function does
- the other is where some object carrying that function documents the
role of the attribute as which it stores that object.  This is directly
analogous to the two forms of type declaration: one describes an object,
regardless of any names we may be calling it, the other describes what
some namespace holds under some name.

OK, now for a *technical* reason in favour of same-sourcefile typedecls:
specifically, for the typedecl of a name to appear in the namespace to
which it is local:

  A typedecl's execution (c.f.: del) can lead to the namespace setting
  up, within its infrastructure (stuff like __dict__), the magic setattr
  hookery that can implement (possibly under the bonnet)
   * such enforcing of type-checking (on the names stipulated) as the
     namespace is prepared to bother with (and the typedecl requests).
   * whatever machinery distant code is meant to use to ask about the
     types of the attributes of the objects whose namespace this is.

and, incidentally, this `each namespace is responsible for managing
itself' mentality says that one can stipulate stuff *within* a function
which isn't ever going to be visible to the outside world (e.g. the
shadow file) - for instance, if a function contains code which defines
and returns a class which defines some method under a name controlled by
the arguments recieved by the function, how on earth is the shadow file
going to say anything at all about the return type of the function that
doesn't simply ignore the argument-dependent stuff ?  (OK, I know that
was hard to read, so a wilfully perverse example follows.)

def crazyIknow(methname):

    class lumpy (previously, defined, bases): pass

    def doit(self, kinky, key):
        return some(expression, involving, self, kinky, key, andmaybe, methname)

    setattr(lumpy, methname, doit)

    return lumpy

A declspec (or, indeed, type-assertion-for-values) scheme can say
something useful about all this, specifically what the type of doit is.
How would a shadow file cope ?

Work calls,