Can't say that I like any of their code or examples.

In J, In addition to boxscan there is also ^: and lexical closures 
http://www.jsoftware.com/jwiki/PascalJasmin/nonads%20revisited

/ is very powerful though

   |. >: i.10 
10 9 8 7 6 5 4 3 2 1 

applying */ to the above not only gives the factorial function, but applying it 
partially to any part (from the right side) of it gives you a result you could 
apply to more of it
    ( |. 11 +  i.10) * reduce */  |. >: i.10 
2432902008176640000 
    */  |. >: i.20 
2432902008176640000

*/ creates the accumulator as it goes, and is basically a repeated function of 
the accumulator and the list tail.

If you wanted an operation that makes a dyadic function between the 2 tail 
elements, and then a further operation with the accumulator.  Say add the last 
2 and multiply by accumulator

    1 *&(+/) reduce~  _2 ]\ >: i.10 
65835 

or wordier general approach of accessing each side separately and then 
combining them with a middle fork verb:

   (_2 ]\ >: i.10)  (] * +/@:[) reduce  1 
65835 

   (] * +/@:[) boxscan (_2 <\ >: i.10)     
(,<) 1 
65835 

Both the cells and the accumulator can be any shape including nested boxes, and 
pretty much any recursive function is a fold to a shape compatible with the 
function (accumulator cell).

Using these ideas with ^: is commonly done with simulations or search 
algorithms where you have a data cell and control cell in 2 boxes, and the left 
side of ^: will use {. and {: to qualify access to each side, and then return 2 
updated boxes.  Any static data should be in x variable.  Writing the function 
at least initially as an explicit verb can simplify it.  Debugging with ^: is 
very easy because you can ask it to do 1 2 3 searches and post intermediate 
result steps.

the lexical closure approach can be neat.  Although performance is not bad, its 
not usually as good as boxscan.

lex =:  2 : 0 
a =. n~ :: ] y 
(n) =: u(a&) 
a 
)

   * lex 'f'"0 ] 1 2 3 
1 2 6 
   f 
6&*

   (* lex 'f') 1 
6 
   f 
6&*

(* lex 'f') is a verb.  It is a verb that will update the verb named 'f' to 
whatever the result of its last application as a bound x parameter.  It will 
create f if it doesn't yet exist too.  The linked page has more advanced uses 
including extracting the x data (accumulator result)

erase 'f'

   (* lex 'f')"0 ] 1 2 3 4 5 
1 2 6 24 120 
   f 
120&* 
   (* lex 'f')"0 ] 6 7 8 9 10 
720 5040 40320 362880 3628800 

the lexical closure approach might be more flexible than boxscan, as the 
function part can be updated:

   ([ lex 'f') 1  NB. locking to a constant function returning x.
3628800 
   f 
3628800&[ 
 f 123   
NB. obviously can be applied without updating

3628800 

   (% lex 'f') 1x NB. reset again
3628800 
   f 
3628800&% 
(% lex 'f') 100 
36288 
   (* lex 'f') 2 NB. note that this applies last % function, but will reset f 
to 18144&*
18144 

linked essay has more uses including the most useful variation of separating 
the result and transformation functions.

The terrible blastoff trampoline example can be implemented with nonads 
(transformative lexical closures)

   erase 'f' 
1 
   ('blast off!'"_^:(0 = [) ; <:@[) lexT 'f' 3 NB. lexT defined in essay
3 
   f  NB. first call just binds x
3&('blast off!'"_^:(0 = [) ; <:@[) 
  f 5 
┌─┬─┐ 
│5│2│ 
└─┴─┘
   ('blast off!'"_^:(0 = [) ; <:@[) lexT 'f' 5
5
   f 
2&('blast off!'"_^:(0 = [) ; <:@[)  NB. note bound var lowered by 1
   ('blast off!'"_^:(0 = [) ; <:@[) lexT 'f' 11 
11 
   ('blast off!'"_^:(0 = [) ; <:@[) lexT 'f' 11  NB. bound value is only 0 
after call.
11 
   ('blast off!'"_^:(0 = [) ; <:@[) lexT 'f' 11 
blast off! 
   
timing is not terrible.  timespacex causes 2 calls to function.
   erase 'f' 
1 
   ('blast off!'"_^:(0 = [) ; <:@[) lexT 'f' 1000
0
1000
0
   timex '(''blast off!''"_^:(0 = [) ; <:@[) lexT ''f''"0 ] 10000 $ 1' 
0.0999663 
   

over 100k calls per second.


----- Original Message -----
From: Jose Mario Quintana <[email protected]>
To: Programming forum <[email protected]>
Cc: 
Sent: Monday, August 25, 2014 8:35:39 PM
Subject: Re: [Jprogramming] Adler-32

Pascal wrote:
"
use of terms like "recursion with tail call optimization" come from lisp
fold implementations where in order to avoid stack growth/exhaustion (/
avoids such stack abuse btw), you need to pass any accumulator (state
between function calls) as a parameter to the function.  boxscan basically
allows the anything lisp can do, can be done with boxscan (and each/ at its
core) thinking.
"

This sounds very interesting.  There is a technique, trampolining, that
supposedly allows for an implementation of tail call optimization; see for
example
http://weblambdazero.blogspot.com/2010/07/advanced-recursion-in-newlisp.html
for an implementation in NewLISP and
http://www.integralist.co.uk/posts/understanding-recursion-in-functional-javascript-programming/
for an implementation in JavaScript.  As far as I can see, this trampoline
is a tool (function) written in a target language that allows for TCO
without the need to alter the interpreter.  Glancing at these articles
references to accumulators and passing arguments pop up.

Can you really write an equivalent trampoline verb or adverb in J using
boxscan (or anything else)?  Further, can you write a wrapper adverb to
modify a recursive verb to optimize it via the trampoline? I would love to
see such tools in a familiar language (explicit versions would be welcome).
Please be gentle with you answer; I am not a computer scientist; I know
next to nothing about LISP, NewLISP or JavaScript; I cannot not even claim
that I know J very well.





On Mon, Aug 25, 2014 at 2:40 PM, 'Pascal Jasmin' via Programming <
[email protected]> wrote:

> / and boxscan are indeed fold and reduce in other languages.  The lisp
> implementations probably the easiest to understand.
>
> The big difference between / and boxscan is that / applied to a list
> implies a requirement that all items in the list are the same shape.
>  boxscan can use any list of arguments as the x, and appends any shape as
> the y, as long x u y results in a shape "compatible with y" (more
> accurately compatible with future applications of x u result .
>
> use of terms like "recursion with tail call optimization" come from lisp
> fold implementations where in order to avoid stack growth/exhaustion (/
> avoids such stack abuse btw), you need to pass any accumulator (state
> between function calls) as a parameter to the function.  boxscan basically
> allows the anything lisp can do, can be done with boxscan (and each/ at its
> core) thinking.
>
> A neat feature regarding tacit adverbs in general, is that I can type
> boxscan in source code, but the actual definition will be "compiled away"
> as if it were called with f. . using the term boxscan can help with
> readability if the intent of the function is to create a rightmost
> accumulator state.
>
>
>
>
> ----- Original Message -----
> From: Raul Miller <[email protected]>
> To: Programming forum <[email protected]>
> Cc:
> Sent: Monday, August 25, 2014 1:16:58 PM
> Subject: Re: [Jprogramming] Adler-32
>
> I have a nitpick with your phrasing here.
>
> Instead of saying "... use / recursively... (tail call optimization)"
> I think you should say something else.
>
> Mind you, I'm not quite sure what you should say.
>
> And, it's a nice clever bit of code. And here's another example of how
> I might use the concept of "use"  - I am using the usual J convention
> where we indent the expression but not the result:
>
>    (long sentence here)    ((&.>)/)(>@:)
> >@:((long sentence here)&.>/)
>
> But I can't quite bring myself to say that this is "using / recursively".
>
> I think I recognize the thought process - the argument to boxscan is a
> binary operator or what we call a dyadic verb, and the underlying
> concept here (which might be called "reduce", "insert" or "fold") is
> often implemented recursively in other contexts.
>
> But / itself represents that same operation. So it's the
> implementation of / or the concept of / which would attach to the
> concept of "recursively", but that's something very different, in my
> mind, from "using / recursively".
>
> Using / recursively seems like it ought to repeatedly use / in the
> same context (instead of just once).
>
> Maybe the sentence should have been "make the use of / more closely
> match a tail call recursive list scan"?
>
> I'm not sure.
>
> (Should I take this kind of side thought to the chat forum?)
>
> Thanks,
>
> --
> Raul
>
> 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