<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>On Jan 18, 2015, at 7:32, Yann Kaiser <<a href="mailto:kaiser.yann@gmail.com">kaiser.yann@gmail.com</a>> wrote:</div><div><br></div><blockquote type="cite"><div><div class="gmail_quote">On Sun Jan 18 2015 at 3:16:47 PM Chris Angelico <<a href="mailto:rosuav@gmail.com">rosuav@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Mon, Jan 19, 2015 at 12:37 AM, Cem Karan <<a href="mailto:cfkaran2@gmail.com" target="_blank">cfkaran2@gmail.com</a>> wrote:<br>
> There may be other uses of annotations that programmers haven't yet thought of, simply because they don't know that annotations exist. Locking out those uses would suck.<br>
<br>
I see a lot of vague "but what if there's something else", and not a<br>
lot of concrete "here's a use of annotations that would be locked<br>
out". Does anyone actually have another use case that would be<br>
seriously harmed by this kind of conflict?</blockquote><div><br></div><div><div style="font-size:13.1999998092651px;line-height:19.7999992370605px">I use annotations in clize, a CLI argument parser, to specify how functions parameters should translate to CLI parameters. This can range from specifying coercion functions/callables for the argument values(ie. int), which could easily be mixed up with typing information as specified here, to specifying aliases for named parameters, marking parameters as undocumented, or simply overriding the translation process altogether for that parameter.</div></div></div></div></blockquote><div><br></div><div>And I can't imagine that you'd ever want to use static types and clize annotations on the same function, given that the whole point of clize is that the functions will be called dynamically by some dispatcher with arguments from the command line.</div><div><br></div><div>So, this is a perfect example for why we need a way to mark a function as "these annotations don't mean types". Which is already part of the PEP.</div><div><br></div><div>(It's also, maybe not coincidentally, another example of the fact that most existing uses of annotations that aren't types are "type-like"--e.g., C types, conversion functions, etc.)</div><div><br></div><div>But it's not an example for why we need to mix two kinds of annotations in the same function, or where it would be unclear which annotations you're using, which is what Chris was asking for.</div><br><blockquote type="cite"><div><div class="gmail_quote"><div><div style="font-size:13.1999998092651px;line-height:19.7999992370605px">Now I could simply instruct users to never use annotations and always use a decorator instead (in fact, I recommend it when Python 2.x compatibility is wished) and have that decorator dump this information elsewhere than in f.__annotations__, but that begs the question of why it isn't as worthy of benefiting from annotation syntax[1] as type-checking. If anything, this is a use of annotations at run-time versus a use at dev-time in an offline fashion.</div></div></div></div></blockquote><div><br></div><div>The obvious answer is to tell users to decorate their CLI functions with @no_type_check, or just not type-check scripts made up of clize functions.</div><div><br></div><div>I'm willing to bet, without searching, that clize already uses a decorator for cli functions. This implies a possible useful extension to the PEP: a way to declare decorators as implying no_type_check. Then your users wouldn't have to do anything; you'd just declare @clize as meaning no type checking, and their existing code would be type-checkable with no changes.</div><div><br></div><blockquote type="cite"><div><div class="gmail_quote"><div><div style="font-size:13.1999998092651px;line-height:19.7999992370605px">I also find it a bit hasty to proclaim no one has found other viable uses for annotations when Python 3 adoption and thus liberty to use annotations still remains poor.</div></div></div></div></blockquote><div><br></div><div>This is an argument for not evolving Python 3 at all until everyone switches. And it's not a very good argument, because the only reason for anyone to switch to Python 3 is that it's evolved features that they want.</div><div><br></div><div>It's also neglecting the fact that Python 3 adoption really isn't that poor. In 2012, many libraries still didn't work in 3.x, any novice question on StackOverflow could be safely assumed to be 2.x-specific, and 2.7 was the obvious and most popular choice for new projects. In 2015, none of that is true anymore. Someone who primarily works on existing applications may not see that, because for an existing application, the cost of moving to 3.x is higher and the benefit lower (you can't design your app to take advantage of new features when it's already designed). But then someone who primarily works on existing applications also has less useful input into the way the language should change.</div><div><br></div><div>Cem made this even more explicit by bringing up C11: if some code can't assume 2011 for C, no code should assume 2010 for Python. That's ridiculous. C is one of the most stable and conservative languages that people are still using. It also tends to take years for new C features to make it into implementations, because of the way C is designed (a committee works out a definition down to the smallest details, votes on it, publishes it, and then compilers implement it), whereas in Python--as with most other languages--it takes a single release cycle (under 18 months) for every new feature to make it into the implementation(s) that 90% of people are using.</div><div><br></div><div>A better comparison would be Java 7, ECMAScript 5, or Ruby 1.9. These were all relatively big changes to their languages that happened within a year of Python 3. And nobody would say you can't judge the new features in those languages yet.</div><br><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Remember, you can simply<br>
not use type hints for the function(s) that use other annotations; the<br>
conflict is only if you're trying to use both on the same function.<br></blockquote><div><br></div><div><div style="font-size:13.1999998092651px;line-height:19.7999992370605px"><div class="F3hlO"><div class="gmail_quote"><div>If typing is to become the default interpretation of annotations, I fear that this will really just turn into "WTF, your annotations aren't type info, fix it", especially given the recursive nature of those checks.</div></div></div></div></div></div></blockquote><div><br></div><div>Why do you fear that? Default just means default. Escape mechanisms that are only meant to be used in rare cases are usually hidden away and ugly; those that are simple and obvious are meant to be used. (At least in Python; not every language is as nice...)</div><br><blockquote type="cite"><div class="gmail_quote"><div><div style="font-size:13.1999998092651px;line-height:19.7999992370605px"><div class="F3hlO"><div class="gmail_quote"><div>Why can't it be explicit that a function's annotations are type info that should be checked? </div></div></div></div></div></div></blockquote><div><br></div><div>Because it's the less common uses that should be explicitly marked. There's cognitive value in marking something uncommon and none in marking something common. Think of how much boilerplate you're suggesting be added to 80% of code, all for the benefit of saving (at most) the same amount of boilerplate for 20%.</div><div><br></div></body></html>