> 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

Reply via email to