Introducing a naive "letrec-set" field to the various kinds of "set" record turned out to be a bad idea. Making the set that a letrec does to stomp on the recursive binding be a "not-really-mutating" set causes the backend to assume there's no change, and to emit code that copies the dummy-init value around. Sure, there's no box, but also there's no linking of any mutually recursive procedures going on. I'll think some more about it and revisit it later. It doesn't look like it'll be easy to avoid the boxing: the alternative is to go into a bunch of environments in lambdas that are already constructed, and stomp on their letrec'd bindings. Nasty. Perhaps Kelsey's CPS/SSA technique will help here - a little analysis to identify mutually recursive /procedures/ could go a long way. The Mono "ilasm" and "al" seem crippled compared to the Portable .NET versions of the same. Newmoon requires the pnet versions to compile properly. (Update: I take that back. Sure, there are features that are missing from the Mono versions of the tools, but now I have corrected the syntax of my generated IL (oops!), the Mono ilasm seems to be quite happy.)