I like the sound of it. Really happy to hear about a new language feature. Just a thought - is there any reason to have a way to specify an early-termination condition, so the entire set of data doesn't need to be evaluated? I don't have a specific use case in mind, so it's not worth it if others don't either
On Wed, Aug 3, 2016 at 9:11 AM, Henry Rich <henryhr...@gmail.com> wrote: > 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