> On Feb 20, 2017, at 4:50 PM, Michel Fortin <michel.for...@michelf.ca > <mailto:michel.for...@michelf.ca>> wrote: > >> Le 20 févr. 2017 à 14:45, Matthew Johnson <matt...@anandabits.com >> <mailto:matt...@anandabits.com>> a écrit : >> >>> >>> On Feb 20, 2017, at 1:42 PM, Michel Fortin <michel.for...@michelf.ca >>> <mailto:michel.for...@michelf.ca>> wrote: >>> >>>> Le 20 févr. 2017 à 14:23, Charles Srstka <cocoa...@charlessoft.com >>>> <mailto:cocoa...@charlessoft.com>> a écrit : >>>> >>>> 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. >>> >>> Version 1: >>> >>> public class A { >>> public let path: String >>> } >>> >>> Version 2: >>> >>> public class A { >>> public pure var path: String { return url.path } >>> public let path: URL >>> } >>> >>> 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. >>> >>> 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. >> >> That’s a very interesting approach that could lighten the syntactic load. >> 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. This approach works especially well for closures. I >> like it a lot! > > 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).
That seems totally fine to me. > > 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. > > So now I'm starting to think this idea of inferring purity was perhaps a bit > reckless. It all depends on how people use it (that’s why I mentioned strategic annotations), but yeah it could be ugly. I wonder if there is a reasonable way to bound the inference to keep error messages tractable. For example, you mentioned inference within a module. 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. 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. > > -- > Michel Fortin > https://michelf.ca <https://michelf.ca/>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution