ayazhafiz / plts

A collection of programming languages and type systems.
https://ayazhafiz.com/plts
33 stars 3 forks source link

[gtlc] Optimize: remove unused parameters/variables #9

Open ayazhafiz opened 2 years ago

ayazhafiz commented 2 years ago

Finding unused variables is trivial, but removing them safely is trickier. If we remove an unused parameter, we need to update all places a value for that parameter is passed, which is non-trivial to figure out (consider using a graph representation of types here to make this easier; we only need to update the type once and then look at all values elaborated with that type).

The other issue to be careful of is the interaction with references. This is best illustrated by an example; consider the program

let a = ref (\x: _. 0) in
a := (\x: nat. x);
!a 1

applying the optimization naively would yield

let a = ref (\: 0) in
a := (\x: nat. x);
!a ()

but the problem is that a now has the type ref ([] -> nat), but then assigned a value of type [nat] -> nat, and the optimized-away call at the end is now unsound.

Nevertheless there are ways to handle this; as an initial pass, we could simply avoid modifying functions later used inside references.

ayazhafiz commented 2 years ago

I realized this opt is always unsound. Due to cast semantics, elision of unused variables in general may make a program that has a cast error no longer have a cast error. this is similar to llvm’s old opt that could trivialize infinite pure loops into noops, which also breaks program semantics.