in the u argument to / there's a couple of cool things you can do
(`])@.(fill -: [) adverb given to u that will skip xs that are "invalid" the other trick to do what you're asking is pattern of reshaping result to "invalid" ($~ 0 , $) will usually do the trick (adds leading 0 shape) so set result to this shape if you want to "break" This "kills" the data though. Ways to preserve the data include adding an illegal boxing level that can be quickly detected with L. , and/or adding a leading box to your data that might say include a complex number that indicate error code (assuming your data does not use complex numbers. leading _. embedded in numeric data (test with 128!:5) or 0$0.5 as first box content are other candidate codes. (`])@.(0 = #@]) is a candidate guard expression but if you use this, the break command might as well have been (0 $ ]) a simple way to use both tricks, and "finish as soon as possible" instead of true break is the guard (`])(@.(0 e. ,&#)) but more complex independent guards (for x and y) can be combined with +. ----- Original Message ----- From: Joe Bogner <joebog...@gmail.com> To: sou...@jsoftware.com Sent: Wednesday, August 3, 2016 3:42 PM Subject: Re: [Jsource] F. WAS: Proposal for new looping primitive x N. 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 ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm