Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Swift disambiguate generic constructors?

Consider the following Swift expression

println(Generic<Foo, Bar>(1))

Normally, one would read this as a generic call to the constructor Generic<Foo, Bar> with the arguments (1).

println( Generic<Foo,Bar>(1) )

However, when re-arranging the tokens a bit, it could also represent two separate comparisons, for example if Generic and Foo were some poorly named numeric variables:

println(Generic < Foo, Bar > (1))
// or, with proper parenthesis
println((Generic < Foo), (Bar > 1))

What we can observe here is that an expression with a generic constructor like this is highly ambiguous, and not easy to disambiguate even for humans. The problem here is that Swift doesn't have a new keyword for constructors, which makes them ambiguous with method calls and operators in some cases. Thus, I am interested in how the Swift compiler (parser) manages to disambiguate the above expressions. Is the way it is parsed dependant on the context (types, variables, functions) or can it be resolved by the parser?

like image 944
Clashsoft Avatar asked Nov 09 '22 08:11

Clashsoft


1 Answers

The answer is simple: The compiler simply does't allow you to declare these variables:

struct Generic<T, U> {

    init(_ i: Int) {}
}
struct Foo {}
struct Bar {}

print(Generic<Foo, Bar>(1))

// error
let Foo = 0      // invalid redeclaration of Foo
let Bar = 3      // invalid redeclaration of Bar
let Generic = 5  // invalid redeclaration of Generic
print(Generic<Foo, Bar>(1))

Making either the variables or the type declarations in another source file the current declaration "overrides" the other one.

like image 112
Qbyte Avatar answered Nov 22 '22 03:11

Qbyte