<div>+1 for pure functions</div><div>+1 for combining them with constexpr</div><div>-1 for the syntax originally proposed</div><div>+1 for pure or @pure keywords (before func and before a closure opening { )</div><div><br></div><div>One thing is probably worth considering if pure functions and closures are combined with constexpr and evaluated at compile-time. This might be problematic if the produced results are large (in size) and in that case it might be interesting to have the possibility to delay the computation at run-time... maybe with another keyword then?</div><div><br></div><div>Nicolas </div><div><br></div><div><br><div class="gmail_quote"><div>On Fri, 17 Feb 2017 at 15:37, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Feb 16, 2017, at 3:18 PM, T.J. Usiyan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-3112773962030589387Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I am ok with a keyword but `pure` in front of func doesn&#39;t work well with inline closures.</div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">The `=&gt;` function arrow syntax is a clever way to avoid making pure functions heaver syntactically than impure functions.  That said, I don’t think it will stand out very clearly when reading code and is likely to be confusing for new programmers who don’t understand purity or why you would sometimes want it and other times that it won’t be possible.  </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Also, what about pure closures that have no need to state a signature because it is inferred?  This syntactic sugar is a pretty important aspect of Swift and often times some of our smallest closures will be pure.  For example Array’s map should be pure when the closure is pure and many map closures are very small.  We don’t want to have to annotate these closures with a signature.  </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Could we allow inference of purity for closures when they are used in a context which accepts a pure function?  If we had an annotation similar to `rethrows` maybe inference could prefer purity, but fall back to an impure semantic for `map` (or other methods using the annotation) when the closure isn’t pure.  Come to think of it, using `-&gt;` vs `=&gt;` to make the distinction kind of falls apart when the purity of a function is conditional depending on the purity of its arguments.  Have you thought about how to handle this?</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Overall, I *really* want to see pure functions in Swift and would be very excited to see them make it into Swift 4.  That said, I’m on the fence about the syntax you have proposed.</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">A few people talked through many of these issues starting with this tweet. <a href="https://twitter.com/griotspeak/status/832247545325842432" class="gmail_msg" target="_blank">https://twitter.com/griotspeak/status/832247545325842432</a></div></div><div class="gmail_extra gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg">On Thu, Feb 16, 2017 at 4:13 PM, Jonathan Hull <span class="gmail_msg">&lt;<a href="mailto:jhull@gbis.com" class="gmail_msg" target="_blank">jhull@gbis.com</a>&gt;</span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">+1 for the idea of pure functions in swift.  Seems like it would enable a lot of good optimizations (in some cases even just evaluating the function at compile time).<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">-1 on the specific notation.  I would much rather just put the word ‘pure’ in front of ‘func’, the same way we put ‘mutating&#39; in front of mutating functions… it seems to me like these are part of the same family.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I agree we should allow inout.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Thanks,</div><div class="gmail_msg">Jon</div><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div class="m_-3112773962030589387h5 gmail_msg"><div class="gmail_msg">On Feb 16, 2017, at 9:03 AM, T.J. Usiyan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-3112773962030589387m_-8285033497674018801Apple-interchange-newline gmail_msg"></div></div><div class="gmail_msg"><div class="gmail_msg"><div class="m_-3112773962030589387h5 gmail_msg"><div class="gmail_msg"><div class="gmail_msg"># Pure Functions</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">* Proposal: [SE-NNNN](<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" class="gmail_msg" target="_blank">https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md</a>)</div><div class="gmail_msg">* Author(s): [TJ Usiyan](<a href="https://github.com/griotspeak" class="gmail_msg" target="_blank">https://github.com/griotspeak</a>)</div><div class="gmail_msg">* Status: **Awaiting review**</div><div class="gmail_msg">* Review manager: TBD</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">## Introduction</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Some functions are, essentially, only meant to be transformations of their input and–as such–do not and should not reference any variables other than those passed in. These same functions are not meant to have any effects other than the aforementioned transformation of input. Currently, Swift cannot assist the developer and confirm that any given function is one of these &#39;pure&#39; functions. To facilitate this, this proposal adds syntax to signal that a function is &#39;pure&#39;.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">&#39;pure&#39;, in this context, means:</div><div class="gmail_msg">1. The function must have a return value</div><div class="gmail_msg">1. This function can only call other pure functions</div><div class="gmail_msg">1. This function cannot access/modify global or static variables.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">## Motivation</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Consider the following example where `_computeNullability(of:)` is meant to create its output solely based on the provided recognizer.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">```</div><div class="gmail_msg">class Recognizer {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>var nullabilityMemo: Bool?</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>var isNullable: Bool {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>func _computeNullability(of recognizer: Recognizer) -&gt; Bool {…}</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>if let back = nullabilityMemo {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>return back<span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span></div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>} else {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>let back =  _computeNullability(of: self)</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>nullabilityMemo = back</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>return back</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>}</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>}</div><div class="gmail_msg">}</div><div class="gmail_msg">```</div><div class="gmail_msg">if `_computeNullability(of:)` is recursive at all, there exists a real potential to accidentally reference `self` in its body and the mistake, depending on circumstance, can be terribly subtle. Converting `_computeNullability(of:)` to a `static` function is an option but obfuscates the fact that it is *only* to be called within `isNullable`.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">## Proposed solution</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Given the ability to indicate that `_computeNullability(of:)` is a &#39;pure&#39; function, the developer gains assurance from the tooling that it doesn&#39;t reference anything or cause any side effects.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">```</div><div class="gmail_msg">class Recognizer {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>var nullabilityMemo: Bool?</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>var isNullable: Bool {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>pfunc _computeNullability(of recognizer: Recognizer) -&gt; Bool {…}</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>if let back = nullabilityMemo {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>return back<span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span></div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>} else {</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>let back =  _computeNullability(of: self)</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>nullabilityMemo = back</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                        </span>return back</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>}</div><div class="gmail_msg"><span class="m_-3112773962030589387m_-8285033497674018801gmail-Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>}</div><div class="gmail_msg">}</div><div class="gmail_msg">```</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">## Detailed design</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">This proposal introduces a new annotation `=&gt;`, which is to be accepted everywhere `-&gt;` currently is. Members created using this kewyord must follow the rules listed in the introduction.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">## Impact on existing code</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">This is an additive feature unless alternative 2 is chosen and, as such, should not require an effect on existing code. It could be used to annotate closures accepted by methods in the standard library such as `map`, `filter`, and `reduce`. While this would fit well with their typical use, such a change is not necessarily part of this proposal.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">## Alternatives considered</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">It should be noted that neither of these alternatives can remain consistent for inline closures.</div><div class="gmail_msg">1. keyword `pfunc` (pronounciation: pifəŋk) for &#39;pure&#39; functions. </div><div class="gmail_msg">2. `proc` keyword for &#39;impure&#39; functions and &#39;func&#39; for &#39;pure&#39; functions. This would be a massively source breaking change and, as such, is unlikely to have any feasibility. It is, however, the most clean semantically, in my opinion.</div><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div><span class="gmail_msg">
_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></span></div></blockquote></div><br class="gmail_msg"></div></div></blockquote></div><br class="gmail_msg"></div>
_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></div></blockquote></div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div></div>