<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>It seems you've been beaten to the punch! <a href="https://github.com/apple/swift/blob/master/docs/HighLevelSILOptimizations.rst#id12">https://github.com/apple/swift/blob/master/docs/HighLevelSILOptimizations.rst#id12</a></div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Please don't use these attributes in production code. They make things go fast, but they also destroy any hope of good debug info and can cause UB if used incorrectly.<br><br>~Robert Widmann</div><div><br>2016/09/08 14:19、Guido Marucci Blas via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> のメッセージ:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8">Hi, I wanted to discussed an idea that I’ve been thinking for the last couple of weeks. First I want to give you a little bit of context. I am the technical leader in the iOS project I am working on. We have been using Swift for almost one year and half. Most of the first part of the project was desinged by me. I am being trying to apply concepts from the functional paradigm and in particular we heavily depend on ReactiveCocoa. For the last year two less experienced developers joined the team. I was in charge of teaching them about iOS programming (this was the first time doing an iOS app for them), functional programming (they are still college student with a background in OOP) and the details of our code base.<div class=""><br class=""></div><div class="">Coming from a background in OOP and imperative programming makes the change to a more functional approach quite “interesting”. I really like Swift and its flexibility to be able to tackle both low level and high level problems. But some times this flexibility makes it more error prone when you try to apply functional programming concepts. For example I found my self reviewing and correcting pull request with things like “When you use functions like map or filter on a collection or a SignalProducer don’t inject side effects”.</div><div class=""><br class=""></div><div class="">This led me to the idea of introducing a @pure annotation for functions. Full disclosure: I have almost no background in compilers and the internals of the Swift language so I have no idea if this makes sense at all. Such a annotation (it could also be a keyword like override o mutating) will make the compiler check if the function is actually a pure function, where by Pure I mean</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- It doesn’t mutate any internal or global state </div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- It doesn’t call any non-pure function</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- It must have a return type != from Void</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- It can access non mutable state</div><div class=""><br class=""></div><div class="">In this context a pure function is “stronger” than the mutating keyword in the sense that the pure function won’t allow any type of mutation even if you are calling a non-pure method (which performs a mutation or a side effect) on an object (reference type) instead of a struct. For example</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">final</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">class</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> Foo {</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><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: #bb2ca2" class="">private</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> count = </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0</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: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> foo(x: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</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: #4f8187" class="">count</span><span style="font-variant-ligatures: no-common-ligatures" class=""> += x</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: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">count</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></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;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Bar {</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: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> count: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</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: #bb2ca2" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> foo: </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Foo</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(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// This method performs a mutation</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// even though is not marked as mutating</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">// You could call it a "transitive mutation".</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: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> bar(x: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</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: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">foo</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">foo</span><span style="font-variant-ligatures: no-common-ligatures" class="">(x)</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: #bb2ca2" class="">mutating</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> baz(x: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</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: #4f8187" class="">count</span><span style="font-variant-ligatures: no-common-ligatures" class=""> += x</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: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">count</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><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></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">This could be extended to classes and structs. Adding “pure” to a class or structs makes all of its methods pure.</div><div class=""><br class=""></div><div class="">The benefit of such feature is that you could gradually add more functional code that is checked by the compiler and it is optional. I am most probably missing a lot issues here. This is just a rough idea but I wanted to share it with the community to better understand the tradeoffs.</div><div class=""><br class=""></div><div class="">If this has already been discussed can anyone point me to that discussion?</div><div class=""><br class=""></div><div class="">Thanks!</div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>