summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-02-29 20:36:25 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-02-29 20:36:25 -0800
commit9cfa3435672667fe0fe9abc59b9e1352c4a276d3 (patch)
tree195865754e78b9f34d06f8d8d6bd4edefd354df7
parente8dedb798f4333e5fc2c85e37c019600010b6f7d (diff)
downloadtxr-9cfa3435672667fe0fe9abc59b9e1352c4a276d3.tar.gz
txr-9cfa3435672667fe0fe9abc59b9e1352c4a276d3.tar.bz2
txr-9cfa3435672667fe0fe9abc59b9e1352c4a276d3.zip
partition, split, split*: iter used for indices
* lib.c (partition_func, split_func, split_star_func): Indices passed through lazy cons are now iterator, rather than a sequence accessed via car and cdr, which is inefficient for nonlists. (partition-split-common): Use iter-begin to convert indices to iterator, which becomes the cdr field of the lazy cons. * txr.1: Update documentation for these functions to clarify that the second argument is a sequence. The inaccurate text claiming that "if the second argument is an atom other than a function" is rewritten. This doesn't describe the behavior that is implemented, where the test applied is seqp, not atom. The indices can be a vector of integers, which is an atom.
-rw-r--r--lib.c24
-rw-r--r--txr.156
2 files changed, 43 insertions, 37 deletions
diff --git a/lib.c b/lib.c
index 94156bd3..52326b2d 100644
--- a/lib.c
+++ b/lib.c
@@ -4003,8 +4003,8 @@ static val partition_func(val base, val lcons)
val len = nil;
for (;;) {
- if (indices) {
- val raw_index = pop(&indices);
+ if (iter_more(indices)) {
+ val raw_index = iter_item(indices);
val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index),
plus(raw_index, if3(len, len, len = length(seq))),
raw_index);
@@ -4019,7 +4019,8 @@ static val partition_func(val base, val lcons)
if (rest) {
val fun = us_lcons_fun(lcons);
us_func_set_env(fun, index);
- us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest, indices));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest,
+ iter_step(indices)));
} else {
us_rplacd(lcons, nil);
}
@@ -4042,8 +4043,8 @@ static val split_func(val base, val lcons)
val len = nil;
for (;;) {
- if (indices) {
- val raw_index = pop(&indices);
+ if (iter_more(indices)) {
+ val raw_index = iter_item(indices);
val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index),
plus(raw_index, if3(len, len, len = length(seq))),
raw_index);
@@ -4059,7 +4060,8 @@ static val split_func(val base, val lcons)
if (rest) {
val fun = us_lcons_fun(lcons);
us_func_set_env(fun, index);
- us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest, indices));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest,
+ iter_step(indices)));
} else {
us_rplacd(lcons, cons(rsub, nil));
}
@@ -4082,8 +4084,8 @@ static val split_star_func(val base, val lcons)
val len = nil;
for (;;) {
- if (indices) {
- val raw_index = pop(&indices);
+ if (iter_more(indices)) {
+ val raw_index = iter_item(indices);
val index = if3((!opt_compat || opt_compat > 170) && minusp(raw_index),
plus(raw_index, if3(len, len, len = length(seq))),
raw_index);
@@ -4099,7 +4101,8 @@ static val split_star_func(val base, val lcons)
if (rest) {
val fun = us_lcons_fun(lcons);
us_func_set_env(fun, succ(index));
- us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest, indices));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest,
+ iter_step(indices)));
} else {
us_rplacd(lcons, cons(rsub, nil));
}
@@ -4135,7 +4138,8 @@ static val partition_split_common(val seq, val indices,
if (!seqp(indices))
indices = cons(indices, nil);
- return make_lazy_cons_car_cdr(func_f1(zero, split_fptr), seq, indices);
+ return make_lazy_cons_car_cdr(func_f1(zero, split_fptr), seq,
+ iter_begin(indices));
}
val partition(val seq, val indices)
diff --git a/txr.1 b/txr.1
index a0e62a0c..a020e625 100644
--- a/txr.1
+++ b/txr.1
@@ -36928,7 +36928,7 @@ otherwise
.coNP Function @ partition
.synb
-.mets (partition < sequence >> { index-list | < index | << function })
+.mets (partition < sequence >> { index-seq | < index | << function })
.syne
.desc
If
@@ -36954,20 +36954,20 @@ of appearance, a sequence
to the original is produced.
If the second argument is of the form
-.metn index-list ,
+.metn index-seq ,
or if an
-.meta index-list
+.meta index-seq
was produced from the
.meta index
or
.meta function
-arguments, each value in that list must be an integer. Each integer
+arguments, each value in that sequence must be an integer. Each integer
value which is nonnegative specifies the index position
given by its value. Each integer value which is negative
specifies an index position given by adding the length of
.meta sequence
to its value. The sequence index positions thus denoted by
-.meta index-list
+.meta index-seq
shall be strictly nondecreasing. Each successive element
is expected to designate an index position at least as high
as all previous elements, otherwise the behavior is unspecified.
@@ -36975,13 +36975,13 @@ Leading index positions which are (still) negative, or zero, are effectively
ignored.
If
-.meta index-list
+.meta index-seq
is empty then a one-element list containing the entire
.meta sequence
is returned.
If
-.meta index-list
+.meta index-seq
is an infinite lazy list, the function shall terminate if that
list eventually produces an index position which is greater than or equal to
the length of
@@ -36991,20 +36991,20 @@ If the second argument is a function, then this function is applied
to
.metn sequence ,
and the return value of this call is then used in place of the
-second argument, which must be a single index value, which is then
+second argument, which must either be a single index value, which is then
taken as if it were the
.meta index
-argument, or else a list of indices, which are taken as the
-.meta index-list
+argument, or else a sequence of indices, which are taken as the
+.meta index-seq
argument.
-If the second argument is an atom other than a function, it is assumed to be
-an integer index, and is turned into an
-.meta index-list
-of one element.
+If the second argument is neither a sequence, nor a function, then it is
+assumed to be an integer index, and is turned into an
+.meta index-seq
+sequence containing one element.
After the
-.meta index-list
+.meta index-seq
is obtained as an argument, or determined from the
.meta index
or
@@ -37013,11 +37013,11 @@ arguments, the
.code partition
function then divides
.meta sequence
-according to the indices given by that list.
+according to the indices.
The first partition begins with the first element of
.metn sequence .
The second partition begins at the first position in
-.metn index-list ,
+.metn index-seq ,
and so on. Indices beyond the length of the sequence are ignored,
as are indices less than or equal to zero.
@@ -37032,8 +37032,8 @@ as are indices less than or equal to zero.
.coNP Functions @ split and @ split*
.synb
-.mets (split < sequence >> { index-list | < index | << function })
-.mets (split* < sequence >> { index-list | < index | << function })
+.mets (split < sequence >> { index-seq | < index | << function })
+.mets (split* < sequence >> { index-seq | < index | << function })
.syne
.desc
If
@@ -37068,20 +37068,20 @@ in that the elements indicated by the split indices are removed.
The
.metn index ,
-.metn index-list ,
+.metn index-seq ,
and
.meta function
arguments are subject to the same restrictions and treatment
as the corresponding arguments of the
.code partition
function, with the following difference: the index positions indicated by
-.code index-list
+.code index-seq
are required to be strictly increasing, rather than nondecreasing.
If the second argument is of the form
-.metn index-list ,
+.metn index-seq ,
or if an
-.meta index-list
+.meta index-seq
was produced from the
.meta index
or
@@ -37090,19 +37090,21 @@ arguments, then the
.code split
function divides
.meta sequence
-according to the indices indicated in the list. The first piece always begins
+according to the indices indicated in
+.metn index-seq .
+The first piece always begins
with the first element of
.metn sequence .
Each subsequent piece begins with the position indicated by
an element of
-.metn index-list .
+.metn index-seq .
Negative indices are ignored.
If
-.meta index-list
+.meta index-seq
includes index zero,
then an empty first piece is generated.
If
-.meta index-list
+.meta index-seq
includes an index greater than or equal to the length of
.meta sequence
(equivalently, an index beyond the last element of the sequence)