[PITCH] ADD AN @RESTRICTED DECLARATION ATTRIBUTE


(Stuart Breckenridge) #1

ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:
The @available attribute indicates a declaration’s life cycle relative to certain platforms and operating systems. Today’s functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form approach.
Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:
@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn’t specified, then the attribute defaults to available.
Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.
Proposal

Implement an @restricted attribute which is the inverse of @available. The effect would be that the compiler would use @restricted to limit the declaration to be available on the platform(s) specified in the attribute. Similar to @available, multiple @restricted attributes can be added to a declaration.
Therefore, where @restricted attribute(s) are present and target platform is not specified, the declaration is not available on the unspecified target platform. In addition, where a @restricted attribute has been applied to a declaration, it should not be commingled with @available on the same declaration (it would lead to intense confusion).
Design

From a syntax perspective, it would follow @available:
@restricted(platform name version number, *)
or
@restricted(platform name, introduced=version number)
Similarly, all @available arguments would be available to @restricted.
Examples

Using the previous example, instead of using @available to specify unavailability, we use @restricted to scope the declarations availability:
Single Platform Restriction
@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.
Multiple Platform Restriction
@restricted(OSX 10.8, iOS 9.4, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.4 or newer.
Restricted within Version Bounds
@restricted(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.
Restricted with Renamed Case
// Initial Release
@restricted(OSX 10.10, *)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@restricted(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo")
case TencentWeibo = "com.apple.social.tencentweibo"

@restricted(OSX 10.11) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.
Benefits & Impact on existing code

@restricted has the benefit of reducing the amount code while maintaining clarity of purpose: it is obvious based on the attribute name what the intent is.
@restricted is purely additive, and therefore has no impact on existing code that makes use of @available.
Alternatives

An alternative, though not a strict replacement of @restricted, could be to extract the unavailableargument and use it as an attribute (@unavailable). In use:
@available(OSX 10.8, *)
@unavailable(iOS, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X but not iOS.
@unavailable is worthy of further discussion as using an unavailable argument inside an @availableattribute seems counterintuitive.
However, this proposal is limited to the consideration of @restricted.


(Charlie Monroe) #2

With the alternatives, I'd mention @deprecated as well.

Charlie

···

On May 26, 2016, at 3:25 PM, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org> wrote:

ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:
The @available attribute indicates a declaration’s life cycle relative to certain platforms and operating systems. Today’s functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form approach.
Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:
@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn’t specified, then the attribute defaults to available.
Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.
Proposal

Implement an @restricted attribute which is the inverse of @available. The effect would be that the compiler would use @restricted to limit the declaration to be available on the platform(s) specified in the attribute. Similar to @available, multiple @restricted attributes can be added to a declaration.
Therefore, where @restricted attribute(s) are present and target platform is not specified, the declaration is not available on the unspecified target platform. In addition, where a @restricted attribute has been applied to a declaration, it should not be commingled with @available on the same declaration (it would lead to intense confusion).
Design

From a syntax perspective, it would follow @available:
@restricted(platform name version number, *)
or
@restricted(platform name, introduced=version number)
Similarly, all @available arguments would be available to @restricted.
Examples

Using the previous example, instead of using @available to specify unavailability, we use @restricted to scope the declarations availability:
Single Platform Restriction
@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.
Multiple Platform Restriction
@restricted(OSX 10.8, iOS 9.4, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.4 or newer.
Restricted within Version Bounds
@restricted(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.
Restricted with Renamed Case
// Initial Release
@restricted(OSX 10.10, *)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@restricted(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo")
case TencentWeibo = "com.apple.social.tencentweibo"

@restricted(OSX 10.11) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.
Benefits & Impact on existing code

@restricted has the benefit of reducing the amount code while maintaining clarity of purpose: it is obvious based on the attribute name what the intent is.
@restricted is purely additive, and therefore has no impact on existing code that makes use of @available.
Alternatives

An alternative, though not a strict replacement of @restricted, could be to extract the unavailableargument and use it as an attribute (@unavailable). In use:
@available(OSX 10.8, *)
@unavailable(iOS, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X but not iOS.
@unavailable is worthy of further discussion as using an unavailable argument inside an @availableattribute seems counterintuitive.
However, this proposal is limited to the consideration of @restricted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Stuart Breckenridge) #3

I thought about including @deprecated as an alternative, but it needs some addition tweaking outside of @unavailable and @restricted.

For example, would arguments like introduced and obsoleted still be available for use, or would they need to be separated out?

@introduced(iOS 9.0)
@deprecated(iOS 9.1, message="Use a.n.other protocol")
@obsoleted(iOS 9.2, message="Use a.n.other protocol")
protocol MyProtocol { }

I think @unavailable and @restricted lend themselves to the existing syntax.

Stuart

···

On 26 May 2016, at 21:48, Charlie Monroe <charlie@charliemonroe.net> wrote:

With the alternatives, I'd mention @deprecated as well.

Charlie

On May 26, 2016, at 3:25 PM, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:
The @available attribute indicates a declaration’s life cycle relative to certain platforms and operating systems. Today’s functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form approach.
Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:
@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn’t specified, then the attribute defaults to available.
Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.
Proposal

Implement an @restricted attribute which is the inverse of @available. The effect would be that the compiler would use @restricted to limit the declaration to be available on the platform(s) specified in the attribute. Similar to @available, multiple @restricted attributes can be added to a declaration.
Therefore, where @restricted attribute(s) are present and target platform is not specified, the declaration is not available on the unspecified target platform. In addition, where a @restricted attribute has been applied to a declaration, it should not be commingled with @available on the same declaration (it would lead to intense confusion).
Design

From a syntax perspective, it would follow @available:
@restricted(platform name version number, *)
or
@restricted(platform name, introduced=version number)
Similarly, all @available arguments would be available to @restricted.
Examples

Using the previous example, instead of using @available to specify unavailability, we use @restricted to scope the declarations availability:
Single Platform Restriction
@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.
Multiple Platform Restriction
@restricted(OSX 10.8, iOS 9.4, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.4 or newer.
Restricted within Version Bounds
@restricted(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.
Restricted with Renamed Case
// Initial Release
@restricted(OSX 10.10, *)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@restricted(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo")
case TencentWeibo = "com.apple.social.tencentweibo"

@restricted(OSX 10.11) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.
Benefits & Impact on existing code

@restricted has the benefit of reducing the amount code while maintaining clarity of purpose: it is obvious based on the attribute name what the intent is.
@restricted is purely additive, and therefore has no impact on existing code that makes use of @available.
Alternatives

An alternative, though not a strict replacement of @restricted, could be to extract the unavailableargument and use it as an attribute (@unavailable). In use:
@available(OSX 10.8, *)
@unavailable(iOS, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X but not iOS.
@unavailable is worthy of further discussion as using an unavailable argument inside an @availableattribute seems counterintuitive.
However, this proposal is limited to the consideration of @restricted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #4

I’m not sure about this, as restricting anything by OS generally makes me uneasy; where possible we should always try to restrict code by availability and version of modules, as these will indicate the actual features that a platform should support. Part of the problem is that we can’t guarantee what new OSes will be supported in future, in your example you’ve already only covered Apple OSes, but Linux support is on its way, and Windows support may come (Visual Studio may already support it).

I mean, it’s no more or less prone to issues than @available I suppose, but I’m not a fan of limiting features and support in this way to begin with.

···

On 26 May 2016, at 14:25, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org> wrote:

ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:
The @available attribute indicates a declaration’s life cycle relative to certain platforms and operating systems. Today’s functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form approach.
Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:
@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn’t specified, then the attribute defaults to available.
Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.
Proposal

Implement an @restricted attribute which is the inverse of @available. The effect would be that the compiler would use @restricted to limit the declaration to be available on the platform(s) specified in the attribute. Similar to @available, multiple @restricted attributes can be added to a declaration.
Therefore, where @restricted attribute(s) are present and target platform is not specified, the declaration is not available on the unspecified target platform. In addition, where a @restricted attribute has been applied to a declaration, it should not be commingled with @available on the same declaration (it would lead to intense confusion).
Design

From a syntax perspective, it would follow @available:
@restricted(platform name version number, *)
or
@restricted(platform name, introduced=version number)
Similarly, all @available arguments would be available to @restricted.
Examples

Using the previous example, instead of using @available to specify unavailability, we use @restricted to scope the declarations availability:
Single Platform Restriction
@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.
Multiple Platform Restriction
@restricted(OSX 10.8, iOS 9.4, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.4 or newer.
Restricted within Version Bounds
@restricted(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.
Restricted with Renamed Case
// Initial Release
@restricted(OSX 10.10, *)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@restricted(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo")
case TencentWeibo = "com.apple.social.tencentweibo"

@restricted(OSX 10.11) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.
Benefits & Impact on existing code

@restricted has the benefit of reducing the amount code while maintaining clarity of purpose: it is obvious based on the attribute name what the intent is.
@restricted is purely additive, and therefore has no impact on existing code that makes use of @available.
Alternatives

An alternative, though not a strict replacement of @restricted, could be to extract the unavailableargument and use it as an attribute (@unavailable). In use:
@available(OSX 10.8, *)
@unavailable(iOS, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X but not iOS.
@unavailable is worthy of further discussion as using an unavailable argument inside an @availableattribute seems counterintuitive.
However, this proposal is limited to the consideration of @restricted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Brent Royal-Gordon) #5

@available(OS X 10.9, restricted)

Personally, I would prefer something like this, perhaps spelled:

  @available(OS X 10.9, only)

When using shorthand form, you would have to write either `*` or `only` as the last element. `*` means "and any other platforms", while `only` means "only the listed platforms".

···

--
Brent Royal-Gordon
Architechies


(Charlie Monroe) #6

Do we then need @restricted? It could be done like this using @available:

@available(only OS X 10.9, iOS 9.1, message="123")
@available(restricted OS X 10.9)
@available(OS X 10.9, restricted)

It would make sense either to split all the availability annotations (deprecated, unavailable, ...), or make the restricted somehow part of @available.

···

On May 26, 2016, at 4:14 PM, Stuart Breckenridge <stuart.breckenridge@icloud.com> wrote:

I thought about including @deprecated as an alternative, but it needs some addition tweaking outside of @unavailable and @restricted.

For example, would arguments like introduced and obsoleted still be available for use, or would they need to be separated out?

@introduced(iOS 9.0)
@deprecated(iOS 9.1, message="Use a.n.other protocol")
@obsoleted(iOS 9.2, message="Use a.n.other protocol")
protocol MyProtocol { }

I think @unavailable and @restricted lend themselves to the existing syntax.

Stuart

On 26 May 2016, at 21:48, Charlie Monroe <charlie@charliemonroe.net <mailto:charlie@charliemonroe.net>> wrote:

With the alternatives, I'd mention @deprecated as well.

Charlie

On May 26, 2016, at 3:25 PM, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:
The @available attribute indicates a declaration’s life cycle relative to certain platforms and operating systems. Today’s functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form approach.
Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:
@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn’t specified, then the attribute defaults to available.
Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.
Proposal

Implement an @restricted attribute which is the inverse of @available. The effect would be that the compiler would use @restricted to limit the declaration to be available on the platform(s) specified in the attribute. Similar to @available, multiple @restricted attributes can be added to a declaration.
Therefore, where @restricted attribute(s) are present and target platform is not specified, the declaration is not available on the unspecified target platform. In addition, where a @restricted attribute has been applied to a declaration, it should not be commingled with @available on the same declaration (it would lead to intense confusion).
Design

From a syntax perspective, it would follow @available:
@restricted(platform name version number, *)
or
@restricted(platform name, introduced=version number)
Similarly, all @available arguments would be available to @restricted.
Examples

Using the previous example, instead of using @available to specify unavailability, we use @restricted to scope the declarations availability:
Single Platform Restriction
@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.
Multiple Platform Restriction
@restricted(OSX 10.8, iOS 9.4, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.4 or newer.
Restricted within Version Bounds
@restricted(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.
Restricted with Renamed Case
// Initial Release
@restricted(OSX 10.10, *)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@restricted(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo")
case TencentWeibo = "com.apple.social.tencentweibo"

@restricted(OSX 10.11) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.
Benefits & Impact on existing code

@restricted has the benefit of reducing the amount code while maintaining clarity of purpose: it is obvious based on the attribute name what the intent is.
@restricted is purely additive, and therefore has no impact on existing code that makes use of @available.
Alternatives

An alternative, though not a strict replacement of @restricted, could be to extract the unavailableargument and use it as an attribute (@unavailable). In use:
@available(OSX 10.8, *)
@unavailable(iOS, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X but not iOS.
@unavailable is worthy of further discussion as using an unavailable argument inside an @availableattribute seems counterintuitive.
However, this proposal is limited to the consideration of @restricted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Stuart Breckenridge) #7

On reflection, I think the introduction of a new argument to limit platform scope is superior — one less attribute to know about.

I've revised the proposal draft: https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md and would welcome further comments.

Add An only Declaration Argument

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#introduction>Introduction

Adapted from the Swift 2.2 Programming Guide:

The @available attribute indicates a declaration's life cycle relative to certain platforms and operating systems. Today's functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form @available approach.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#motivation>Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:

@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX, introduced=10.8)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn't specified, then the attribute defaults to available.

Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#proposal>Proposal

Implement an only attribute argument. The effect would be that the compiler would use only to limit the declaration to be available on the target platform(s) specified in the attribute. Similar to existing @available attributes, multiple platforms can be specified in an single declaration and multiple @available attributes can applied to a single declaration.

Therefore, where only arguments(s) are present and the target platform is not specified, the declaration is not available on the unspecified target platform(s).

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#design>Design

From a design perspective, only would be a new argument for use with @available. It would replace the trailing * that denotes all other platforms: only and * cannot be used on the same declaration.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#syntnax>Syntnax

@available(platform name version number, only) or @available(platform name, introduced=version number, only)

No changes would be required to other @available arguments.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#examples>Examples

Using the previous example, we use only to scope the declarations availability:

Single Platform Restriction

@available(OSX 10.8, only)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.

Multiple Platform Restriction

@available(OSX 10.8, only)
@available(iOS 9.3, only)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.3 or newer.

Restricted within Version Bounds

@available(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.

Restricted with Renamed Case

// Initial Release
@available(OSX 10.10, only)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@available(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo", only)
case TencentWeibo = "com.apple.social.tencentweibo"

@available(OSX 10.11, only) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.

Illegal Usage

@available(OSX 10.8, only)
@available(iOS 9.3, *)
case LinkedIn = "com.apple.social.linkedin"
Reason: * and only are mutually exclusive.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#benefits--impact-on-existing-code>Benefits & Impact on existing code

only has the benefit of reducing the amount of attribute code, while maintaining clarity of purpose: it is obvious based on the argument name what the intent is.

only is purely additive, and therefore has no impact on existing declarations that make use of @available.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#alternatives>Alternatives

An alternative considered was the introduction of an @restricted attribute that would be used in place of @available. In use:

@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X 10.8 and newer.

@restricted and only achieve the same goal of providing a simple way of scoping a declaration's availability to specific platform(s) while reducing the amount of code required to do so. The general feedback from the initial proprosal was that an introduction of a new argument (only) was preferred over the introduction of a new attribute @restricted.

···

On 27 May 2016, at 05:14, Brent Royal-Gordon <brent@architechies.com> wrote:

@available(OS X 10.9, restricted)

Personally, I would prefer something like this, perhaps spelled:

  @available(OS X 10.9, only)

When using shorthand form, you would have to write either `*` or `only` as the last element. `*` means "and any other platforms", while `only` means "only the listed platforms".

--
Brent Royal-Gordon
Architechies


(Xiaodi Wu) #8

On reflection, I think the introduction of a new argument to limit
platform scope is superior — one less attribute to know about.

I've revised the proposal draft:
https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md and
would welcome further comments.

Add An only Declaration Argument

   - Proposal: SE-NNNN
   - Author: Stuart Breckenridge
   - Status: DRAFT
   - Review Manager: TBD

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#introduction>
Introduction

Adapted from the Swift 2.2 Programming Guide:

The @available attribute indicates a declaration's life cycle relative to
certain platforms and operating systems. Today's functionality allows you
to add multiple @available attributes on a declaration to specify its
availability on different platforms.

In a related Swift Evolution discussion examining the @available attribute,
it was confirmed that there is currently no way to limit availability to
specific platform without using the long form @available approach.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#motivation>
Motivation

When a declaration is only available on a certain platform, it requires
multiple @available attributes to restrict its availability to that
platform. Consider the following example using SLServiceType like
constants:

@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX, introduced=10.8)
case LinkedIn = "com.apple.social.linkedin"

The compiler will only use an @available attribute when the attribute
specifies a platform that matches the current target platform. The
implication being that if the target platform isn't specified, then the
attribute defaults to available.

Thus, while it is clear that the above is restricting availability to OS X
10.8 and later, it is verbose and can be simplified.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#proposal>
Proposal

Implement an only attribute argument. The effect would be that the
compiler would use only to limit the declaration to be available on the
target platform(s) specified in the attribute. Similar to existing
@available attributes, multiple platforms can be specified in an single
declaration and multiple @available attributes can applied to a single
declaration.

Therefore, where only arguments(s) are present and the target platform *is
not* specified, the declaration is not available on the unspecified
target platform(s).

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#design>
Design

From a design perspective, only would be a new argument for use with
@available. It would replace the trailing * that denotes all other
platforms: only and * cannot be used on the same declaration.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#syntnax>
Syntnax

@available(platform name version number, only) or @available(platform name
, introduced=version number, only)

No changes would be required to other @available arguments.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#examples>
Examples

Using the previous example, we use only to scope the declarations
availability:

*Single Platform Restriction*

@available(OSX 10.8, only)
case LinkedIn = "com.apple.social.linkedin"

Effect: only available on OS X 10.8 or newer.

*Multiple Platform Restriction*

@available(OSX 10.8, only)
@available(iOS 9.3, only)
case LinkedIn = "com.apple.social.linkedin"

Effect: Available on OSX 10.8 or newer, and iOS 9.3 or newer.

*Restricted within Version Bounds*

@available(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"

Effect: Available on OS X from 10.8 through 10.11 only.

*Restricted with Renamed Case*

// Initial Release
@available(OSX 10.10, only)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@available(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo", only)
case TencentWeibo = "com.apple.social.tencentweibo"

@available(OSX 10.11, only) case Weibo = "com.apple.social.weibo"

Effect: Initial release case is restricted to 10.10 and newer; second
release has the original case deprecated from 10.11, with a new case
introduced which is available on OS X 10.11 and newer only.

*Illegal Usage*

@available(OSX 10.8, only)
@available(iOS 9.3, *)
case LinkedIn = "com.apple.social.linkedin"

Reason: * and only are mutually exclusive.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#benefits--impact-on-existing-code>Benefits
& Impact on existing code

only has the benefit of reducing the amount of attribute code, while
maintaining clarity of purpose: it is obvious based on the argument name
what the intent is.

I see what you're going for, but it is not at all obvious what the word
"only" means. In fact, the intuitive interpretation of `@available(OSX
10.8, only)` is that "only" applies to the version number and not the
platform--i.e. the feature is available only in OS X 10.8 and not in
earlier or later versions; that interpretation is only reinforced by your
proposed syntax allowing "only" to be written multiple times, once for each
platform. The only intuitive interpretation of `@available(OSX 10.8, only)`
followed by `@available(iOS 9.3, only)` is that the feature is available
only in version 10.8 of OS X and only in version 9.3 of iOS, not that you
are restricting availability on other platforms. By contrast, the current
syntax is verbose but unambiguous.

···

On Thu, May 26, 2016 at 7:37 PM, Stuart Breckenridge via swift-evolution < swift-evolution@swift.org> wrote:

only is purely additive, and therefore has no impact on existing
declarations that make use of @available.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#alternatives>
Alternatives

An alternative considered was the introduction of an @restricted attribute
that would be used in place of @available. In use:

@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"

Effect: Available on OS X 10.8 and newer.
@restricted and only achieve the same goal of providing a simple way of
scoping a declaration's availability to specific platform(s) while reducing
the amount of code required to do so. The general feedback from the initial
proprosal was that an introduction of a new argument (only) was preferred
over the introduction of a new attribute @restricted.

On 27 May 2016, at 05:14, Brent Royal-Gordon <brent@architechies.com> > wrote:

@available(OS X 10.9, restricted)

Personally, I would prefer something like this, perhaps spelled:

@available(OS X 10.9, only)

When using shorthand form, you would have to write either `*` or `only` as
the last element. `*` means "and any other platforms", while `only` means
"only the listed platforms".

--
Brent Royal-Gordon
Architechies

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


(Stuart Breckenridge) #9

I disagree. If you look the S
wift 2.2 guide:

"You can also use an asterisk (*) to indicate availability of the declaration on all of the platform names listed above."

What this proposal would add is:

"Alternatively, you can use the word 'only' to indicate that the declaration is only available on the platform name(s) listed in the attribute."

···

Sent from my iPhone

On 27 May 2016, at 09:09, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, May 26, 2016 at 7:37 PM, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org> wrote:
On reflection, I think the introduction of a new argument to limit platform scope is superior — one less attribute to know about.

I've revised the proposal draft: https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md and would welcome further comments.

Add An only Declaration Argument
Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:

The @available attribute indicates a declaration's life cycle relative to certain platforms and operating systems. Today's functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form @available approach.

Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:

@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX, introduced=10.8)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn't specified, then the attribute defaults to available.

Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.

Proposal

Implement an only attribute argument. The effect would be that the compiler would use only to limit the declaration to be available on the target platform(s) specified in the attribute. Similar to existing @available attributes, multiple platforms can be specified in an single declaration and multiple @available attributes can applied to a single declaration.

Therefore, where only arguments(s) are present and the target platform is not specified, the declaration is not available on the unspecified target platform(s).

Design

From a design perspective, only would be a new argument for use with @available. It would replace the trailing * that denotes all other platforms: only and * cannot be used on the same declaration.

Syntnax

@available(platform name version number, only) or @available(platform name, introduced=version number, only)

No changes would be required to other @available arguments.

Examples

Using the previous example, we use only to scope the declarations availability:

Single Platform Restriction

@available(OSX 10.8, only)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.

Multiple Platform Restriction

@available(OSX 10.8, only)
@available(iOS 9.3, only)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.3 or newer.

Restricted within Version Bounds

@available(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.

Restricted with Renamed Case

// Initial Release
@available(OSX 10.10, only)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@available(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo", only)
case TencentWeibo = "com.apple.social.tencentweibo"

@available(OSX 10.11, only) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only.

Illegal Usage

@available(OSX 10.8, only)
@available(iOS 9.3, *)
case LinkedIn = "com.apple.social.linkedin"
Reason: * and only are mutually exclusive.

Benefits & Impact on existing code

only has the benefit of reducing the amount of attribute code, while maintaining clarity of purpose: it is obvious based on the argument name what the intent is.

I see what you're going for, but it is not at all obvious what the word "only" means. In fact, the intuitive interpretation of `@available(OSX 10.8, only)` is that "only" applies to the version number and not the platform--i.e. the feature is available only in OS X 10.8 and not in earlier or later versions; that interpretation is only reinforced by your proposed syntax allowing "only" to be written multiple times, once for each platform. The only intuitive interpretation of `@available(OSX 10.8, only)` followed by `@available(iOS 9.3, only)` is that the feature is available only in version 10.8 of OS X and only in version 9.3 of iOS, not that you are restricting availability on other platforms. By contrast, the current syntax is verbose but unambiguous.

only is purely additive, and therefore has no impact on existing declarations that make use of @available.

Alternatives

An alternative considered was the introduction of an @restricted attribute that would be used in place of @available. In use:

@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X 10.8 and newer.

@restricted and only achieve the same goal of providing a simple way of scoping a declaration's availability to specific platform(s) while reducing the amount of code required to do so. The general feedback from the initial proprosal was that an introduction of a new argument (only) was preferred over the introduction of a new attribute @restricted.

On 27 May 2016, at 05:14, Brent Royal-Gordon <brent@architechies.com> wrote:

@available(OS X 10.9, restricted)

Personally, I would prefer something like this, perhaps spelled:

  @available(OS X 10.9, only)

When using shorthand form, you would have to write either `*` or `only` as the last element. `*` means "and any other platforms", while `only` means "only the listed platforms".

--
Brent Royal-Gordon
Architechies

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


(Brent Royal-Gordon) #10

What I'm saying here is that even if you accept that the asterisk means all platforms, it does not follow that another argument in the same place should refer to the platform names *listed in the attribute*. That's not at all precedented in the meaning of the asterisk.

The problem is, the most natural way to express this is absolutely this:

  @available(OSX 10.8, iOS 8, *) // includes other platforms
  @available(OSX 10.8, iOS 8) // excludes other platforms

But we don't want to do that because we want people to use `*` by default. You could maybe do something like:

  @available(OSX 10.8, iOS 8, * unavailable)

But I think that reads very strangely, and it doesn't seem consistent with the other parameters. (Well, unless you can write `OSX unavailable`, which would actually be kind of convenient, but would still read oddly in a declaration named `@available`.) Hence my suggestion:

  @available(OSX 10.8, iOS 8, only)

Which is meant to be read as "Available in OS X (starting in 10.8) and iOS (starting in 8) only".

(It would be nice if the syntax actually said "OSX 10.8+", and maybe even permitted a range for things that have been retired, like `OSX 10.8..<10.10`. The main problem I see with supporting a range is that the most natural interpretation of the right end is an unavailability version, but the most useful thing to have there would be a deprecation version.)

Furthermore, the asterisk is put after a list of things *only in the shorthand syntax*, whereas you are proposing that "only" should be usable in the full syntax as well, in a position where the asterisk is not allowed. It is something else entirely to say that a feature is available in OSX version so-and-so only and then to say it's available in iOS version so-and-so only, when in fact you mean that it's not available *on other platforms*.

Yes, that was not what I intended when I suggested `only`.

What makes more sense to me would be allowing (if it isn't already allowed) `@available(*, unavailable)` to follow a previous @available declaration in order to mean that the feature is unavailable on all platforms not otherwise specified.

Yes, something like this makes sense to me too. Basically, I think the shorthand form should look like:

  @available(OSX 10.8, iOS 9.4, only)

And the longhand form like:

  @available(OSX, introduced: 10.8)
  @available(iOS, introduced: 9.4)
  @available(*, unavailable)

(The switch from `introduced=` to `introduced:` is an already-approved Swift 3 change.)

Perhaps you should even be required to say either `@available(*)` or `@available(*, unavailable)` if there are longhand `@available` attributes on the type.

···

--
Brent Royal-Gordon
Architechies


(Xiaodi Wu) #11

I disagree. If you look the S
wift 2.2 guide:

"You can also use an asterisk (*) to indicate availability of the
declaration on all of the platform names listed above."

What this proposal would add is:

"Alternatively, you can use the word 'only' to indicate that the
declaration is only available on the platform name(s) listed in the
attribute."

We'll leave aside that the asterisk isn't exactly intuitive in the first
place.

What I'm saying here is that even if you accept that the asterisk means all
platforms, it does not follow that another argument in the same place
should refer to the platform names *listed in the attribute*. That's not at
all precedented in the meaning of the asterisk.

Furthermore, the asterisk is put after a list of things *only in the
shorthand syntax*, whereas you are proposing that "only" should be usable
in the full syntax as well, in a position where the asterisk is not
allowed. It is something else entirely to say that a feature is available
in OSX version so-and-so only and then to say it's available in iOS version
so-and-so only, when in fact you mean that it's not available *on other
platforms*.

What makes more sense to me would be allowing (if it isn't already allowed)
`@available(*, unavailable)` to follow a previous @available declaration in
order to mean that the feature is unavailable on all platforms not
otherwise specified.

···

On Thu, May 26, 2016 at 8:37 PM, Stuart Breckenridge < stuart.breckenridge@icloud.com> wrote:

Sent from my iPhone

On 27 May 2016, at 09:09, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, May 26, 2016 at 7:37 PM, Stuart Breckenridge via swift-evolution < > swift-evolution@swift.org> wrote:

On reflection, I think the introduction of a new argument to limit
platform scope is superior — one less attribute to know about.

I've revised the proposal draft:
https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md and
would welcome further comments.

Add An only Declaration Argument

   - Proposal: SE-NNNN
   - Author: Stuart Breckenridge
   - Status: DRAFT
   - Review Manager: TBD

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#introduction>
Introduction

Adapted from the Swift 2.2 Programming Guide:

The @available attribute indicates a declaration's life cycle relative
to certain platforms and operating systems. Today's functionality allows
you to add multiple @available attributes on a declaration to specify
its availability on different platforms.

In a related Swift Evolution discussion examining the @available attribute,
it was confirmed that there is currently no way to limit availability to
specific platform without using the long form @available approach.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#motivation>
Motivation

When a declaration is only available on a certain platform, it requires
multiple @available attributes to restrict its availability to that
platform. Consider the following example using SLServiceType like
constants:

@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX, introduced=10.8)
case LinkedIn = "com.apple.social.linkedin"

The compiler will only use an @available attribute when the attribute
specifies a platform that matches the current target platform. The
implication being that if the target platform isn't specified, then the
attribute defaults to available.

Thus, while it is clear that the above is restricting availability to OS
X 10.8 and later, it is verbose and can be simplified.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#proposal>
Proposal

Implement an only attribute argument. The effect would be that the
compiler would use only to limit the declaration to be available on the
target platform(s) specified in the attribute. Similar to existing
@available attributes, multiple platforms can be specified in an single
declaration and multiple @available attributes can applied to a single
declaration.

Therefore, where only arguments(s) are present and the target platform *is
not* specified, the declaration is not available on the unspecified
target platform(s).

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#design>
Design

From a design perspective, only would be a new argument for use with
@available. It would replace the trailing * that denotes all other
platforms: only and * cannot be used on the same declaration.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#syntnax>
Syntnax

@available(platform name version number, only) or @available(platform
name, introduced=version number, only)

No changes would be required to other @available arguments.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#examples>
Examples

Using the previous example, we use only to scope the declarations
availability:

*Single Platform Restriction*

@available(OSX 10.8, only)
case LinkedIn = "com.apple.social.linkedin"

Effect: only available on OS X 10.8 or newer.

*Multiple Platform Restriction*

@available(OSX 10.8, only)
@available(iOS 9.3, only)
case LinkedIn = "com.apple.social.linkedin"

Effect: Available on OSX 10.8 or newer, and iOS 9.3 or newer.

*Restricted within Version Bounds*

@available(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"

Effect: Available on OS X from 10.8 through 10.11 only.

*Restricted with Renamed Case*

// Initial Release
@available(OSX 10.10, only)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@available(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo", only)
case TencentWeibo = "com.apple.social.tencentweibo"

@available(OSX 10.11, only) case Weibo = "com.apple.social.weibo"

Effect: Initial release case is restricted to 10.10 and newer; second
release has the original case deprecated from 10.11, with a new case
introduced which is available on OS X 10.11 and newer only.

*Illegal Usage*

@available(OSX 10.8, only)
@available(iOS 9.3, *)
case LinkedIn = "com.apple.social.linkedin"

Reason: * and only are mutually exclusive.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#benefits--impact-on-existing-code>Benefits
& Impact on existing code

only has the benefit of reducing the amount of attribute code, while
maintaining clarity of purpose: it is obvious based on the argument name
what the intent is.

I see what you're going for, but it is not at all obvious what the word
"only" means. In fact, the intuitive interpretation of `@available(OSX
10.8, only)` is that "only" applies to the version number and not the
platform--i.e. the feature is available only in OS X 10.8 and not in
earlier or later versions; that interpretation is only reinforced by your
proposed syntax allowing "only" to be written multiple times, once for each
platform. The only intuitive interpretation of `@available(OSX 10.8, only)`
followed by `@available(iOS 9.3, only)` is that the feature is available
only in version 10.8 of OS X and only in version 9.3 of iOS, not that you
are restricting availability on other platforms. By contrast, the current
syntax is verbose but unambiguous.

only is purely additive, and therefore has no impact on existing
declarations that make use of @available.

<https://github.com/stuartbreckenridge/swift-evolution/blob/master/proposals/NNNN-add-only-declaration-argument.md#alternatives>
Alternatives

An alternative considered was the introduction of an @restricted attribute
that would be used in place of @available. In use:

@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"

Effect: Available on OS X 10.8 and newer.
@restricted and only achieve the same goal of providing a simple way of
scoping a declaration's availability to specific platform(s) while reducing
the amount of code required to do so. The general feedback from the initial
proprosal was that an introduction of a new argument (only) was
preferred over the introduction of a new attribute @restricted.

On 27 May 2016, at 05:14, Brent Royal-Gordon <brent@architechies.com> >> wrote:

@available(OS X 10.9, restricted)

Personally, I would prefer something like this, perhaps spelled:

@available(OS X 10.9, only)

When using shorthand form, you would have to write either `*` or `only`
as the last element. `*` means "and any other platforms", while `only`
means "only the listed platforms".

--
Brent Royal-Gordon
Architechies

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


(Stuart Breckenridge) #12

Are we back in a position where a different attribute (back to @restricted or similar keyword) would clear up the readability concerns?

The current equivalent in @available terms:

Short form:
  @available(OSX 10.8, iOS 8.0, *)
  @available(tvOS, unavailable)
  @available(watchOS, unavailable)

Long form:
  @available(OSX, introduced: 10.8, deprecated: 10.10)
  @available(iOS, introduced: 8.0, deprecated: 8.4, obsoleted: 9.0)
  @available(tvOS, unavailable)
  @available(watchOS, unavailable)

Short form replacement:
  @restricted(OSX 10.8, iOS 8.0) // Restricted to OSX, iOS from 10.8 and 8.0, respectively.

Long form replacement:
  @restricted(OSX, introduced: 10.8, deprecated: 10.10)
        @restricted(iOS, introduced: 8.0, deprecated: 8.4, obsoleted: 9.0)

I would amend the draft proposal: * would not be permitted with @restricted. The rationale being that if you are restricting to everything, or marking everything as unavailable, @available(*,unavailable) is a better candidate.

Stuart

···

On 27 May 2016, at 11:06, Brent Royal-Gordon <brent@architechies.com> wrote:

What I'm saying here is that even if you accept that the asterisk means all platforms, it does not follow that another argument in the same place should refer to the platform names *listed in the attribute*. That's not at all precedented in the meaning of the asterisk.

The problem is, the most natural way to express this is absolutely this:

  @available(OSX 10.8, iOS 8, *) // includes other platforms
  @available(OSX 10.8, iOS 8) // excludes other platforms

But we don't want to do that because we want people to use `*` by default. You could maybe do something like:

  @available(OSX 10.8, iOS 8, * unavailable)

But I think that reads very strangely, and it doesn't seem consistent with the other parameters. (Well, unless you can write `OSX unavailable`, which would actually be kind of convenient, but would still read oddly in a declaration named `@available`.) Hence my suggestion:

  @available(OSX 10.8, iOS 8, only)

Which is meant to be read as "Available in OS X (starting in 10.8) and iOS (starting in 8) only".

(It would be nice if the syntax actually said "OSX 10.8+", and maybe even permitted a range for things that have been retired, like `OSX 10.8..<10.10`. The main problem I see with supporting a range is that the most natural interpretation of the right end is an unavailability version, but the most useful thing to have there would be a deprecation version.)

Furthermore, the asterisk is put after a list of things *only in the shorthand syntax*, whereas you are proposing that "only" should be usable in the full syntax as well, in a position where the asterisk is not allowed. It is something else entirely to say that a feature is available in OSX version so-and-so only and then to say it's available in iOS version so-and-so only, when in fact you mean that it's not available *on other platforms*.

Yes, that was not what I intended when I suggested `only`.

What makes more sense to me would be allowing (if it isn't already allowed) `@available(*, unavailable)` to follow a previous @available declaration in order to mean that the feature is unavailable on all platforms not otherwise specified.

Yes, something like this makes sense to me too. Basically, I think the shorthand form should look like:

  @available(OSX 10.8, iOS 9.4, only)

And the longhand form like:

  @available(OSX, introduced: 10.8)
  @available(iOS, introduced: 9.4)
  @available(*, unavailable)

(The switch from `introduced=` to `introduced:` is an already-approved Swift 3 change.)

Perhaps you should even be required to say either `@available(*)` or `@available(*, unavailable)` if there are longhand `@available` attributes on the type.

--
Brent Royal-Gordon
Architechies


(Xiaodi Wu) #13

I dislike `@restricted` for several reasons. First of all, but for a desire
for brevity, @available and @restricted would do the same thing. I don't
think that's justifiable or intuitive. Second, I don't think it's at all
readable: are the named platforms restricted from using the function, or is
the function restricted to those platforms? The name could equally mean
either one.

Brent's suggestion is perfectly cogent:

@available(OSX, introduced: 10.8)
@available(iOS, introduced: 9.4)
@available(*, unavailable)

I would even go so far as to say that neither `only` nor `@restricted` are
needed. By that I mean, if you type this:

@available(OSX 10.8, iOS 9.4)

That's not valid. You'll be prompted to write this:

@available(OSX 10.8, iOS 9.4, *)

I'd propose to give the user the additional option of writing this:

@available(OSX 10.8, iOS 9.4)
@available(*, unavailable)

In other words, the rule for using the @available shorthand would be that
you must mention * somewhere; it can be at the end of the shorthand, or it
can be on its own line. This would maintain the desired verbosity so that
the latter option is not as accessible as the preferred one, but it avoids
the recitation of all unavailable platforms currently required.

···

On Thu, May 26, 2016 at 11:59 PM, Stuart Breckenridge < stuart.breckenridge@icloud.com> wrote:

Are we back in a position where a different attribute (back to @restricted or
similar keyword) would clear up the readability concerns?

The current equivalent in @available terms:

Short form:
@available(OSX 10.8, iOS 8.0, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)

Long form:
@available(OSX, introduced: 10.8, deprecated: 10.10)
@available(iOS, introduced: 8.0, deprecated: 8.4, obsoleted: 9.0)
@available(tvOS, unavailable)
@available(watchOS, unavailable)

Short form replacement:
@restricted(OSX 10.8, iOS 8.0) // Restricted to OSX, iOS from 10.8 and
8.0, respectively.

Long form replacement:
@restricted(OSX, introduced: 10.8, deprecated: 10.10)
        @restricted(iOS, introduced: 8.0, deprecated: 8.4, obsoleted: 9.0)

I would amend the draft proposal: * would not be permitted with
@restricted. The rationale being that if you are restricting to *everything,
*or marking everything as unavailable, @available(*,unavailable) is a
better candidate.

Stuart

On 27 May 2016, at 11:06, Brent Royal-Gordon <brent@architechies.com> > wrote:

What I'm saying here is that even if you accept that the asterisk means
all platforms, it does not follow that another argument in the same place
should refer to the platform names *listed in the attribute*. That's not at
all precedented in the meaning of the asterisk.

The problem is, the most natural way to express this is absolutely this:

@available(OSX 10.8, iOS 8, *) // includes other platforms
@available(OSX 10.8, iOS 8) // excludes other platforms

But we don't want to do that because we want people to use `*` by default.
You could maybe do something like:

@available(OSX 10.8, iOS 8, * unavailable)

But I think that reads very strangely, and it doesn't seem consistent with
the other parameters. (Well, unless you can write `OSX unavailable`, which
would actually be kind of convenient, but would still read oddly in a
declaration named `@available`.) Hence my suggestion:

@available(OSX 10.8, iOS 8, only)

Which is meant to be read as "Available in OS X (starting in 10.8) and iOS
(starting in 8) only".

(It would be nice if the syntax actually said "OSX 10.8+", and maybe even
permitted a range for things that have been retired, like `OSX
10.8..<10.10`. The main problem I see with supporting a range is that the
most natural interpretation of the right end is an unavailability version,
but the most useful thing to have there would be a deprecation version.)

Furthermore, the asterisk is put after a list of things *only in the
shorthand syntax*, whereas you are proposing that "only" should be usable
in the full syntax as well, in a position where the asterisk is not
allowed. It is something else entirely to say that a feature is available
in OSX version so-and-so only and then to say it's available in iOS version
so-and-so only, when in fact you mean that it's not available *on other
platforms*.

Yes, that was not what I intended when I suggested `only`.

What makes more sense to me would be allowing (if it isn't already
allowed) `@available(*, unavailable)` to follow a previous @available
declaration in order to mean that the feature is unavailable on all
platforms not otherwise specified.

Yes, something like this makes sense to me too. Basically, I think the
shorthand form should look like:

@available(OSX 10.8, iOS 9.4, only)

And the longhand form like:

@available(OSX, introduced: 10.8)
@available(iOS, introduced: 9.4)
@available(*, unavailable)

(The switch from `introduced=` to `introduced:` is an already-approved
Swift 3 change.)

Perhaps you should even be required to say either `@available(*)` or
`@available(*, unavailable)` if there are longhand `@available` attributes
on the type.

--
Brent Royal-Gordon
Architechies


(Stuart Breckenridge) #14

Named platforms always take precedence over the *, in essence.

···

Sent from my iPad

On 27 May 2016, at 15:44, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I dislike `@restricted` for several reasons. First of all, but for a desire for brevity, @available and @restricted would do the same thing. I don't think that's justifiable or intuitive. Second, I don't think it's at all readable: are the named platforms restricted from using the function, or is the function restricted to those platforms? The name could equally mean either one.

Brent's suggestion is perfectly cogent:

@available(OSX, introduced: 10.8)
@available(iOS, introduced: 9.4)
@available(*, unavailable)

I would even go so far as to say that neither `only` nor `@restricted` are needed. By that I mean, if you type this:

@available(OSX 10.8, iOS 9.4)

That's not valid. You'll be prompted to write this:

@available(OSX 10.8, iOS 9.4, *)

I'd propose to give the user the additional option of writing this:

@available(OSX 10.8, iOS 9.4)
@available(*, unavailable)

In other words, the rule for using the @available shorthand would be that you must mention * somewhere; it can be at the end of the shorthand, or it can be on its own line. This would maintain the desired verbosity so that the latter option is not as accessible as the preferred one, but it avoids the recitation of all unavailable platforms currently required.

On Thu, May 26, 2016 at 11:59 PM, Stuart Breckenridge <stuart.breckenridge@icloud.com> wrote:
Are we back in a position where a different attribute (back to @restricted or similar keyword) would clear up the readability concerns?

The current equivalent in @available terms:

Short form:
  @available(OSX 10.8, iOS 8.0, *)
  @available(tvOS, unavailable)
  @available(watchOS, unavailable)

Long form:
  @available(OSX, introduced: 10.8, deprecated: 10.10)
  @available(iOS, introduced: 8.0, deprecated: 8.4, obsoleted: 9.0)
  @available(tvOS, unavailable)
  @available(watchOS, unavailable)

Short form replacement:
  @restricted(OSX 10.8, iOS 8.0) // Restricted to OSX, iOS from 10.8 and 8.0, respectively.

Long form replacement:
  @restricted(OSX, introduced: 10.8, deprecated: 10.10)
        @restricted(iOS, introduced: 8.0, deprecated: 8.4, obsoleted: 9.0)

I would amend the draft proposal: * would not be permitted with @restricted. The rationale being that if you are restricting to everything, or marking everything as unavailable, @available(*,unavailable) is a better candidate.

Stuart

On 27 May 2016, at 11:06, Brent Royal-Gordon <brent@architechies.com> wrote:

What I'm saying here is that even if you accept that the asterisk means all platforms, it does not follow that another argument in the same place should refer to the platform names *listed in the attribute*. That's not at all precedented in the meaning of the asterisk.

The problem is, the most natural way to express this is absolutely this:

  @available(OSX 10.8, iOS 8, *) // includes other platforms
  @available(OSX 10.8, iOS 8) // excludes other platforms

But we don't want to do that because we want people to use `*` by default. You could maybe do something like:

  @available(OSX 10.8, iOS 8, * unavailable)

But I think that reads very strangely, and it doesn't seem consistent with the other parameters. (Well, unless you can write `OSX unavailable`, which would actually be kind of convenient, but would still read oddly in a declaration named `@available`.) Hence my suggestion:

  @available(OSX 10.8, iOS 8, only)

Which is meant to be read as "Available in OS X (starting in 10.8) and iOS (starting in 8) only".

(It would be nice if the syntax actually said "OSX 10.8+", and maybe even permitted a range for things that have been retired, like `OSX 10.8..<10.10`. The main problem I see with supporting a range is that the most natural interpretation of the right end is an unavailability version, but the most useful thing to have there would be a deprecation version.)

Furthermore, the asterisk is put after a list of things *only in the shorthand syntax*, whereas you are proposing that "only" should be usable in the full syntax as well, in a position where the asterisk is not allowed. It is something else entirely to say that a feature is available in OSX version so-and-so only and then to say it's available in iOS version so-and-so only, when in fact you mean that it's not available *on other platforms*.

Yes, that was not what I intended when I suggested `only`.

What makes more sense to me would be allowing (if it isn't already allowed) `@available(*, unavailable)` to follow a previous @available declaration in order to mean that the feature is unavailable on all platforms not otherwise specified.

Yes, something like this makes sense to me too. Basically, I think the shorthand form should look like:

  @available(OSX 10.8, iOS 9.4, only)

And the longhand form like:

  @available(OSX, introduced: 10.8)
  @available(iOS, introduced: 9.4)
  @available(*, unavailable)

(The switch from `introduced=` to `introduced:` is an already-approved Swift 3 change.)

Perhaps you should even be required to say either `@available(*)` or `@available(*, unavailable)` if there are longhand `@available` attributes on the type.

--
Brent Royal-Gordon
Architechies