<div>I like the first option, concatenate(parameters:)</div><div><br></div><div>It may not have issues conflicting if "parameters" was renamed to something which is an invalid label, this would also make it clearer that it's doing something special. For example:</div><div> concatenate(#parameters: tuple)</div><div><br></div><div>It may be that it can also distinguish different labels if the label is stored as part of the type information. If I remember correctly there is a bug which would allow this when fixed.</div><div><br></div><div>For example:</div><div> concatenate(#parameters: (123, with: "string"))</div><div><br></div><div>I'm fairly sure this should be sufficient, even in generics, the tuple just needs to have the labels.</div><div><br></div><div>It may also be nice to allow unlabelled tuples if the function is unambiguous.</div><div><br></div>The thread on tuples combining operators was probably this one:<div><h2 style="text-align:start;margin:0px 0px 20px;padding:0px"><font size="2"><span style="background-color:rgba(255,255,255,0)">Tuple conversion and type composition</span></font></h2></div><div><a href="http://comments.gmane.org/gmane.comp.lang.swift.evolution/5334" target="_blank">http://comments.gmane.org/gmane.comp.lang.swift.evolution/5334</a><br><br>On Thursday, 11 February 2016, Brent Royal-Gordon via swift-evolution <<a href="javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');" target="_blank">swift-evolution@swift.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> I'm curious what the type signature of the splat operator would be?<br>
<br>
None of the options I present actually involves a standalone operator; even 3 is a magic syntax which happens to look like an operator. That's why you can use the splat without specifying a tuple to get a tuple-taking version of the function.<br>
<br>
I *did* consider adding a fourth option, that of annotating parameters as converting n-ary functions to tuple-taking equivalents, but I didn't feel like I had a good enough idea of how that would work to really suggest it. Roughly, an `apply(_:to:)` function would look something like this:<br>
<br>
func apply<In, Out>(function: @splatting In -> Out, to params: In) -> Out {<br>
// `function` is of type `In -> Out`, where In is a tuple containing the types<br>
// of the parameters of the function that was passed. Essentially, the generic system<br>
// implicitly wraps the function in a trampoline that takes a tuple of compatible arguments.<br>
return function(params)<br>
}<br>
<br>
But this starts getting deep into type checker and generic system territory, which I don't understand well enough to feel comfortable proposing.<br>
<br>
> If it can't, I have a strong preference against the options (#1 & #2) that look like normal function call syntax. Because you won't be able to do several things that you're accustomed to with functions: assign them to variables, store them in containers, pass them as parameters to other functions.<br>
<br>
I think this feature has to be able to make a first-class, tuple-taking closure, and all three alternatives I presented are intended to do that. That's what the second example for each syntax (the one where I map it over an array of tuples) is meant to show.<br>
<br>
> This is less of a problem with explicit language syntax, because you could have a rule in the typechecker that says "If the expression being splatted is a tuple of type (A, B, x: C), then it must be applied to a function of type (A, B, C) -> Ret, with the result type of the call being Ret." I think you can also get around many of the type inference pitfalls as well, because in most cases the types of the function and tuple are unlikely to need inferring (occasionally this will require explicit type annotations on tuple components, but it seems like most of the time they will have already been inferred when the tuple was declared).<br>
<br>
As long as the splatting is explicit—that is, the parser can tell whether you're making a normal call or a tuple call—I don't think the overload resolution on a splatted version of a function is any more difficult than the non-splatted version. Possibly even easier, depending on how we handle default arguments.<br>
<br>
> And it's much easier to do "partial splat" operations, where, for example, you may want to pass the first couple arguments of a function explicitly but splat the rest.<br>
<br>
I haven't really considered how to do this kind of thing, but I think it's probably better represented by constructing a single tuple containing all of the arguments. I believe there was another thread recently that discussed tuple combining operators.<br>
<br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a>swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>