From c102c798213053d30ee9ba4ab0aefcf5d97f4634 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 2 May 2025 21:37:14 -0700 Subject: callf, juxt: rewrite. * lib.[ch] (do_juxt, juxtv): Functions removed. * eval.c (do_callf): New static function. Implements callf without consing up an argument list with juxt which is then applied to the function. It's all done with a loop which builds args on the stack. (callf): Rewritten to use do_callf. We have to convert the function list to dynamic args, but that is more compact than all the consing done by the removed juxt implementation. (juxt): New static function: implemented trivially using callf and list_f. (eval_init): Change registration from removed juxtv to juxt. Going forward, I won't be using the v suffix on functions. That should only be used when two versions of a function exist: one which takes vargs, and one which takes C variable arguments or something else like a list. Example: format is a variadic C function with a ... in its argument list. formatv takes a varg and is the main implementation. vformat takes a va_list. Leading v is the standard C convention, like vsprintf. trailing v is the TXR convention for a function that takes vargs, but only if it is an alternative to one which doesn't. --- eval.c | 31 +++++++++++++++++++++++++++---- lib.c | 10 ---------- lib.h | 1 - 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/eval.c b/eval.c index 43f36fdf..d4a5cf7e 100644 --- a/eval.c +++ b/eval.c @@ -7108,11 +7108,34 @@ static val ipf(val fun, varg args) return func_f0v(dyn_args(args, fun, nil), do_args_ipf); } +static val do_callf(val dargs, varg inargs) +{ + val self = lit("callf"); + val func = dargs->a.car; + varg funlist = dargs->a.args; + cnum funcount = args_count(funlist, self); + cnum inacount = args_count(inargs, self); + args_decl(funargs, max(funcount, ARGS_MIN)); + args_decl(inargs_cp, max(inacount, ARGS_MIN)); + cnum index = 0; + + while ((args_copy(inargs_cp, inargs), args_more(funlist, index))) { + val afun = args_get(funlist, &index); + val arg = generic_funcall(afun, inargs_cp); + args_add(funargs, arg); + } + + return generic_funcall(func, funargs); +} + static val callf(val func, varg funlist) { - val juxt_fun = juxtv(funlist); - val apf_fun = apf(func, 0); - return chain(juxt_fun, apf_fun, nao); + return func_f0v(dyn_args(funlist, func, nil), do_callf); +} + +static val juxt(varg funlist) +{ + return callf(list_f, funlist); } static val do_mapf(val env, varg args) @@ -7778,7 +7801,7 @@ void eval_init(void) func_n2(lexical_lisp1_binding)); reg_fun(intern(lit("chain"), user_package), func_n0v(chainv)); reg_fun(intern(lit("chand"), user_package), func_n0v(chandv)); - reg_fun(intern(lit("juxt"), user_package), func_n0v(juxtv)); + reg_fun(intern(lit("juxt"), user_package), func_n0v(juxt)); reg_fun(intern(lit("andf"), user_package), func_n0v(andv)); reg_fun(intern(lit("orf"), user_package), func_n0v(orv)); reg_fun(intern(lit("notf"), user_package), func_n1(notf)); diff --git a/lib.c b/lib.c index ca6c6fe2..8be3f708 100644 --- a/lib.c +++ b/lib.c @@ -9672,16 +9672,6 @@ val chandv(varg funlist) return func_f0v(args_get_list(funlist), do_chand); } -static val do_juxt(val funcs, varg args) -{ - return mapcar(pa_12_1(func_n2(apply), args_get_list(args)), funcs); -} - -val juxtv(varg funlist) -{ - return func_f0v(args_get_list(funlist), do_juxt); -} - static val do_and(val fun1_list, varg args_in) { cnum argc = args_in->argc; diff --git a/lib.h b/lib.h index 848a8303..614263de 100644 --- a/lib.h +++ b/lib.h @@ -1286,7 +1286,6 @@ val pa_1234_34(val fun3, val arg1, val arg2); val chain(val first_fun, ...); val chainv(varg funlist); val chandv(varg funlist); -val juxtv(varg funlist); val andf(val first_fun, ...); val andv(varg funlist); val orv(varg funlist); -- cgit v1.2.3