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