[Further Discussion] Naming Attributes


(Erica Sadun) #1

Here's a problem

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

Modernization

In my initial discussion for modernizing Swift attributes (https://gist.github.com/erica/29c1a7fb7f49324d572f), I wanted to eliminate snakecase from @warn-unused-result and `mutable_variant`. Of these, the second is a no-brainer. Instead of the non-standard argument label `mutable_variant`, use `mutableVariant`. Problem solved.

Converting `warn-unused-result` to the current standard of lowercase `warnunusedresult` produces a hard-to-read outcome. So in my write-up, I proposed the following amendments:

@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

This was greeted somewhere between warmly and Siberian Winter depending on respondent.

Possible Approaches

After reading through Joe Groff's update to SE-0030, I'd like to push this again in a broader context (which is why I'm starting a new email thread).

* Is traditional namespacing the way to go?
* Could a simpler solution to upper camel all system-supplied attributes and lower camel all custom attributes be sufficient?
* Could any other "custom" decoration differentiate the two with easy parsing: for example @@lazy, @@delayed for custom and single-@ tokens for system supplied?
* Should I simply back off on modernizing warn-unused-result until SE-0030 is resolved?

What are your thoughts?

Thanks, -- Erica


(Joe Groff) #2

Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Appley stuff); name collisions would hopefully be rare enough that "@Swift.AutoClosure" or whatever hopefully won't often be necessary.

-Joe

···

On Feb 19, 2016, at 12:17 PM, Erica Sadun <erica@ericasadun.com> wrote:

> Here's a problem

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

> Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

> Modernization

In my initial discussion for modernizing Swift attributes (https://gist.github.com/erica/29c1a7fb7f49324d572f), I wanted to eliminate snakecase from @warn-unused-result and `mutable_variant`. Of these, the second is a no-brainer. Instead of the non-standard argument label `mutable_variant`, use `mutableVariant`. Problem solved.

Converting `warn-unused-result` to the current standard of lowercase `warnunusedresult` produces a hard-to-read outcome. So in my write-up, I proposed the following amendments:

@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

This was greeted somewhere between warmly and Siberian Winter depending on respondent.

> Possible Approaches

After reading through Joe Groff's update to SE-0030, I'd like to push this again in a broader context (which is why I'm starting a new email thread).

* Is traditional namespacing the way to go?
* Could a simpler solution to upper camel all system-supplied attributes and lower camel all custom attributes be sufficient?
* Could any other "custom" decoration differentiate the two with easy parsing: for example @@lazy, @@delayed for custom and single-@ tokens for system supplied?
* Should I simply back off on modernizing warn-unused-result until SE-0030 is resolved?

What are your thoughts?


(Erica Sadun) #3

That would solve stuff.

How do you feel about my upcasing the attributes for readability?

-- E

···

On Feb 19, 2016, at 2:04 PM, Joe Groff <jgroff@apple.com> wrote:

On Feb 19, 2016, at 12:17 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

> Here's a problem

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

> Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

> Modernization

In my initial discussion for modernizing Swift attributes (https://gist.github.com/erica/29c1a7fb7f49324d572f), I wanted to eliminate snakecase from @warn-unused-result and `mutable_variant`. Of these, the second is a no-brainer. Instead of the non-standard argument label `mutable_variant`, use `mutableVariant`. Problem solved.

Converting `warn-unused-result` to the current standard of lowercase `warnunusedresult` produces a hard-to-read outcome. So in my write-up, I proposed the following amendments:

@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

This was greeted somewhere between warmly and Siberian Winter depending on respondent.

> Possible Approaches

After reading through Joe Groff's update to SE-0030, I'd like to push this again in a broader context (which is why I'm starting a new email thread).

* Is traditional namespacing the way to go?
* Could a simpler solution to upper camel all system-supplied attributes and lower camel all custom attributes be sufficient?
* Could any other "custom" decoration differentiate the two with easy parsing: for example @@lazy, @@delayed for custom and single-@ tokens for system supplied?
* Should I simply back off on modernizing warn-unused-result until SE-0030 is resolved?

What are your thoughts?

Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Appley stuff); name collisions would hopefully be rare enough that "@Swift.AutoClosure" or whatever hopefully won't often be necessary.

-Joe


(Brent Royal-Gordon) #4

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

I don't think this is a problem in and of itself. All the things that can come after an @ are attributes; behaviors allow you to declare your own attributes with a (small, but hopefully growing over time) subset of the full attribute semantics.

> Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

This *is* cumbersome and ugly, but so is `Foundation.NSArray`. You only fully qualify identifiers when the extra precision is necessary. Sure, it means you should try to give behaviors names that don't conflict with modules you're likely to work with (including the standard library), but this is already true of all Swift global symbols, including top-level type names. So I don't think this is problematic at all.

(Incidentally, I assume that `@Custom.lazy` comes from a module called "Custom", not that "Custom" is a prefix for all behaviors.)

···

--
Brent Royal-Gordon
Architechies


(Shawn Erickson) #5

Yeah I agree but I personally struggling with how it will play out.

For example given attributes are often only valid in narrow semantic
contexts. The compiler will enforce the semantics as needed of course and a
human reading the code would likely understand the attribute in the context
as written.

A human however may not easily understand the context in which a given
attribute could be used especially if user defined ones start popping up.
...so is a naming methodology used to help, e.g.
@Swift.PropertyBehaviour.lazy? or @MyStuff.PropertyBehaviour.extraLazy? ...
however this quickly become overly verbose and likely ill-defined in
naming, etc. Also it can duplicate what already can be understood from the
usage context.

Sorry handing waving about this nothing clear to add on a way forward. It
could imply contraction of problem domain to a more solvable one for a
first iteration or two on this unless things are better understood in
actually usage.

-Shawn

···

On Fri, Feb 19, 2016 at 1:05 PM Joe Groff via swift-evolution < swift-evolution@swift.org> wrote:

On Feb 19, 2016, at 12:17 PM, Erica Sadun <erica@ericasadun.com> wrote:

*> Here's a problem*

* There are Swift attributes: @autoclosure, @available, @objc, @noescape,
@nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged,
@NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable,
@IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy,
@delayed; these are certainly attribute-ish, and it makes sense to present
these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space
up to user attributes at some point"

*> Namespacing*

If Swift were to start accepting user-defined attributes, it would need
some way to differentiate and namespace potential conflicts. The most
obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`,
`@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

Once we open the floodgates for user-defined attributes, I think
traditional namespacing and name lookup makes a lot of sense. We could
conceptually namespace the existing hardcoded attributes into appropriate
modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as
appropriate for Appley stuff); name collisions would hopefully be rare
enough that "@Swift.AutoClosure" or whatever hopefully won't often be
necessary.


(David Waite) #6

There was discussion about having property behaviors be addressable via @ as well,

self.state@lazy.reset() or the like

I would imagine the ability to namespace attributes would impact this?

-DW

···

On Feb 19, 2016, at 2:04 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Appley stuff); name collisions would hopefully be rare enough that "@Swift.AutoClosure" or whatever hopefully won't often be necessary.


(Joe Groff) #7

Uppercasing seems reasonable to me.

-Joe

···

On Feb 19, 2016, at 1:10 PM, Erica Sadun <erica@ericasadun.com> wrote:

On Feb 19, 2016, at 2:04 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Feb 19, 2016, at 12:17 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

> Here's a problem

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

> Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

> Modernization

In my initial discussion for modernizing Swift attributes (https://gist.github.com/erica/29c1a7fb7f49324d572f), I wanted to eliminate snakecase from @warn-unused-result and `mutable_variant`. Of these, the second is a no-brainer. Instead of the non-standard argument label `mutable_variant`, use `mutableVariant`. Problem solved.

Converting `warn-unused-result` to the current standard of lowercase `warnunusedresult` produces a hard-to-read outcome. So in my write-up, I proposed the following amendments:

@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

This was greeted somewhere between warmly and Siberian Winter depending on respondent.

> Possible Approaches

After reading through Joe Groff's update to SE-0030, I'd like to push this again in a broader context (which is why I'm starting a new email thread).

* Is traditional namespacing the way to go?
* Could a simpler solution to upper camel all system-supplied attributes and lower camel all custom attributes be sufficient?
* Could any other "custom" decoration differentiate the two with easy parsing: for example @@lazy, @@delayed for custom and single-@ tokens for system supplied?
* Should I simply back off on modernizing warn-unused-result until SE-0030 is resolved?

What are your thoughts?

Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Appley stuff); name collisions would hopefully be rare enough that "@Swift.AutoClosure" or whatever hopefully won't often be necessary.

-Joe

That would solve stuff.

How do you feel about my upcasing the attributes for readability?


(Eli Hini) #8

Erica and Joe,
Upcasing would be fine but are we going to combine it with traditional namespacing ?

Eli

···

On Feb 19, 2016, at 13:17, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 19, 2016, at 1:10 PM, Erica Sadun <erica@ericasadun.com> wrote:

On Feb 19, 2016, at 2:04 PM, Joe Groff <jgroff@apple.com> wrote:

On Feb 19, 2016, at 12:17 PM, Erica Sadun <erica@ericasadun.com> wrote:

> Here's a problem

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

> Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

> Modernization

In my initial discussion for modernizing Swift attributes (https://gist.github.com/erica/29c1a7fb7f49324d572f), I wanted to eliminate snakecase from @warn-unused-result and `mutable_variant`. Of these, the second is a no-brainer. Instead of the non-standard argument label `mutable_variant`, use `mutableVariant`. Problem solved.

Converting `warn-unused-result` to the current standard of lowercase `warnunusedresult` produces a hard-to-read outcome. So in my write-up, I proposed the following amendments:

@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

This was greeted somewhere between warmly and Siberian Winter depending on respondent.

> Possible Approaches

After reading through Joe Groff's update to SE-0030, I'd like to push this again in a broader context (which is why I'm starting a new email thread).

* Is traditional namespacing the way to go?
* Could a simpler solution to upper camel all system-supplied attributes and lower camel all custom attributes be sufficient?
* Could any other "custom" decoration differentiate the two with easy parsing: for example @@lazy, @@delayed for custom and single-@ tokens for system supplied?
* Should I simply back off on modernizing warn-unused-result until SE-0030 is resolved?

What are your thoughts?

Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Appley stuff); name collisions would hopefully be rare enough that "@Swift.AutoClosure" or whatever hopefully won't often be necessary.

-Joe

That would solve stuff.

How do you feel about my upcasing the attributes for readability?

Uppercasing seems reasonable to me.

-Joe

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #9

And revised with feedback: Modernizing Attribute Cases and Argument Naming <https://gist.github.com/erica/29c1a7fb7f49324d572f>

This discussion seems to be drawing to a natural close, so please let me know if there are any gaping issues that remain as well as any quibbles. Thank you, -- Erica

Modernizing Attribute Case and Attribute Argument Naming

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica>
Status: TBD
Review manager: TBD

<https://gist.github.com/erica/29c1a7fb7f49324d572f#introduction>Introduction

Two isolated instances of snake case <https://en.wikipedia.org/wiki/Snake_case> remain in the Swift attribute grammar. This proposal updates those elements to bring them into compliance with modern Swift language standards and applies a new consistent pattern to existing attributes.

The Swift-Evolution discussion of this topic took place in the [Discussion] Modernizing Attribute Case and Attribute Argument Naming <http://article.gmane.org/gmane.comp.lang.swift.evolution/7335> thread. Hat tip to Michael Well, Dmitri Gribenko, Brent Royal-Gordon, Shawn Erickson, Dany St-Amant

<https://gist.github.com/erica/29c1a7fb7f49324d572f#motivation>Motivation

Two elements of Swift attribute grammar retain lower_snake_case patterns: Swift's warn_unused_result attribute and its mutable_variant argument. This pattern is being actively eliminated from Swift in an effort to modernize the language and adopt common naming patterns. Renaming these elements fall into two separate problems: one trivial, one forward-looking.

<https://gist.github.com/erica/29c1a7fb7f49324d572f#detail-design-updating-the-mutable_variant-argument>Detail Design: Updating the mutable_variant argument

The mutable_variant argument refactor is minimal. It should use the lower camel case Swift standard for arguments and be renamed mutableVariant.

<https://gist.github.com/erica/29c1a7fb7f49324d572f#detail-design-updating-the-warn_unused_result-attribute>Detail Design: Updating the warn_unused_result attribute

In the current version of Swift, most native attributes use lowercase naming: for example @testable and noescape. The most natural approach is to mimic this with @warn-unused-result, namely @warnunusedresult.

While this lower case pattern matches other compound attribute examples: objc, noescape, nonobjc, and noreturn, the re-engineered version of warnunusedresult is hard to read. It looks like a continuous string of lowercase characters instead of punching clear, identifiable semantic elements. Using lowercase for complex attributes names, including future names yet to be introduced into the language, becomes confusing when used with longer compound examples.

For this reason, I recommend the Swift team adopt an upper camel case convention for attributes, matching the existing Cocoa participants: UIApplicationMain, NSManaged, NSCopying, NSApplicationMain, IBAction, IBDesignable, IBInspectable, and IBOutlet. This approach avoids the otherwise confusing long name issue.

The renamed elements look like this:

@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
Here is the public declaration of sort() in Swift 2.2:

@warn_unused_result(mutable_variant="sortInPlace")
public func sort() -> [Self.Generator.Element]
This is the proposed public declaration of sort() in Swift 3.0:

@WarnUnusedResult(mutableVariant: "sortInPlace")
public func sort() -> [Self.Generator.Element]
This revised example uses an argument colon (as proposed in "Replacing Equal Signs with Colons For Attribute Arguments") rather than the equal sign currently specified in Swift 2.2

<https://gist.github.com/erica/29c1a7fb7f49324d572f#se-0030-impact>SE-0030 Impact

Joe Groff's Swift-Evolution SE-0030 Property Behaviors <https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md> proposal introduces property implementation patterns using attributes to declare behavior function names, for example: @lazy and @deferred.

If Swift were to start accepting user-defined attributes, it needs a way to differentiate potential conflicts. The most obvious solution uses namespacing, for example @Swift.Autoclosure, @UIKit.UIApplicationMain, @UIKit.IBOutlet, @Swift.NoReturn, @StdLib.lazy, @Custom.deferred, etc.

@AttributeName // built-in, upper camel case
@attributename // or @attributeName, custom element that may not follow built-in patterns
@Module.AttributeName // case follows source convention
Name collisions should be limited enough that fully-qualified attributes would be rare, as they already are with top-level calls such as differentiating NSView's print function (print a view) from Swift's (output to the console or custom stream).

Joe Groff writes, "Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Apple-y stuff)."

<https://gist.github.com/erica/29c1a7fb7f49324d572f#alternatives-considered>Alternatives Considered

Reaction to upper-case naming has been mixed. I personally believe the redesign is more readable. Others object to using uppercase outside of types, even though Cocoa imports are already doing so. Although the Swift team might prefer using lower camel case @autoClosure, @available, @objC, @noEscape, @nonObjC, @noReturn, @testable, @warnUnusedResult, @convention, @noReturn but this would be out of step with non-native Swift attributes, specifically UIApplicationMain, NSManaged, NSCopying, NSApplicationMain, IBAction, IBDesignable, IBInspectable, and IBOutlet

Dany St-Amant suggests that attributes be case-insensitive, enabling coders to choose their casing. "[Maybe] cases could be ignored, making everybody writing code happy, and everyone reading code of others unhappy"

···

On Feb 19, 2016, at 4:31 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

I don't think this is a problem in and of itself. All the things that can come after an @ are attributes; behaviors allow you to declare your own attributes with a (small, but hopefully growing over time) subset of the full attribute semantics.

Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

This *is* cumbersome and ugly, but so is `Foundation.NSArray`. You only fully qualify identifiers when the extra precision is necessary. Sure, it means you should try to give behaviors names that don't conflict with modules you're likely to work with (including the standard library), but this is already true of all Swift global symbols, including top-level type names. So I don't think this is problematic at all.

(Incidentally, I assume that `@Custom.lazy` comes from a module called "Custom", not that "Custom" is a prefix for all behaviors.)

--
Brent Royal-Gordon
Architechies


(Dave Abrahams) #10

Wow, both our list archives munched that line:

  https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010799.html

But Gmane did a number on that one with its privacy controls.
Lars, can we do anything about this?

···

on Sun Feb 21 2016, David Waite <swift-evolution@swift.org> wrote:

There was discussion about having property behaviors be addressable via @ as well,

self.state@lazy.reset() or the like

--
-Dave


(David Hart) #11

+1 as long as we keep user-defined attributes (SE0030) lowerCamelCase

···

On 21 Feb 2016, at 02:11, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

And revised with feedback: Modernizing Attribute Cases and Argument Naming <https://gist.github.com/erica/29c1a7fb7f49324d572f>

This discussion seems to be drawing to a natural close, so please let me know if there are any gaping issues that remain as well as any quibbles. Thank you, -- Erica

Modernizing Attribute Case and Attribute Argument Naming

Proposal: TBD
Author(s): Erica Sadun <http://github.com/erica>
Status: TBD
Review manager: TBD

<https://gist.github.com/erica/29c1a7fb7f49324d572f#introduction>Introduction

Two isolated instances of snake case <https://en.wikipedia.org/wiki/Snake_case> remain in the Swift attribute grammar. This proposal updates those elements to bring them into compliance with modern Swift language standards and applies a new consistent pattern to existing attributes.

The Swift-Evolution discussion of this topic took place in the [Discussion] Modernizing Attribute Case and Attribute Argument Naming <http://article.gmane.org/gmane.comp.lang.swift.evolution/7335> thread. Hat tip to Michael Well, Dmitri Gribenko, Brent Royal-Gordon, Shawn Erickson, Dany St-Amant

<https://gist.github.com/erica/29c1a7fb7f49324d572f#motivation>Motivation

Two elements of Swift attribute grammar retain lower_snake_case patterns: Swift's warn_unused_result attribute and its mutable_variant argument. This pattern is being actively eliminated from Swift in an effort to modernize the language and adopt common naming patterns. Renaming these elements fall into two separate problems: one trivial, one forward-looking.

<https://gist.github.com/erica/29c1a7fb7f49324d572f#detail-design-updating-the-mutable_variant-argument>Detail Design: Updating the mutable_variant argument

The mutable_variant argument refactor is minimal. It should use the lower camel case Swift standard for arguments and be renamed mutableVariant.

<https://gist.github.com/erica/29c1a7fb7f49324d572f#detail-design-updating-the-warn_unused_result-attribute>Detail Design: Updating the warn_unused_result attribute

In the current version of Swift, most native attributes use lowercase naming: for example @testable and noescape. The most natural approach is to mimic this with @warn-unused-result, namely @warnunusedresult.

While this lower case pattern matches other compound attribute examples: objc, noescape, nonobjc, and noreturn, the re-engineered version of warnunusedresult is hard to read. It looks like a continuous string of lowercase characters instead of punching clear, identifiable semantic elements. Using lowercase for complex attributes names, including future names yet to be introduced into the language, becomes confusing when used with longer compound examples.

For this reason, I recommend the Swift team adopt an upper camel case convention for attributes, matching the existing Cocoa participants: UIApplicationMain, NSManaged, NSCopying, NSApplicationMain, IBAction, IBDesignable, IBInspectable, and IBOutlet. This approach avoids the otherwise confusing long name issue.

The renamed elements look like this:

@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
Here is the public declaration of sort() in Swift 2.2:

@warn_unused_result(mutable_variant="sortInPlace")
public func sort() -> [Self.Generator.Element]
This is the proposed public declaration of sort() in Swift 3.0:

@WarnUnusedResult(mutableVariant: "sortInPlace")
public func sort() -> [Self.Generator.Element]
This revised example uses an argument colon (as proposed in "Replacing Equal Signs with Colons For Attribute Arguments") rather than the equal sign currently specified in Swift 2.2

<https://gist.github.com/erica/29c1a7fb7f49324d572f#se-0030-impact>SE-0030 Impact

Joe Groff's Swift-Evolution SE-0030 Property Behaviors <https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md> proposal introduces property implementation patterns using attributes to declare behavior function names, for example: @lazy and @deferred.

If Swift were to start accepting user-defined attributes, it needs a way to differentiate potential conflicts. The most obvious solution uses namespacing, for example @Swift.Autoclosure, @UIKit.UIApplicationMain, @UIKit.IBOutlet, @Swift.NoReturn, @StdLib.lazy, @Custom.deferred, etc.

@AttributeName // built-in, upper camel case
@attributename // or @attributeName, custom element that may not follow built-in patterns
@Module.AttributeName // case follows source convention
Name collisions should be limited enough that fully-qualified attributes would be rare, as they already are with top-level calls such as differentiating NSView's print function (print a view) from Swift's (output to the console or custom stream).

Joe Groff writes, "Once we open the floodgates for user-defined attributes, I think traditional namespacing and name lookup makes a lot of sense. We could conceptually namespace the existing hardcoded attributes into appropriate modules (Swift for the platform-neutral stuff, Foundation/AppKit/UIKit as appropriate for Apple-y stuff)."

<https://gist.github.com/erica/29c1a7fb7f49324d572f#alternatives-considered>Alternatives Considered

Reaction to upper-case naming has been mixed. I personally believe the redesign is more readable. Others object to using uppercase outside of types, even though Cocoa imports are already doing so. Although the Swift team might prefer using lower camel case @autoClosure, @available, @objC, @noEscape, @nonObjC, @noReturn, @testable, @warnUnusedResult, @convention, @noReturn but this would be out of step with non-native Swift attributes, specifically UIApplicationMain, NSManaged, NSCopying, NSApplicationMain, IBAction, IBDesignable, IBInspectable, and IBOutlet

Dany St-Amant suggests that attributes be case-insensitive, enabling coders to choose their casing. "[Maybe] cases could be ignored, making everybody writing code happy, and everyone reading code of others unhappy"

On Feb 19, 2016, at 4:31 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

* There are Swift attributes: @autoclosure, @available, @objc, @noescape, @nonobjc, @noreturn, @testable, @warn-unused-result, @convention, @noreturn.
* There are ObjC-ish/Xcode-ish attributes: @UIApplicationMain, @NSManaged, @NSCopying, @NSApplicationMain, @IBAction, @IBDesignable, @IBInspectable, @IBOutlet
* There may be user-definable attributes under SE-0030: for example @lazy, @delayed; these are certainly attribute-ish, and it makes sense to present these using attribute-syntax.
* The attribute syntax using `@` has had an intention "to open the space up to user attributes at some point"

I don't think this is a problem in and of itself. All the things that can come after an @ are attributes; behaviors allow you to declare your own attributes with a (small, but hopefully growing over time) subset of the full attribute semantics.

Namespacing

If Swift were to start accepting user-defined attributes, it would need some way to differentiate and namespace potential conflicts. The most obvious solution looks like this:

`@Swift.autoclosure`, `@UIKit.UIApplicationMain`, `@UIKit.IBOutlet`, `@Swift.noreturn`, `@Custom.lazy`, etc.

Cumbersome, ugly, problematic.

This *is* cumbersome and ugly, but so is `Foundation.NSArray`. You only fully qualify identifiers when the extra precision is necessary. Sure, it means you should try to give behaviors names that don't conflict with modules you're likely to work with (including the standard library), but this is already true of all Swift global symbols, including top-level type names. So I don't think this is problematic at all.

(Incidentally, I assume that `@Custom.lazy` comes from a module called "Custom", not that "Custom" is a prefix for all behaviors.)

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution