<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Dec 19, 2014 at 11:59 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On Fri, Dec 19, 2014 at 04:55:37PM -0800, Guido van Rossum wrote:<br>
</span><span class="">> A few months ago we had a long discussion about type hinting. I've thought<br>
> a lot more about this. I've written up what I think is a decent "theory"<br>
> document -- writing it down like this certainly helped *me* get a lot of<br>
> clarity about some of the important issues.<br>
><br>
> <a href="https://quip.com/r69HA9GhGa7J" target="_blank">https://quip.com/r69HA9GhGa7J</a><br>
<br>
</span>Very interesting indeed.<br>
<br>
Some questions, which you may not have answers to yet :-)<br>
<br>
(1) Under "General rules", you state "No type can be subclassed unless<br>
stated." That's not completely clear to me. I presume you are talking<br>
about the special types like Union, Generic, Sequence, Tuple, Any etc.<br>
Is that correct?<br></blockquote><div><br></div><div>Yes. (Having to answer this  is the price I pay for attempting brevity.)<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
(2) Under "Types", you give an example Tuple[t1, t2, ...], a tuple<br>
whose items are instances of t1 etc. To be more concrete, a declaration<br>
of Tuple[int, float, str] will mean "a tuple with exactly three items,<br>
the first item must be an int, the second item must be a float, the<br>
third item must be a string." Correct?<br></blockquote><div><br></div><div>Yes. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
(3) But there's no way of declaring "a tuple of any length, which each<br>
item is of type t". We can declare it as Sequence[t], but cannot specify<br>
that it must be a tuple, not a list. Example:<br>
<br>
class MyStr(str):<br>
    def startswith(self, prefix:Union[str, ???])->bool:<br>
        pass<br>
<br>
There's nothing I can use instead of ??? to capture the current<br>
behaviour of str.startswith. Correct?<br></blockquote><div><br></div><div>Yes, though there's a proposal to let you write Union[str, Tuple[str, ...]] -- the ... are literally that (i.e. Ellipsis). <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
(4) Under "Pragmatics", you say "Don't use dynamic type expressions; use<br>
builtins and imported types only. No 'if'." What's the reason for this<br>
rule? Will it be enforced by the compiler?<br></blockquote><div><br></div><div>No, but it will get you on the static checker's nasty list. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
(5) I presume (4) above also applies to things like this:<br>
<br>
    if condition():<br>
        X = Var('X', str)<br>
    else:<br>
        X = Var('X', bytes)<br>
<br>
    # Later on<br>
    def spam(arg: X)-> X:<br>
        ...<br></blockquote><div><br></div><div>Yes. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
How about this?<br>
<br>
    try:<br>
        from condition_is_true import X  # str<br>
    except ImportError:<br>
        from condition_is_false import X  # bytes<br></blockquote><div><br></div><div>Probably also. In mypy there is limited support for a few specific tests, IIRC it has PY3 and PY2 conditions built in. In any case this is all just to make the static checker's life easier (since it won't know whether the condition is true or false at runtime).<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
(6) Under "Generic types", you have:<br>
<br>
    X = Var('X'). Declares a unique type variable.<br>
    The name must match the variable name.<br>
<br>
To be clear, X is a type used only for declarations, right? By (1)<br>
above, it cannot be instantiated? But doesn't that make it impossible to<br>
satisfy the declaration? I must be misunderstanding something.<br></blockquote><div><br></div><div>It's in support of generic types. Read up on them in the mypy docs about generics. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
I imagine the declaration X = Var("X") to be something equivalent to:<br>
<br>
    class X(type):<br>
        pass<br>
<br>
except that X cannot be instantiated.<br></blockquote><div><br></div><div>No. See above. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
(7) You have an example:<br>
<br>
    AnyStr = Var('AnyStr', str, bytes)<br>
    def longest(a: AnyStr, b: AnyStr) -> AnyStr:<br>
<br>
<br>
Would this be an acceptable syntax?<br>
<br>
    def longest(a:str|bytes, b:str|bytes) -> str|bytes<br>
<br>
It seems a shame to have to invent a name for something you might only<br>
use once or twice.<br clear="all"></blockquote><div><br></div><div>That was proposed and rejected (though for Union, which is slightly different) because it would require changes to the builtin types to support that operator at runtime.<br><br></div><div>Please do read up on generic types in mypy. <a href="http://mypy.readthedocs.org/en/latest/generics.html">http://mypy.readthedocs.org/en/latest/generics.html</a><br></div></div><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>
</div></div>