ivy icon indicating copy to clipboard operation
ivy copied to clipboard

Game of Life in )demo?

Open tcolgate opened this issue 1 year ago • 3 comments

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?

tcolgate avatar Dec 27 '24 10:12 tcolgate

It's pretty cool but I feel it's a bit too rich a concoction for the demo, which aims to show the fundamentals.

robpike avatar Dec 28 '24 10:12 robpike

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.

rsc avatar Dec 28 '24 13:12 rsc

@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.

tcolgate avatar Jan 14 '25 12:01 tcolgate