Static Argument Transform needs some love
This is a pretty non-specific title for a pretty non-specific issue.
Basically, static argument transform should be absolutely good a transformation now that we have a rule for recursive-let to be multiplicity aliases (which we absolutely need for recursive join points anyway).
But, the current implementation of Static Argument Transform (SAT.hs) produces (intermediate) terms which do not preserve linearity. From the file documentation:
Example: transform this
map :: forall a b. (a->b) -> [a] -> [b] map = /\ab. \(f:a->b) (as:[a]) -> body[map]to
map :: forall a b. (a->b) -> [a] -> [b] map = /\ab. \(f:a->b) (as:[a]) -> letrec map' :: [a] -> [b] -- The "worker function map' = \(as:[a]) -> let map :: forall a' b'. (a -> b) -> [a] -> [b] -- The "shadow function map = /\a'b'. \(f':(a->b) (as:[a]). map' as in body[map] in map' as
The non-recursive, inner, let map is not linear in f, even if the original map were (because f is summarily dropped).
For the moment, static argument transform must be deactivated for linear arguments. But better would be to re-engineer it a smidge, so that the we don't have to perform any inlining and beta-reduction before getting a manifestly linear term.