On 6/30/13 10:56 PM, Timon Gehr wrote:
On 07/01/2013 03:08 AM, Kenji Hara wrote:
2013/7/1 JS <[email protected] <mailto:[email protected]>>
I am simply talking about having the compiler enlarge the type if
needed. (this is mainly for built in types since the type hierarchy
is explicitly known)
Just a simple matter, it would *drastically* increase compilation time.
void foo()
{
auto elem;
auto arr = [elem];
elem = 1;
....
elem = 2.0;
// typeof(elem) change should modify the result of typeof(arr)
}
Such type dependencies between multiple variables are common in the
realistic program.
When `elem = 2.0;` is found, compiler should run semantic analysis of
the whole function body of foo _once again_, because the setting type of
elem ignites the change of typeof(arr), and it would affect the code
meaning.
If another variable type would be modified, it also ignites the whole
function body semantic again.
After all, semantic analysis repetition would drastically increase.
I can easily imagine that the compilation cost would not be worth the
small benefits.
Kenji Hara
The described strategy can easily result in non-termination, and which
template instantiations it performs can be non-obvious.
auto foo(T)(T arg){
static if(is(T==int)) return 1.0;
else return 1;
}
void main(){
auto x;
x = 1;
x = foo(x);
}
Just tried it in Crystal and it ends alright. It works like this:
1. x is an Int
2. you call foo(x), it returns a float so x is now a float (right now in
Crystal that's a union of int and float, but that will soon change).
3. Since x is a float, foo returns an int, but assigning it to x, which
is already a float, gives back a float.
4. No type changed, so we end.
Crystal also supports recursive and mutuilly recursive functions. The
compiler is always guaranteed to finish.
(I'm just using Crystal as an example to have a proof that it can be done)