I don't understand the 'lazily produce the arguments' bit. Please amplify.

I also don't understand 'streaming data'.  Please amplify.



It would be in keeping with the language for gerund u to be a Cyclic Gerund.



I am leaning toward a primitive/foreign (call it c. for continue) that would cause termination of F. if set.

Argument to c. would be 1 to continue, 0 to stop after the current iteration, _1 to stop after current iteration & discard result thereof. Result of c. would be previous value (1 initially).


Henry Rich


On 8/3/2016 9:35 PM, Joe Bogner 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> 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> 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

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to