> On 5 Jan 2017, at 02:25, Jay Abbott via swift-evolution 
> <[email protected]> wrote:
> 
> When you have a function with a closure and then another optional default = 
> nil closure at the end, like this:
> 
> open static func animate(identifier: String,
>                          duration: Double,
>                          update: @escaping AnimationUpdate,
>                          completion: AnimationCompletion? = nil) {
> You can’t use trailing closure syntax for the update argument when leaving 
> the completion argument out/default.
> 
> This kind of breaks one of the benefits of default arguments, which is that 
> you can add them to existing released functions without breaking the calling 
> code. This means you have to add a separate convenience function without the 
> extra argument, which is annoying and inelegant. Another annoying thing is 
> that you can easily miss this error if you happen to not use trailing closure 
> syntax in your tests or other usage, because adding the extra default 
> argument compiles fine for code that uses normal syntax.
> 
> Are there any issues/gotchas if the trailing closure syntax were to work for 
> the last specified argument rather than the last defined argument?
> 

I'm not sure I'd call having another convenience function "annoying and 
inelegant" personally, as that's kind of the whole point of them, but yes I do 
agree in this case it could be handled more easily.

Personally I like the idea of having a new @trailing attribute to allow any 
closure to be specified as the trailing closure, regardless of placement, as 
this would also be useful for methods where you may accept multiple closures, 
but where it may make the most logical sense to have say a main body closure as 
the first parameter, yet it also makes most sense to be the trailing closure, 
which becomes awkward.

I'm not in favour at all of allowing multiple trailing closures as someone 
mentioned, I think one is enough (and even then, I only really like them 
personally for language-construct like methods such as .forEach and similar).


However, I think the real issue in this specific example is that the 
function/method is being modified after its initial definition, and I wonder if 
this falls into the ability to reorder arguments? Since most Swift methods and 
functions have argument labels it doesn't necessarily matter if they are given 
in a different order as they are still well-defined; thing is, I think Swift 
actually had this ability and no-one was using it so I don't know if 
reintroducing it would be the right fix, unless perhaps it is done as an 
attribute of the function/method?

For example:

@reorderable
static func animate(identifier: String, duration: String, update: @escaping 
AnimationUpdate, completion: AnimationCompletion? = nil) { … }

With this attribute the order of the parameters is no-longer fixed, but as 
update is still the last closure it is considered to be the trailing closure? A 
@trailing attribute would still be useful in this case though as it's possible 
the new parameter(s) might include a new closure, and you wouldn't want it to 
suddenly become the new trailing closure.

Also, can't test right now, but can you not add your new completion parameter 
before the update closure? This should still satisfy existing calls to the 
method while allowing others to optionally set the completion parameter?


Finally, one other interesting thought, but could we simply allow trailing 
closures to be any closure the developer hasn't defined? For example:

        function myFunc(body:() -> Void, loop: () -> Bool) { … }
        myFunc(loop: myLoopClosure) { /* this is the body */ }
        myFunc(body: myBodyClosure) { /* this is the loop closure */ }

Perhaps that's a bit too confusing and should be activated with an attribute, 
but it should be possible to allow this as in both calls above the closure that 
is trailing is unambiguous.


Just my thoughts on all possible solutions I can think of ;)
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to