[swift-evolution] Proposal: Make $0 always refer to a closure’s first argument

davesweeris at mac.com davesweeris at mac.com
Wed Jan 27 14:20:07 CST 2016


> On Jan 27, 2016, at 10:09, Chris Lattner via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I’m sorry, I’ve lost context on what the proposal here is.  Can you please restate it?  To me, it seems most natural that $0 always refer to the first parameter of a closure.
> 
> -Chris


Paul Cantrell’s original post documented behavior which causes $0 to sometimes refer to a tuple of all the arguments instead of the just first argument. John McCall said it was bug, but then Jordan Rose replied and said, ”I wouldn’t go as far as to say it’s a bug. It’s known and occasionally useful for forwarding arguments". My understanding is that everyone agrees on two things: the bug should eventually be fixed, and the bug’s functionality is actually kinda cool (when it’s not biting you) and there should still be a way to invoke it. The debate was over whether to do it now and make $*, $_, $$, $…, or $# (I think that’s all of them) be the “all args” tuple, or whether we should wait fix it until Swift gets “a more complete revision of the varargs system” (which was assumed to be at least Swift 4).

At least that’s how I understand it. Here’s Paul’s original post:

- Dave Sweeris

> On Jan 19, 2016, at 19:20, Paul Cantrell via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Surprisingly, this code does not compile:
> 
>     func foo(val: Int) { }
> 
>     func bar(closure: (Int,Int) -> Void) {
>         closure(0, 1)
>     }
> 
>     bar { foo($0) }       // compiler error
>     bar { foo($1) }       // just dandy
>     bar { foo($0 + $1) }  // also works
> 
> The compiler error is:
> 
>     Cannot convert value of type (Int, Int) to expected argument type Int
> 
> It appears that the meaning of $0 is overloaded: it can refer either to the tuple of all arguments, or to just the first argument. The presence of another placeholder variable ($1 in the third example) seems to trigger the latter behavior.
> 
> This is certainly confusing. I’m posting to the list after receiving two Siesta user questions in the same day that both boil down to this issue.
> 
> Even if you do understand the behavior, it’s a real nuisance: it prevents concise implementation of a multi-arg closure which wants to ignore all but its first argument. Instead, such a closure has to drop back to the more verbose syntax:
> 
>     bar { a, _ in foo(a) }   // sigh
> 
> …or use this legibility-proof workaround:
> 
>     bar { foo($0.0) }   // yuck! wat?!
> 
> (Note that this problem exists only for the first argument; a closure that wants to ignore all but the second has no such problem.)
> 
> This behavior contradicts the Swift documentation, which clearly says that $0 refers to the first argument:
> 
>> Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.
> 
> And:
> 
>> A closure may omit names for its parameters. Its parameters are then implicitly named $ followed by their position: $0, $1, $2, and so on.
> 
> 
> I can’t find anything in the docs that mentions this “all args tuple” behavior, so perhaps it’s a bug? Let me know if it is, and I’ll just file a bug report for it.
> 
> However the “whole tuple” behavior does seem to be intentional, and preserving that while fixing the problem above appears to require a language change. Thus…
> 
> Proposal
> 
> The implicit closure variable $0 should always refer to the closure’s first argument, and a different implicit name — perhaps $* or $_ or $... — should refer to the all-args tuple.
> 
> Thoughts?
> 
> Cheers,
> 
> Paul
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160127/d547cf1f/attachment-0001.html>


More information about the swift-evolution mailing list