gren-lang / compiler

Compiler for the Gren programming language
https://gren-lang.org
Other
342 stars 21 forks source link

tail call optimization → bad closures #90

Open lue-bird opened 2 years ago

lue-bird commented 2 years ago

https://github.com/elm/compiler/issues/2268

mbartlett21 commented 1 month ago

Reproducible example from andrewMacmurray:

Details

```elm import Html main = Html.text (run (wrapMany 1 (Done "test"))) type Trampoline a = More ({} -> Trampoline a) | Done a wrapMany : Int -> Trampoline a -> Trampoline a wrapMany n trampoline = if n > 0 then wrapMany (n - 1) (More (\_ -> trampoline)) else trampoline run : Trampoline a -> a run trampoline = case trampoline of More next -> run (next {}) Done a -> a ``` Compiles into ```js var $author$project$Main$Done = function (a) { return { $: 'Done', a: a }; }; var $author$project$Main$run = function(trampoline) { run: while (true) { if (trampoline.$ === 'More') { var next = trampoline.a; var $temp$trampoline = next({ }); trampoline = $temp$trampoline; continue run; } else { var a = trampoline.a; return a; } } }; var $gren_lang$browser$VirtualDom$text = _VirtualDom_text; var $gren_lang$browser$Html$text = $gren_lang$browser$VirtualDom$text; var $author$project$Main$More = function (a) { return { $: 'More', a: a }; }; var $gren_lang$core$Basics$gt = _Utils_gt; var $gren_lang$core$Basics$sub = _Basics_sub; var $author$project$Main$wrapMany = F2(function(n, trampoline) { wrapMany: while (true) { if (_Utils_cmp(n, 0) > 0) { var $temp$n = n - 1, $temp$trampoline = $author$project$Main$More(function(_v0) { return trampoline; }); n = $temp$n; trampoline = $temp$trampoline; continue wrapMany; } else { return trampoline; } } }); var $author$project$Main$main = $gren_lang$browser$Html$text($author$project$Main$run(A2($author$project$Main$wrapMany, 10, $author$project$Main$Done('test')))); ```