@Marshall I'll consider it. might just add both to the planning and then decide later. both options seem interesting though, so maybe I could include both with different glyphs?
could ⍅ and ⍆ work for behead/"belast"? or maybe swapped, idk
The major cells of a list are enclosed elements, so you have to deal with enclosed stuff in either model. The only way BQN avoids it is by having ´ require its argument to be a list.
i implemented it in the most straightforward way possibile:
let cells = majorCells xs
let go :: [Array] -> St Array
go [] = throwError $ DomainError "Reduce empty axis"
go [x] = return x
go (a : b : xs) = do
x <- callDyad f a b
go $ x : xs
go cells
hmm, because scan takes elements from the left, but then reduces from the right, is there a way to implement it without having to recalculate all the reductions for each prefix?
(not that i care about performance, of course, but i'm curious)
If you're fixing stuff, I think it's best to make all the reductions run from left to right (K does this). For flat array programming, - is the only affected function that gets used much, and it's not all that common.
@Adám these of the proposed ones are the most appealing to me, because / and \ still retain their meaning, and to a certain extent ⌿ and ⍀ do too. but then i need glyph ideas for replicate and expand (:
kap does ⫽/⑊ for replicate/expand, right?
no actually I think kap only has replicate and ⑊ only exists in the keyboard but is given no meaning
anyways, i'll put reduce & scan development on pause and work on array notation while we discuss the best behavior and syntax.
i've read through the wiki and it actually doesn't seem all that bad
I think the only thing to watch for in the implementation (after dodging the parsing concerns) is evaluation order. To keep ⋄ consistent, it'd go left to right, so ⟨a←1⋄a+2⟩ is allowed but not ⟨a+2⋄a←1⟩.
K goes the other way for consistency with function calls, like (a+2;a:1) versus *[a+2;a:1] versus (a+2)*a:1, but without that intermediate form [] that concern isn't nearly as strong in APL.
⤈ Reduce down
⇟ Scan down
⤉ Reduce up
⇞ Scan up
⇸ Reduce right
⇻ Scan right
⇷ Reduce left
⇺ Scan left
⌿ Replicate vertically
⍀ Replicate vertically
/ Replicate horizontally
\ Expand horizontally
The J strategy was to have a separate prefixes operator that just calls the function on each (non-empty) prefix. So then you could combine that with reduction in either direction, and it would recognize and combine a linear-time scan. Except J doesn't have left-to-right reduction so that's only possible in one direction...
Well, personally I'd just define scan as "reduction, but save the intermediate results" like K does and not have this cross-direction scan concept at all.
If you want to define all possibilities then there's also the exclusive scan, which comes up a fair amount. Array shape to strides is a right-to-left exclusive scan for one.
Modified assignment parsing is a complicated rule, happens when ← has a function to the left and an array to the right (and then requires a target to the further left). At least with a name convention it's resolvable statically.
I pushed an executable with array notation. it also has reduce and scan but i can't remember what state i left them in. i think reduce is rtl but scan is ltr.