From 128e59c15912c1a598616bf7c091043f95b6984c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 28 Mar 2025 22:24:45 -0700 Subject: New function keep: generalized keepqual. * eval.c (eval_init): Register keep intrinsic. * lib.[ch] (keep): New function. * stdlib/compiler.tl (compiler comp-fun-form): Transform two argument keep to keepqual. * txr.1: Documented. --- eval.c | 1 + lib.c | 6 ++++++ lib.h | 1 + stdlib/compiler.tl | 1 + txr.1 | 9 +++++++++ 5 files changed, 18 insertions(+) diff --git a/eval.c b/eval.c index 11545a12..93576d00 100644 --- a/eval.c +++ b/eval.c @@ -7490,6 +7490,7 @@ void eval_init(void) reg_fun(intern(lit("keepqual"), user_package), func_n3o(keepqual, 2)); reg_fun(intern(lit("keep-if"), user_package), func_n4o(keep_if, 2)); reg_fun(intern(lit("keep-keys-if"), user_package), func_n4o(keep_keys_if, 2)); + reg_fun(intern(lit("keep"), user_package), func_n5o(keep, 2)); reg_fun(intern(lit("separate"), user_package), func_n3o(separate, 2)); reg_fun(intern(lit("separate-keys"), user_package), func_n3o(separate_keys, 2)); reg_fun(intern(lit("remq*"), user_package), func_n2(remq_lazy)); diff --git a/lib.c b/lib.c index 68634b4f..ca6c6fe2 100644 --- a/lib.c +++ b/lib.c @@ -3616,6 +3616,12 @@ val keep_keys_if(val pred, val seq, val keyfun_in, val mapfun_in) return rem_if_impl(notf(pred), seq, keyfun_in, mapfun, lit("keep-keys-if")); } +val keep(val obj, val seq, val testfun_in, val keyfun_in, val mapfun_in) +{ + val testfun = default_arg(testfun_in, equal_f); + return remov(obj, seq, notf(testfun), keyfun_in, mapfun_in); +} + val separate(val pred, val seq, val keyfun_in) { val self = lit("separate"); diff --git a/lib.h b/lib.h index 977fbddf..848a8303 100644 --- a/lib.h +++ b/lib.h @@ -896,6 +896,7 @@ val keepql(val obj, val seq, val keyfun); val keepqual(val obj, val seq, val keyfun); val keep_if(val pred, val seq, val keyfun_in, val mapfun_in); val keep_keys_if(val pred, val seq_in, val keyfun_in, val mapfun_in); +val keep(val obj, val seq, val testfun_in, val keyfun_in, val mapfun_in); val separate(val pred, val seq, val keyfun); val separate_keys(val pred, val seq_in, val keyfun_in); val remq_lazy(val obj, val list); diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl index 836d53cd..98232c7b 100644 --- a/stdlib/compiler.tl +++ b/stdlib/compiler.tl @@ -1407,6 +1407,7 @@ ((pos @obj @seq) (set form (rlcp ^(posqual ,obj ,seq) form))) ((member @obj @seq) (set form (rlcp ^(memqual ,obj ,seq) form))) ((subst @obj @seq) (set form (rlcp ^(subqual ,obj ,seq) form))) + ((keep @obj @seq) (set form (rlcp ^(keepqual ,obj ,seq) form))) (@(require (chain . @nil) (> olev 5) (can-inline-chain form)) diff --git a/txr.1 b/txr.1 index 42774995..b7e031d9 100644 --- a/txr.1 +++ b/txr.1 @@ -36578,6 +36578,7 @@ is compared to .synb .mets (remove < key < sequence >> [testfun >> [ keyfun <> [ mapfun ]]]) .mets (remove-if < predfun < sequence >> [ keyfun <> [ mapfun ]]) +.mets (keep < key < sequence >> [testfun >> [ keyfun <> [ mapfun ]]]) .mets (keep-if < predfun < sequence >> [ keyfun <> [ mapfun ]]) .mets (separate < predfun < sequence >> [ keyfun <> [ mapfun ]]) .mets (remove-if* < predfun < sequence >> [ keyfun <> [ mapfun ]]) @@ -36676,6 +36677,14 @@ will delete, and removes those that .code remove-if will preserve. +Likewise, the +.code keep +function is the predicate-inverting counterpart of +.codn remove . +It retains those items which +.code remove +will delete and vice versa. + The .code separate function combines -- cgit v1.2.3