[swift-evolution] [Discussion] Modernizing Attribute Case and Attribute Argument Naming

Joshua Kopin jkopin at apple.com
Wed Feb 24 18:26:01 CST 2016


+1

Jacob, I think your proposal is on point. Although I know this is 
probably outside the scope of what Erica would like to propose, I think 
it's important to point out that the custom attributes you called out 
arguably are so different semantically from the other attributes that 
they deserve their own syntactic treatment. Since the following analysis 
might affect the naming discussion, I'll put this out there now and see 
how it lands.

It seems to me that there are two broad categories of attributes, each 
of which wants its own level of syntactic optimization:

- General Swift Attributes - use should be optimized
    - Semantic Modifiers
       - **@autoclosure** / **@autoclosure(escaping)** - modifies 
expression semantics at call site
       - **@convention(**...**)** - modifies declared function's calling 
convention
       - **@testable** - modifies declaration's visibility
       - **@noescape** - modifies closure capture semantics, closure 
declaration syntax, escape analysis
       - **@noreturn** - modifies control flow analysis
       - **@objc** / **@objc(**...**)** / **@nonobjc** - modifies 
calling convention, class synthesis
       - **@NSCopying** - modifies property storage and semantics
   - Warning and Error Generation Modifiers
       - **@available(**<expression in the availability DSL>**)**
       - **@warn_unused_result**
       - **@warn_unused_result(message=**...**)**
       - **@warn_unused_result(mutable_variant=**...**)**

- Specific Attributes - use should not be optimized
    - Semantic Modifiers
       - **@UIApplicationMain** / **@NSApplicationMain** - specific to 
UIKit/AppKit
       - **@NSManaged** - specific to CoreData
    - Xcode Semantic Modifiers
       - **@IBAction**
       - **@IBDesignable**
       - **@IBInspectable**
       - **@IBOutlet**

(To be fair, @objc, @nonobjc, and @NSCopying are all tied to the 
Objective-C runtime and/or Foundation pretty closely and could arguably 
be considered framework-specific.)

As a first stab, how about something along the lines of the following?

- General Swift Attributes
    - Semantic Modifiers
       - **@autoclosure** / **@autoclosure(escaping)**
       - **@convention(**...**)**
       - **@testable**
       - **@noescape**
       - **@noreturn**
       - **@objc** / **@objc(**...**)** / **@nonbjc**
       - **@copy**
   - Warning and Error Generation Modifiers
       - **@available(**<expression in the availability DSL>**)**
       - **@warning(**<expression in a new warning DSL>**)**
          - **@warning(unusedResult)**
          - **@warning(unusedResult, message=**...**)**
          - **@warning(unusedResult, mutableVariant=**...**)**

- Specific Attributes (syntax subject to bikeshedding)
    - **@modifyingCustomSemanticAttribute(**<expression in semantic 
attribute modifier DSL>**)**
	   - **@modifyingCustomSemanticAttribute(Cocoa, applicationMain)**
	   - **@modifyingCustomSemanticAttribute(CoreData, managed)**
	   - **@modifyingCustomSemanticAttribute(InterfaceBuilder, action)**
	   - **@modifyingCustomSemanticAttribute(InterfaceBuilder, 
designable)**
	   - **@modifyingCustomSemanticAttribute(InterfaceBuilder, 
inspectable)**
	   - **@modifyingCustomSemanticAttribute(InterfaceBuilder, outlet)**


On 17 Feb 2016, at 23:29, Jacob Bandes-Storch via swift-evolution wrote:

> Arguably, these are all framework/IDE-specific functionality, a.k.a.
> "custom attributes", which should have an entirely different syntax.
>
> On Wed, Feb 17, 2016 at 9:43 PM, Erica Sadun via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> How would you re-design the existing upper camel attributes then?
>>
>> They are: @UIApplicationMain, @NSManaged, @NSCopying, 
>> @NSApplicationMain,
>> @IBAction, @IBDesignable, @IBInspectable, and @IBOutlet
>>
>> -- E
>>
>>
>>> On Feb 17, 2016, at 10:29 PM, Brent Royal-Gordon 
>>> <brent at architechies.com>
>> wrote:
>>>
>>>> @Autoclosure // was @autoclosure
>>>> @Available // was @available
>>>> @ObjC // was @objc
>>>> @NoEscape // was @noescape
>>>> @NonObjC // was @nonobjc
>>>> @NoReturn // was @noreturn
>>>> @Testable // was @testable
>>>> @WarnUnusedResult // was @warn-unused-result
>>>> @Convention  // was @convention
>>>> @NoReturn // was @noreturn
>>>>
>>>> In the revised design, the following example for Swift 2.2
>>>>
>>>> @warn_unused_result(mutable_variant="sortInPlace")
>>>> public func sort() -> [Self.Generator.Element]
>>>>
>>>> becomes
>>>>
>>>> @WarnUnusedResult(mutableVariant: "sortInPlace")
>>>> public func sort() -> [Self.Generator.Element]
>>>
>>> Wow, I'm surprised by how much I hate this. Currently, all Swift
>> keywords are entirely lowercase (ignoring things like `Type`, 
>> `Protocol`,
>> and `dynamicType` which come after a dot). I think I've learned to
>> half-ignore things that look like that, but capitalizing suddenly 
>> pulls the
>> spotlight onto these keywords. I'm just not a fan.
>>>
>>> I think we're better off renaming or redesigning 
>>> `warn_unused_result` so
>> that it's readable when it's all-lowercase with no underscores. Some 
>> ideas:
>>>
>>>       @onlyreturns func sorted() -> [Self.Generator.Element]
>>>       func sorted() -> @important [Self.Generator.Element]
>>>
>>> Alternatively, we could reverse the semantic and make all all 
>>> non-Void
>> functions warn unless they have an attribute saying not to.
>>>
>>>       @ignoreresult mutating func updateValue(value: Value, forKey 
>>> key:
>> Key) -> Value?
>>>       mutating func updateValue(value: Value, forKey key: Key) ->
>> @ignorable Value?
>>>       mutating func updateValue(value: Value, forKey key: Key) ->
>> @convenience Value?
>>>
>>> If we do that, we'll likely still want to be able to annotate
>> non-mutating methods with their mutating variants (well, unless we 
>> think
>> the compiler can guess based on the API Guidelines.)
>>>
>>>       @variant(mutating: "sort") func sorted() ->
>> [Self.Generator.Element]
>>>       @alternative(mutating: "sort") func sorted() ->
>> [Self.Generator.Element]
>>>
>>> That opens the possibility of using `@variant(nonmutating:)` on 
>>> mutating
>> functions, too.
>>>
>>> --
>>> Brent Royal-Gordon
>>> Architechies
>>>
>>
>> _______________________________________________
>> 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/20160224/41e017c8/attachment.html>


More information about the swift-evolution mailing list