Discussion: Enforce usage of @available on enum cases


(Stuart Breckenridge) #1

Presently, you can mark enum cases as @available but it has no impact. Take the following example:

enum Things:String {
  @available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
  @available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no warnings:

func takesA(thing:Things) {
  print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be considered? At the very least, if @available doesn't do anything on cases, it shouldn't be permitted.


(Jordan Rose) #2

The “*” in @available means “all other platforms”. If you want to mark something unavailable on a particular platform, you’ll have to use the long form of the @available attribute. There’s currently no way to mark something “only available on these platforms”.

Jordan

···

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

Presently, you can mark enum cases as @available but it has no impact. Take the following example:

enum Things:String {
  @available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
  @available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no warnings:

func takesA(thing:Things) {
  print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be considered? At the very least, if @available doesn't do anything on cases, it shouldn't be permitted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jacob Bandes-Storch) #3

Was this an intentional choice, or is it just a temporary limitation? Would
a proposal to allow something like "@available(OS X 10.11)" be welcomed?

···

On Wed, May 25, 2016 at 8:17 PM, Jordan Rose via swift-evolution < swift-evolution@swift.org> wrote:

The “*” in @available means “all other platforms”. If you want to mark
something *unavailable* on a particular platform, you’ll have to use the
long form of the @available attribute. There’s currently no way to mark
something “only available on these platforms”.

Jordan

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

Presently, you can mark enum cases as @available but it has no impact.
Take the following example:

enum Things:String {
@available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
@available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no
warnings:

func takesA(thing:Things) {
print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be
considered? At the very least, if @available doesn't do anything on
cases, it shouldn't be permitted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Jordan Rose) #4

This was deliberate, and came from the pain of bringing up tvOS (and watchOS). Clang actually had a hack to treat “available on iOS” as “available on tvOS” for a while because of this. When you port something to a new platform, presumably everything that’s been introduced so far should be available from the start.

If we introduced a limited availability attribute, I think we’d want to make it more verbose than the normal one, so that you know you’re choosing it.

Jordan

···

On May 25, 2016, at 20:18, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Was this an intentional choice, or is it just a temporary limitation? Would a proposal to allow something like "@available(OS X 10.11)" be welcomed?

On Wed, May 25, 2016 at 8:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
The “*” in @available means “all other platforms”. If you want to mark something unavailable on a particular platform, you’ll have to use the long form of the @available attribute. There’s currently no way to mark something “only available on these platforms”.

Jordan

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

Presently, you can mark enum cases as @available but it has no impact. Take the following example:

enum Things:String {
  @available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
  @available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no warnings:

func takesA(thing:Things) {
  print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be considered? At the very least, if @available doesn't do anything on cases, it shouldn't be permitted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Stuart Breckenridge) #5

Taking the long form approach:

enum Things:String {
    @available (iOS 9.0, tvOS 9.0, watchOS 2.0, *)
    @available (OSX, unavailable, message="Not available on OS X.")
    case MobileThing = "com.example.mobile"
    
    @available (iOS, unavailable, message="Not available on iOS.")
    @available (tvOS, unavailable, message="Not available on tvOS.")
    @available (watchOS, unavailable, message="Not available on watchOS.")
    @available (OSX 10.11, *)
    case DesktopThing = "com.example.desktop"
}

This yields the expected result in a tvOS app:

func that(thing:Things) -> () {
        print(thing)
}
that(.DesktopThing) // 'DesktopThing' is unavailable. Not available on tvOS.

A limited availability attribute does have some merit, perhaps using a different keyword (so you know you are choosing it), for example:

      @restricted (OSX 10.11, *, message="Only available on OS X.")
      case DesktopThing = "com.example.desktop"
  
  func that(thing:Things) -> () {
          print(thing)
  }
  that(.DesktopThing) // 'DesktopThing' is unavailable. Only available on OS X.

...but this is outside the scope of the original topic.

Stuart

···

On 26 May 2016, at 11:23, Jordan Rose <jordan_rose@apple.com> wrote:

This was deliberate, and came from the pain of bringing up tvOS (and watchOS). Clang actually had a hack to treat “available on iOS” as “available on tvOS” for a while because of this. When you port something to a new platform, presumably everything that’s been introduced so far should be available from the start.

If we introduced a limited availability attribute, I think we’d want to make it more verbose than the normal one, so that you know you’re choosing it.

Jordan

On May 25, 2016, at 20:18, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Was this an intentional choice, or is it just a temporary limitation? Would a proposal to allow something like "@available(OS X 10.11)" be welcomed?

On Wed, May 25, 2016 at 8:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
The “*” in @available means “all other platforms”. If you want to mark something unavailable on a particular platform, you’ll have to use the long form of the @available attribute. There’s currently no way to mark something “only available on these platforms”.

Jordan

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

Presently, you can mark enum cases as @available but it has no impact. Take the following example:

enum Things:String {
  @available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
  @available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no warnings:

func takesA(thing:Things) {
  print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be considered? At the very least, if @available doesn't do anything on cases, it shouldn't be permitted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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


(Charlie Monroe) #6

Personally, I'd support splitting the @available attribute into:

@available - indicating that the identifier is available since some version.
@unavailable - indicating that it's unavailable for certain.
@deprecated - indicating deprecation.

···

+

@restricted as Stuart suggests, which seems very useful.

@available (iOS, unavailable, message="Not available on iOS.")

vs.

@unavailable (iOS, message="Not available on iOS.")

IMHO removes some unnecessary boilerplate.

Charlie

On May 26, 2016, at 6:36 AM, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org> wrote:

Taking the long form approach:

enum Things:String {
    @available (iOS 9.0, tvOS 9.0, watchOS 2.0, *)
    @available (OSX, unavailable, message="Not available on OS X.")
    case MobileThing = "com.example.mobile"
    
    @available (iOS, unavailable, message="Not available on iOS.")
    @available (tvOS, unavailable, message="Not available on tvOS.")
    @available (watchOS, unavailable, message="Not available on watchOS.")
    @available (OSX 10.11, *)
    case DesktopThing = "com.example.desktop"
}

This yields the expected result in a tvOS app:

func that(thing:Things) -> () {
        print(thing)
}
that(.DesktopThing) // 'DesktopThing' is unavailable. Not available on tvOS.

A limited availability attribute does have some merit, perhaps using a different keyword (so you know you are choosing it), for example:

      @restricted (OSX 10.11, *, message="Only available on OS X.")
      case DesktopThing = "com.example.desktop"
  
  func that(thing:Things) -> () {
          print(thing)
  }
  that(.DesktopThing) // 'DesktopThing' is unavailable. Only available on OS X.

...but this is outside the scope of the original topic.

Stuart

On 26 May 2016, at 11:23, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

This was deliberate, and came from the pain of bringing up tvOS (and watchOS). Clang actually had a hack to treat “available on iOS” as “available on tvOS” for a while because of this. When you port something to a new platform, presumably everything that’s been introduced so far should be available from the start.

If we introduced a limited availability attribute, I think we’d want to make it more verbose than the normal one, so that you know you’re choosing it.

Jordan

On May 25, 2016, at 20:18, Jacob Bandes-Storch <jtbandes@gmail.com <mailto:jtbandes@gmail.com>> wrote:

Was this an intentional choice, or is it just a temporary limitation? Would a proposal to allow something like "@available(OS X 10.11)" be welcomed?

On Wed, May 25, 2016 at 8:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
The “*” in @available means “all other platforms”. If you want to mark something unavailable on a particular platform, you’ll have to use the long form of the @available attribute. There’s currently no way to mark something “only available on these platforms”.

Jordan

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

Presently, you can mark enum cases as @available but it has no impact. Take the following example:

enum Things:String {
  @available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
  @available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no warnings:

func takesA(thing:Things) {
  print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be considered? At the very least, if @available doesn't do anything on cases, it shouldn't be permitted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

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


(Stuart Breckenridge) #7

I'll put together a draft in a new thread.

···

Sent from my iPhone

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

Personally, I'd support splitting the @available attribute into:

@available - indicating that the identifier is available since some version.
@unavailable - indicating that it's unavailable for certain.
@deprecated - indicating deprecation.

+

@restricted as Stuart suggests, which seems very useful.

@available (iOS, unavailable, message="Not available on iOS.")

vs.

@unavailable (iOS, message="Not available on iOS.")

IMHO removes some unnecessary boilerplate.

Charlie

On May 26, 2016, at 6:36 AM, Stuart Breckenridge via swift-evolution <swift-evolution@swift.org> wrote:

Taking the long form approach:

enum Things:String {
    @available (iOS 9.0, tvOS 9.0, watchOS 2.0, *)
    @available (OSX, unavailable, message="Not available on OS X.")
    case MobileThing = "com.example.mobile"
    
    @available (iOS, unavailable, message="Not available on iOS.")
    @available (tvOS, unavailable, message="Not available on tvOS.")
    @available (watchOS, unavailable, message="Not available on watchOS.")
    @available (OSX 10.11, *)
    case DesktopThing = "com.example.desktop"
}

This yields the expected result in a tvOS app:

func that(thing:Things) -> () {
        print(thing)
}
that(.DesktopThing) // 'DesktopThing' is unavailable. Not available on tvOS.

A limited availability attribute does have some merit, perhaps using a different keyword (so you know you are choosing it), for example:

      @restricted (OSX 10.11, *, message="Only available on OS X.")
      case DesktopThing = "com.example.desktop"
  
  func that(thing:Things) -> () {
          print(thing)
  }
  that(.DesktopThing) // 'DesktopThing' is unavailable. Only available on OS X.

...but this is outside the scope of the original topic.

Stuart

On 26 May 2016, at 11:23, Jordan Rose <jordan_rose@apple.com> wrote:

This was deliberate, and came from the pain of bringing up tvOS (and watchOS). Clang actually had a hack to treat “available on iOS” as “available on tvOS” for a while because of this. When you port something to a new platform, presumably everything that’s been introduced so far should be available from the start.

If we introduced a limited availability attribute, I think we’d want to make it more verbose than the normal one, so that you know you’re choosing it.

Jordan

On May 25, 2016, at 20:18, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Was this an intentional choice, or is it just a temporary limitation? Would a proposal to allow something like "@available(OS X 10.11)" be welcomed?

On Wed, May 25, 2016 at 8:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:
The “*” in @available means “all other platforms”. If you want to mark something unavailable on a particular platform, you’ll have to use the long form of the @available attribute. There’s currently no way to mark something “only available on these platforms”.

Jordan

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

Presently, you can mark enum cases as @available but it has no impact. Take the following example:

enum Things:String {
  @available (iOS 9.3, *) case MobileThing = "com.example.mobilething"
  @available (OSX 10.11, *) case DesktopThing = "com.example.desktopthing"
}

Despite the above compiling, the following code will run iOS with no warnings:

func takesA(thing:Things) {
  print(thing)
}

takesA(.DesktopThing)

Are there enough compelling use-cases for @available on enum cases to be considered? At the very least, if @available doesn't do anything on cases, it shouldn't be permitted.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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

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