I've been re-reading Spencer Tipping's excellent Javascript in Ten Minutes and for the life of me can't figure out what is going on in this example of using lazy scoping to create syntactic macros:
var f = function () {return $0 + $1};
var g = eval (f.toString ().replace (/\$(\d+)/g,
function (_, digits) {return 'arguments[' + digits + ']'}));
g(5,6); // => 11 (except on IE)
In particular,
JavaScript has 3 types of scope: Block scope. Function scope. Global scope.
Asynchronous JavaScript (promises, callbacks, async/await) Closures. The event loop. Recursion.
JavaScript is a multi-paradigm, dynamic language with types and operators, standard built-in objects, and methods. Its syntax is based on the Java and C languages — many structures from those languages apply to JavaScript as well.
I'll agree with pst here, this code is pretty scary. It's horrific for readability. It's neat, though:
f
is defined as sort of a placeholder function. It seems to be the actual
macro itself; the numeric variables will be replaced when it's evaluated
into g
. They act as positional, variadic arguments which we'll see below.g
is where the magic happens: the function definition of f
is converted
to a string, and the numeric variables in the macro definition f
are
replaced with references to the indexed arguments for as many numeric
variables there are in the definition of f
(hence the regular expression
and call to replace
). The underscore is just used because we don't care
about the first parameter to the callback for replace
.The whole thing is then eval
ed, once f
is essentially expanded to the
following:
function () { return arguments[0] + arguments[1] }
So, it's neat, in that you could define f
with as many positional numeric
arguments as you wanted:
var f = function() { return $0 + $1 + $2 }
and it'd get evaluated to
function() { return arguments[0] + arguments[1] + arguments[2] }
Neat, but useless, arguably dangerous, impractical and hard to read. I probably wouldn't ever use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With