<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="">On Dec 19, 2015, at 9:00 PM, Jimmy Sambuo via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><p class="">My proposal is to add a `pure` keyword/attribute to Swift.</p></div></div></blockquote><div>I’m a fan of this in concept, and the mechanics for this feature would probably allow us to have safe “computed lets” as well. &nbsp;My one concern about this is that there probably has to be some way to unsafely “force a call to a non-pure function to be allowed in a pure one”, both because of type system limitations as well as interoperability with C and other languages. &nbsp;Even ignoring issues around errno, it would be sad for a pure function to not be able to call “sin(x)” just because it weren’t marked __attribute__((const)).</div><div><br class=""></div><div>A proposal in this area should consider how “pure” would interact with the type system, and it would probably make sense as an attribute @pure instead of a declmodifier.</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><p class=""><span class="">Similar to throws, you would mark a function as pure to say it will not cause any observable side-effects and hold referential transparency:</span></p><p class=""><span class="">```swift</span></p><p class=""><span class="">func pure add(x: Int, y: Int) -&gt; Int {</span></p><p class=""><span class=""><span class=""></span>&nbsp; &nbsp; return x + y</span></p><p class=""><span class="">}</span></p><p class=""><span class="">```</span></p><p class=""><span class="">By adding this attribute, the function is guaranteed to have some properties:</span></p>
<ol class="">
<li class=""><span class="">The function must have a return value</span></li>
<li class=""><span class="">This function can only call other pure functions</span></li>
<li class=""><span class="">This function cannot access/modify global or static variables.</span></li></ol><p class=""><span class="">```swift</span></p><p class=""><span class="">func pure getDate() -&gt; NSDate {</span></p><p class=""><span class=""><span class=""></span>&nbsp; &nbsp; return NSDate.date() //&nbsp;Error: pure function 'getDate' cannot call impure function 'date'&nbsp;</span></p><p class=""><span class="">}</span></p><p class=""><span class="">```</span></p><p class=""><span class="">This would be similar to the pure keyword in D (</span><a href="https://dlang.org/spec/function.html#pure-functions" class="">https://dlang.org/spec/function.html#pure-functions</a>) or the noSideEffect pragma in Nim (<a href="http://nim-lang.org/docs/manual.html#pragmas-nosideeffect-pragma" class=""><span class="">http://nim-lang.org/docs/manual.html#pragmas-nosideeffect-pragma</span></a>).</p><p class=""><span class="">My motivation for this is that I want to create applications that follow a "Functional Core, Imperative Shell" style [Gary Bernhardt]. By marking all of my functions within the functional core as pure, the compiler can help me if I accidentally start writing impure functions. In theory, this should make my application simpler and more testable. Reviewing pull requests will also be simpler since in the functional portion of my codebase, checking for pure can be a criteria. Ideally, I'd run a static analyzer to see that I have more pure functions than impure ones, which should help me control complexity by encouraging me to have a larger "value" layer and smaller "object" layer [Andy Matuschak].</span></p><p class=""><span class="">Logically, I think of this as Swift having all functions return "Implicitly Impure Values" (similar to how every object from objective-c is an implicitly unwrapped optional). All existing Swift functions are actually returning a IO&lt;SomeType&gt;, and functions using that are implicitly unwrapping them. Swift can be super nice by hiding this fact, making the language much more familiar and accessible to developers not used to purity. Adding `pure` allows devs to tap into the compiler's power and prevent unwanted side-effects without directly exposing the IO type.</span></p><p class=""><span class="">The benefits I see are:</span></p>
<ul class="">
<li class=""><span class="">Explicit intentions - This allows design decisions to be communicated clearly to other developers and maintainers, as well as the compiler and other static analysis tools.</span></li>
<li class=""><span class="">Compile-time guarantee - The compiler can help prevent unintentional state modifications.&nbsp;</span></li>
<li class=""><span class="">Encouragement of better state management practices - More people will be aware of the concept of functional purity and may try to design their code to have more pure functions, which should make more code simpler and testable. This isn't a guarantee it will happen, but more people should understand it if it brings concrete results instead of just being an abstract concept.</span></li>
<li class=""><span class="">Reduced cognitive load when understanding code - More pure functions should make it easier to reason about code.&nbsp;</span></li>
<li class=""><span class="">Opt-in to purity - Swift will be just as accessible to new developers, but experienced developers will be able to take advantage of this.</span></li>
<li class=""><span class="">Backwards compatible (mostly) - Existing codebases should still compile without any change (unless pure was used as a variable/method/class name).</span></li></ul><p class=""><span class="">Of course, there are risks of this feature. Some of the risks include:</span></p>
<ul class="">
<li class=""><span class="">This could make the language more difficult to work with. Developers maintaining an existing codebase with lots of pure function may become confused or frustrated when they realize they cannot do easy things such as logging within the method.</span></li>
<ul class="">
<li class=""><span class="">A counterargument to this may be that when Swift was introduced, optionals also made the language difficult to use. People implicitly unwrapped them just so things will compile, or returned them from methods without much consideration to what that implies. Nevertheless, this made Swift a safer language to use by explicitly when nil is a possible value. Developers are more conscious about nil being a potential value. Similarly, I think developers should be more aware about side-effect causing functions. Being clear about this and separating these concerns should bring about more safer and testable Swift applications.</span></li>
</ul>
<li class=""><span class="">Implementation of this feature could be difficult. Swift can implement it in several different ways depending on the desired result of this feature, such as having stronger or weaker purity guarantees to make the feature easier to use or simpler to implement. An effect system may have to be created.</span></li><ul class=""><li class=""><span class="">Alternatively, this could be done in a lightweight manner where the feature is introduced and known "pure-like" functions are marked in&nbsp;swift-corelibs-foundation.</span></li></ul></ul><p class=""><span class="">To be honest, I don't have much experience in languages that have this feature. I would imagine many people are interested in the notion of pure functions, but the question here is if it would be worth it, feasible, or even aligned with Swift's goals to have this feature. I'm half-expecting that this has already been brought up and determined to be out of scope or not a good idea.</span></p><p class=""><span class="">Thanks for your consideration. Please let me know what you think.</span></p>-- <br class=""><div class="gmail_signature">Jimmy Sambuo</div><div class="gmail_signature"><a href="http://www.sambuo.com/" class="">www.sambuo.com</a></div>
</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=RC5Cq0zAxCHc1sM9Uy3-2BojrrUAw-2F96zH69NULNHPvCsua1wCWnVlQ9souriTqiisb9TITXaD6s4SeNETDjhxSWpxSml4-2Ba0K9EMzZyv4S2i6RjMhZCKe0IISM-2FyuTixKZSwTfTDda7dSSFpLB5OQSLzCmJGNoj85yS4Ugo7QLLiyvrCKeppfBaLcj5Ps80I1WIK5TeeBA1FbMzNRfOKnfGKY8VRmKKzpb0daW6lVJtA-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>