Last active
August 7, 2016 18:13
-
-
Save bmccutchon/9affcb2a0c991613806dda1e9fee45ab to your computer and use it in GitHub Desktop.
Workaround for the lack of Scheme-style let expressions in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Workaround for the lack of Scheme-style let expressions in JavaScript. | |
* | |
* Usage: | |
* letexp((var1 = <expr1>, var2 = <expr2>, [...] varN = <exprN>) => | |
* <body>) | |
* | |
* Executes and returns the result of the expression defined in <body>. Said | |
* expression can make use of the variables defined above (var1, var2, etc.). In | |
* general, the variables follow the the rules of ECMAScript 6 default function | |
* parameters, which they are. This function allows the programmer to build | |
* complex expressions. | |
*/ | |
const letexp = f => f(); | |
/** | |
* For example, here is a function to compute the length of the hypotenuse of a | |
* triangle given the lengths of its legs. It uses letexp to define a helper | |
* function for squaring a number while keeping the body down to one expression. | |
*/ | |
const hypot = (x, y) => | |
letexp((sq = n => n*n) => | |
Math.sqrt(sq(x) + sq(y))); | |
/** | |
* Example 2: factorial function. This emulates a Scheme idiom where a | |
* tail-recursive function with an accumulator is hidden within a function that | |
* supplies the correct value for the accumulator. (This is a bit contrived, | |
* since it would be better to write factAcc at the top level, then do `export | |
* fact = n => factAcc(n, 1)`.) | |
*/ | |
const fact = n => | |
letexp((factAcc = (n, acc) => | |
n === 1 ? acc : factAcc(n - 1, acc * n)) => | |
factAcc(n, 1)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment