perf: optimize for constant arguments in tail call optimization
Consider:
public func find<K, V>(
map : AssocList<K, V>,
key : K,
equal : (K, K) -> Bool
) : ?V {
switch (map) {
case (?((hd_k, hd_v), tl)) {
if (equal(key, hd_k)) {
?hd_v
} else {
find(tl, key, equal)
}
};
case (null) { null }
}
};
This is tail recursive and should be optimized to a loop by moc. However, arguments key and equal don't change on recursive calls/loop iterations and should only be set once, not on every iteration. I suspect we don't do that optimization.
@kentosugama might be an interesting optimization to consider doing
Will look at this once I get to IR level / motoko specific opts. Going to look at WASM level opts first
Btw, the tail calls proposal for Wasm is now at stage 4, which means it's completed and merely needs to be merged into the main spec. I hope this can happen in the next few weeks.