YAML Parser for Dyalog APL
github.com
github.com
c←∊LF,⍪⊆⍵ ⋄ k←0⍴⍨≢c k c⌿⍨←⊂n≤(⊂¯1++⍀m)⌷(m←c=LF)⌿n←+⍀(≠⍀c∊'"''')<(c='#')∧¯1⊖c∊LF⍪WS k[⍸(⊢∨¯1⊖⊢)≠⍀(k=¯1)<c∊'"''']←Q k[⍸(k∊¯1 Q)<(c∊'-?:')∧1⊖c∊LF,' ']←S k[⍸sm∧im←m<(n-i⌷m⌿n←⍳≢n)=n-(i←⊂¯1++⍀m)⌷(m←c=LF)⌿n←+⍀(k=S)∨sm←c=' ']←¯2 k[⍸im<k=S]←0 d←n-(⊂¯1++⍀m)⌷(m←c=LF)⌿n←+⍀0⍪¯1↓k∊¯2 S k[i←⍸(k∊S Q)<(c=':')∧1⊖c∊LF⍪WS]←S d k c m⌿⍨←⊂1+m←(⍳≢k)∊(i-1)(⊣I⍸)⍨⍸¯1⊖(k=S)∨c=LF ⋄ k c(⊣@(⍸m←m∧1⊖m))⍨←S'?' d+←(c=':')<n>(⊂¯1++⍀m)⌷0⍪¯1↓(1⊖m←c=LF)⌿n←+⍀¯1⊖m d k c⌿⍨←⊂k≠¯1 ⋄ p←⍳≢i←⍸(c=LF)⍱k<0 _←((¯1⊖⍪⍀){p[⍵]←(⊂a⍸⍵)⌷a←⍺I⍋⍺}¨⊢){⊂1↓⍵-≢x}⌸d[i]⍪⍨x←(⊢I⍋)∪d[i] k[i]×←S=k[i] I I@{k[i][⍵]=S}⍣≡⍨p ⊣ k←k[i][y I x[y←⍸≠x]⍳x←¯1@{p=⍳≢p}p]@i⊢k ld←d ⋄ d←(⊂+⍀m)⌷0⍪d⌿⍨m←(¯1⊖m)∨m←k=S d k c⌿⍨←⊂(m∧k=¯2)⍱(d>ld)∧~m←(i⌷m⌿n)<(i←⊂¯1++⍀m)⌷(1⊖m←c=LF)⌿n←+⍀k=S d⌿⍨←m←(1↑⍨≢)⍣(~∨⌿m)⊢m←k=S ⋄ k←S M Q I'-:'⍳m⌿c ⋄ k[⍸k≡,Q]←0 ⋄ c⊂⍨←m c[i]←1↓¨c[i←⍸('-?:'∊⍨⊃¨c)∧k∊S M Q] c⌿¨⍨←(∨⍀∧∨⍀U⊖)∘(~⊢∊LF⍪WS⍨)¨c ⋄ d k c⌿⍨←⊂(k=0)⍲0=≢¨c c←(1↓¯1↓⊢)¨@(⍸'"'''∊⍨∊1↑¨c)⊢c q←(k=M)⍀x⍳⍨qq←∪(⊂'')⍪x←c⌿⍨k=Q ⋄ d k q c⌿⍨←⊂k≠Q d k q c⍪⍨←(d+←S M∊⍨⊃k)↑¨d k 0(⊂'') k⊖⍨←1 ⋄ k[⍸d≥1⊖d]←K
As someone unfamiliar with it, this looks like the product of some sort of charset/unicorn decoding error rather than a cohesive program.
But I would also like to know from APL aficionados whether it is a “write-only” power tool akin to a “Perl for math”, or if it’s also easy to read other people’s APL code once you get used to the most common symbols in APL.
This project specifically looks to be done in a flat array style similar to Co-dfns[0]. It's not a very common way to use APL. However, I've maintained an array-based compiler [1] for several years, and don't find that reading is a particular difficulty. Debugging is significantly easier than a scalar compiler, because the computation works on arrays drawn from the entire source code, and it's easy to inspect these and figure out what doesn't match expectations. I wrote most of [2] using a more traditional compiler architecture and it's easier to write and extend but feels about the same for reading and small tweaks. See also my review [3] of the denser compiler and Co-dfns.
As for being read by others, short snippets are definitely fine. Taking some from the last week or so in the APL Farm, {⍵÷⍨+/|-/¯9 ¯11+.○?2⍵2⍴0} and {(⍸⍣¯1+\⎕IO,⍺)⊂[⎕IO]⍵} seemed to be easily understood. Forum links at [4]; the APL Orchard is viewable without signup and tends to have a lot of code discussion. There are APL codebases with many programmers, but they tend to be very verbose with long names. Something like the YAML parser here with no comments and single-letter names would be hard to get into. I can recognize, say, that c⌿¨⍨←(∨⍀∧∨⍀U⊖)∘(~⊢∊LF⍪WS⍨)¨c trims leading and trailing whitespace from each string in a few seconds, but in other places there are a lot of magic numbers so I get the "what" but not the "why". Eh, as I look over it things are starting to make sense, could probably get through this in an hour or so. But a lot of APLers don't have experience with the patterns used here.
[0] https://github.com/Co-dfns/Co-dfns
[1] https://github.com/mlochbaum/BQN/blob/master/src/c.bqn
[2] https://github.com/mlochbaum/Singeli/blob/master/singeli.bqn
[3] https://mlochbaum.github.io/BQN/implementation/codfns.html
Hoping to hear your thoughts in the future once the project is more in shape!
https://tv.dyalog.com/Dyalog23/?v=bb6sIAJjMeM
In a sibling comment, mlochbaum impressively just reads my code without too much effort. However, it is first and foremost written for a domain expert, with all affordances for outsiders discarded in favor of parsimony and direct expression of thought. Even if you know all the APL symbols, you'd need some domain knowledge about parsing and YAML specifically to really understand the why.Learning to read the APL symbols is super easy. Just give yourself a couple weeks of 30 minutes a day or so. That's definitely enough to get you started solving challenge problems.
However, "fluently reading APL" is like talking about fluently reading math. The focus is on the concepts and communicating those concepts. Fluency is tied to familiarity with the underlying ideas of the problem domain.