[swift-evolution] Disallow arbitrary expressions in selectors
David Rönnqvist
david.ronnqvist at gmail.com
Fri Apr 29 11:19:26 CDT 2016
I noticed in our code that we had one occurrence of
#selector(SomeClass().someFunction)
which to my eyes looked like a bug.
Disallowing arbitrary expressions looks very reasonable to me and would help catch small mistakes like this one.
> 29 apr. 2016 kl. 16:40 skrev Thorsten Seitz via swift-evolution <swift-evolution at swift.org>:
>
> Looks good to me!
>
> -Thorsten
>
>> Am 28.04.2016 um 16:56 schrieb Alex Hoppen via swift-evolution <swift-evolution at swift.org>:
>>
>> During the implementation of SE-0064 (Referencing Objective-C selector of property getters and setters) I have come across an issue that could be resolved my a minor change to the language and simplify the compiler a lot. I have drafted a proposal below.
>>
>> Thoughts, comments, especially objections, appreciated.
>>
>> – Alex
>>
>> GitHub-Link: https://github.com/ahoppen/swift-evolution/blob/arbitrary-expressions-in-selectors/proposals/0000-arbitrary-expressions-in-selectors.md
>>
>> Disallow arbitrary expressions in selectors
>> Proposal: SE-NNNN
>> Author(s): Alex Hoppen
>> Status: Draft
>> Review manager: TBD
>> Introduction
>> It is currently possible to write arbitrary expressions inside #selector like the following: #selector(callThisFunc().bar). This complicates the implementation of proposals SE-0064 (Referencing Objective-C selector of property getters and setters) and SE-0062 (Referencing Objective-C key-paths) a lot.
>>
>> This proposal restricts expressions inside selectors to be a sequence of property or method refernces. I believe this will not be a major restrictions since arbitrary expressions in selectors are probably rarely used, have some rough edges and removing them would simplify the compiler.
>>
>> Proposed solution
>> I propose allowed expressions inside #selector (and once implemented #keyPath) to be a series of instance or class members separated by . and allow disambiguating the last component using as.
>>
>> Detailed design
>> Examples
>>
>> class Address: NSObject {
>> dynamic var street: String
>> dynamic var town: String
>>
>> init(street: String, town: String) {
>> self.street = street
>> self.town = town
>> }
>> }
>>
>> class Person: NSObject {
>> dynamic var name: String
>> dynamic var homeAddress: Address
>>
>> func workAddress() -> Address {
>> // ...
>> }
>>
>> func workAddress(formatter: AddressFormatter) -> String {
>> // ...
>> }
>>
>> init(name: String, homeAddress: Address) {
>> self.name = name
>> self.homeAddress = homeAddress
>> }
>> }
>>
>> let me: Person = ...
>> The following examples will continue to work:
>>
>> let _ = #selector(getter: Person.name)
>> let _ = #selector(getter: me.name)
>>
>> let _ = #selector(getter: Person.homeAddress.street)
>> // Could also be written as
>> let _ = #selector(getter: Address.street)
>>
>> let _ = #selector(Person.workAddress as () -> Address)
>> let _ = #selector(Person.workAddress(formatter: ))
>> I propose removing this kind of selector:
>>
>> // Should produce selector "street". Note that the method workAddress() is never
>> // called and its return type only used during type checking
>> let _ = #selector(getter: me.workAddress().street)
>>
>> // The above can be rewritten in a cleaner way like the following
>> let _ = #selector(getter: Address.street)
>> The proposed way to rewrite the selector elimininates potential confusion about the fact that calling a method inside #selector actually doesn't invoke it.
>>
>> Grammar
>>
>> selector → #selector(selector-modiferopt selector-path)
>>
>> selector-modifier → getter:
>> selector-modifier → setter:
>>
>> selector-path → type-identifier . selector-member-path as-disambiguationopt
>> selector-path → selector-member-path as-disambiguationopt
>>
>> selector-member-path → identifier
>> selector-member-path → unqualified-name
>> selector-member-path → identifier . selector-member-path
>>
>> as-disambiguation → as type-identifier
>> For a further rationale on why arbitrary expressions are no longer possible, see the discussion on bugs.swift.org.
>>
>> Impact on existing code
>> Code that currently uses this feature needs to be rewritten as described in the example above. I believe, however, that the feature is rarely used so it will affect only very little source code and where it is currently used the proposed update is actually more readable.
>>
>> Alternatives considered
>> The only alternative I see is trying to keep the current semantics and implement them for the getter:/setter: selectors.
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> 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/20160429/7acceb85/attachment-0001.html>
More information about the swift-evolution
mailing list