Hacker News new | ask | show | jobs
by mikercampbell 1145 days ago
I walked in, realized just how advanced this was and then proceeded to read through the same way I pan through the Abstract Art section of the museum.

I freaking love APL and would love to learn it, but it is so incredibly jarring not knowing anything about the syntax.

4 comments

I have a video series that covers every glyph in Dyalog APL, if you're interested in learning APL syntax:

https://www.youtube.com/playlist?list=PLfYUBJiXbdtSgU6S_3l6p...

There's also a concise guide covering every glyph, which if read in order only ever uses glyphs in examples that have been covered previously:

https://fastai.github.io/apl-study/

Finally, we have a discussion forum for learners:

https://forums.fast.ai/t/apl-array-programming/97188

I'd be happy to teach you; just let me know.

The syntax is in fact quite simple, and the semantics of the core language is mnemonic and limited, so I believe that a reasonably intelligent person can learn the entire core lanuage in 24 hours of dedicated studies. Subtract a few if the student has a knack for mathematics, but add a few if they have a CS degree.

I share your sentiments and it is incredible. To an outsider this might as well be a parody of programming blog posts. Such impenetrable syntax taken in stride:

    We can improve this approach by recognizing that we can handle the edge cases by using a catenation:
        ⍸0 1⍷0,⍵
        ⍸1 0⍷⍵,0
    Notice immediately how much better this feels.
Ah yes, how immediate is the feeling, much better, indeed. APL is so ridiculous, you have to love it.
As for the semantics, here are the equivalent JS functions:

    I =    y  => [...y.keys()].filter((e,i) => y[i])            // ⍸y Indices of trues in y
    E = (x,y) => y.map((e,i) => x.every((e,j) => e == y[i+j]))  // x⍷y mask indicating indices where x Exists as a sub-array in y
    C = (x,y) => [x,y].flat()                                   // x,y Catenate x and y into a single array
    
    w = [1,1,1,1,0,1,1,1,0,1,0,1,1,0,0,0,1,1,1,1]
    I(E([0,1],C(0,w)))  // [0,5,9,11,16]
Now, if I, E, and C were prefix/infix JS operators, with x being the left argument (if any) and y being the right argument, we'd write:

    I([0,1] E (0 C w))
All APL operators have long right scope, so we don't need to parenthesise right arguments:

    I [0,1] E 0 C w  // same syntax as APL's ⍸ 0 1 ⍷ 0 , ⍵
Alternatively, you can see the infix operators as being methods of all types:

   I([0,1].E(0.C(w)))
Now we remove all the .() noise:

   I [0,1] E 0 C w  // same syntax as APL's ⍸ 0 1 ⍷ 0 , ⍵
Wasn't that hard, was it?
The syntax is actually quite simple, but you may be confused by the unfamiliar symbols and lack of syntax. 0 1 is simply [0,1] in JSON and ⍵ is the argument name. The other symbols cirrespond to prefix and infix operators. Compare the following JS expression which is syntactically (but not semantically) equivalent to the APL expression below it:

    - [0,1] * 0 ** w
    ⍸  0 1  ⍷ 0 , ⍵
If you are interested in learning APL, take a look at https://xpqz.github.io/learnapl/intro.html

Disclaimer: author