[swift-evolution] [Proposal draft #2] Naming Functions with Argument Labels

Wallacy wallacyf at gmail.com
Mon Jan 11 16:55:36 CST 2016


+1 from me as well! This version looks pretty good.

Em seg, 11 de jan de 2016 às 17:03, Douglas Gregor via swift-evolution <
swift-evolution at swift.org> escreveu:

> Hi all,
>
> I’ve updated and simplified my “Generalized Naming for Any Function”
> proposal to only deal with naming functions with argument labels, and
> dropping the back-ticks. Comments welcome! Proposal is here
>
>
> https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/0000-generalized-naming.md
>
> and inline:
>
> Naming Functions with Argument Labels
>
>    - Proposal: SE-NNNN
>    <https://github.com/apple/swift-evolution/blob/master/proposals/0000-generalized-naming.md>
>    - Author(s): Doug Gregor <https://github.com/DougGregor>
>    - Status: *Awaiting Review*
>    - Review manager: TBD
>
>
> <https://github.com/DougGregor/swift-evolution/tree/generalized-naming#introduction>
> Introduction
>
> Swift includes support for first-class functions, such that any function
> (or method) can be placed into a value of function type. However, when
> specifying the name of a function, one can only provide the base name,
> (e.g., insertSubview) without the argument labels. For overloaded
> functions, this means that one must disambiguate based on type information,
> which is awkward and verbose. This proposal allwos one
>
> it is not possible to specifically name every function that is part of a
> Swift program---one cannot provide the argument labels when naming a
> function, nor are property and subscript getters and setters referenceable.
> This proposal introduces a general syntax that allows one to name anything
> that is a function within Swift in an extensible manner.
>
> Swift-evolution thread: The first draft of this proposal was discussed
> here
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004555.html>.
> It included support for naming getters/setters (separately brought up by
> Michael Henson here
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/002168.html>,
> continued here
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002203.html>).
> Joe Groff convinced
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004579.html> me
> that lenses are a better approach for working with getters/setters, so I've
> dropped them from this version of the proposal.
>
> <https://github.com/DougGregor/swift-evolution/tree/generalized-naming#motivation>
> Motivation
>
> It's fairly common in Swift for multiple functions or methods to have the
> same "base name", but be distinguished by parameter labels. For example,
> UIView has three methods with the same base name insertSubview:
>
> extension UIView {
>   func insertSubview(view: UIView, at index: Int)
>   func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
>   func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
> }
>
> When calling these methods, the argument labels distinguish the different
> methods, e.g.,
>
> someView.insertSubview(view, at: 3)
> someView.insertSubview(view, aboveSubview: otherView)
> someView.insertSubview(view, belowSubview: otherView)
>
> However, when referencing the function to create a function value, one
> cannot provide the labels:
>
> let fn = someView.insertSubview // ambiguous: could be any of the three methods
>
> In some cases, it is possible to use type annotations to disambiguate:
>
> let fn: (UIView, Int) = someView.insertSubview    // ok: uses insertSubview(_:at:)let fn: (UIView, UIView) = someView.insertSubview // error: still ambiguous!
>
> To resolve the latter case, one must fall back to creating a closure:
>
> let fn: (UIView, UIView) = { view, otherView in
>   button.insertSubview(view, aboveSubview: otherView)
> }
>
> which is painfully tedious.
>
> One additional bit of motivation: Swift should probably get some way to
> ask for the Objective-C selector for a given method (rather than writing a
> string literal). The argument to such an operation would likely be a
> reference to a method, which would benefit from being able to name any
> method, including getters and setters.
>
> <https://github.com/DougGregor/swift-evolution/tree/generalized-naming#proposed-solution>Proposed
> solution
>
> I propose to extend function naming to allow compound Swift names (e.g.,
> insertSubview(_:aboveSubview:)) anywhere a name can occur. Specifically,
>
> let fn = someView.insertSubview(_:at:)let fn1 = someView.insertSubview(_:aboveSubview:)
>
> The same syntax can also refer to initializers, e.g.,
>
> let buttonFactory = UIButton.init(type:)
>
> The "produce the Objective-C selector for the given method" operation will
> be the subject of a separate proposal. However, here is one possibility
> that illustrations how it uses the proposed syntax here:
>
> let getter = Selector(NSDictionary.insertSubview(_:aboveSubview:)) // produces insertSubview:aboveSubview:.
>
>
> <https://github.com/DougGregor/swift-evolution/tree/generalized-naming#detailed-design>Detailed
> Design
>
> Grammatically, the *primary-expression* grammar will change from:
>
> primary-expression -> identifier generic-argument-clause[opt]
>
> to:
>
> primary-expression -> unqualified-name generic-argument-clause[opt]
>
> unqualified-name -> identifier
>                   | identifier '(' ((identifier | '_') ':')+ ')'
>
> Within the parentheses, the use of "+" is important, because it
> disambiguates:
>
> f()
>
> as a call to f rather than a reference to an f with no arguments.
> Zero-argument function references will still require disambiguation via
> contextual type information.
>
> <https://github.com/DougGregor/swift-evolution/tree/generalized-naming#impact-on-existing-code>Impact
> on existing code
>
> This is a purely additive feature that has no impact on existing code.
>
> <https://github.com/DougGregor/swift-evolution/tree/generalized-naming#alternatives-considered>Alternatives
> considered
>
>    -
>
>    Joe Groff notes
>    <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003008.html>
>     that *lenses* are a better solution than manually retrieving
>    getter/setter functions when the intent is to actually operate on the
>    properties.
>    -
>
>    Bartlomiej Cichosz suggests
>    <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004739.html> a
>    general partial application syntax using _ as a placeholder, e.g.,
>
>    aGameView.insertSubview(_, aboveSubview: playingSurfaceView)
>
>    When all arguments are _, this provides the ability to name any method:
>
>    aGameView.insertSubview(_, aboveSubview: _)
>
>    I decided not to go with this because I don't believe we need such a
>    general partial application syntax in Swift. Closures using the $ names are
>    nearly as concise, and eliminate any questions about how the _ placeholder
>    maps to an argument of the partially-applied function:
>
>    { aGameView.insertSubview($0, aboveSubview: playingSurfaceView) }
>
>
>
>
>
>
> - Doug
>
> _______________________________________________
> 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/20160111/cfe6ba82/attachment.html>


More information about the swift-evolution mailing list