LET allows you to introduce local bindings and use them to name intermediate results.
I’m trying out a new format with this post. I introduce the feature, explain its intended semantics, and give you examples to test your understanding before walking through how I implemented it. There’s also a place to pause and try implementing it yourself.
LETPAR and LETSEQ were the two variations I originally planned to explore. LETDEP came out of asking what would happen if forward references were allowed, which led to dependency graphs, topological sorting, free-variable analysis, and some interesting lexical-scope edge cases.
LETDEP also ends up fairly close to Elm’s let semantics, since definitions are not constrained by source order.