Sent from my iPad
> On Jun 1, 2016, at 4:38 PM, Tony Allevato via swift-evolution > <[email protected]> wrote: > > I find myself agreeing with the idea that ad hoc enums are to enums as > structs are to tuples. Based on that analogy, why should an ad hoc enum > *need* a name (autogenerated or otherwise) any more than a tuple needs a > name? Would those who dislike ad hoc enums argue that this also shouldn't be > allowed: > > func foo(bar: (x: Int, y: Int)) {} > let t: (x: Int, y: Int) = (x: 5, y: 5) > > If someone writes `(.fit | .fill)` (or whatever the hypothetical syntax might > be), that should just *be* the type the same way that `(x: Int, y: Int)` is a > type without a name, and that type can be used in argument lists, variables, > or whatever. There shouldn't be any worry about declarations across multiple > functions colliding or being incompatible any more than we would worry about > two functions declaring arguments of type `(x: Int, y: Int)` would collide or > be incompatible. > > One side of ad hoc enums that I'd like to see explored is that, by being > unnamed, they're basically anonymous finite sets and we could apply > well-defined subset relationships to them: in other words, we could consider > allowing this: > > func foo(bar: (.fit | .fill)) { > baz(bar: bar) > } > func baz(bar: (.fit | .fill | .florp) { ... } > > In other words, an ad hoc enum T can be used wherever an ad hoc enum U is > expected if T ⊆ U. When I said I am very opposed to this feature *unless* these ad-hoc enums have structural subtyping this is what I was talking about. IMO this is absolutely essential if we introduce ad-hoc enums (as well as the ability to use the types for variables, not just parameters). > > >> On Wed, Jun 1, 2016 at 1:43 PM L. Mihalkovic via swift-evolution >> <[email protected]> wrote: >> >> >> > On Jun 1, 2016, at 6:51 PM, Vladimir.S <[email protected]> wrote: >> > >> > Yes, I also can support the idea of autogenerated type name (like >> > Enum_fit_OR_fill) as long as it allows to do all the things we are >> > discussing here: declare (.fit|.fill) in function, use .fit on calling >> > side, use (.fit|.fill) to declare temporary variable of type compatible >> > with such function parameter etc. >> > >> >> It all works because the compiler is just being a thoughless scribe that >> just writes the standard enum we don't bother to write ourselves. Because >> the heuristic is simple and straightforward then it is predictible. The enum >> can be used with its long name be ause it is a real enum. And writing the >> short form of it also works because the compiler knowns uniquely what the >> long name is everytime it runs into the short name. >> >> >> > But how do you suggest to define a type of such function in `typealias` >> > for example? i.e. for func my(option: (.fit|.fill) {..} >> > >> > typealias MyFunc = ((.fit|.fill)) -> () >> > or as >> > >> > typealias MyFunc = (Enum_fit_OR_fill) -> () >> > >> >> Ideally there is no difference whatsoever, there is a single enum, it is >> produced at the module level, and it has the long form name. >> >> There can be rules that would prevent us from doing that with externally >> visible APIs, if the core team fuges that we should take the time to write >> our enums manually and cleanly to make them visible to the world, but it is >> not a necessary rule. >> >> >> > >> > But I still can't support the idea of limiting the usage of such enums - >> > i.e. "To deal with milti site definition, the compiler would simply flag a >> > error/warning, or be silent in the presence of a new annotation:". I >> > really think we need then introduce the same rule for tuples - so no one >> > can use the same tuple declaration in function - they then should declare >> > separate struct type or use @something for such functions. Nobody wants >> > such rule for tuples. >> > >> >> Multi site thing is not a limitation... Is is a proposed rule to say that we >> are able to be lazy twice without being penalized. Yhe compiler does not >> like when we define the same thing twice, and thse short form amount to >> doing what he does not let us do. But because this is about concise and >> lazy, then the compiler can let us get away with it if we use an annotation >> that lets it know that "it is not a mistake.. I really dont want to write >> that enum myself, even though I am using the same abbreviation twice". >> Otherwise, the compiler would let us know that the second time could be a >> mistake because there is already something with the same name... >> >> But again this is a separate idea from the core notion of a syntax sugaring >> for writing real enums the lazy (clever) way >> >> >> On 01.06.2016 19:04, L. Mihalkovic wrote: >> >> The only problem with this proposal is to consider them ad-hoc enums... >> >> If we view them as having nothing ad-hoc about them and the thing to be a >> >> simple sugaring exercise, then I think all the opositions on grounds of >> >> breaking the language disapear. It still does not mean it should be done >> >> if the core team does not like the idea of encouraging laziness, or >> >> simply do not like what it makes them look like. No matter what, this >> >> type of sugaring exercise has been clearly stated as out of scope for 3.0 >> >> >> >>>> On Jun 1, 2016, at 2:38 PM, Vladimir.S via swift-evolution >> >>>> <[email protected]> wrote: >> >>>> >> >>>> On 01.06.2016 11:00, Austin Zheng wrote: >> >>>> Tuples are a structural type, they are described entirely by the fact >> >>>> that they are a tuple, plus their contained types. >> >>>> >> >>>> Enum cases are not individual types; that precedent exists nowhere in >> >>>> Swift. You can't (yet) build a structural type out of something that >> >>>> isn't a type. The fact that you had to propose something like >> >>>> "AdhocEnumFitFill_2383748" as an autogenerated name for the type >> >>>> demonstrates the proposal's weaknesses: a tuple is an ad-hoc type that >> >>>> describes itself, while an anonymous enum isn't. >> >>> >> >>> Yes, I understand the point about the type of such adhoc enum. >> >>> The only workaround I can see in this case(if we'd really want to have >> >>> it in language) if adhoc enum type will be `(.Fit|.Fill)` i.e. textual >> >>> representation if the declared type. As I understand this also could not >> >>> be a solution.. I.e. for example `(Int,String,(.Fit|.Fill))->String` >> >>> >> >>> From other point of view, adding such type to typesystem will add some >> >>> consistence : you can create a function that don't need definition of >> >>> separate structure type(tuple will be used) and don't need separate enum >> >>> type(ad-hoc enum will be used). I.e. all data the function needs to >> >>> process could be described in function definition. Today we need to use >> >>> ugly Bool flags in case we want to achieve the same target. >> >>> >> >>>> >> >>>> Now if enum cases were equivalent if they had the same name (like how >> >>>> "Int" means the same thing no matter what tuple or generic type it is >> >>>> used in), we'd have a good foundation for a self-describing structural >> >>>> type. But this isn't how the existing named enum types work. Why would >> >>>> it be a good idea to make anonymous enum cases interchangeable by name? >> >>>> Properties on different types aren't interchangeable, even if they have >> >>>> the same type. In fact, no type member that I am aware of is >> >>>> interchangeable solely on the basis of name. An "ArtistAction.Draw" and >> >>>> "CowboyAction.Draw" might have the same name, but they mean completely >> >>>> different things. >> >>> >> >>> I don't think they should be 'interchangeable by name', but just like >> >>> tuples if you defined adhoc enum with exactly the same cases as ad-hoc >> >>> enum in function parameters - then they are of the same type. >> >>> >> >>> I.e. : >> >>> >> >>> func foo(option: (.fit|.fill)) {..} >> >>> >> >>> foo(.fit) // .fit is of type (.fit|.fill) from definition >> >>> >> >>> let e : (.fit|.fill) = .fit >> >>> foo(e) // e is of (.fit|.fill) type, equal to definition >> >>> >> >>> but >> >>> >> >>> func foo2(option: (.fit|.fill|.other)) {..} >> >>> >> >>> foo2(.fit) // ok, here .fit is of (.fit|.fill|.other) type >> >>> foo2(e) --> Error, e is not of type (.fit|.fill|.other) >> >>> >> >>>> >> >>>> Finally, I have to ask: if you are updating your anonymous enum in >> >>>> multiple places, how much effort have you actually saved over a one-line >> >>>> enum definition? In fact, tuples are a great example of this: best >> >>>> practices usually state that they are good for ad-hoc destructuring, >> >>>> such as retrieving multiple return values from a function or pattern >> >>>> matching across several values at once, but structs are better used for >> >>>> almost everything else, since they carry semantic meaning that tuples >> >>>> don't. >> >>>> >> >>> >> >>> Just the same pros and cons for ad-hoc enums vs enum declaration as for >> >>> tuples vs struct declaration. Yes can use it with care and you can use >> >>> it in wrong way. >> >>> >> >>> Btw, I feel like this could be very handy to return adhoc enum: >> >>> >> >>> func something() -> (.one|.two|.three) {...} >> >>> >> >>>> I hope that clarifies my thoughts on the matter. >> >>>> >> >>>> Best, Austin >> >>>> >> >>>> >> >>>>> On Jun 1, 2016, at 12:36 AM, Vladimir.S <[email protected]> wrote: >> >>>>> >> >>>>> On 01.06.2016 9:55, Austin Zheng via swift-evolution wrote: >> >>>>>> Maybe it's overkill. My personal opinion is that breaking the >> >>>>>> symmetry of the language like this (are there any other types of >> >>>>>> function arguments that cannot be passed as either variable values >> >>>>>> or literals?) is too much a price to pay. Your library thinks it's >> >>>>>> being clever and vends its functions as taking anonymous enum flags, >> >>>>>> and now there are a bunch of things I can't do with those functions >> >>>>>> anymore. >> >>>>>> >> >>>>>> A regular enum can be declared in one line anyways: >> >>>>>> >> >>>>>> enum ScaleCropMode { case Fit, Fill } >> >>>>> >> >>>>> Why do we have tuples? Struct could be defined by one line `struct >> >>>>> SomeValue { var x = 0, y = 0 }` ;-) I.e. from my point of view >> >>>>> developer should decide what he/she wants to use: ad-hoc enum or >> >>>>> defined enum type *exactly* as now he/she can decide to use the same >> >>>>> tuples in multiply functions instead of one defined struct type. >> >>>>> >> >>>>> I replied regarding the variable on other message. (In short: I think >> >>>>> of the same principle as for tuples: you can declare variable `let e: >> >>>>> (.fill | .fit) = .fill` and use it) >> >>>>> >> >>>>>> >> >>>>>> Austin >> >>>>>> >> >>>>>>> On May 31, 2016, at 11:44 PM, Charles Constant >> >>>>>>> <[email protected] <mailto:[email protected]>> wrote: >> >>>>>>> >> >>>>>>>> It breaks the ability to pass in a variable containing the >> >>>>>>>> desired >> >>>>>>> value, rather than the literal value itself. >> >>>>>>> >> >>>>>>> Maybe that's appropriate? If the caller is not passing in a >> >>>>>>> hardcoded enum case, then that enum is probably general enough >> >>>>>>> that it warrants a normal enum. But there are also situations >> >>>>>>> where the same function is called from several files in the same >> >>>>>>> code-base with different flags. Those are situations where it >> >>>>>>> feels like overkill to clutter up my codebase with separate enums, >> >>>>>>> only used by a single function. >> >>>>>>> >> >>>>>>> >> >>>>>>> >> >>>>>>> >> >>>>>>> >> >>>>>>> On Tue, May 31, 2016 at 9:24 PM, Austin Zheng via swift-evolution >> >>>>>>> <[email protected] <mailto:[email protected]>> >> >>>>>>> wrote: >> >>>>>>> >> >>>>>>> I admire the desire of this proposal to increase the readability >> >>>>>>> of code. I'm -1 to the proposal itself, though: >> >>>>>>> >> >>>>>>> - It breaks the ability to pass in a variable containing the >> >>>>>>> desired value, rather than the literal value itself. (Unless you >> >>>>>>> actually want a not-so-anonymous enum type whose definition >> >>>>>>> happens to live in a function signature rather than somewhere >> >>>>>>> you'd usually expect a type definition to live.) - It breaks the >> >>>>>>> ability to store a reference to the function in a variable of >> >>>>>>> function type (ditto). - Almost every time I've wanted to use one >> >>>>>>> of these "anonymous enums" in my code, I've ended up needing to >> >>>>>>> use that same enum elsewhere. In my experience, 'lightweight >> >>>>>>> enums' don't end up saving much time compared to a full-fledged >> >>>>>>> one. >> >>>>>>> >> >>>>>>> Like Brent said, I have to say no to any proposal that tries to >> >>>>>>> make enums synonyms for numerical values. What happens if you >> >>>>>>> rearrange your anonymous enum cases between library versions? Do >> >>>>>>> you somehow store an opaque case-to-UInt8 table somewhere for >> >>>>>>> every anonymous enum you define for resilience? What happens when >> >>>>>>> people start bringing back terrible C patterns, like doing >> >>>>>>> arithmetic or bitwise ops on the underlying case values? At least >> >>>>>>> you have to try pretty hard as it is to abuse Swift's enums. >> >>>>>>> >> >>>>>>> Austin >> >>>>>>> >> >>>>>>> On Tue, May 31, 2016 at 8:25 PM, Brent Royal-Gordon via >> >>>>>>> swift-evolution <[email protected] >> >>>>>>> <mailto:[email protected]>> wrote: >> >>>>>>> >> >>>>>>>> And the obvious answer is you can have up to 255 of these babies >> >>>>>>>> for the anonymous enum type, and be able to pass numerical >> >>>>>>>> equivalents UInt8 with compile time substitution. That the >> >>>>>>>> ad-hoc enumeration is basically a syntactic shorthand for UInt8, >> >>>>>>>> with an enforced upper bound compile time check simplifies >> >>>>>>>> everything including switch statements. >> >>>>>>> >> >>>>>>> If I wanted a language like that, I'd be writing C, not Swift. >> >>>>>>> >> >>>>>>> -- Brent Royal-Gordon Architechies >> >>>>>>> >> >>>>>>> _______________________________________________ swift-evolution >> >>>>>>> mailing list [email protected] >> >>>>>>> <mailto:[email protected]> >> >>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >>>>>>> >> >>>>>>> >> >>>>>>> >> >>>>>>> _______________________________________________ swift-evolution >> >>>>>>> mailing list [email protected] >> >>>>>>> <mailto:[email protected]> >> >>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >>>>>>> >> >>>>>>> >> >>>>>> >> >>>>>> >> >>>>>> >> >>>>>> _______________________________________________ swift-evolution >> >>>>>> mailing list [email protected] >> >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >>>>>> >> >>>> >> >>>> >> >>> _______________________________________________ >> >>> swift-evolution mailing list >> >>> [email protected] >> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
