From c058a946c6fbc918ff233aea1e301921e7ce68b8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 15 Jan 2021 16:07:31 -0800 Subject: mapcar/maprod: show-stopper bug. Observed wrong result: (mapcar (lambda (. args) (list . args)) '#(1 2 3) '#(4 5 6)) -> #((1 4) nil nil) Correct result: -> #((1 4) (2 5) (3 6)) This is not specific to vector input; it's broken for sequences of all types. Functions affected are mapcar, mapf, mappend, mapdo, maprod, maprend, maprodo. * eval.c (map_common, prod_common): Because we reuse the args structure across iterations, we must reinitialize the fill and list members. These can be modified by the functionw which is called. In particular, the arguments are applied, they may be turned into a list (fill decrements to zero, and a list is produced). --- eval.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 0b707e78..a466fde8 100644 --- a/eval.c +++ b/eval.c @@ -5303,7 +5303,6 @@ static val map_common(val self, val fun, struct args *lists, seq_iter_t *iter_array = coerce(seq_iter_t *, alloca(argc * sizeof *iter_array)); args_decl(args_fun, max(argc, ARGS_MIN)); - args_fun->fill = argc; list_collect_decl (out, otail); for (i = 0, idx = 0; i < argc; i++) @@ -5325,6 +5324,9 @@ static val map_common(val self, val fun, struct args *lists, args_fun->arg[i] = elem; } + args_fun->fill = argc; + args_fun->list = 0; + fun_ret = generic_funcall(fun, args_fun); if (collect_fn != 0) @@ -5438,7 +5440,6 @@ static val prod_common(val self, val fun, struct args *lists, args_copy(args_reset, lists); args_normalize_exact(args_reset, argc); args_work->fill = argc; - args_fun->fill = argc; for (i = 0; i < argc; i++) if (!iter_more((args_work->arg[i] = iter_begin(args_reset->arg[i])))) @@ -5449,6 +5450,9 @@ static val prod_common(val self, val fun, struct args *lists, for (i = 0; i < argc; i++) args_fun->arg[i] = iter_item(args_work->arg[i]); + args_fun->fill = argc; + args_fun->list = 0; + ptail = collect_fn(ptail, generic_funcall(fun, args_fun)); for (i = argc - 1; ; i--) { -- cgit v1.2.3