[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