<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=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 20, 2017, at 4:50 PM, Michel Fortin &lt;<a href="mailto:michel.fortin@michelf.ca" class="">michel.fortin@michelf.ca</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">Le 20 févr. 2017 à 14:45, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; a écrit :<br class=""><br class=""><blockquote type="cite" class=""><br class="">On Feb 20, 2017, at 1:42 PM, Michel Fortin &lt;<a href="mailto:michel.fortin@michelf.ca" class="">michel.fortin@michelf.ca</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class="">Le 20 févr. 2017 à 14:23, Charles Srstka &lt;<a href="mailto:cocoadev@charlessoft.com" class="">cocoadev@charlessoft.com</a>&gt; a écrit :<br class=""><br class="">I’m not sure how I feel about that, since it hamstrings the ability to improve APIs in a lot of ways without breaking backwards compatibility. A quick example off the top of my head would be all the Cocoa APIs that started out having ivars representing paths backed by simple getter methods, and were later refactored to be URL-based, but with the original path properties become computed properties pointing to the URL’s “path” property. With this, properties would not be able to be refactored in this way unless the library developer had previously declared the “path” property as private(set), which is unlikely for a property that was not intended to be changed after the class was initialized.<br class=""></blockquote><br class="">Version 1:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>public class A {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>public let path: String<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class="">Version 2:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>public class A {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>public pure var path: String { return url.path }<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>public let path: URL<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class="">This is assuming `let` is implicitly pure. It probably should not be. Or at least it should not when crossing module boundaries. Note that internal to the module it wouldn't violate any contract to allow pure code access to `let` variables.<br class=""><br class="">Which makes me think of an idea: internal to the module, `pure` could be inferred for everything. Only the published APIs would require the annotations, and only if you want `pure` to be part of the API contract. Attaching `pure` to an internal function could still be useful for your own reasoning though.<br class=""></blockquote><br class="">That’s a very interesting approach that could lighten the syntactic load. &nbsp;We could strategically annotate our code where we want purity verified, but otherwise omit the annotation for members that don’t need to be visible outside the module. &nbsp;This approach works especially well for closures. &nbsp;I like it a lot!<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">There is an important limitation to this though: a class method that mutate something in the class is never going to be implicitly pure (per the rules of purity for instance methods). For that the compiler would have to prove the method is only called from unique references, and that'd be a bit weird (add a method call somewhere and suddenly the function becomes impure).</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div class=""><br class=""></div><div class="">That seems totally fine to me.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">There's also an issue with diagnostics: say you have func1 that calls func2 that calls func3. Func1 is `pure`, the other two are pure only implicitly. Then you change something in func3, and suddenly func1 complains that it can't call impure func2 and you are left wondering why because you haven't changed anything in func2. Perhaps the compiler could dig in the call tree to find the impure operation and tell you, but that's starting to look like the awful diagnostic messages for C++ templates.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">So now I'm starting to think this idea of inferring purity was perhaps a bit reckless.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></div></blockquote><div class=""><br class=""></div><div class="">It all depends on how people use it (that’s why I mentioned strategic annotations), but yeah it could be ugly. &nbsp;I wonder if there is a reasonable way to bound the inference to keep error messages tractable. &nbsp;For example, you mentioned inference within a module. &nbsp;If that’s too broad a scope for inference, maybe within a file would be ok and annotation would be required for anything with `internal` or greater visibility. &nbsp;This would still address closures which would be cool and outside of crazy large files it wouldn’t be too bad to track down the meaning of an error.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">--<span class="Apple-converted-space">&nbsp;</span></span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Michel Fortin</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://michelf.ca/" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://michelf.ca</a></div></div></blockquote></div><br class=""></div></body></html>