<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Apr 13, 2018 at 7:36 AM, Nick Coghlan <span dir="ltr"><<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 13 April 2018 at 22:35, Chris Angelico <<a href="mailto:rosuav@gmail.com">rosuav@gmail.com</a>> wrote:<br>
> The 'as' syntax already has that going for it. What's the advantage of<br>
> the arrow over the two front-runners, ':=' and 'as'?<br>
<br>
</span>I stumbled across<br>
<a href="https://www.hillelwayne.com/post/equals-as-assignment/" rel="noreferrer" target="_blank">https://www.hillelwayne.com/<wbr>post/equals-as-assignment/</a> earlier this<br>
week, and I think it provides grounds to reconsider the suitability of<br>
":=", as that symbol has historically referred to *re*binding an<br>
already declared name. That isn't the way we're proposing to use it<br>
here: we're using it to mean both implicit local variable declaration<br>
*and* rebinding of an existing name, the same as we do for "=" and<br>
"as".<br></blockquote><div><br></div><div>I've not done much research about this topic, but I lived through it (my first languages were Algol-60 And Fortran=IV, in 1974, soon followed by Pascal and Algol-68) and I think that blog post is overly biased by one particular thread of C's ancestry. CPL, BCPL and B were bit players in the world of languages (I suspect mostly focused on Bell Labs and/or MIT, at least US east coast). I should probably blog about my own view of this history, but basically I don't believe that the distinction between initialization and re-assignment is the big decider here. Python historically doesn't care, all its assignments work like dict[key] = value (with a slight exception for the analyses related to local scopes and closures).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think the "we already use colons in too many unrelated places"<br>
argument also has merit, as we already use the colon as:<br>
<br>
1. the header terminator when introducing a nested suite<br>
2. the key:value separator in dictionary displays and comprehensions<br>
3. the name:annotation separator in function parameter declarations<br>
4. the name:annotation separator in variable declarations and<br>
assignment statements<br>
5. the parameter:result separator in lambda expressions<br>
6. the start:stop:step separator in slice syntax<br></blockquote><div><br></div><div>But := is not a colon -- it's a new symbol spelled as two characters. The lexer returns it as a single symbol, like it does != and ==. And we're lucky in the sense that no expression or statement can start with =, so there is no context where : = and := would both be legal.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
"as" is at least more consistently associated with name binding, and<br>
has fewer existing uses in the first place, but has the notable<br>
downside of being thoroughly misleading in with statement header<br>
lines, as well as being *so* syntactically unobtrusive that it's easy<br>
to miss entirely (especially in expressions that use other keywords).<br></blockquote><div><br></div><div>Right -- 'as' signals that there's something funky happening to its left argument before the assignment is made.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The symbolic "right arrow" operator would be a more direct alternative<br>
to the "as" variant that was more visually distinct:<br>
<span class=""><br>
    # Handle a matched regex<br>
</span>    if (pattern.search(data) -> match) is not None:<br>
        ...<br>
<br>
    # More flexible alternative to the 2-arg form of iter() invocation<br>
    while (read_next_item() -> item) is not None:<br>
<span class="">        ...<br>
<br>
    # Share a subexpression between a comprehension filter clause and its output<br>
</span>    filtered_data = [y for x in data if (f(x) -> y) is not None]<br>
<br>
    # Visually and syntactically unambigous in with statement headers<br>
    with create_cm() -> cm as enter_result:<br>
        ...<br>
<br>
(Pronunciation-wise, if we went with that option, I'd probably<br>
pronounce "->" as "as" most of the time, but there are some cases like<br>
the "while" example above where I'd pronounce it as "into")<br>
<br>
The connection with function declarations would be a little tenuous,<br>
but could be rationalised as:<br>
<br>
Given the function declation:<br>
<br>
    def f(...) -> Annotation:<br>
        ...<br>
<br>
Then in the named subexpression:<br>
<br>
    (f(...) -> name)<br>
<br>
the inferred type of "name" is "Annotation"<span class="im HOEnZb"></span><br></blockquote></div><br></div><div class="gmail_extra">I am not excited about (expr -> var) at all, because the existing use of -> in annotations is so entirely different.<br clear="all"></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div></div>