Game of Life in )demo?
With the addition of @, ivy now does a half decent looking GoL one liner (based on the TryAPL version, the use of box is different from the use in TryAPL, and I'm not 100% sure why).
# One run of GoL
op life M = 1 M or.and 3 4 == box +/ +/ 1 0 -1 o.flip 1 0 -1 @rot M
# Run life on N times on N
op M gen N = N == 0: M; life M gen N - 1
# Generate an initial board with some padding
R = -1 flip -2 rot 5 7 take (3 3 rho iota 9) in 2 3 4 5 8
# Show 3 generations of R
R gen@ iota 3
The only feature that is really missing is ⍣ (repeat, which repeatedly applies the operator "to the power"), and there's some "binding" thing ∘ which seems to bind one argument of a binary operator and then can be used with an each to repeatedly apply the resulting "unary" operator. It's easily replaced with a loop (and I guess a more direct syntax would require first class operators?). edit: The "Binding thing" is just the outer product, R∘gen¨ ⍳4, but maybe binaryOp@ 1 2 3 4, is producing some kind of closure?)
Is this worth including in the demo?
It's pretty cool but I feel it's a bit too rich a concoction for the demo, which aims to show the fundamentals.
I ran the code to see what 'box' was doing in 3 4 == box .... The boxed item is a 5x7 matrix, so normally that would be a (2) == (5 7) shape error, but boxing it makes it look like a (2) == (1), which distributes the left vector over the ==, producing the vector (3 == t) (4 == t=...). A more direct way to write that would now be 3 4 @== ....
Ivy and TryAPL use different models of boxing. In Ivy, boxing something just means creating a singleton vector containing that thing: rho rho box 1 is 1 (and rho box 1 is the vector [1]). In TryAPL, a boxed value is not a 1-element vector but a distinct kind of scalar value: ⍴⍴⊂1 is 0 (and ⍴⊂1 is the empty vector). In the TryAPL life, the boxed matrix stays boxed all the way through the rotate each and outer flip and and sums, leaving a boxed matrix of neighbor counts. And then 3 4 = scalar (boxed matrix) distributes automatically. In the Ivy version, you have to reintroduce the box for the 3 4 == to distribute, or else use 3 4 @==.
They kind of look like the same model because the pretty-printer in TryAPL does not distinguish them. In the display below, the boxed R (⊂R) and the 1-element vector containing R (2 ↓ 1 2 R) look exactly the same, but you can distinguish them with rho.
⊂R
┌─────────────┐
│0 0 0 0 0 0 0│
│0 0 0 1 1 0 0│
│0 0 1 1 0 0 0│
│0 0 0 1 0 0 0│
│0 0 0 0 0 0 0│
└─────────────┘
2 ↓ 1 2 R
┌─────────────┐
│0 0 0 0 0 0 0│
│0 0 0 1 1 0 0│
│0 0 1 1 0 0 0│
│0 0 0 1 0 0 0│
│0 0 0 0 0 0 0│
└─────────────┘
⍴⊂R
⍴⍴⊂R
0
⍴2 ↓ 1 2 R
1
⍴⍴2 ↓ 1 2 R
1
I don't fully understand the interactions in TryAPL between boxed values and "each". I would not have expected the two features to interact at all, but empirically they do: 1 ⌽ X is X for any scalar X, meaning 1 ⌽ 2 is 2, and 1 ⌽ ⊂R is ⊂R, not ⊂1⌽R. However, 1 ⌽¨ ⊂R is ⊂1⌽R: the box is apparently opened to apply the each'ed operator and then reapplied.
@robpike can we close this? There's already a discussion in the discussion section which mentions )demo, so that might be a better place to ponder where larger examples might live.