> Le 20 févr. 2017 à 18:02, Matthew Johnson <matt...@anandabits.com> a écrit : > > >> On Feb 20, 2017, at 4:50 PM, Michel Fortin <michel.for...@michelf.ca> wrote: >> >>> Le 20 févr. 2017 à 14:45, Matthew Johnson <matt...@anandabits.com> a écrit : >>> >>>> >>>> On Feb 20, 2017, at 1:42 PM, Michel Fortin <michel.for...@michelf.ca> >>>> wrote: >>>> >>>>> Le 20 févr. 2017 à 14:23, Charles Srstka <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.
If a closure can be inferred pure, then it should be pure. We already infer `throws` and return types for closures, so inferring `pure` is natural. But for functions declared with a full signature, I'm hesitant to allow them to be inferred. Now that I think of it, overrides could be another source of problem with inference: add an impure override and the method in the base class can no longer be inferred as pure. So it can't apply to any non-final class property or function. -- Michel Fortin https://michelf.ca _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution