[Types-sig] Type annotations

Tim Peters tim_one@email.msn.com
Fri, 17 Dec 1999 05:05:07 -0500


I'm burned out on SIG msgs for tonight, so one quickie:

[Paul]
> ...
> Here are some Haskell-ish syntax ideas for type declarations:
>
> First we need to be able to talk about types. We need a "type
> expression" which evalutates to a type.
>
> Rough Grammar:
>
> Type : Type ['|' Type] # allow unions
> Unit : dotted_name | Parameterized | Function | Tuple | List | Dict
> Parameterized : dotted_name '(' Basic (',' Basic)* ')'
> Basic : dotted_name | PythonLiteral | "*" # * means anything.
> PythonLiteral : atom
> Function : Type '->' Type
> Tuple : "(" Type ("," Type )* )
> List: "[" Type "]"
> Dict: "{" Type ":" Type "}"

The Function defn above is appropriate for Haskell because all functions
there are curried (exactly one argument).  The LHS should be different in
Python, because we have multiple-argument functions, and some arglist
gimmicks Haskell doesn't have.  In my examples I've been using

Function : 'def' '(' arglist ')' '->' Type

I think that's what's required.  With the "def" it's obvious.  Without the
"def" it's too easy to mistake the parenthesized arglist for a tuple of some
sort (yes, the '->' later disambiguates it, but unbounded lookahead isn't
machine- or human-friendly).  An explict def also allows the variant

Function : 'def' '(' arglist ')'

for functions that don't return results.

The "*" and "**" elements of arglists need also to be addressed.

BTW, there appear to be two holes in Tuple:  the empty tuple, and a tuple
with unknown length.  Shivery as it is, I expect we have to follow Python in
this regard, and say

   (T)

is a tuple-of-T of arbitrary length, while

   (T,)

is a tuple containing one T.

> ...
> maptype(intype, outtype) =
>     (( intype -> outtype ), List( intype )) -> List( outtype )

Don't the parens around (intype->outtype) say that it's a tuple containing a
function?

BTW, Python's actual "map" function is quite a puzzle to describe!  I can't
do it:

    map: def(def(_A)->_B, Seq(_A) -> [_B] |
         def(def(_A, _B)->_C, Seq(_A), Seq(_B)) -> [_C] | ...

is just the start of an unbounded sequence of legit map signatures.  Haskell
avoids the difficulty here thanks to currying.

> ...
> Interfaces look like Python classes but they use an "interface"
> keyword.

Weren't we leaving interfaces to JimF <wink>?

too-late-now-ly y'rs  - tim