<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">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. </div><div class=""><br class=""></div><div class=""><b class="">Case-based dispatch for enum methods</b></div><div class=""><b class=""><br class=""></b></div><div class="">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:</div><div class=""><br class=""></div><div class="">func insert(value:T) {</div><div class=""> switch self {</div><div class=""> case let Leaf1(a, b, c): …</div><div class=""> case let Leaf2(a, b): …</div><div class=""> case let Parent1(x, y): …</div><div class=""> }</div><div class="">}</div><div class=""><br class=""></div><div class="">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. </div><div class=""><br class=""></div><div class="">Now, suppose there was a way to add a method implementation that is case-specific:</div><div class=""><br class=""></div><div class="">enum MyTree {</div><div class=""> case Leaf1(Float, Float) {</div><div class=""> mutating func insert(value: T) {</div><div class=""> let (a, b) = self.Leaf1 // or something like that</div><div class=""> // handle insert for the case that node is of type Parent1</div><div class=""><br class=""></div><div class=""> ...</div><div class=""> }</div><div class=""> }</div><div class=""><br class=""></div><div class=""> case Parent1(Int, Float) {</div><div class=""> mutating func insert(value: T) {</div><div class=""> let (x, y) = self.Parent1 // or something like that</div><div class=""> // handle insert for the case that node is of type Parent1</div><div class=""> ...</div><div class=""> }</div><div class=""> }</div><div class=""><br class=""></div><div class="">default {</div><div class=""> mutating func insert(value: T) {</div><div class=""> // handle insert for all other cases </div><div class=""> ...</div><div class=""> }</div><div class="">}</div><div class="">}</div><div class=""><br class=""></div><div class="">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. </div><div class=""><br class=""></div><div class="">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:) }</div><div class=""><br class=""></div><div class="">Looking forward to your thoughts on this!</div><div class=""><br class=""></div><div class="">Best, </div><div class=""><br class=""></div><div class=""> Taras</div><div class=""><br class=""></div><br class=""></body></html>