Skip to content

Commit b8f269c

Browse files
committed
make excess fold behavior more inline with repeat and do
1 parent 129bcb8 commit b8f269c

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

src/algorithm/reduce.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{convert::identity, iter::repeat};
66
use ecow::{eco_vec, EcoVec};
77

88
use crate::{
9-
algorithm::{get_ops, loops::flip, multi_output, pervade::*},
9+
algorithm::{get_ops, loops::flip, pervade::*},
1010
check::{nodes_clean_sig, nodes_sig},
1111
cowslice::cowslice,
1212
Array, ArrayValue, Complex, ImplPrimitive, Node, Ops, Primitive, Shape, SigNode, Uiua,
@@ -1049,7 +1049,7 @@ pub fn fold(ops: Ops, env: &mut Uiua) -> UiuaResult {
10491049
crate::profile_function!();
10501050
let [f] = get_ops(ops, env)?;
10511051
let sig = f.sig;
1052-
let (iterable_count, acc_count, collect_count) = if sig.args() > sig.outputs() {
1052+
let (iterable_count, acc_count, excess_count) = if sig.args() > sig.outputs() {
10531053
(sig.args() - sig.outputs(), sig.outputs(), 0)
10541054
} else {
10551055
let iter = sig.args().min(1);
@@ -1095,7 +1095,7 @@ pub fn fold(ops: Ops, env: &mut Uiua) -> UiuaResult {
10951095
if row_count == 0 && arrays.iter().all(Result::is_err) {
10961096
row_count = 1;
10971097
}
1098-
let mut collect = multi_output(collect_count, Vec::with_capacity(row_count));
1098+
let mut excess_rows = vec![Vec::new(); excess_count];
10991099
for _ in 0..row_count {
11001100
for array in arrays.iter_mut().rev() {
11011101
env.push(match array {
@@ -1104,17 +1104,23 @@ pub fn fold(ops: Ops, env: &mut Uiua) -> UiuaResult {
11041104
});
11051105
}
11061106
env.exec(f.clone())?;
1107-
for collected in &mut collect {
1108-
collected.push(env.remove_nth_back(acc_count)?);
1107+
if excess_count > 0 {
1108+
for (i, row) in env
1109+
.remove_n(excess_count, acc_count + excess_count)?
1110+
.enumerate()
1111+
{
1112+
excess_rows[i].push(row);
1113+
}
11091114
}
11101115
}
1111-
let accs = env.pop_n(acc_count)?;
1112-
for collected in collect.into_iter().rev() {
1113-
let val = Value::from_row_values(collected, env)?;
1114-
env.push(val);
1116+
// Remove preserved/excess values
1117+
if excess_count > 0 {
1118+
_ = env.remove_n(acc_count, acc_count)?;
11151119
}
1116-
for acc in accs {
1117-
env.push(acc);
1120+
// Collect excess values
1121+
for rows in excess_rows.into_iter().rev() {
1122+
let new_val = Value::from_row_values(rows, env)?;
1123+
env.push(new_val);
11181124
}
11191125
Ok(())
11201126
}

src/compile/modifier.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,10 +1221,10 @@ impl Compiler {
12211221
}
12221222
Fold => {
12231223
let (sn, _) = self.monadic_modifier_op(modified)?;
1224-
if sn.sig.args() <= sn.sig.outputs() {
1224+
if sn.sig.args() < sn.sig.outputs() {
12251225
self.experimental_error(&modified.modifier.span, || {
12261226
format!(
1227-
"{} with arguments outputs is experimental. To use it, \
1227+
"{} with arguments < outputs is experimental. To use it, \
12281228
add `# Experimental!` to the top of the file.",
12291229
prim.format()
12301230
)

tests/loops.ua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ A ← ↯2_3_4⇡24
169169
⍤⤙≍ [2222 0] [∧(⊃(+/+)⋅⋅∘) ♭₂ [1_1]_[10_10]_[100_100]_[1000_1000] 0 0]
170170
⍤⤙≍ 60 ∧(+×) 10 1_2_3 0
171171
⍤⤙≍ [] ∧(+) [1] []
172+
⍤⤙≍ [0 1 3 6] ∧(⊸+) [1 2 3 4] 0
173+
⍤⤙≍ [1 3 6 10] ∧(.+) [1 2 3 4] 0
172174

173175
# Each pervasive
174176
⍤⤙≍ ¯5 ∵¯ 5

0 commit comments

Comments
 (0)