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

Joe Groff jgroff at apple.com
Wed Jan 20 11:49:04 CST 2016


> On Jan 20, 2016, at 8:57 AM, Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
> 
>> 
>> On Jan 19, 2016, at 20:35 , John McCall via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> On Jan 19, 2016, at 7:20 PM, Paul Cantrell via swift-evolution <swift-evolution at swift.org <mailto: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.
>> 
>> It’s dumber than that.  The type-checker assumes that the closure has a tuple of arguments ($0, $1, …, $N), where $N is the largest N seen in the closure.  Thus, a two-argument closure falls down if you ignore the second argument.  It’s dumb, and we’ve known about it for a long time; and yet it’s been remarkably annoying to fix, and so we haven’t yet.
>> 
>> Anyway, it’s a bug and doesn’t need to go through evolution.
> 
> I wouldn't go as far as to say it's a bug. It's known and occasionally useful for forwarding arguments. (For a while I had it as a fix-it for doing function representation conversions.)
> 
> I agree that having it always be the first argument is less surprising and probably more generally useful, though.

In the spirit of the Great Argument Simplification to distinguish arguments from tuples, we probably ought to introduce a separate '$*'-like sigil to bind "all arguments" distinct from $0.

-Joe

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


More information about the swift-evolution mailing list