> 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

Reply via email to