-
-
Save anonymous/a56e21e2c120178446b2aa43bad697e0 to your computer and use it in GitHub Desktop.
This file contains 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
// Paste this entire file into your browser console: | |
atom = function (x) { return typeof x === "number" || typeof x === "string" || typeof x === "boolean" || typeof x === "function" || x == null; } | |
run = eval; | |
function evaluate(json) { | |
if (atom(json)) { return run(json); } | |
var item = json[0]; | |
var args = Array.prototype.slice.call(json, 1); | |
if (item === "quote") { return json[1]; } | |
if (item === "do") { for (var i = 0; i < args.length; i++) { item = evaluate(args[i]); } return item; } | |
if (item === "if") { if (evaluate(json[1])) { return evaluate(json[2]); } else { return evaluate(json[3]); } } | |
item = evaluate(item); | |
if (!atom(item) && item[0] === "macro") { | |
var f = evaluate(item[1]); | |
return evaluate(f.apply(this, args)); | |
} | |
return item.apply(this, args.map(evaluate)); | |
}; | |
echo = console.log; | |
evaluate(["echo", 42]) | |
evaluate(["do", ["echo", 42], ["echo", 99], 7]); | |
add = function () { var n = 0; for ( var i = 0; i < arguments.length; i++) { n += arguments[i]; } return n; } | |
evaluate(["if", false, 42, ["add", 1, 2, ["add", 3, 4]]]) | |
when = ["macro", function(cond) { | |
var body = Array.prototype.slice.call(arguments, 1); | |
return ["if", cond, ["do"].concat(body)]; | |
}] | |
evaluate(["when", true, 42]) | |
evaluate(["when", true, ["echo", 42], 7]) | |
// Puzzle: How do you perform the equivalent of console.log([1,2,3])? | |
// | |
// In other words, your goal is to write "evaluate(...)" | |
// | |
// What would you replace "..." with to solve the puzzle? | |
// | |
// You could do this: | |
// | |
// foo = [1,2,3]; | |
// evaluate(["echo", "foo"]) | |
// | |
// But suppose you couldn't use variables. How would you achieve the | |
// goal? | |
// | |
// Another way to frame the puzzle: "How do you do the equivalent of | |
// console.log("x") without writing single quotes or backslashes?" | |
// | |
// There are many ways to *technically* solve this. But once you find | |
// the real answer, you'll know it. And you'd be depriving yourself of | |
// a wonderful "aha" moment by asking someone. | |
// | |
// Think carefully. There's a way to solve this using nothing more | |
// than the source code above. | |
// | |
// Try not to spoil the solution for others. Resist the urge to post | |
// the answer as a reply, slack, or IRC message. If you knew the | |
// answer instantly, this puzzle wasn't for you. | |
// | |
// I probably would've spent hours on this as a teenager before | |
// spotting the answer. So if you feel frustrated, just put it down | |
// and come back later. The payoff will be worth it. | |
// | |
// When you discover the solution, you might feel cheated, like it was | |
// a cheap trick. But it's a fundamental requirement with deep | |
// implications. You could remove it. But then there would be no way | |
// treat code as data. | |
// | |
// -- S |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment