Here's a complete cleaned up presentation of S combinator:

lambda=:3 :0
  if. 1=#;:y do.
    3 :((y,'=.y');<;._2]0 :0)`''
  else.
    (,<#;:y) Defer (3 :(('''',y,'''=.y');<;._2]0 :0))`''
  end.
)


Defer=:2 :0
  if. (_1 {:: m) <: #m do.
    v |. y;_1 }. m
  else.
    (y;m) Defer v`''
  end.
)

I=: lambda 'x'
  x
)

K=: lambda 'x y'
  x
)

S=: lambda 'x y z'
  (x`:6 z)`:6 y`:6 z
)


I is a simple identity mechanism.

K produces a constant function.  Conceptually it's similar to [ (with
something like an implicit & when you give it only one argument
because of the way lambda is used)

S is something like a monadic hook.

Thus,
   ((S`:6 K)`:6 K)`:6 'a'
a
   ((S`:6 K)`:6 I)`:6 'a'
a
   ((S`:6 K)`:6 S)`:6 'a'
a

It does not matter what the second operation is, since it gets
ignored.  Here's a presentation of this concept in native J:
   ([ [) 'a'
a
   ([ ]) 'a'
a
   ([ S`:6) 'a'
a
   ([ (; #)) 'a'
a

When you use a left identity as the left tine of a monadic fork, any
valid verb used in the right tine of the fork will be ignored.

Also, here's the Y combinator expressed using this system:

Y=: lambda 'f x'
  (f`:6 (Y`:6 f))`:6 x
)

almost_factorial=: lambda 'f n'
  if. 0 >: n do. 1
  else. n * f`:6 n-1 end.
)

almost_fibonacci=: lambda 'f n'
  if. 2 > n do. n
  else. (f`:6 n-1) + f`:6 n-2 end.
)

   (Y`:6 almost_factorial)`:6] 5
120

And to get rid of the word forming issue with `:6 you might instead want to use

Ev=: `:6

   (Y Ev almost_factorial)Ev 5
120
   (Y Ev almost_fibonacci)Ev 8
21

And, finally:

successor=: lambda 'f n'
  try. f`:6 n+1 catch. n end.
)

   (Y Ev successor)Ev 0

This will hang the machine.

So here we have a model for recursion in J which is not limited by the C stack.

And, in fact, jbreak will not work here -- so be careful.

FYI,

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

Reply via email to