I like it. Still, some thoughts: monad F.
+ Fdot {: 2 ,. 1 2 3 4 10 9 7 4 equivalent to this pattern/expression, {:@(+/)\. 2 ,. 1 2 3 4 10 9 7 4 The usefulness depends on the optimization potential of v@(u/)\. Fcolon: The monad case should be consistent with dyad and use &.|. instead of @:|. But completely reasonable is to leave both as @:|. , and let the user choose to do |. if he prefers. This idea allows the concept of potentially eliminating Fcolon: Both F. and F: can be expressed as the adverb u`v F. instead of passing cap, u F. would be used. When using v, no extra parentheses are needed with gerund call. You needed or not to parentheses v with conjunction call the same way. We can use the freed conjunction parameter to make a new one. Rdot =: 2 : 0 '`u s' =. 2 {. u`[: cap =. [: if. 's' -:&(5!:1)&< 'cap' do. u&:>/ v (<"_1 y) else. s@> u&.>/\. v (<"_1 y) end. : '`u s' =. 2 {. u`[: cap =. [: if. 's' -:&(5!:1)&< 'cap' do. (<"_1 y) u&:>/@v < x else. (<"_1 y) s@>@:(u&.>/\.)@v < x end. ) u Fdot v -: u`v Rdot , u Fdot [: -: u Rdot , u Fcolon v -: |.@:(u`v Rdot , |.) u Fcolon v -: x |.@:(u`v Rdot , ) |. y u Fcolon v -: |. x (u`v Rdot , |.) y u Fcolon v -: |. x u`v Rdot (|.@[ , ]) y Fcolon seems too easily expressible as Fdot |. hook. (or Rdot), as long as the monad/dyad consistency is resolved with @:|. instead of &.|. Getting back to Rdot, for monad, v can be ], and usually would be (though , typically doesn't hurt). but Fcolon version would be |. The idea allows the flexibility of putting x and y on which ever side is convenient. But there are additional not that esoteric candidates. Notice @v was used instead of @:v : candidates for v (] ,.~ N f\ [) NB. f simply ] most often. <@(<@f/.@[ ,. ]) NB. \ instead of /. (@f) optional both of the above create tables. In the 2nd u would need to include its own embedded &.> In terms of optimization, perhaps only (R. ,) (still called F. - just refering to my function) would get optimized, but I'd imagine that even when v creates a table such as the above, its possible to extract the unboxed x and ys for optimization in fold or scan. Basically, if the leftmost train dyad (middle tine in a 3 fork) is , or ,. (with optional ~) then there would seem to be an unboxed extraction optimization strategy. ----- Original Message ----- From: Henry Rich <henryhr...@gmail.com> To: sou...@jsoftware.com Sent: Wednesday, August 3, 2016 9:11 AM Subject: Re: [Jsource] F. WAS: Proposal for new looping primitive x N. Thanks for the ideas, guys. New proposal below. Let's keep the definition in explicit form, so that we can have more readers involved. u/\ has no place here: it requires u to be associative. Definition: [x] u F. v y where u is a verb to be applied repeatedly v is a verb to apply to the result of each execution of u, to produce the part saved in the final result, or [: to get the full result of only the final execution of u x is the (optional) initial value (if omitted, u is applied first between the last 2 items of y) y is the argument array F. applies between items of y starting at the end, F: starts at the front. In either case the x argument to u is the next item of y, and the y argument to u is the initial value/state from previous execution. Formal definition: Fdot =: 2 : 0 cap =. [: if. 'v' -:&(5!:1)&< 'cap' do. u&:>/ (<"_1 y) else. v@> u&.>/\. (<"_1 y) end. : cap =. [: if. 'v' -:&(5!:1)&< 'cap' do. u&:>/ (<"_1 y) , <x else. v@> u&.>/\. (<"_1 y) , <x end. ) Fcolon =: 2 : 0 cap =. [: if. 'v' -:&(5!:1)&< 'cap' do. u&:>/@|. (<"_1 y) else. v@> u&.>/\.&.|. (<"_1 y) end. : cap =. [: if. 'v' -:&(5!:1)&< 'cap' do. u&:>/ (|. <"_1 y) , <x else. v@> u&.>/\.&.|. (<"_1 y) ,~ <x end. ) Example: f =. ((i. , ]) >./)@:(({:@])`({.@])`[}) this takes x=list and y=index,value. It stores value into x at location index, and returns the index and value of the largest atom in the resulting list. (Yeah, it's a punk function.) 0 0 f Fdot (1&{) a =: 20 20 ?@$ 10099 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 96 0 The result is the list of the indexes that were encountered. 0 0 f Fdot [: a =: 20 20 ?@$ 100 2 99 The result is the result of the last execution only. Henry Rich On 8/3/2016 4:11 AM, 'Pascal Jasmin' via Source wrote: > 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 ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm