I don't think there's any computer science type theory reason, but that we just simply forgot. (It's actually a struct
, not an enum
.)
Sounds reasonable semantically. Would need proposal. What is a practical use case for it though?
The same for any other CaseIterable
-conforming type, to make loops over all of its values. We can make a two-element array with a map
. And not conforming is viral on any enumeration type that wants to use Bool
as part of a payload.
You're describing the API of CaseIterable
. But what is an example of a practical use case for that, for Bool
?
There might be generic algorithms or data-structures which depend on CaseIterable
(after all, it exists as a protocol because it is a useful abstraction). If you wanted to use that code with Bool
, you’d need to make a type you don’t own conform to a protocol you don’t own, which is a big no-no.
So I agree that it is reasonable, even without concrete use-cases (just inferring that it is useful because CaseIterable
is), and only the standard library can properly enable it.
Sure, if we posit the existence of these algorithms and we assume they would make sense to use with Bool
; do we have real-world examples of such? Phrased differently, are there use cases where this protocol is a useful abstraction that would equally be useful for Bool
?
Personally I’ve only found limited use for CaseIterable, but I know others have found it useful.
I guess what I’m saying is that, since we discourage these kinds of retroactive conformances, every conformance we don’t add between standard library types and protocols is almost a conscious design decision. In other words, stdlib types should conform to as many stdlib protocols as they can, even if we can’t picture a specific use.
That would be entirely counter to the principles behind evolving the design of the standard library. If a feature is not demonstrably useful, and we can't even picture a specific use, it absolutely should not be added (or even considered). Each conformance adds to the design complexity of the standard library. We would not go around conforming types to protocols just because we can.
Without replying on whether or not we should do this, we still don't have any syntax or compiler support to add conformances to stdlib types post ABI. See: Backwards-deployable Conformances. So even if a proposal were to be born, evaluated, and accepted, it would forever be blocked by this. Not trying to be a debbie downer, just trying to set expectations here.
There appear to be libraries which build form UIs for types with CaseIterable
properties. That’s a use-case that I think could apply to Bool
.
This is a recipe for bad design IMHO. Bool
should ne be represented in UI like a CaseIterable
. It should use a check box or a switch, and CaseIterable
should use a dropdown list or something like that.
It's the only scalar type provided by the Standard Library that doesn't currently provide any form of automated traversal. (The other scalar types are the default numeric types, and as such all conform to Strideable
.) It would be even less appropriate to make Bool
conform to Comparable
(let alone Strideable
) to use with ranges, so CaseIterable
is the only other way to do it.
The inspiration came from a test suite I'm writing. I originally made separate testing statements for each enumeration case. Then I remembered about CaseIterable
and made my type conform. So I could redo the tests as a loop:
let expected = [ /*...*/ ]
let expectedResults = Dictionary(uniqueKeysAndValues: zip(MyEnum.allCases, expected))
for c in MyEnum.allCases {
XCTAssertEqual(myFunction(c), expectedResults[c], "\(c)")
}
I realized I may want to test function results against a Bool
argument someday, and checked if Bool
supports CaseIterable
. We have these higher-order functions, but can't use them with Bool
without explicitly writing a "[false, true]
" or "[myFunc(false), myFunc(true)]
".
Depends on the platform - what you said is what Apple recommend for their most popular platforms, but is not necessarily a universal rule. Some Interfaxes might not even be visual - you might generate an audio interface, or one that is presented on some special assistive device.
The more general point is - CaseIterable
is useful for generating interfaces based on the possible values that a type can have, and Bool
is able to provide that information, which is the only thing that generic code cares about. Whether or not that code wishes to special-case Bool
is their own decision.
I didn't think about Apple OS in particular. This is true for the web (HTML), for Android, for Java (Swing, JavaFX, …), and for any other toolkit I had to use.
And even for non-graphical interfaces, I don't think presenting a Bool like any choice list is the best way to represent them.
Bool
have a very well defined and well-known semantic that you just ignore when using them like any CaseIterable
.
There may be some rare case where it does not matter, but I don't think they are common enough to make Bool
conform to CaseIterable
.
It doesn’t make sense because one of the orders is as good as the other.
Are there any Types that have CaseIterabe
conformance built-in? I'm not aware of any. I would expect the reasons it shouldn't be added to Bool is the same reason it shouldn't automatically be added to every enum
There's no objective order that can be applied in all situations, and it's very easy for users that need the functionality to opt-in.
I want to automatically traverse every value, not necessarily want the publication order to be part of any semantic. Yet another reason to have a Sequence
-with-the-publication-order-is-part-of-the-type's-semantics-"requirement"-ripped-out protocol. (It should be a base protocol to Sequence
, but that brings ABI difficulties.)