3 ms·
People are so quick to reject K and APL-style languages for superficial reasons that they never get to the deep and interesting reasons! I am mostly familiar w
by Athas 7y ago
People are so quick to reject K and APL-style languages for superficial reasons that they never get to the deep and interesting reasons! I am mostly familiar with APL, but I think the things I appreciate and dislike are about the same in K.
One interesting philosophical difference, at least among some APL programmers, is that building abstractions should be avoided. TFA has a hint of that philosophy, in its suggestion that perhaps naming (the root of abstraction) hinders clarity. I think this is definitely worth considering, and it doesn't really have anything to do with the (supposedly) cryptic syntax.
One reason I don't like K/APL-ish vector programming is performance. I once spent some time working with others on a GPU-targeting APL compiler, and I found that some common programming patterns are quite antithetical to good performance. In particular, the use of "nested arrays" (not the same as multidimensional arrays) induces pointer structures that are difficult to do anything with. Such nested arrays are typically necessary when you want to do the equivalent of a "map" operation that does not apply to each of the scalars at the bottom, but perhaps merely the rows of a matrix. Thus, control flow and data are conflated. This is fine conceptually, but makes it difficult to generate high-performance code.
Another concern is that encoding control flow as data requires a lot of memory traffic (unless you have a Sufficiently Smart Compiler; much smarter than I have ever seen). Consider computing the Mandelbrot set, which is essentially a 'while' for each of a bunch of points. An idiomatic APL implementation will often put the while loop on the outside of the loop over the point array, which means it will be written to memory for every iteration. In other languages, it would be more idiomatic to apply the 'while' loop to each point individually, which will then be able to run entirely in registers. You can also do that in APL, but it is normally not idiomatic (and sometimes awkward) to apply complex scalar functions to array elements.
Just look at this Mandelbrot implementation from Dyalog; they do it in exactly the way I described: https://www.dyalog.com/blog/2014/08/isolated-mandelbrot-set-explorer/ https://www.dyalog.com/blog/2014/08/isolated-mandelbrot-set-...
Specifically, the conceptual 'while' loop has been turned into an outer 'for' loop (this is OK because the 'while' loop is always bounded anyway):
:For cnt :In 1↓⍳256 ⍝ loop up to 255 times (the size of our color palette)
escaped←4<coord×+coord ⍝ mark those that have escaped the Mandelbrot set
r[escaped/inds]←cnt ⍝ set their index in the color palette
(inds coord)←(~escaped)∘/¨inds coord ⍝ keep those that have not yet escaped
:If 0∊⍴inds ⋄ :Leave ⋄ :EndIf ⍝ anything left to do?
coord←set[inds]+×⍨coord ⍝ the core Mandelbrot computation... z←(z*2)+c
:EndFor
- chrispsn 7y agoThere's a q Mandelbrot here: https://github.com/indiscible/qmandel https://github.com/indiscible/qmandel And Arthur's version in k (also below): http://www.kparc.com/z/comp.k http://www.kparc.com/z/comp.k I should convert it to k9 (Shakti)... +/~^+/b*b:49{c+(-/x*x;2**/x)}/c:-1.5 -1+(2*!2#w)%w:10
- Athas 7y agoMy K is weak, but I think that implementation is also putting the fixed point iteration on the outside, isn't it?
- jstimpfle 7y ago> One interesting philosophical difference, at least among some APL programmers, building abstractions should be avoided Humans need abstractions to think. What programmers need are abstractions that are not black boxes. I.e. can be opened.
- earenndil 7y agoWhat is TFA? > the use of "nested arrays" (not the same as multidimensional arrays) induces pointer structures that are difficult to do anything with J doesn't allow nested arrays by default; if you want to create such a structure, you have to use boxes (and then unbox the values inside of them to get at them), which makes it explicit and reduces its usage. AFAIK, k doesn't have nested arrays at all.