Open ceedubs opened 1 year ago
I'm not exactly sure what is going on in all these examples (haven't actually experimented with anything; just read the issue).
What you're seeing in the first example has to do with recursive lets just establishing bindings for things. They don't actually do evaluation of their definitions. The odd thing is that I think there are usually checks that these kinds of local letrecs are for (syntactic) functions, where you wouldn't expect them to be evaluated anyway. Somehow this example avoids that.
The second example loops because you're actually evaluating y
now.
The third example might just be a decompilation issue. The result is x
(which won't loop because it's a lambda), which at runtime is a floated out 'combinator,' and maybe its definition (or the one for y
) wasn't stored. I'm not 100% sure, though.
The first one should be a type error, I think, in that x
and y
are part of a cycle, but y
isn't guarded by a lambda. I'm curious what's happening there.
I'll preface this by saying that I don't know what the behavior should be in any of these scenarios. But I was surprised by at least a couple of them.
I expected this code to infinitely recurse, but interestingly it immediately returns. Maybe an optimization that realizes that the result is never used? Anyway, this seems like a good thing probably.
This version infinitely recurses. In a perfect world it might produce a compile error, but it feels kind of fair that it hangs forever.
If we examine
x
instead ofy
then it crashes: