From 906e15674e7645513891ea95539aaaa42344eb19 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sat, 9 May 2020 16:52:05 -0700 Subject: [PATCH] Make minor edits to the content --- content/blog/12_compiler_let_in_lambda/index.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/content/blog/12_compiler_let_in_lambda/index.md b/content/blog/12_compiler_let_in_lambda/index.md index 1e55616..21faaac 100644 --- a/content/blog/12_compiler_let_in_lambda/index.md +++ b/content/blog/12_compiler_let_in_lambda/index.md @@ -91,15 +91,18 @@ addSingle6 x = 6 + x -- ... and so on ... ``` + But now, we end up creating several functions with almost identical bodies, with the exception of the free variables themselves. Wouldn't it be better to perform the well-known strategy of reducing code duplication by factoring out parameters, and leaving only instance of the repeated code? We would end up with: + ```Haskell {linenos=table} addToAll n xs = map (addSingle n) xs addSingle n x = n + x ``` + Observe that we no longer have the "infinite" number of functions - the infinitude of possible behaviors is created via currying. Also note that `addSingle` {{< sidenote "right" "global-note" "is now declared at the global scope," >}} Wait a moment, didn't we just talk about nested polymorphic definitions, and how they change our typechecking model? If we transform our program into a bunch of global definitions, we don't need to make adjustments to our typechecking.

This is true, but why should we perform transformations on a malformed program? Typechecking before pulling functions to the global scope will help us save the work, and breaking down one dependency-searching problem (which is \(O(n^3)\) thanks to Warshall's) into smaller, independent problems may even lead to better performance. Furthermore, typechecking before program transformations will help us come up with more helpful error messages. {{< /sidenote >}} and can be transformed into a sequence of instructions just like any other global function. It has been pulled from its `where` (which, by the way, is pretty much equivalent to a `let/in`) to the top level. -This technique of replacing captured variables with arguments, and pulling closures into the global scope to aid compilation, is called [Lambda Lifting](https://en.wikipedia.org/wiki/Lambda_lifting). Its name is no coincidence - lambda functions need to undergo the same kind of transformation as our nested definitions (unlike nested definitions, though, lambda functions need to be named). This is why they are included in this post together with `let/in`! \ No newline at end of file +This technique of replacing captured variables with arguments, and pulling closures into the global scope to aid compilation, is called [Lambda Lifting](https://en.wikipedia.org/wiki/Lambda_lifting). Its name is no coincidence - lambda functions need to undergo the same kind of transformation as our nested definitions (unlike nested definitions, though, lambda functions need to be named). This is why they are included in this post together with `let/in`!