From Competitive Programming to APL
corecursive.com
corecursive.com
The APL book is a classic programming language book. Expensive to acquire, though. $150+ for a used copy.
data = [1,2,3]
# . means element-wise operation
sum(exp.(filter(isodd,data)))
# or, where x |> f is f(x)
data |> x -> filter(isodd,x) .|> exp |> sum
Which looks quite clean to me. But Julia does not have partial function evaluation (just using filter(isodd) above would not work). Is this one of the main differences?
https://www.youtube.com/watch?v=gLULrFY2-fI
I found both of these presentations enlightening, and interesting enough to get me to put J on my list of things to learn.
reduce(+, (j -> j*2^-j).(Float64.(1:n)))
which can be written, but then kinda differs from APL approach of combining primitives sum((j -> j*2^-j).(Float64.(1:n)))
compared to +/j×2*-j←⍳n
Also the statement is more succinct, and that is better understood when you compare an APL one-liner with a multi-line code in the other two languages. I think this is its true strength. sum([(j*2**(-j),j=1,n)])
Modern Fortran is arguably an array programming language. It has array operations like Matlab, Python/Numpy, and R.sum(j -> j*2.0^(-j),1:n)
sum(function,array) applies function to all elements of array before the summation (without need to allocate an intermediate array).
To my knowledge other languages like Julia and numpy don't offer the same range of index-based primitives, like grades, or classifications, which are used pervasively in APLs.
APLs better support a pattern of computing some permutation of a set of arrays, and then viewing other arrays through that permutation, than other languages. You can do it, of course, in numpy, but it's not nearly as pleasant.
I wouldn’t be surprised if there was a performance hit relative to a language with partial evaluation as a design feature.
Conor's knowledge of solving problems in a data parallel fashion using masks and such in APL helped him with his day job of building GPU accelerated data-science tools at NVidia.
But it's not just a NVidia thing - CPUs can do data parallel operations and also get slowed down by branching. I don't think this means that you should write everything in an array language, but it means that learning how to solve problems under those constraints will teach you important lessons.
https://news.ycombinator.com/item?id=10876975
https://news.ycombinator.com/item?id=8476113
https://news.ycombinator.com/item?id=27223086
https://news.ycombinator.com/item?id=25484587
https://news.ycombinator.com/item?id=25903740
https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...
Conor: ...it’s not C, it’s like a macro variant of C, where it’s a CDSL, where 80% of your “library” is macros. I did a search, there’s 10,000 macros in the source code, and those macros are used like functions ... some of the exact same macros that exist in the J code base are exactly what competitive programmers use.
He is, of course, talking about things like this (from the "J incunabulum"): #define DO(n,x) {I i=0,_n=(n);for(;i<_n;++i){x;}}
Which is actually pretty concise and readable. Sometimes I think it would be nice if enough people could agree on a header library of "concise C" macros that they could become part of the idiom. Or at least a minority dialect instead of an idiolect.If just the for loop is in the macro you can put the braces in yourself.
If the braces are up to you, nested loops are cleaner.
DO(y,height) DO(x, width) blur(x,y);I'm not sure when these leetcode style interviews became pervasive but it makes sense that recruiters would figure out quickly where to find people that would excel at that interview process.