FEATURE: Syntax improvement for map filter and reduce.

closes #33
This commit is contained in:
Jeremy Wall 2019-01-31 16:33:12 -06:00
parent 8aacd49a77
commit 3619153218
5 changed files with 57 additions and 51 deletions

View File

@ -13,8 +13,8 @@ let boolfiltrator = func (item) => item < 5;
let identity_list_reducer = func (acc, item) => acc + [item];
assert {
ok = reduce identity_list_reducer, [], list1 == list1,
desc = "reduce identity_list_reducer, [], list1 == list1",
ok = reduce(identity_list_reducer, [], list1) == list1,
desc = "reduce(identity_list_reducer, [], list1) == list1",
};
let nested_list = {
@ -22,53 +22,53 @@ let nested_list = {
};
assert {
ok = reduce identity_list_reducer, [], (nested_list.list) == list1,
desc = "reduce identity_list_reducer, [], (nested_list.list) == list1",
ok = reduce(identity_list_reducer, [], (nested_list.list)) == list1,
desc = "reduce(identity_list_reducer, [], (nested_list.list)) == list1",
};
let list_reducer = func (acc, item) => acc + item;
assert {
ok = reduce list_reducer, 0, list1 == 0 + 1 + 2 + 3 + 4,
desc = "reduce list_reducer, 0, list1 == 0 + 1 + 2 + 3 + 4",
ok = reduce(list_reducer, 0, list1) == 0 + 1 + 2 + 3 + 4,
desc = "reduce(list_reducer, 0, list1) == 0 + 1 + 2 + 3 + 4",
};
assert {
ok = map mapper, list1 == [2, 3, 4, 5],
desc = "map mapper, list1 == [2, 3, 4, 5]",
ok = map(mapper, list1) == [2, 3, 4, 5],
desc = "map(mapper, list1) == [2, 3, 4, 5]",
};
assert {
ok = (map mapper, [1, 2, 3, 4]) == [2, 3, 4, 5],
desc = "(map mapper, [1, 2, 3, 4]) == [2, 3, 4, 5]",
ok = (map(mapper, [1, 2, 3, 4])) == [2, 3, 4, 5],
desc = "(map(mapper, [1, 2, 3, 4])) == [2, 3, 4, 5]",
};
assert {
ok = map mapper, [1, 2, 3, 4] == [2, 3, 4, 5],
desc = "map mapper, [1, 2, 3, 4] == [2, 3, 4, 5]",
ok = map(mapper, [1, 2, 3, 4]) == [2, 3, 4, 5],
desc = "map(mapper, [1, 2, 3, 4]) == [2, 3, 4, 5]",
};
let s_mapper = func (arg) => arg + ",";
assert {
ok = map s_mapper, "foo" == "f,o,o,",
ok = map(s_mapper, "foo") == "f,o,o,",
desc = "we can map over each character",
};
assert {
ok = filter filtrator, list2 == ["foo", "foo"],
desc = "filter filtrator, list2 == [\"foo\", \"foo\"]",
ok = filter(filtrator, list2) == ["foo", "foo"],
desc = "filter(filtrator, list2) == [\"foo\", \"foo\"]",
};
assert {
ok = (filter filtrator, ["foo", "bar", "foo", "bar"]) == ["foo", "foo"],
desc = "(filter filtrator, [\"foo\", \"bar\", \"foo\", \"bar\"]) == [\"foo\", \"foo\"]",
ok = (filter(filtrator, ["foo", "bar", "foo", "bar"])) == ["foo", "foo"],
desc = "(filter(filtrator, [\"foo\", \"bar\", \"foo\", \"bar\"])) == [\"foo\", \"foo\"]",
};
assert {
ok = filter filtrator, ["foo", "bar", "foo", "bar"] == ["foo", "foo"],
desc = "filter filtrator, [\"foo\", \"bar\", \"foo\", \"bar\"] == [\"foo\", \"foo\"]",
ok = filter(filtrator, ["foo", "bar", "foo", "bar"]) == ["foo", "foo"],
desc = "filter(filtrator, [\"foo\", \"bar\", \"foo\", \"bar\"]) == [\"foo\", \"foo\"]",
};
assert {
ok = filter boolfiltrator, [1, 2, 3, 4, 5, 6, 7] == [1, 2, 3, 4],
desc = "filter boolfiltrator, [1, 2, 3, 4, 5, 6, 7] == [1, 2, 3, 4]",
ok = filter(boolfiltrator, [1, 2, 3, 4, 5, 6, 7]) == [1, 2, 3, 4],
desc = "filter(boolfiltrator, [1, 2, 3, 4, 5, 6, 7]) == [1, 2, 3, 4]",
};
// Tuple processing
@ -80,8 +80,8 @@ let test_tpl = {
let identity_tpl_mapper = func (name, val) => [name, val];
assert {
ok = map identity_tpl_mapper, test_tpl == test_tpl,
desc = "map identity_tpl_mapper, test_tpl == test_tpl",
ok = map(identity_tpl_mapper, test_tpl) == test_tpl,
desc = "map(identity_tpl_mapper, test_tpl) == test_tpl",
};
let tpl_mapper = func (name, val) => select name, [name, val], {
@ -90,8 +90,8 @@ let tpl_mapper = func (name, val) => select name, [name, val], {
};
assert {
ok = map tpl_mapper, test_tpl == {foo = "barbar", cute = "pygmy"},
desc = "map tpl_mapper, test_tpl == {foo = \"barbar\", cute = \"pygmy\"}",
ok = map(tpl_mapper, test_tpl) == {foo = "barbar", cute = "pygmy"},
desc = "map(tpl_mapper, test_tpl) == {foo = \"barbar\", cute = \"pygmy\"}",
};
let identity_tpl_filter = func (name, val) => true;
@ -100,19 +100,19 @@ let identity_tpl_filter = func (name, val) => true;
let tpl_filter = func (name, val) => name != "foo";
assert {
ok = filter identity_tpl_filter, test_tpl == test_tpl,
desc = "filter identity_tpl_filter, test_tpl == test_tpl",
ok = filter(identity_tpl_filter, test_tpl) == test_tpl,
desc = "filter(identity_tpl_filter, test_tpl) == test_tpl",
};
assert {
ok = filter tpl_filter, test_tpl == { quux = "baz" },
desc = "filter tpl_filter, test_tpl == { quux = \"baz\" }",
ok = filter(tpl_filter, test_tpl) == { quux = "baz" },
desc = "filter(tpl_filter, test_tpl) == { quux = \"baz\" }",
};
let o_str_filter = func (s) => s != "o";
assert {
ok = filter o_str_filter, "foobar" == "fbar",
ok = filter(o_str_filter, "foobar") == "fbar",
desc = "We can strip out characters",
};
@ -122,25 +122,25 @@ let tpl_reducer = func (acc, name, val) => acc{
};
assert {
ok = reduce tpl_reducer, {keys = [], vals = []}, test_tpl == {keys = ["foo", "quux"], vals = ["bar", "baz"]},
desc = "reduce tpl_reducer, {keys = [], vals = []}, test_tpl == {keys = [\"foo\", \"quux\"], vals = [\"bar\", \"baz\"]}",
ok = reduce(tpl_reducer, {keys = [], vals = []}, test_tpl) == {keys = ["foo", "quux"], vals = ["bar", "baz"]},
desc = "reduce(tpl_reducer, {keys = [], vals = []}, test_tpl) == {keys = [\"foo\", \"quux\"], vals = [\"bar\", \"baz\"]}",
};
let str_identity_reducer = func (acc, s) => acc + s;
assert {
ok = reduce str_identity_reducer, "", "foo" == "foo",
ok = reduce(str_identity_reducer, "", "foo") == "foo",
desc = "identity reducer copies string",
};
let char_iter = func (acc, s) => acc + [s];
assert {
ok = reduce char_iter, [], "foo" == ["f", "o", "o"],
ok = reduce(char_iter, [], "foo") == ["f", "o", "o"],
desc = "we can split a string into grapheme clusters",
};
assert {
ok = reduce (char_iter), [], "foo" == ["f", "o", "o"],
ok = reduce((char_iter), [], "foo") == ["f", "o", "o"],
desc = "We can use arbitrary expressions to refer to the macro.",
};

View File

@ -574,11 +574,13 @@ make_fn!(
do_each!(
pos => pos,
_ => word!("reduce"),
_ => must!(punct!("(")),
func => must!(expression),
_ => must!(punct!(",")),
acc => must!(trace_parse!(non_op_expression)),
_ => must!(punct!(",")),
tgt => must!(trace_parse!(non_op_expression)),
_ => must!(punct!(")")),
(Expression::FuncOp(FuncOpDef::Reduce(ReduceOpDef{
func: Box::new(func),
acc: Box::new(acc),
@ -593,9 +595,11 @@ make_fn!(
do_each!(
pos => pos,
_ => word!("map"),
_ => must!(punct!("(")),
func => must!(expression),
_ => must!(punct!(",")),
list => must!(trace_parse!(non_op_expression)),
_ => must!(punct!(")")),
(Expression::FuncOp(FuncOpDef::Map(MapFilterOpDef{
func: Box::new(func),
target: Box::new(list),
@ -609,9 +613,11 @@ make_fn!(
do_each!(
pos => pos,
_ => word!("filter"),
_ => must!(punct!("(")),
func => must!(expression),
_ => must!(punct!(",")),
list => must!(trace_parse!(non_op_expression)),
_ => must!(punct!(")")),
(Expression::FuncOp(FuncOpDef::Filter(MapFilterOpDef{
func: Box::new(func),
target: Box::new(list),

View File

@ -11,7 +11,7 @@ let str_join = module{
},
};
let result = (reduce joiner, {sep=mod.sep, out=""}, (mod.list)).out;
let result = reduce(joiner, {sep=mod.sep, out=""}, (mod.list)).out;
};
let len = module{
@ -19,7 +19,7 @@ let len = module{
} => {
let counter = func (acc, item) => acc + 1;
let result = reduce counter, 0, (mod.list);
let result = reduce(counter, 0, (mod.list));
};
let reverse = module{
@ -27,7 +27,7 @@ let reverse = module{
} => {
let reducer = func (acc, item) => [item] + acc;
let result = reduce reducer, [], (mod.list);
let result = reduce(reducer, [], (mod.list));
};
let enumerate = module{
@ -42,7 +42,7 @@ let enumerate = module{
let acc = {count=mod.start, list=[], step=mod.step};
let enumerated = reduce reducer, acc, (mod.list);
let enumerated = reduce(reducer, acc, (mod.list));
let result = enumerated.list;
};
@ -52,8 +52,8 @@ let zip = module{
} => {
let counter = func (acc, item) => acc + 1;
let len1 = reduce counter, 0, (mod.list1);
let len2 = reduce counter, 0, (mod.list2);
let len1 = reduce(counter, 0, (mod.list1));
let len2 = reduce(counter, 0, (mod.list2));
let rng = select (len1 >= len2), NULL, {
true = 0:(len1 - 1),
@ -72,5 +72,5 @@ let zip = module{
idxs = [],
};
let result = (reduce reducer, acc, rng).result;
let result = reduce(reducer, acc, rng).result;
};

View File

@ -17,7 +17,7 @@ let base_type_reducer = func (acc, f) => select (acc.val is f), f, {
};
// Computes the base type of a value.
let base_type_of = func (val) => (reduce base_type_reducer, {val=val, typ="null"}, base_types).typ;
let base_type_of = func (val) => reduce(base_type_reducer, {val=val, typ="null"}, base_types).typ;
// Turns any schema check module into a compile failure.
// The module must export the computed value as the result field.
@ -39,7 +39,7 @@ let any = module {
let reducer = func (acc, t) => acc{
ok = acc.ok || (schema.shaped{val=acc.val, shape=t}.result),
};
let any = func (val, types) => reduce reducer, {ok=false, val=val}, types;
let any = func (val, types) => reduce(reducer, {ok=false, val=val}, types);
let result = any(mod.val, mod.types).ok;
};
@ -82,7 +82,7 @@ let shaped = module {
float = simple_handler(mod.val, mod.shape),
bool = simple_handler(mod.val, mod.shape),
null = simple_handler(mod.val, mod.shape),
tuple = (reduce tuple_handler, {shape=mod.shape, ok=false}, (mod.val)).ok,
tuple = reduce(tuple_handler, {shape=mod.shape, ok=false}, (mod.val)).ok,
list = simple_handler(mod.val, mod.shape),
func = simple_handler(mod.val, mod.shape),
module = simple_handler(mod.val, mod.shape),

View File

@ -12,7 +12,7 @@ let fields = module{
let reducer = func (acc, field, value) => acc + [field];
let result = reduce reducer, [], (mod.tpl);
let result = reduce(reducer, [], (mod.tpl));
};
// return a list of the values in a tuple.
@ -25,7 +25,7 @@ let values = module{
let reducer = func (acc, field, value) => acc + [value];
let result = reduce reducer, [], (mod.tpl);
let result = reduce(reducer, [], (mod.tpl));
};
let iter = module{
@ -37,7 +37,7 @@ let iter = module{
let reducer = func (acc, field, value) => acc + [[field, value]];
let result = reduce reducer, [], (mod.tpl);
let result = reduce(reducer, [], (mod.tpl));
};
let strip_nulls = module{
@ -49,7 +49,7 @@ let strip_nulls = module{
let filterer = func (name, value) => value != NULL;
let result = filter filterer, (mod.tpl);
let result = filter(filterer, (mod.tpl));
};
let has_fields = module{
@ -64,7 +64,7 @@ let has_fields = module{
let reducer = func (acc, f) => acc && (f in fs);
let result = reduce reducer, true, (mod.fields);
let result = reduce(reducer, true, (mod.fields));
};
let field_type = module{
@ -95,7 +95,7 @@ let field_type = module{
false = true, // if this isn't the field then we propagate true
});
let is_type = reduce reducer, true, it;
let is_type = reduce(reducer, true, it);
let result = has_field && is_type;
};