If performance is the issue, I would either leave out early return from the first draft, or implement it several ways and benchmark each of them.
Understandability also hints at leaving early return for explicit code. -- Raul On Wednesday, August 3, 2016, Joe Bogner <joebog...@gmail.com> wrote: > The gerund sounds like a good approach for performance reasons. It would > only need to evaluate the termination function if it was supplied compared > to checking for a termination error code that could be in the user-code. > > A possible use case would be something like find the first player who > reaches 100 points > > On the topic of gerunds, could y be a gerund that could lazily produce the > arguments? If so, that could also account for termination maybe? > > If y could also be a gerund that accepted the partial result to produce the > next argument, that seems like it could be useful. Not sure if it's > possible or if there would be performance implications. It seems 'streaming > data' is a weak area of J too > > > > > On Wed, Aug 3, 2016 at 6:29 PM, Henry Rich <henryhr...@gmail.com > <javascript:;>> wrote: > > > This is a very good idea. Perhaps gerund v could be (selection > > function)`(termination function) > > > > or > > > > perhaps we could define a 'termination' error code that would be signaled > > with 13!:8 > > > > or maybe someone has a better way. > > > > Henry Rich > > > > > > > > On 8/3/2016 3:42 PM, Joe Bogner wrote: > > > >> 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 > <javascript:;>> 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 <javascript:;>> > >>>> To: Source forum <sou...@jsoftware.com <javascript:;>> > >>>> 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 > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm