posting code before words, reduce2 =: (((&.>)/)(>@:))(@:(<"_1@:[ , <@:])) reduce3 =: ((((&.>)/)\.)(>@:))(@:(<"_1@:[ , <@:]))
Rdot =: 2 : '>@:(u&.>(n aar 5!:0))@:(<"_1@:[ , <@:])' Rdot1 =: 2 : '>@:(u&.>(n aar 5!:0))@:(<"_1@:[ ,~ <@:])' + reduce2 >@:(+&.>/)@:(<"_1@:[ , <@:]) + Rdot '/' >@:(+&.>/)@:(<"_1@:[ , <@:]) + reduce2 >@:(+&.>/)@:(<"_1@:[ , <@:]) + reduce3 >@:(+&.>/\.)@:(<"_1@:[ , <@:]) + Rdot '/\.' >@:(+&.>/\.)@:(<"_1@:[ , <@:]) They are grouped by equivalent use. Rdot1 reverses the order, but the only point of that seems to use (Rdot1 '/\') instead of Rdot '/\.' Rdot1 '/\' could easily have a reduce4 adverb "predefinition". The first thing you seem to be missing is using just / instead of /\. Its a much more common use. The next point is that Ndot1 probably should use /\ instead of /\. 1 2 + Rdot'/'~ 1 2 3 4 11 12 1 2 + Rdot'/\.'~ 1 2 3 4 11 12 10 11 8 9 5 6 1 2 1 2 + Rdot1'/\'~ 1 2 3 4 1 2 2 3 4 5 7 8 11 12 Rdot1 isn't absolutely necessary because (u Rdot'/\.'~ |.) will produce all of the same items in reverse order. I don't think any other use case makes sense. And I don't see a monadic application making sense either. A monad would just use / or /\. or /\ instead. The other model is: reducE =: 1 : (':'; 'o=. x for_i. y do. o =. o u i end.') which is the same as u~ reduce2~ The next point to notice is that the pattern (adverb) (>@:)(@:(<"_1@:[ , <@:])) imposes a guarantee on its u argument to produce a consistent shape. In terms of looking for special code, there's just 2 necessary patterns on the left: (&.>/) or (&.>/\.) bit 1: if / and /\. are the only practical uses of this, then the result can always be unboxed at the end. because u&.>/ started with 2 boxes on. If u wants to add "extra" box layers, then u can do so, and it is up to u to figure out a consistent interpretation. Usually pretty straightforward, but I'd need to see a use case for bit1 "auto-boxing" that is diffucult to do in u. imo bit0 is not needed, but bit 2 is / or /\. . A 3rd conceivable use that may be too esoteric is instead of (<"_1@:[ , <@]) : <@(<\@:[ ,. <@]) or <@(<\.@:[ ,. <@]) this builds boxes of lists of boxes, and is different from the "core pattern" I described above. What seems to actually be the core pattern is the 2: ((&.>)/)(>@:)(list of boxings adverb) ((&.>)/\.)(>@:)(list of boxings adverb) where the "list of boxings adverb" could be limited to: @:(u(<"_1@:) , v(<@:)) and maybe @:(u(<"_1@:) ,~ v(<@:)) u and v can maybe even be limited to [ ] there's a similar pattern in ,&< ... We know that both sides (and that count = 2) were homogeneous prior to their boxings. In the case of (>@:)(list of boxings adverb) we know that u (to left of this adverb) must create a homogeneous result (or error). In addition to fold/scan operations, u can also be something like x&{ leaf. in the context of fold/scan, fold(initialstate, array, function) the u and v in the above pattern are initialstate and array. As you know, the optimization potential is that they never have to be boxed. The point of the rambling, is that there is a more general pattern in (>@:)(@:(boxing of 2 variables verb)) I'd recommend against putting an extra function parameter for twiddling (reversing) x or y. I think its better for user to pretweak them, or they can write/use a modifier that adds the functionality. about v, your implementation I think means that it can only be a noun, and so I think the result would always have a compatible shape, and so no need to box it. An alternative to a v parameter to function is special code for (v {"_1 (bound N.)), and then consider {. {: # without the "_1 restriction. (v {"1 _1 L:0 _ (bound N.)) might also solve the box/no box bit. A problem with having a v embedded parameter in the modifier is that it may be a function of the data. 90%+ of the time, you will want all of it. A selection formula might be (<@i.@#"_1 {"1 _1 leaf ]) even though the same (selection vector) value would most likely be generated for all items. Basically having a v parameter embedded in the modifier would mean instead of v&{&.> u&.>/\. (<"_1 y) , <x have v&.> u&.>/\. (<"_1 y) , <x This would let ] be a simple v parameter to get the full results. In terms of optimization, you may not need to care whether # or {. is used. The shape is not guaranteed linear either, so v may be much more complex than a noun argument to { . The v parameter is obviously not needed for / version. Seperate functions are good if you accept that both are useful. But you can also look at it as 3 function patterns u (((&.>)/)(>@:))(@:(boxing of 2 variables)) (reduce2) u reduce3(v&>@:) NB. /\. version u reduce3(v&.>@:) But for the latter 2, it may be better and simpler to do it through special code detection? If you call either (u reduce3)(v&.>@:) or v&.>@:(u reduce3) then v can get "optimized within the main loop" ----- Original Message ----- From: Henry Rich <henryhr...@gmail.com> To: Source forum <sou...@jsoftware.com> Sent: Tuesday, August 2, 2016 8:43 PM Subject: [Jsource] Proposal for new looping primitive x N. As Marshall once noted, the biggest deficiency in J is looping over an array when you need a result from each iteration, and the calculation requires an initial value and some internal state. Your code looks like result {"_1 f/\. array , initialstate where each execution of f produces a result value plus the internal state to feed into the next iteration. The problems are: * the result is the entire array of internal state, which is more, maybe MUCH more than you need, since the final result needs only a portion of the state * The state is probably not commensurate with a item of the array, so you end up boxing the initial state and the array items, which is very wasteful. I propose a new primitive, call it N. (for insert). N. is an adverb that produces a conjunction. In (x N.), x specifies options for the processing, much as the right operand of u;.n does. Definition: [x] u (n N.) v y where u is the function to be applied v is the selector to apply to the result of each execution of u, to produce the part saved in the final result x is the (optional) initial value (if omitted, f is applied first between the last 2 items of y) y is the argument array n selects from several variants: bit 0=0 operation goes back to front bit 0=1 operation goes front to back, as if using &.|. bit 1=0 selected result from each iteration becomes one item of result bit 1=1 selected result from each iteration is boxed before becoming an item of result Formal definition: Ndot0 =: 2 : 0 v&{@> u&.>/\. (<"_1 y) : v&{@> u&.>/\. (<"_1 y) , <x ) Ndot1 =: 2 : 0 v&{@> u&.>/\.&.|. (<"_1 y) : v&{@> u&.>/\.&.|. (<"_1 y) ,~ <x ) Ndot2 =: 2 : 0 v&{&.> u&.>/\. (<"_1 y) : v&{&.> u&.>/\. (<"_1 y) , <x ) Ndot3 =: 2 : 0 v&{&.> u&.>/\.&.|. (<"_1 y) : v&{&.> u&.>/\.&.|. (<"_1 y) ,~ <x ) Ndot =: 1 : 0 assert. m e. i. 4 select. m case. 0 do. Ndot0 case. 1 do. Ndot1 case. 2 do. Ndot2 case. 3 do. Ndot3 end. ) I look forward to criticism of this proposal. Henry Rich ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm