> One of the things that surprised me is that there still isn’t concise syntax 
> for creating option sets, a pattern I see out in the wild a fair bit.  While 
> Swift 2 did introduce OptionSetType for structs, it still feels somewhat 
> obtuse and non-obvious.  It would be great if we could something like:
> 
> options NotSoSecretVariations {
>       case ProteinStyle,
>       case AnimalStyle,
>       case GrilledOnions,
>       ...
> }
> 
> That said, I have a feeling this isn’t the first time the Swift team has come 
> across a pitch like this.  If this really is unfeasible, it would be great 
> and really educational to hear what the challenges are.

Personally, what I'd like to see is the concept of an option separated from 
that of an option *set*. Once you do that, you can define an individual option 
simply using an enum, and let the set handle combining the options together.

Here's what I mean. Take an Objective-C NS_OPTIONS enum:

        typedef NS_OPTIONS(NSUInteger, NSStringCompareOptions) {
            NSCaseInsensitiveSearch = 1,
            NSLiteralSearch = 2,                /* Exact character-by-character 
equivalence */
            NSBackwardsSearch = 4,              /* Search from end of source 
string */
            NSAnchoredSearch = 8,               /* Search is limited to start 
(or end, if NSBackwardsSearch) of source string */
            NSNumericSearch = 64,               /* Added in 10.2; Numbers 
within strings are compared using numeric value, that is, Foo2.txt < Foo7.txt < 
Foo25.txt; only applies to compare methods, not find */
            NSDiacriticInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 128, /* 
If specified, ignores diacritics (o-umlaut == o) */
            NSWidthInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 256, /* If 
specified, ignores width differences ('a' == UFF41) */
            NSForcedOrderingSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 512, /* If 
specified, comparisons are forced to return either NSOrderedAscending or 
NSOrderedDescending if the strings are equivalent but not strictly equal, for 
stability when sorting (e.g. "aaa" > "AAA" with NSCaseInsensitiveSearch 
specified) */
            NSRegularExpressionSearch NS_ENUM_AVAILABLE(10_7, 3_2) = 1024    /* 
Applies to rangeOfString:..., stringByReplacingOccurrencesOfString:..., and 
replaceOccurrencesOfString:... methods only; the search string is treated as an 
ICU-compatible regular expression; if set, no other options can apply except 
NSCaseInsensitiveSearch and NSAnchoredSearch */
        };

I think this should be translated to Swift like this:

        enum NSStringCompareOption: Int {
            case CaseInsensitiveSearch = 0      // Because 1 << 0 == 1
            case LiteralSearch = 1      // 1 << 1 == 2
            case BackwardsSearch = 2
            case AnchoredSearch = 3
            case NumericSearch = 6      // 1 << 6 == 64
            case DiacriticInsensitiveSearch = 7
            case WidthInsensitiveSearch = 8
            case ForcedOrderingSearch = 9
            case RegularExpressionSearch = 10
        }

Meanwhile, a method taking NSStringCompareOptions like this:

        - (NSComparisonResult)compare:(NSString *)string 
options:(NSStringCompareOptions)mask;

Should be translated as:

        func compare(string: NSString, options mask: 
OptionSet<NSStringCompareOption>) -> NSComparisonResult

OptionSet would be a generic type like this:

        struct OptionSet<Option: RawRepresentable where Option.RawValue: 
IntegerType>: SetAlgebraType, RawRepresentable {
            typealias Element = Option
            typealias RawValue = Option.RawValue
            ...
        }

This definition should work for any NS_OPTIONS where the options are 
non-overlapping. I'm not sure if that's *every* option set in the Apple 
frameworks, but I think it's the vast majority of them. (The incompatible ones 
could use the existing mechanism.) And to create your own option set, all you 
have to do is write an enum with an integer raw type that has less than 32 or 
64 cases, depending on your target. You don't even have to specify the raw 
values—the default ones will work fine.

-- 
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to