[HN Gopher] In Praise of APL (1977)
       ___________________________________________________________________
        
       In Praise of APL (1977)
        
       Author : tosh
       Score  : 87 points
       Date   : 2026-01-22 08:44 UTC (14 hours ago)
        
 (HTM) web link (www.jsoftware.com)
 (TXT) w3m dump (www.jsoftware.com)
        
       | kholis_ab wrote:
       | i love APL, but never ever tried it ... only watched videos of
       | code_report
        
         | abrudz wrote:
         | I'll be happy to give you a live personalised intro in
         | https://apl.chat or head over to https://challenge.dyalog.com/
         | for an automated guided introduction (with a chance of winning
         | a prize).
        
         | jodrellblank wrote:
         | https://tryapl.org/
        
         | ofalkaed wrote:
         | https://xpqz.github.io/learnapl/intro.html is a good place to
         | start learning.
        
       | singularity2001 wrote:
       | Should be the ultimate final incomprehensible programming
       | language for code agents
        
         | ofalkaed wrote:
         | ChatGPT is pretty good at correcting my mistakes. Give it a
         | snippet of not quite working code with no explanation and it
         | almost always correctly identifies what I am trying to do and
         | explains where I went wrong. Its corrected code almost never
         | works but its explanation of why my code failed gets me my
         | answer and that is what I really want. A year ago it could not
         | help me in the slightest, it has improved quite a bit. The
         | biggest issue with AI and APL seems to be that it does not
         | quite understand the differences between the various versions
         | of APL and seems to view APL2, Dyalog and GnuAPL as all the
         | same language.
         | 
         | Edit: It probably would be useless to someone at all competent
         | in APL and whose problems are more complex than their own
         | failings.
        
         | adrian_b wrote:
         | True. Due to its lack of verbosity, APL is not at all forgiving
         | for any substitution or transposition in its symbols, which can
         | cause great differences in program output, so it is quite
         | improbable for LLMs to generate a working program, unless it is
         | identical with one from its training set.
         | 
         | What I have said matches exactly what another poster said about
         | his experience in using a LLM with APL: "Its corrected code
         | almost never works".
         | 
         | The LLM recognizes the problem that must be solved by the code,
         | but it fails to generate the right APL symbol string.
         | 
         | I doubt that here a coding agent that attempts to verify the
         | generated code by compiling it can help, because the LLM will
         | generate eventually some syntactically-correct symbol string,
         | but which will implement a different function than desired.
         | 
         | Only a complete feedback loop, with a battery of varied tests
         | for the executable program produced by the generated code,
         | which can verify if it really implements the desired
         | functionality, can be used to filter the results for a working
         | program.
         | 
         | APL is greatly superior to almost all programming languages
         | that are popular today, for writing expressions involving
         | arrays (this includes expressions that do not involve arrays in
         | other languages, but which could be made simpler by using
         | arrays in APL).
         | 
         | However, the original APL has defects, due mainly to the fact
         | that it was an incomplete programming language, e.g. when
         | compared to the other contemporaneous IBM language, i.e. PL/I.
         | 
         | What one needs is a programming language with modern program
         | structures, data types and data type definition facilities, but
         | also with an expression syntax matching the power of APL
         | expressions.
         | 
         | The fact that in 2026 most programmers continue tho write "for"
         | loops for handling arrays, instead of using array expressions
         | like it was possible in 1966 in APL, 60 years ago, seems an
         | aberration of history. Even in the 1966 PL/I one could use
         | array expressions, even if only expressions that were much
         | simpler than those of APL.
         | 
         | Using symbols instead of keywords, like in APL, is not cryptic
         | for anyone who uses such a language regularly. It is cryptic
         | for those who have not used them. The English-based keywords
         | are somewhat less cryptic only for English speakers, and even
         | for them they can be misleading before they learn their correct
         | meanings.
        
           | skruger wrote:
           | Whilst LLMs still perform weakly in APL, the situation is
           | improving at pace, and giving it a "skill" to evaluate code
           | makes a dramatic difference. I gave a conference talk about
           | it recently (video): https://youtu.be/H_wdKeJ8gt4
        
           | pavlov wrote:
           | _> "it is quite improbable for LLMs to generate a working
           | program, unless it is identical with one from its training
           | set"_
           | 
           | This is a fascinating result. In some sense it's like APL is
           | actually the most human programming language, despite being
           | one of the most difficult for ordinarily trained human
           | programmers to pick up.
        
             | ofalkaed wrote:
             | >it's like APL is actually the most human programming
             | language
             | 
             | As an incompetent programmer who is far more comfortable
             | with even the most experimental and abstract literature
             | than any of the "easy" programming languages, I agree with
             | this.
             | 
             | Edit: I was going to fix that sentence, but it is a good
             | example of what thinking about programming languages does
             | to my brain. The idea of a context free human language is
             | alien, thinking in such absolute and concrete terms is
             | weirdly abstract.
        
       | misja111 wrote:
       | > The virtues of APL that strike the programmer most sharply are
       | its terseness -- complicated acts can be described briefly, its
       | flexibility -- there are a large number of ways to state even
       | moderately complicated tasks (the language provides choices that
       | match divergent views of algorithm construction), and its
       | composability
       | 
       | I had an introduction to APL in university and what I absolutely
       | hated was this terseness. I guess when you're a mathematician APL
       | is more natural but to me, as a programmer, I much prefer to have
       | some extra verbosity to make my code more (human-)readable.
        
         | adrian_b wrote:
         | Terseness is easier to remove from a programming language than
         | verbosity.
         | 
         | You can use a source preprocessor to enable you to write APL
         | programs by using keywords instead of any symbols that you do
         | not like. You can also use a source preprocessor to expand any
         | traditional APL source, by converting symbols into keywords, so
         | that it will be easier to read for you.
         | 
         | Using symbols instead of keywords is a minor feature of APL,
         | which was inherited from the standard mathematical notation,
         | from which APL was derived.
         | 
         | The important features of APL are the expression syntax and the
         | set of available operators, not the symbols used for them.
         | 
         | Moreover, if you have difficulties in following complicated
         | expressions, you can always break them in smaller
         | subexpressions.
         | 
         | When someone presents an "incomprehensible" APL program, they
         | show a huge expresion without comments.
         | 
         | A decent APL program, like in any other programming language,
         | would need good comments, but here comments are frequently
         | desirable at the level of subexpressions.
        
           | misja111 wrote:
           | > A decent APL program, like in any other programming
           | language, would need good comments, but here comments are
           | frequently desirable at the level of subexpressions.
           | 
           | I guess that might be true for APL, for other programming
           | languages that's not true at all. The ideal program is clear
           | enough to be self explanatory. Of course there might be some
           | implementation choices that need a comment. Or in some cases
           | the problem is so difficult that this is not possible.
           | 
           | But readability should be the goal and most of the time this
           | is feasible without comments. E.g. by using descriptive
           | variable and function names. And by breaking up your program
           | into logical and cohesive parts, using functions, objects,
           | modules or whatever construct your language is offering.
        
             | creata wrote:
             | > The ideal program is clear enough to be self explanatory.
             | 
             | That depends on what you're doing and who you expect to be
             | reading your code, doesn't it? Sometimes what the human
             | needs and what the computer/runtime needs are too far
             | apart.
        
             | misja111 wrote:
             | @creata:
             | 
             | yes I agree. In case of APL, if your readers are
             | mathematicians, I guess it could well be the language of
             | choice.
             | 
             | And yes like I already said, self explanatory code is not
             | always possible but more often than not it is. It just
             | takes a little extra care and thought.
        
             | adrian_b wrote:
             | What you say about readability is right, but it is
             | something completely orthogonal to the syntax of APL
             | expressions. All those things can be done in any language
             | that uses the APL expression syntax.
             | 
             | For someone who knows the APL symbols, _what_ an APL
             | expression does is self-explanatory. Someone who does not
             | like symbols can replace them with keywords, that does not
             | change the APL syntax.
             | 
             | The only problem is that you can write a very complex APL
             | expression, which may be equivalent with a page of text in
             | other programming languages. In such cases it is still easy
             | to see _what_ the expression does, but its purpose may be
             | completely obscure, e.g. because you are unfamiliar with
             | the algorithm implemented there, so you need comments
             | explaining _why_ those operations are done.
             | 
             | In many cases you can do like you suggest, you can split a
             | very big expression in many subexpressions and store
             | intermediate results in temporary variables to which you
             | give names that are suggestive for their purpose, instead
             | of adding comments.
             | 
             | However, I see this solution as inferior to just providing
             | short comments for the subexpressions, which give you the
             | same information as the intermediate variable names, but
             | without forcing the compiler to choose an expression
             | evaluation strategy that may be suboptimal.
             | 
             | I completely agree that "The ideal program is clear enough
             | to be self explanatory".
             | 
             | However, regardless of the programming language, it is very
             | frequent to see programs where it is clear what is done,
             | but you cannot understand why that is done. In most cases
             | you already have precise expectations about what the
             | program should do, but you see that it does something else,
             | without any apparent reason. In many cases, the program
             | does certain things because there are certain corner cases
             | that are not at all obvious from the existing system
             | documentation, or worse they are not documented at all
             | anywhere, except for the presence of a mysterious program
             | section that handles them. Even worse is when such
             | mysterious program sections are present only because of
             | some historical reasons, which are no longer true, and now
             | the code is superfluous or even harmful.
             | 
             | These frequently encountered situations can be prevented
             | only by adequate comments about the purpose of the code,
             | regardless how self-explanatory is what it does.
        
             | gitonthescene wrote:
             | Serious question: Why is readability so important? For me
             | consistency is far more important than anything as
             | subjective as readability. I'd rather be able to reason
             | about a code in its own logic than feel comfortable
             | browsing code without much consistency. In the end all code
             | needs to be understood for its internal logic and notation
             | is secondary.
        
               | misja111 wrote:
               | 2 reasons:
               | 
               | - in a corporate environment, your code is going to be
               | read by many other people than just you. Your team mates,
               | the guy after you left etc.
               | 
               | - also, by making your code more readable, you're making
               | your own life easier as well. You might have thought at
               | first that your code was fine, but by structuring it
               | properly and possibly removing some redundancy, you might
               | find that you were overlooking some things.
        
               | gitonthescene wrote:
               | In my experience code reviews are generally cursory and
               | the emphasis on "readability" is more about a culture
               | that seeks to treat programmers as fungible. Also
               | complaints about APL's lack of readability are never
               | about its lack of structure. So I took "readability" to
               | mean something else as should be clear from my previous
               | comment. Is your complaint about its lack of structure?
               | If so would you mind elaborating?
        
               | gbacon wrote:
               | Jokesters quip "If a program was hard to write, it should
               | be hard to read."
        
             | Avshalom wrote:
             | >>The ideal program is clear enough to be self explanatory.
             | 
             | No one has ever written an "ideal program".
        
       | runeks wrote:
       | I find APL very difficult to read. Incidentally, I am told (by
       | stack overflow) that the APL expression "A B C" can have at least
       | four different meanings depending on context[1]. I suspect
       | there's a connection here.
       | 
       | [1] https://stackoverflow.com/a/75694187
        
         | skruger wrote:
         | Yes, it's either an array (if A, B and C are arrays), a
         | function derived via the dyadic operator B, with operands A and
         | C being either arrays or functions, a dyadic function call of
         | the dyadic function B (A and C are arrays), or the sequential
         | monadic application of functions A and B to array C, or a
         | derived function as the tacit fork (A, B and C are functions).
         | Did I miss anything?
        
           | abrudz wrote:
           | Yes, it can also a fork where A is an array while B and C are
           | function and a tacit atop where either B is a monadic
           | operator and A its array or function operand or A is a
           | function and C is a monadic operator with B being its array
           | or function operand. Finally, it can be a single derived
           | function where B and C are monadic operators while A is B's
           | array or function operand.
        
             | boxed wrote:
             | Do APL programmers think this is a good thing? It sounds a
             | lot like how I feel about currying in language that have it
             | (meaning it's terrible because code can't be reasoned about
             | locally, only with a ton of surrounding context, the entire
             | program in the worst case)
        
               | creata wrote:
               | Huh? Currying doesn't require any nonlocal reasoning.
               | It's just the convention of preferring functions of type
               | a -> (b -> c) to functions of type (a, b) -> c. (Most
               | programming languages use the latter.)
        
               | boxed wrote:
               | Of course it requires non-local reasoning. You either get
               | a function back or a value back depending on if you've
               | passed all the arguments. With normal function calling in
               | C-family languages you know that a function body is
               | called when you do `foo(1, 2, 3)` or you get a
               | compilation error or something. In a currying language
               | you just get a new function back.
        
               | creata wrote:
               | Functions are just a different kind of value. Needing to
               | know the type of the values you're using when you use
               | them isn't "nonlocal reasoning".
               | 
               | And it's not like curried function application involves
               | type-driven parsing or anything. (f x y) is just parsed
               | and compiled as two function calls ((f x) y), regardless
               | of the type of anything involved, just as (x * y * z) is
               | parsed as ((x * y) * z) in mainstream languages. (Except
               | for C, because C _actually does_ have type-driven parsing
               | for the asterisk.)
               | 
               | Another way to look at it: languages like Haskell _only_
               | have functions with one argument, and function
               | application is just written  "f x" instead of "f(x)".
               | Everything follows from there. Not a huge difference.
        
               | bunderbunder wrote:
               | It arguably depends on the syntax.
               | 
               | In an ML-like syntax where there aren't any delimiters to
               | surround function arguments, I agree it can get a little
               | ambiguous because you need to know the full function
               | signature to tell whether an application is partial.
               | 
               | But there are also languages like F# that tame this a bit
               | with things like the forward application operator |>
               | that, in my opinion, largely solve the readability
               | problem.
               | 
               | And there are languages like Clojure that don't curry
               | functions by default and instead provide a partial
               | application syntax that makes what's happening a bit more
               | obvious.
        
               | ofalkaed wrote:
               | I am not good enough with APL to be certain but I think
               | you can generally avoid most of these sorts of
               | ambiguities and the terseness of APL helps a great deal
               | because the required context is never far away, generally
               | don't even have to scroll. I have been following this
               | thread to see what the more experienced have to say,
               | decided to force the issue.
        
               | skruger wrote:
               | It makes parsing tricky. But for the programmer it's
               | rarely an issue, as typically definitions are physically
               | close. Some variants like BQN avoids this ambiguity by
               | imposing a naming scheme (function names upper case,
               | array names lower case or similar).
        
               | bunderbunder wrote:
               | It gets me thinking about the "high context / low
               | context" distinction in natural languages. High context
               | languages are one where the meaning of a symbol depends
               | on the context in which it's embedded.
               | 
               | It's a continuum, so English is typically considered low
               | context but it does have some examples. "Free as in
               | freedom versus free as in beer," is one that immediately
               | comes to mind.
               | 
               | A high context language would be one like Chinese where,
               | for example, the character Guo  can be a grammatical
               | marker for experiential aspect, a preposition equivalent
               | to "over" "across" or "through" depending on context, a
               | verb with more English equivalents than I care to try and
               | enumerate, an affix similar to "super-", etc.
               | 
               | When I was first starting to learn Chinese it seemed like
               | this would be hopelessly confusing. But it turns out that
               | human brains are incredibly well adapted to this sort of
               | disambiguation task. So now that I've got some time using
               | the language behind me it's so automatic that I'm not
               | really even aware of it anymore, except to sit here
               | racking my brain for examples like this for the purpose
               | of relating an anecdote.
               | 
               | I would bet that it's a similar story for APL: initially
               | seems weird if you aren't used to it, but not actually a
               | problem in practice.
        
           | yvdriess wrote:
           | And they could be 0- or 1- indexed? :P
        
           | UncleEntity wrote:
           | >> Did I miss anything?
           | 
           | Derived operators?
           | 
           | And, 'A B C' as an array isn't valid (ISO) APL but an
           | extension, the 'array syntax' only covers numbers and the
           | parser is supposed to treat is as a single token.
           | 
           | Your useless information of the day...
        
       | JaumeGreen wrote:
       | One of my list of dream projects that I might never have time to
       | do, and so feel free to "steal" the idea, would be a eink notepad
       | in where you could code in APL or similar.
       | 
       | APL was born as a mathematical notation, pertaining to the
       | blackboard, so it makes sense to write it using a writing
       | implement. Its terseness would make it ideal for the handwriting
       | world, it's REPL implementation would give quick feedback loops,
       | you could move around input and output streams.
       | 
       | You could be in a sofa, writing the solution, expending most of
       | your energy thinking, not writing, once you got used to the new
       | way of thinking and the vocabulary.
       | 
       | If you haven't tested any array language I would recommend you
       | try to solve things using one, and check existing solutions so
       | you can see how to think differently. Some problems are naturally
       | easier with this approach, some are harder.
        
         | icen wrote:
         | You might be interested in this then:
         | https://mlajtos.mu/posts/new-kind-of-paper
         | 
         | I've not used it myself, but it appears to be the thing you're
         | wanting?
        
           | kkylin wrote:
           | I've had the same dream! thanks for the pointer.
        
         | bunderbunder wrote:
         | I would probably just go for an Android eink tablet like the
         | ones made by Bigme and Onyx Boox.
         | 
         | It looks like there are a few APL implementations for Android
         | out there, or you could use a remote editor or terminal app to
         | access an APL implementation running elsewhere.
        
       | baruchel wrote:
       | I've practiced array languages extensively myself, including for
       | code golfing, and I fully understand the intellectual joy they
       | can provide. But as I've gotten older, I've come to see a deep
       | mismatch between what these languages present as "elegant" and
       | what I find truly elegant from a computer science perspective.
       | 
       | Sure, realizing that the foobar of x is nothing more than the
       | transpose of the 15th foo of x, combined via an inner product
       | with the 7th bar of x raised to the power of baz, can be an
       | ineffable intellectual delight. But actually computing that,
       | rather than writing a "boring" loop, feels horrible to me. To my
       | eyes, a "boring" piece of code written by Dijkstra in some Algol-
       | like language contains more beauty than all these dazzling
       | sleights of hand that hide zillions of loops under the rug while
       | pretending that the actual computation doesn't matter.
        
         | bunderbunder wrote:
         | On the other hand, whenever I see Python code that does
         | calculations over arrays of data with nested loops instead of
         | using numpy, it always takes me a distressing amount of time to
         | see what the code is actually doing and that the bug is because
         | of a typo buried deep in that 100 lines of code that caused one
         | of the inner products to be incorrect.
        
         | veqq wrote:
         | Array languages are more conceptually simple. What do you
         | concretely mean to mock with:
         | 
         | > realizing that the foobar of x is nothing more than the
         | transpose of the 15th foo of x, combined via an inner product
         | with the 7th bar of x raised to the power of baz
        
         | t-3 wrote:
         | It's not like array languages don't do any optimizations...
         | Denying the programmer the ability to be clever by manually
         | writing loops makes some things easier and simpler for the
         | compiler as well.
        
       | meken wrote:
       | I enjoyed the FBAPP acroymn. There should be a modern day
       | equivalent.
        
       | kstrauser wrote:
       | I'd like to play with an array language because I've never used
       | one. I don't want to pay for it; this is just for fun and as an
       | experiment. I also want to run it locally in a shell, writing it
       | in a local editor, not working in a web UI. And while popularity
       | isn't everything, and none of these are exactly Python levels of
       | widespread, I also don't want to find myself learning a cool one
       | along with 3 other people in the world and then find out all
       | other array language programmers do things completely
       | differently. (Analogy: I don't want the equivalent experience of
       | picking Haskell as my first ever PL.)
       | 
       | This topic tends to bring up a few, like APL itself, J, K, and
       | BQN. Given those (soft!) constraints, what's the one I want to
       | start hacking around with?
        
         | vegabook wrote:
         | there's also a Forth-meets-APL project called uiua
         | [https://www.uiua.org/]
        
           | kstrauser wrote:
           | That may require a little more mental bandwidth than I can
           | summon right now. It looks incredibly cool, though.
        
         | invalidOrTaken wrote:
         | I haven't tried the others, but J meets all those requirements.
        
           | RodgerTheGreat wrote:
           | Yep. J has a small userbase, but it isn't fragmented into
           | dialects like K or even APL, J uses ASCII characters instead
           | of requiring a custom font/keyboard layout, J is FOSS, J has
           | extensive learning materials, and J is reasonably batteries-
           | included and suitable for making practical nontrivial
           | programs.
           | 
           | I like K better than J aesthetically, but it's harder to
           | recommend to beginners due to the fragmentation of the
           | ecosystem.
        
           | kstrauser wrote:
           | I keep getting nudged in that direction. I'll check it out,
           | thanks!
        
         | skruger wrote:
         | I faced exactly this situation a few years ago - I went with
         | APL as the "OG", but it probably doesn't matter that much.
         | Learning k or j once you know APL is much easier. I wrote a bit
         | about this (apl and k)
         | 
         | https://xpqz.github.io/learnapl
         | 
         | https://xpqz.github.io/kbook
        
           | kstrauser wrote:
           | Oh, perfect. Thanks for the links!
        
       | i-blis wrote:
       | J is, within the APL family of languages, the one I have always
       | found the most useful. I reach for it as I used to reach for my
       | HP calculator in the past, to quickly compute or numerically
       | model things. I always have it running in a terminal window.
       | 
       | Contrary to popular belief, its learning curve isn't steep. I
       | once introduced it to high school freshmen who had no real
       | experience with programming. I recommend the series of booklets
       | by Kenneth Iverson himself: Arithmetic, Algebra, Calculus --
       | there is even a Concrete Mathematics companion to accompany the
       | book of the same name by Graham, Knuth et alii. They're all
       | available for download on the site.
        
       ___________________________________________________________________
       (page generated 2026-01-22 23:01 UTC)