One of the topics addressed in the codfns presentation this year is that APL is particularly difficult to parse. Are there any good blog posts investigating how the syntax of APL would have to change to make it easier to parse?
I guess I don't mean syntax, I mean grammar. And I ran across a literature review on APL, which makes me less convinced that APL grammar is in fact difficult. Part of my thinking is in the context of meta-programming, although I suppose that meta-programming doesn't need to operate on the textual representation of a given language.
@Quintec sequences of names are hard to parse because you don't know until runtime whether they represent arrays, functions, or monadic/dyadic operators
in dyalog some expressions containing dots cause trouble because a dot could mean many things - inner product, outer product (after a jot), lookup from a namespace, decimal point in an fp literal
@Quintec Hard to parse for a compiler. Rather than humans. @ngn After resolving the ambiguity of square brackets using a lexical analyzer, Giradot and Rollin show that APL2 is LALR. The review is: https://cs.nyu.edu/manycores/litrev.pdf
@eyepatch a simple question - in {⍺⍺ - ⍵} is - called monadically or dyadically? A compiler must know that, but that requires knowing rhe operands type, which is annoying to deal with in a compiler
i have no idea if that's what codfns was talking about, but it surely is a thing that's annoyed me
Page 30 of "An Introduction to Array Programming in Klong" [1] introduces an exercise involving pretty-printing matrices of numbers. Here's my solution (38 characters):
`pm::{.p'(,/'+{(-|/1+#'x)$'x}'+$x);[]}`
That's half the size of the book's solution (76 characters):
@nathanrogers p2: You may want to exploit the fact that when you try to evenly divide a non-integer by 1, the remainder is the fractional part.
@nathanrogers p3: You have an unnecessary parenthesis around ⍺ and can get rid of the inner dfn with '*'⊣¨⍵. Also, I'd recommend using monadic , over monadic ∊ whenever possible, as it "does less".
@nathanrogers p4: Consider using A⊃⍨B instead of ⊃A[B] when A is nested and B is a scalar.
@nathanrogers p5 is really clever. Nice! You could avoid splitting ⍵ by changing the dfn to be dyadic and insert it into the pair ⊃{wzod⊃⍨12|m+⍵<dates⊃⍨12|m←⍺-1}/ or you could use indexing and pre-process the argument with {wzod⊃⍨12|⍵[0]-⍵[1]<dates⊃⍨12|⊃⍵}-∘1 0 but don't get me wrong, your solution is good as it is.
@nathanrogers p6 requires work. Here are some hints: You can filter with ∩ and look for starting points of contiguous subarrays with ⍷
@nathanrogers p7 does the same (expensive) computation twice. When you see things like (f g A)h g A consider "factoring out" g: (f h ⊢)g A or even h⍨∘f⍨g A
@nathanrogers p9 could benefit greatly from looking into dyadic ⍸.
@jordancurve so, from what i gather, klong is "in the public domain or whatever you call it" (quoting from its licence file), yet the book is paywalled. klong's performance is "abysmal" compared to k and it deviates substantially from its syntax and semantics. i wonder, what's the point...
It would have been helpful if I included the exercise I was solving, given that the book isn't free. Here it is: imgur.com/gallery/kJSFlGV
@ngn, Klong's reference guides are both comprehensive and in the public domain (t3x.org/klong/index.html). I wanted to learn how K-like languages worked, and I couldn't find that kind of documentation for oK, or for the version of k I downloaded from kx systems, so I started with Klong, even though it diverges from K. Would like to hear other suggestions.
Thanks, I intend to ask more questions here, but I come from a RTFM background. I prefer to learn from well-documented systems. I spend a lot of time poring over references.
My ultimate goal is to learn actual K. Just starting Klong because I found it small, approachable, and well-documented, and it claims some similarity with K.
Q is well documented, but I didn't see a direct way to translate Q knowledge into K (though I suspect it would work that way once I learned Q well enough).
@Adám yes, they do different (but related) things depending on the types of the arguments
@jordancurve keep in mind that k changes a lot between releases (every few years), and copycat implementations are often incomplete or incompatible with the original
klong is the most incompatible i've seen so far
oh... maybe kerf is in that category too
they should probably be considered completely different languages, just like how apl and j are different
@ngn J is definitely a dialect of APL. It is basically identical to the last version of Sharp APL, just with an ASCII spelling scheme. It was originally called "APL\?".
@Adám i'm a self taught programmer, but have recently been doing much more security related work. learning apl was my way of taking a bit of a break from that, and i'm just interested in alternative models of programming/computation in general.
@Adám mostly dyalog. i liked tacit composition way too much to switch to GNU APL which i think was missing that last i checked. ngn/apl is also lovely though.
@Adám i don't have many people to compare myself too, so i don't know how fluent i am relatively, but i feel quite comfortable with it, comfortable enough that i lead some introductory APL workshops at The Recurse Center.
i highly recommend The Recurse Center as a programming community :) while relatively few people there were specifically interested in APL, a lot of people were curious enough that they were well-attended and fun to give. the spirit is such that anyone in the community and just go ahead and give workshops if they want.
@Adám oh, those lessons look great. i'll bookmark them and work through them. in the past when i've lurked here i've really appreciated the idioms you've posted.
@feeb That's really interesting. Maybe we should have people who pass through NYC be guest speakers there (if that even exists). And that may be a good place for US companies looking for potential APLers to find those willing to learn it.
@Adám, would you like me to reach out to some of the people that run it on your behalf? (i'll cc you in if they show interest).
for the second point, definitely :) if i had any idea of how to find people looking for APLers, i would've tried to work there rather than where i am now.
if i added a built-in like ⍣ but which returns all the results, should it also return the argument? i.e. should 1∘+ reps {7=⍵}⊢3 have the 1st item be 3 or 4?
@dzaima Maybe have it take an array of number of iterations, then ⍣0 1 2 3 would return a list of four (including initial value) and ⍣3 would just be the last one, and ⍣∞ would be the fixpoint.
@dzaima I mean, with regular ⍣, one would alter the function so that it uses an array with previous results in as well (that is ⍵), and each result would be appended to the previous ones, so, in the first iteration, the original ⍵ (which might have already been enclosed to accomodate for the function) won't be removed just because it's the first iteration
@Adám and either way I'd have to add a new built-in for the function ⍵⍵ case, since there's no other way to make 1∘+ reps {7=⍵}⊢3 work as expected (assuming the return condition isn't that easily calculable)
@dzaima That'd need cheating. OK, looked it up. J does the array thing, but has a shortcut, ⍣(⊂n) means ⍣(⍳n) and ⍣(⊂∞) means ⍣(⍳k) where k is the smallest integer which is large enough to stabilise the result.
@dzaima Not true, because A f⍣g B is defined (in J) as A f⍣(A g B)⊢B so if g returns ~exitCondition you can write ⍣ExitCondition⍣(⊂∞) for all values until the exit condition is met.
Since ⍣ExitCondition becomes a no-op eventually (by g causing 0 applications of f), ⍣(⊂∞) will stop.
@Adám oh wait so if one of the iterations of 1∘+ would return the same value as the previous (yes, impossible here, but with side-effects it can) it'd terminate the loop early?
@Adám that's why i feel like that having a simple inline repeat functionality is useful, as otherwise you just can't do some things in a simple inline expression
@Adám well between the choices of recursion and a repeat one has to be taken. Allowing writing code that requires some looping is a thing for the programmer
and personally I find a repeat builtin more understandable than recursion, it being easier for a computer is just a coincidence.
currently I've got this, with ⍡ being a random character choice. If anyone has any objections, please voice them for me to read for tomorrow. (no idea what I'll do with ⍺)