[swift-dev] Swift C enum Case Mapping

Ryan Lovelett swift-dev at ryan.lovelett.me
Mon Jan 11 15:25:41 CST 2016


I think I get where you are going. But I'm not going to drop it quite
that easily. Forgive my insolence but I still think there is room for a
sane default here.

To answer your question: it is an enum that deliberately does not start
at 0. If Swift made that the default import symantics then I think all
the cases you covered (selfishly even my case) would be adequately
addressable.

Lets say there are, at least, 3 types of enums:
 1. A non-overlapping, non-option set enum
 2. A non-overlapping option set
 3. An overlapping option set

In this case, I'd say the enum was of type 2; a non-overlapping option
set. If it was something the developer needed to conform to the
`OptionSetType` then the developer who imported the type could provide a
simple extension to the enum that provides conformance with the
`OptionSetType`. Voila. Now it is an option set.

More concretely:

enum Foo: Int {      case A = 1      case B = 2    }

// Not automatic but available in this hypothetical world    extension
Foo: OptionSetType {      init(rawValue: Int) {        self =
Foo.init(rawValue: rawValue) ?? Foo.A      }    }

If it was really some sort of constant then now it can be accessed via
it's `rawValue` property (isn't that the way it would be accessed as it
currently stands?).

If it was just an enum, well then that's covered too.

I tried compiling a few contrived enums based on this one to illustrate
how I'd expect them to be mapped. I've put them into this gist[1].

I think if you took it in terms of pattern matching where the the first
case is the strictest pattern (and thus the hardest to conform to) by
the time you reach the 3rd case your back to the current behavior. Swift
would then be able to account for more generic enum imports than it
currently can.

On Mon, Jan 11, 2016, at 02:51 PM, Jordan Rose wrote:
> Oh, you can certainly define a macro named NS_ENUM yourself, but that
> doesn't really seem like the right thing to do on Linux.
>
> As for why we can't "guess" that this is a true enum, consider the
> following:
>
>> enum Foo {  A = 1,  B = 2, };
>
> Is this a very small option set, or an enum that deliberately doesn't
> start at 0? Or just a way to define constants for some other type,
> rather than using "static const"? If the compiler guesses here, (a) it
> might guess wrong, making the type hard to use *now,* and (b) if the
> headers are updated in a newer version of the library, it might
> *change* its guess, which would break source compatibility. (This can
> happen anyway, e.g. the first time an annotation is added, but at
> least that's supposed to be changing in the right direction, and is
> unlikely to change again.)
>
> Hope that clarifies the motivation here, even if it's less than
> satisfactory.
>
> Jordan
>
>
>> On Jan 11, 2016, at 11:22, Ryan Lovelett <swift-
>> dev at ryan.lovelett.me> wrote:
>>
>> Jordan,
>>
>> Perhaps I'm not following that parenthetical comment. Are you saying
>> that even if I could add NS_ENUM to the header it still wouldn't
>> compile into a true Swift enum (on a non-Apple platform)?
>>
>> Swift's pattern matching capability is probably a top 3 reason why I
>> am trying to port my C application to use Swift rather than just
>> straight C. Not being able to get this nicety out-of-the-box is just
>> part of doing business on a bleeding edge programming language.
>>
>> However this *seems* like something that should be able to be
>> achieved. Looking at the fe_type enum definition, because it had no
>> bit pattern associated with it, I would have assumed it was a true
>> non-overlapping enum. Its probable I'm not seeing the whole landscape
>> here so would you be able to illuminate why isn't this the default?
>>
>> On Mon, Jan 11, 2016, at 01:11 PM, Jordan Rose wrote:
>>> Right. This is because Swift can't tell if your enum is actually an
>>> option set, a true, non-overlapping enum, or just a set of related
>>> constants, so it picks the lowest common denominator. We currently
>>> don't have a great way to override that in headers you don't
>>> control.
>>>
>>> (Heck, on non-Apple platforms we don't have a great way to do it in
>>> headers you do control; Swift is currently keying off the macro
>>> names.)
>>>
>>> Jordan
>>>
>>>> On Jan 10, 2016, at 13:25 , Austin Zheng via swift-dev <swift-
>>>> dev at swift.org> wrote:
>>>>
>>>> I spoke too soon, the cases are also defined as values of that
>>>> type. So, a working version of your code:
>>>>
>>>> extensionfe_type:CustomStringConvertible{
>>>> publicvardescription:String{ switchself{ caseFE_QPSK:return"QPSK"
>>>> caseFE_QAM:return"QAM" caseFE_OFDM:return"OFDM"
>>>> caseFE_ATSC:return"ATSC" default:fatalError("can't be exhaustive")
>>>> }  } }
>>>>
>>>> Best, Austin
>>>>
>>>>> On Jan 10, 2016, at 1:22 PM, Austin Zheng <austinzheng at gmail.com>
>>>>> wrote:
>>>>>
>>>>> Hi Ryan,
>>>>>
>>>>> Apologies, I should have been more clear. In Xcode you can alt(?)-
>>>>> click on a type (e.g the 'MyType' in "let a : MyType = 123") in
>>>>> the IDE to pop up a little window that shows you the definition,
>>>>> including the type and some other information. If you're on a
>>>>> Linux box or not using an IDE you probably don't have that option.
>>>>>
>>>>> The only methods I see exposed on the Swift imported type are
>>>>> initializers taking a integer raw value, and a 'rawValue' property
>>>>> for getting back out the raw value. Hope that helps.
>>>>>
>>>>> Austin
>>>>>
>>>>>> On Jan 10, 2016, at 1:18 PM, Ryan Lovelett <swift-
>>>>>> dev at ryan.lovelett.me> wrote:
>>>>>>
>>>>>> Austin,
>>>>>>
>>>>>> I guess I should say that the `typedef` is coming from aLinux
>>>>>> kernel header[2]. So I don't think I'm going to be able to add
>>>>>> any macros to the definition.
>>>>>>
>>>>>> What do you mean about alt-click? Alt click where?
>>>>>>
>>>>>> On Sun, Jan 10, 2016, at 04:12 PM, Austin Zheng wrote:
>>>>>>> fe_type is being imported as a struct (alt-click 'fe_type' in
>>>>>>> Swift). I think if you want it to be imported as an enum you
>>>>>>> need to use the NS_ENUM macro in the definition, which might not
>>>>>>> be possible in your case.
>>>>>>>
>>>>>>> Austin
>>>>>>>
>>>>>>>> On Jan 10, 2016, at 1:06 PM, Ryan Lovelett via swift-dev <swift-
>>>>>>>> dev at swift.org> wrote:
>>>>>>>>
>>>>>>>> typedef enum fe_type { FE_QPSK, FE_QAM, FE_OFDM, FE_ATSC }
>>>>>>>> fe_type_t;
>>>>>>
>>>>>
>>>>
>>>>  _______________________________________________
>>>> swift-dev mailing list swift-dev at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-dev
>>



Links:

  1. https://gist.github.com/anonymous/232d62d77999f5eb27cd
  2. http://lxr.free-electrons.com/source/include/linux/dvb/frontend.h?v=3.2
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160111/2fb26331/attachment.html>


More information about the swift-dev mailing list