> On 7 Nov 2016, at 19:31, Charlie Monroe <char...@charliemonroe.net> wrote:
> There are two cases:
> 
> if foo != nil { 
>     foo!.doSomething() 
> }
> 
> Currently, accessing a non-optional value with ! produces an error:
> 
> let foo = Bar()
> foo!.doSomething() // ERROR
> 
> Second:
> 
> if foo != nil { 
>     // Using ? to be extra cautious, if foo is var
>     foo?.doSomething() 
> }
> 
> This again currently produces an error:
> 
> let foo = Bar()
> foo?.doSomething() // ERROR
> 
> Which is generally, what would semantically happen - the variable would loose 
> it optionality. Or am I wrong?

I probably haven't clarified well enough but under type-narrowing these would 
be warnings rather than errors; i.e- the general type of foo is still Optional, 
the type-checker merely knows that it can't be nil at that point, so would 
inform you that the ? or ! are unnecessary.

This is what I was trying to get at in the type-widening section; basically, if 
you have a variable whose type is narrowed, but do something that makes no 
sense for the narrowed type, then the type is widened until either a match is 
found or it can't go any wider (producing an error as normal).

So in your examples foo is Optional<Bar>.some, as a result the ? and ! 
operators make no sense, so the type is widened back to Optional<Bar> where it 
does make sense and the code compiles, but a warning is produced to inform you 
that you don't need to use those operators.

> On 7 Nov 2016, at 19:31, Charlie Monroe <char...@charliemonroe.net> wrote:
> I agree that designing a language around the compiler speed is wrong, but I 
> believe designing the language without taking it into account is just as 
> wrong. It's not worth designing features that would make the compilation so 
> slow it would render the language unusable.
> 
> Note that I have only very limited experience with compiler implementation, 
> I've only made a few minor things with Clang a few years back, so please feel 
> free to correct me.

I'm not that familiar with the actual architecture either, but narrowing 
*should* be fairly simple; basically any time the compiler hits a condition or 
statement defined as a narrowing trigger, it pops the new narrower type onto a 
stack of types for that variable (in that branch). Now whenever the compiler 
reaches another statement for that variable (method call etc.) it resolves it 
first against the narrowest type, otherwise it goes up the stack (widening) 
till it finds a match or fails.

When a branch closes with a stack of types, the compiler will compare to other 
branches to see which type is the narrowest that they have in common; this is 
actually fairly simple (shorten the stack for each branch to the length of the 
shortest stack, then discard elements until the current one is a match for all 
branches, thus you now know what the narrowest type is past that point).

So, for types that never narrow there should be no speed difference, while for 
narrowed types there shouldn't be much of a difference, as these stacks of 
types shouldn't get very large in most cases (I'd expect anything more than 
three to be pretty rare).
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to