> On Feb 20, 2017, at 6:54 PM, Michel Fortin <michel.for...@michelf.ca> wrote: > >> >> 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.
Yeah, I’m ok with requiring annotation if inference is going to be hairy or confusing. > > -- > Michel Fortin > https://michelf.ca <https://michelf.ca/>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution