Last active
August 29, 2015 14:26
-
-
Save wavebeem/c190d1b5ecab6ebaa0ac to your computer and use it in GitHub Desktop.
Squiggle pattern matching idea
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
// map = fn(f, xs) match (xs) { | |
// case [] => [] | |
// case [x, ...xs] => [f(x)] ++ map(f, xs) | |
// } | |
// This approach is going to be the best, but it requires the compiler to become | |
// aware of being inside functions, so it can expand things into statements, | |
// rather than being purely expression oriented. It's sort of amazing how far | |
// you can get only using expressions in JS, though. It will also need to | |
// rewrite variable usage, which might be a little tricky. | |
var map = function(f, xs) { | |
var $match1 = xs; | |
var $match1_x, $match1_xs; | |
if ($eq($match1, [])) { | |
return []; | |
} else if ($match1.length >= 1) { | |
$match1_x = $match1[0]; | |
$match1_xs = $match1.slice(1); | |
return $plus$plus([f($match1_x)], map(f, $match1_xs)); | |
} else { | |
throw new Error("match fail"); | |
} | |
} | |
// This approach should allow for a clean "attempt to give me bindings, but | |
// allow for failed matches easily". "match" would return an object {ok: true, | |
// bindings: [...]} or simply {ok: false}. There could be nested accumulation | |
// of bindings, with a "throw" happening deep within, causing the top level to | |
// catch it and return {ok: false}. Maybe a little *gross*, but it would allow | |
// short, readable code, probably. | |
var map = function(f, xs) { | |
return (function(xs) { | |
var $_test = false; | |
$_test = $match(xs, ...); | |
if ($_test.ok) { | |
return (function() { | |
return []; | |
}($_test.values)); | |
} | |
$_test = $match(xs, ...); | |
if ($_test.ok) { | |
return (function(x, xs) { | |
return [f(x)] ++ map(f, xs); | |
}($_test.values)); | |
} | |
}()); | |
}; |
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
# not sure if i want "=>" or "then" or something. | |
match (data) { | |
# arrays strictly match the number of elements provided --- no more, no less | |
case [x] => 1 | |
case [_, y] => 2 | |
case [x, ...xs] => "more" | |
# it's ok if objects have more keys you don't mention! | |
case {"length": n} => n | |
# shorthand for same key and binding name | |
case {length} => length | |
# if you want to assert more elements exist but ignore their values... | |
case {"foo": _, "bar": _, baz} => baz | |
# maybe % is some match suffix that asserts a predicate function passes? | |
# could be any user defined function in scope. | |
# this one i'm not as sure about | |
case x % isNumber => x | |
# you can nest expressions, of course! | |
case [{"name": n1}, {"name": n2}] => | |
"Hello " ++ n1 ++ " and " ++ n2 ++ "!" | |
case "hello" => "world" | |
case 0 => "zero" | |
case 1 => "one" | |
# match will throw if no cases hold, so it's idiomatic to provide a catch-all fallback when appropriate. | |
case _ => "no match" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment