amuletml / amulet

An ML-like functional programming language
https://amulet.works/
BSD 3-Clause "New" or "Revised" License
328 stars 16 forks source link

Optimiser η-contraction makes mutual recursion too strict #286

Open plt-amy opened 4 years ago

plt-amy commented 4 years ago
let x <|> y =
  match x with
  | Some _ -> x
  | None -> y

let chainr1 p op =
  let rec scan =
    let! x = p
    rest x
  and rest x =
    ( let! f = op
      let! y = scan
      pure (f x y)
    ) <|> pure x
  scan

This code oughtta be compiled something like:

  local scan, rest
  scan = bind(dict)(p)(function(x)
     return rest(x)
  end)
  rest = ...

But, nah, amc eta-contracts the fun x -> rest x into just rest, which forces it early, which results in attempt to call nil.

      local scan, rest
      scan = _greater_greater_equals(p, rest)
      rest = function(x)
plt-amy commented 4 years ago

Repro here