<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On 2 Apr 2017, at 02:56, Karl Wagner &lt;<a href="mailto:karl.swift@springsup.com" class="">karl.swift@springsup.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">struct UnaryPredicate&lt;Parameter&gt; {</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">&nbsp; &nbsp; let evaluate: (Parameter) -&gt; Bool</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">}</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font face="Courier" class="">struct BinaryPredicate&lt;Left, Right&gt; {</font></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; let evaluate: (Left, Right) -&gt; Bool</font></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font face="Courier" class="">}</font></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class=""><br class=""></font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">extension KeyPath where Value: Equatable {</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">&nbsp; &nbsp; func equals(_ value: Value) -&gt; UnaryPredicate&lt;Root&gt; {</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; return UnaryPredicate { $0[keyPath: self] == value }</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; func equals&lt;KP: KeyPath&gt;(_ other: KP) -&gt; BinaryPredicate&lt;Root, KP.Root&gt; where KP.Value == Value {</font></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; return BinaryPredicate { $0[keyPath: self] == $1[keyPath: other] }</font></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">}</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class=""><br class=""></font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">let isDog = #keypath(Pet, .type).equals(.dog) // UnaryPredicate&lt;Pet&gt;</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">if isDog.evaluate(somePet) {</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">&nbsp; &nbsp; print(“It’s a dog”)</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">}</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">let areSameLength = #keypath(Array&lt;Int&gt;, .count).equals(#keypath(Array&lt;String&gt;, .count))</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span class="" style="font-family: Courier;">// BinaryPredicate&lt;Array&lt;Int&gt;, Array&lt;String&gt;&gt;</span></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">if areSameLength.evaluate([1,2,3], [“a”, “b”, “c”]) {</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">&nbsp; &nbsp; print(“same lengths”)</font></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><font face="Courier" class="">}</font></div></div></blockquote></div><br class=""><div class=""><br class=""></div><div class="">Apologies, been working with lots of generic closures today and the ‘Result’ just came out instinctively. Of course the Result of a predicate is a Boolean…</div><div class=""><br class=""></div><div class="">Still, it’s useful to think about what some more advanced use-cases of keypaths might look like with this proposal. As far as syntax is concerned, operators may ultimately be the best way to make long predicate combinations cleaner.</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="text-align: left;" class=""><font face="Courier" class="">extension UnaryPredicate {</font></div><div style="text-align: left;" class=""><font face="Courier" class="">&nbsp; &nbsp; static func &amp;&amp;&lt;P&gt;(left: UnaryPredicate&lt;P&gt;, right: UnaryPredicate&lt;P&gt;) -&gt; UnaryPredicate&lt;P&gt; {</font></div><div style="text-align: left;" class=""><font face="Courier" class="">&nbsp; &nbsp; &nbsp; &nbsp; return UnaryPredicate { self($0) &amp;&amp; other($0) }</font></div><div style="text-align: left;" class=""><font face="Courier" class="">&nbsp; &nbsp; }</font></div><div style="text-align: left;" class=""><font face="Courier" class="">}</font></div><div style="text-align: left;" class=""><font face="Courier" class=""><br class=""></font></div><div style="text-align: left;" class=""><font face="Courier" class="">let isHealthyPuppy = #keypath(Pet, .type).equals(.dog) &amp;&amp; #keypath(Pet, .age).isLessThan(12) &amp;&amp; #keypath(Pet, .health).equals(.good)</font></div><div style="text-align: left;" class=""><font face="Courier" class=""><br class=""></font></div><div style="text-align: left;" class=""><font face="Courier" class="">vs</font></div><div style="text-align: left;" class=""><font face="Courier" class=""><br class=""></font></div><div style="text-align: left;" class=""><font face="Courier" class="">let isHealthyPuppy = #keypath(Pet, .type).equals(.dog).and(#keypath(Pet, .age).isLessThan(12)).and(#keypath(Pet, .health).equals(.good))</font></div></blockquote><div class=""><br class=""></div><div class="">- Karl</div></body></html>