<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="">I could use some advice on how to architect things for Swift (as opposed to ObjC). This seems like the most appropriate list to ask, but let me know if there is a more appropriate place.<div class=""><br class=""></div><div class="">I am updating an old library to Swift 3 (from 2), and it seemed like a good opportunity to experiment and modernize things. The library allows you to write expressions, which you can simplify and calculate the end result. The API I am going for is similar to a class cluster, where it looks like a single type to the outside world, but behind the scenes there are different structs to efficiently represent different types of equations. These structs all adhere to a common protocol:</div><div class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">public</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ExpressionProtocol {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(4, 51, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">associatedtype</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> Result</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value(using provider:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ValueProvider</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class=""> -> Result</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simplified(using provider:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ValueProvider</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><Result></span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> variables<Identifier:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Hashable</span><span style="font-variant-ligatures: no-common-ligatures" class="">>() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Set</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Identifier</span><span style="font-variant-ligatures: no-common-ligatures" class="">></span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> isConstant:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">get</span><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> isLeaf:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">get</span><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">public extension</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">ExpressionProtocol</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value()</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class=""> -> Result {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">value</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(using: </span><span style="font-variant-ligatures: no-common-ligatures" class="">EmptyValueProvider</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">())</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simplified() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><Result>{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">simplified</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(using: </span><span style="font-variant-ligatures: no-common-ligatures" class="">EmptyValueProvider</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">())</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">}</span><span class="Apple-tab-span" style="white-space:pre">        </span></div><div class=""><br class=""></div><div class="">The ‘ValueProvider’ mentioned here is an abstraction that provides values (of Result) in return for a given Identifier. Basically, it lets you fill in values for variables.</div><div class=""><br class=""></div><div class="">All of this gets wrapped behind an ‘Expression’ class which type erases the various conforming structs and provides initializers for constant values. Then in separate files, I define various private types of expressions as structs and use an extension to add convenience initializers to Expression that create them. The class has a default initializer which takes anything conforming to ExpressionProtocol.</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">public extension</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">public convenience</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(left: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">>, right: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">>, operation:</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">@escaping</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class="">-></span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">OperationExpression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs: left, rhs: right, operation: operation))</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span> </div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> OperationExpression<T>:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ExpressionProtocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">typealias</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Result = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> lhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> rhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> operation:(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class="">-></span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">>, rhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">>, operation:</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">@escaping</span><span style="font-variant-ligatures: no-common-ligatures" class=""> (</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">,</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class="">-></span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = lhs</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = rhs</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">operation</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = operation</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value(using provider:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ValueProvider</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class=""> -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Result</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">operation</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider), </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider))</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simplified(using provider:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ValueProvider</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Result</span><span style="font-variant-ligatures: no-common-ligatures" class="">> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleLeft = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">simplified</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleRight = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">simplified</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleLeft.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures" class="">, let left = </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class="">? simpleLeft.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleRight.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures" class="">, let right = </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class="">? simpleRight.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> answer = </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">operation</span><span style="font-variant-ligatures: no-common-ligatures" class="">(left, right) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(answer)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">else</span><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">OperationExpression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(left), rhs: simpleRight, operation: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">operation</span><span style="font-variant-ligatures: no-common-ligatures" class="">))</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">OperationExpression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs: simpleLeft, rhs: simpleRight, operation: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">operation</span><span style="font-variant-ligatures: no-common-ligatures" class="">))</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> variables<Identifier:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Hashable</span><span style="font-variant-ligatures: no-common-ligatures" class="">>() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Set</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Identifier</span><span style="font-variant-ligatures: no-common-ligatures" class="">> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">variables</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">().</span><span style="font-variant-ligatures: no-common-ligatures" class="">union</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">variables</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">())</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> isConstant:</span><span style="font-variant-ligatures: no-common-ligatures" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">&&</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> isLeaf:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">false</span><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class="">This all works pretty well, but I am having two main areas of difficulty:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>1) <b class="">Containers such as Optionals and Arrays</b> - I can go one way, but not the other. If Result is [T] or T?, I can’t seem to get at the internal type T. I can do it with a free function, but not as an init or even static function for some reason.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>2) <b class="">Bools</b> - This one surprised me. Most of my expression structs are generic over their result, but there are a few (e.g. checking equality) where their Result should always be a Bool. The compiler freaks out about this and says it isn’t able to convert Result/T to Bool.</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression </span><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures;" class="">convenience</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures;" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class=""><E:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Equatable</span><span style="font-variant-ligatures: no-common-ligatures" class="">>(</span><span style="font-variant-ligatures: no-common-ligatures;" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class=""> left:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">E</span><span style="font-variant-ligatures: no-common-ligatures" class="">>, isEqual right:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">E</span><span style="font-variant-ligatures: no-common-ligatures" class="">>) {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 143, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">init</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(EqualsExpression(lhs: left, rhs: right)) </span><span style="font-variant-ligatures: no-common-ligatures" class="">//ERROR: 'T' is not convertable to 'EqualsExpression.Result' (aka Bool)</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> EqualsExpression<T:Equatable>:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ExpressionProtocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">typealias</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Result = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Bool</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> lhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> rhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">></span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">>, rhs:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">>) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = lhs</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = rhs</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value(using provider:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ValueProvider</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">throws</span><span style="font-variant-ligatures: no-common-ligatures" class=""> -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Result</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider) </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">==</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simplified(using provider:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">ValueProvider</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Result</span><span style="font-variant-ligatures: no-common-ligatures" class="">> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleLeft = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">simplified</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleRight = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">simplified</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleLeft.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures" class="">, let left = </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class="">? simpleLeft.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> simpleRight.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures" class="">, let right = </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">try</span><span style="font-variant-ligatures: no-common-ligatures" class="">? simpleRight.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class="">(using: provider) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(left </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">==</span><span style="font-variant-ligatures: no-common-ligatures" class=""> right)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">else</span><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">EqualsExpression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(left), rhs: simpleRight))</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Expression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">EqualsExpression</span><span style="font-variant-ligatures: no-common-ligatures" class="">(lhs: simpleLeft, rhs: simpleRight))</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> variables<Identifier:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Hashable</span><span style="font-variant-ligatures: no-common-ligatures" class="">>() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Set</span><span style="font-variant-ligatures: no-common-ligatures" class=""><</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Identifier</span><span style="font-variant-ligatures: no-common-ligatures" class="">> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">variables</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">().</span><span style="font-variant-ligatures: no-common-ligatures" class="">union</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(</span><span style="font-variant-ligatures: no-common-ligatures" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">variables</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">())</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><p style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(52, 149, 175);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> isConstant:</span><span style="font-variant-ligatures: no-common-ligatures" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">lhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">&&</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">rhs</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span><span style="font-variant-ligatures: no-common-ligatures" class="">isConstant</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> isLeaf:</span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">false</span><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class="">I have tried about a dozen ways, and I can’t seem to make it fit. I can do free functions, but not initializers.</div><div class=""><br class=""></div><div class="">Is there a way to make this work? Is my architecture fundamentally wrong for Swift? Is there another design I should be considering instead?</div><div class=""><br class=""></div><div class="">What I like about the current approach that I would like to keep:</div><div class="">• Everything is a single type to the end user. They don’t have to remember whether it was called an EqualsExpression, etc… there are just a bunch of inits which autocomplete.</div><div class="">• I like the generic return type, as it lets me put things together correctly, and reads clearly. e.g. Expression<Int> is a very clear type to explain to people.</div><div class="">• There aren’t restrictions on what you can have an Expression of. I may conditionally add some features based on the Result type, but at the very least, you can make an Expression of anything and combine them with operations.</div><div class="">• It is retroactively extensible with new types of expressions while keeping all of the above features.</div><div class=""><br class=""></div><div class="">Any advice is appreciated…</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""></div></body></html>