Earlier quoted context omitted.
While this code is awesomely mindbending, it does seem to be limited to a 20×20 grid, rather than being applicable to grids of any size. Also, and correct me if I'm wrong here, it looks like it would take more than 5 minutes to write. The more interesting aspect, though, is that it seems to be organized in an almost totally different way from the APL code. I suggest that this is largely because the two languages fost…
It doesn't have to be a finite grid. Here is another comonadic implementation of Life with an infinite board: https://github.com/BartoszMilewski/GameOfLife/blob/master/Li... Either version would definitely take me more than five minutes to write, but then again it would take me more than five minutes to write the APL version too. For someone like Penner or Milewski the comonadic Haskell versions might be achievable i…
Loopless Programming
101–110 of 129 posts
Re: Loopless Programming
#102There are only some instances where I ever need a loop:
- map cannot produce a Dictionary, so Dictionary manipulations usually require a loop
- Sometimes, a more complex qualifier or stopping condition is needed. Like striding through a Collection in a non-linear way.
Re: Loopless Programming
#103So to have fine granular control over your generated code, classic loops in C always relevant, while a simple array operation can be expressed in such high level way for other use cases.
Re: Loopless Programming
#104Re: Loopless Programming
#105As an example of the implications, consider computing the Mandelbrot set. I'll be using Numpy here to ensure people can follow what I'm doing, but for the point I wish to make, it's similar to how you'd write it in APL. The Mandelbrot set is compute by applying a function like this to each of a bunch of complex numbers:
def divergence(c, d):
i = 0
z = c
while i
To apply this to many points simultaneously in a vectorised "loopless" style, we'd write it like this: def mandelbrot_numpy(c, d):
output = np.zeros(c.shape)
z = np.zeros(c.shape, np.complex32)
for it in range(d):
notdone =
np.less(z.real*z.real + z.imag*z.imag,
4.0)
output[notdone] = it
z[notdone] = z[notdone]**2 + c[notdone]
return output
There is just one `for` loop, which is pretty easy to do in APL. The `while` loop has been subsumed into control flow encoded in boolean arrays. This is not exactly how you'd do in APL, but it has a similar feel. It's also pretty slow, because we are manifesting the entire `z` array in memory for every iteration in the outer loop. In contrast, an old school loop over every point, with an inner while loop for every point, would involve only two memory accesses per point. On a GPU, I have measured the vectorised style to be about 30x slower than one with a conventional `while` loop.Re: Loopless Programming
#106Swift provides many of the required Collection operators to go loopless - map, reduce, flatMap, compactMap (eliminate nil values), filter, first, contains, prefix/suffix, ... there’s even an OSS library that gives a compile time guarantee that a Collection is non-empty. There are only some instances where I ever need a loop: - map cannot produce a Dictionary, so Dictionary manipulations usually require a loop - Somet…
Assuming you meaning mapping over a list, some sort of fold function could produce a dictionary, in some languages, such as Elm. [1]
[1] https://package.elm-lang.org/packages/elm/core/latest/List#f...
Re: Loopless Programming
#107Last time I did APL programming I was a bit bothered by the performance implications of some of the standard loopless programming styles. In particular, it's hard to nest loops. As an example of the implications, consider computing the Mandelbrot set. I'll be using Numpy here to ensure people can follow what I'm doing, but for the point I wish to make, it's similar to how you'd write it in APL. The Mandelbrot set is…
Re: Loopless Programming
#108Most programmers have worked in a largely loopless programming language: SQL. IT lets you easily build the same sort of ‘Boolean state for every item’ as this discusses, but it requires you to be much more explicit about which items you want to line up next to one another if you’re joining two lists together. In modern languages we usually just use mapreduce like functional approaches to handle the same sort of thing…
Re: Loopless Programming
#109"(x + y) is an expression rather than a statement. The J programmer can embed (x + y) in a larger expression, perhaps a matrix multiplication (w +/ . * (x + y)) which adds the equivalent of three more nested loops, but is still a single expression. Expressions can be combined; statements cannot."
What about an expression like (x * x + y * y)? This would still be a single loop in C. Is J smart enough to figure that out, or will it turn that into three loops?
Re: Loopless Programming
#110Earlier quoted context omitted.
You described the GPs point perfectly. This is also covered in the article; it exhaustively covers the use cases for loops and provides higher level functions and operators instead.
It covers the use cases for loops over arrays/lists, not over more general graph-like structures.