[swift-evolution] [Proposal] Type Narrowing
Rien
Rien at Balancingrock.nl
Wed Nov 9 06:19:45 CST 2016
> On 09 Nov 2016, at 10:51, Haravikk via swift-evolution <swift-evolution at swift.org> wrote:
>
>
>> On 8 Nov 2016, at 12:22, ilya <ilya.nikokoshev at gmail.com> wrote:
>>
>> (1) You can define different methods with the same name on T and Optional<T> (description is such an example). Then what does this do?
>>
>> // someMethod is defined both for T and T?
>> // var foo: T?
>> if foo != nil {
>> foo.someMethod()
>> }
>>
>> I say there is a clear expectation that foo.someMethod() should call the method of T?, even inside the if block, since this is how the dot works. However, according to the proposal it will call another method (or become an error?).
>>
>> I think the languages that use optional narrowing are the ones where T? is not a separate type, so that it cannot have its own methods.
>
> Hmm, that is definitely a wrinkle in the plan; it's very much an edge case (someone defining something on optionals that they probably shouldn't) but not an easy one to resolve. I suppose I'll have to amend the proposal to suggest type widening in that case, such that you would need to use ! or ? as normal to specify the unwrapped value. The tricky part is that it means the value would have to be widened from the start, otherwise you'd be accessing the value in two different ways in the same block of code, which would mean that narrowing would need to be blocked if there's an incompatible statement further down… ugh, perhaps a keyword will be necessary then? I was really hoping to avoid having to add one though.
>
>> (2) Should this work?
>>
>> // compilcatedStuff is a method of T
>> // class A { var foo: T? }
>>
>> if foo != nil {
>> foo.compilcatedStuff()
>> foo.compilcatedStuff()
>> foo.compilcatedStuff()
>> }
>>
>> Suppose the compiler doesn't have enough information about compilcatedStuff to know what happens inside. Then it's possible that foo.compilcatedStuff will actually change foo (for example, foo could be a relationship and compilcatedStuff may be deleting the relationship). So, what is the suggestion for this example? Perhaps
>>
>> if foo != nil {
>> foo.compilcatedStuff()
>> foo?.compilcatedStuff()
>> foo?.compilcatedStuff()
>> }
>>
>> or some other choice?
>
> What do you imagine being inside .complicatedStuff()? It shouldn't be possible for it to change foo to nil, as even if .complicatedStuff() reassigned this, it would be doing so as type T.
>
>> On 9 Nov 2016, at 06:51, David Hart <david at hartbit.com> wrote:
>>> On 3 Nov 2016, at 20:23, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution at swift.org> wrote:
>>>
>>> This looks like a lot of complexity for very little gain.
>>>
>>> Aside from any implementation concerns, this proposal substantially increases the cognitive load on developers. To figure out what a piece of code means, someone reading it will have to mentally keep track of a “type stack” for every variable. That is the opposite of “clarity at the point of use”.
>>
>> Very well said. I think this is perhaps the number one complaint I have about the proposal.
>
> Did you see my response to this? There should be no particular cognitive load increase; think of the feature like type inference, the idea here is that the type-checker is gaining the same knowledge that you already have, i.e- you know something isn't nil, so the type-checker should too.
Locally in short routines yes.
But in larger modules and non-local this does not apply.
Imo it should always be possible to look at a type declaration and -from that- derive all necessary knowledge about the type.
Besides when using a narrowed type as a parameter for an optional it must be automatically be widened again? hence you would mentally keep track of the status of that variable.
Regards,
Rien
Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Swiftrien
Project: http://swiftfire.nl
More information about the swift-evolution
mailing list