Is the lack of comments due to general disinterest in such a thing or did my 
mail go amiss somehow? ;)

Best, 

 Taras

> On 31 Mar 2016, at 14:39, Taras Zakharko <[email protected]> wrote:
> 
> Recently, I have been working on implementing some non-trivial data 
> structures in Swift (its about storing polygons in a space-partitioning 
> tree). I am using enums to represent different types of parent nodes and 
> leafs and I had some ideas to make them more fit for this kind of work. I 
> expect that I will write multiple enum-related emails, each one concentrating 
> on one particular feature. A usual disclaimer: these are random, quite rough 
> ideas that might or not make sense, but I’d like to get some feedback  from 
> the community. 
> 
> Case-based dispatch for enum methods
> 
> Often, behaviour of enum method depends on the enum value. For instance, 
> imagine a tree structure with an insert(value:) method: the way how the 
> inserting is handled depends on the type of the node. Usually, you’d 
> implement it as a switch operation:
> 
> func insert(value:T) {
>   switch self {
>     case let Leaf1(a, b, c): …
>     case let Leaf2(a, b): …
>     case let Parent1(x, y): …
>   }
> }
> 
> If the insert operation is non-trivial, this becomes quite convoluted. You 
> can of course define private helper methods or functions that perform the 
> specific functionality, but I don’t find it to be a very satisfying solution: 
> there is still the switch boilerplate + you need to be careful to call the 
> correct helper, so there are some safety issues. 
> 
> Now, suppose there was a way to add a method implementation that is 
> case-specific:
> 
> enum MyTree {
>   case Leaf1(Float, Float) {
>     mutating  func insert(value: T) {
>        let (a, b) = self.Leaf1 // or something like that
>        // handle insert for the case that node is of type Parent1
> 
>        ...
>      }
>   }
> 
>  case Parent1(Int, Float) {
>      mutating func insert(value: T) {
>        let (x, y) = self.Parent1 // or something like that
>        // handle insert for the case that node is of type Parent1
>        ...
>      }
>   }
> 
> default {
>    mutating func insert(value: T) {
>       // handle insert for all other cases 
>        ...
>      }
> }
> }
> 
> etc. The case method specification needs to be exhaustive and adhere to the 
> same signature. It is a compile-time error to specify a method or property 
> only in some cases but not in the other ones (that is why we have the default 
> implementation). Outer scope definitions apply to all cases and cannot be 
> overridden by a case-specific implementation. 
> 
> Basically, the compiler would synthesise an outer-scope method that does a 
> switch operator to dispatch to the particular implementation. This is thus 
> mostly syntactic sugar which also promotes safety (as it becomes impossible 
> to call the wrong implementation). These would make the case-specific methods 
> fully compatible with protocols etc. (e.g. a protocol Insertable { mutating 
> func insert(value:) }
> 
> Looking forward to your thoughts on this!
> 
> Best, 
> 
>  Taras
> 
> 

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

Reply via email to