[swift-evolution] Will Swift ever support optional methods without @objc?

Shawn Erickson shawnce at gmail.com
Tue Nov 15 12:38:55 CST 2016


Using sub-protocols may be sufficient and make sense... to be honest I
haven't had the time to fully explore this space and convert some things I
have done in objective-c to pure swift. I do wonder how often that those
sub-protocols would degenerate into having single methods.

In a nut shell it isn't atypical for a delegate to only care about
"injecting itself" (e.g. implementing a delegate function) for a subset of
the available delegation points leaving the others unimplemented. In the
objective-c case the delegator can evaluate what delegation points a
delegate implements at time of delegate registration (or more dynamically
... however I often did imp caching for performance reasons in some of my
designs). This probe on delegate registration may make sense for the
delegator if additional bookkeeping, processing, state management, or
potentially whole code path/objects can be avoided if the delegate doesn't
implement a delegation point(s). If the delegation points happened to be
implemented using a default nop implementation this type of optimization
may not be possible.

In a nutshell I see and have the need for the delegator to know if the
delegate has actually provided an implementation of their own or not so I
can potentially leverage optimizations internal to my delegator. As a
delegate is also nice to know clearly what I have to implement or not and
the optional protocol member concept is one way of doing that, it would be
nice to have something like that to help delegate implementors.

I suggest mentally evaluating the delegation points of URLSession with the
perspective of the delegator (URLSession) being able to optimize what it
does based what it delegate has provided and implementation for. For
example the new metrics delegation point like could optimize away book
keeping and related processing if the delegate isn't interested.
Additionally look at it from the point of view of a delegate implementor
noting the despite already having some number of sub-protocols you still
often only implement one or two delegate points. Alternate swifty
implementations likely exist that would be interesting to explore to help
inform what makes sense as a language addition and/or help folks used to
"traditional" delegation pattern under Objective-C follow more Swifty
patterns going forward.

-Shawn

On Tue, Nov 15, 2016 at 9:24 AM Karl <razielim at gmail.com> wrote:

>
> On 15 Nov 2016, at 16:46, Shawn Erickson <shawnce at gmail.com> wrote:
>
> This has been discussed somewhat heavily in the past and nothing yet has
> really moved forward on it. I do think a good way of doing something like
> this would be helpful. I have resulted to defining an interface with an
> extension that provides empty defaults and for each function a match bool
> var exists to imply if it exists or not. The code accepting a delegate can
> probe these bool vars to configure itself to efficiently operate based on
> knowledge about what the delegate expects (some missing from most proposed
> solutions other then @objc optional).
> On Tue, Nov 15, 2016 at 6:59 AM Karl via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On 15 Nov 2016, at 12:22, Haravikk via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On 15 Nov 2016, at 07:53, Rick Mann via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On Nov 14, 2016, at 22:51 , Charlie Monroe via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> One major example is the NS/UITableViewDataSource or Delegate - there are
> many many methods that you don't need to implement, hence are optional.
>
> But I think that this was partially solved by default implementation of
> protocol methods, which pretty much does what you want...
>
>
> I just realized I only responded to someone else, and not the whole list.
> It does, but it forces me to make the return value of the protocol method
> optional, so that the default implementation can return nil.
>
> In the end, I guess that's not so bad, since I'm not happy with the entire
> approach, but it'll do for now.
>
>
> What's different about having the method return nil vs being optional?
> You're attempting to call it either way, and presumably need some means of
> handling the return value, except in Swift it's all nice and explicit and
> easy to put in a conditional like:
>
> if let result = myObject.someOptionalMethod() { /* Do some stuff */ }
> print(myObject.someOptionalStringMethod() ?? "")
>
> And so-on. If you need a method to be both optional, and return a nilable
> result then you can use a double optional like so:
>
> if let result = myObject.someDoubleOptionalMethod() { // Method was
> implemented
> if let value = result { // Method returned a value
> /* Do some stuff */
> }
> }
>
>
> By defining the methods as returning an Optional and throwing in default
> implementations you can specify fewer, bigger protocols and make clear what
> the requirements really are, though personally given the choice I'd prefer
> a dozen smaller protocols that are absolutely explicit in what they do.
>
> But yeah, I think the tools you need are all there already; maybe there's
> an argument to be made for allowing default return values on protocol
> methods, to reduce the boiler-plate?
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> I think there is a difference between:
>
> - A method which returns an optional result, and
> - An optional method which, if present, always returns a result
>
> Perhaps not so much of a difference at the usage site (it’s just a
> question of placing a ? for optional chaining), but semantically and when
> conforming to the protocol, they mean different things.
>
> - Karl
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> If you don’t mind me asking, what is your use-case?
>
> Even though I think "optional methods" and “methods returning optionals”
> are different things, I don’t really have any examples where optional
> methods are better than sub-protocols.
>
> e.g.
>
> ```
> // Core callbacks
> protocol MyDelegate { }
>
> // Optional callbacks, added like a mixin
> protocol MyDelegateWithExtras : MyDelegate { }
>
> // Some more optional callbacks
> protocol MySubDelegate : MyDelegate {}
>
> class DelegateImpl : MySubDelegate, MyDelegateWithExtras {
>   // Implement all core + optional callbacks
> }
>
> var d : MyDelegate = DelegateImpl()
>
> if let extras = d as? MyDelegateWithExtras {
>     // invoke optional functionality
> }
> ```
>
> I don’t know what the overhead of the as? call is, but it’s almost
> certainly less than an Obj-C `respondsToSelector` call. Depending on
> whether you need to swap the delegate for objects of different types, you
> could also use generics to optimise the checks (and possibly more) away.
>
> - Karl
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161115/b316e55d/attachment.html>


More information about the swift-evolution mailing list