6 ms·
Here's what I don't get about APL. Why is it so important that everything be a single symbol? Why not give the symbols more descriptive names and let people use
by civilized 5y ago
Here's what I don't get about APL. Why is it so important that everything be a single symbol? Why not give the symbols more descriptive names and let people use those names, instead of being forced to work with only the symbols? Heck, it wouldn't be much work to make a text editor that lets you switch back and forth.
APL seems to be designed for people who place an extremely, extremely high weight on code golf-level terseness. IMHO, terseness isn't the be-all, end-all of comprehensibility. I'd rather just use the words "max" and "min" than learn redundant special symbols for the same that save me a couple characters.
- mlochbaum 5y agoIf you're used to it, I'd guess you can read [EDIT: was five; thought more] two to four symbols in the time you can read a short name. And you can use the higher-level pattern-recognition skills that would otherwise be applied to reading names to understand combinations of symbols. At least for me it's much easier to visually manipulate symbols in my head. You've written as though using symbols instead of names comes at an extraordinary cost. Having used both I don't think this is the case (and it's the conventional languages that force you to use words; you're free to define reverse ← ⌽ in APL but usually not the other way around). If you want to read more about this perspective, you could check out my page "What is a primitive?" discussed on HN yesterday: https://news.ycombinator.com/item?id=28060423 https://news.ycombinator.com/item?id=28060423
- valenterry 5y agoI doubt that it can be read much faster. Think about newspaper: you don't read the symbols that make up words - you literally read the words themselves. Taht's why it is pettry esay to fllw txet wtih miexd up caharcetrs. As long as first and last latter stay the same. One advantage is that long expressions might fit in one line, but that's about it. I mainly use Scala, which allows to use symbols like ← ⌽ as well and quite a few libraries do that - but I found unless it's a very commonly used symbol, it's not helpful for productivity.
- mlochbaum 5y agoThese are the "higher-level pattern-recognition skills" that I was talking about. You use them to read words; I can also use them for something like (in BQN) -⟜» (subtract previous from current) or +`⊸⊔ (split using start markers). There's an opportunity cost. To be clear, you do think there's an advantage to using symbols for very common operations? APL doesn't have all that many primitives (~60 symbols), and most would fit this requirement. Here's Alan Perlis[0]: "The large number of primitive functions, at first mind-numbing in their capabilities, quickly turn out to be easily mastered, soon almost all are used naturally in every program — the primitive functions form a harmonious and useful set." [0] https://www.jsoftware.com/papers/perlis77.htm https://www.jsoftware.com/papers/perlis77.htm
- civilized 5y agoIf APL is so ideally productive and the barriers to its adoption so substantially slight, why has it not won? The programming community has been extremely open-minded to revolutionary new approaches. So very many have gained at least a foothold and a small group of devotees, from LISP to Haskell to Forth to APL. But none of these languages have built communities of a size and productivity to match Python or C or the many other highly successful Algol-family languages. This despite the fact that some of these off-the-beaten-path languages, especially LISP, have a long history of being used as teaching languages. So why hasn't APL taken off already? Surely there must be a more thoughtful answer than "people are Philistines". Perhaps both APLers and LISPers greatly underestimate the challenges of adopting new symbolic notations that are very different from what they're used to in written language and mathematics. Maybe for the average technical person, the cognitive costs are much greater and the benefits much less than they seem to the average APL or LISP fan.
- foxfluff 5y agoI think it's naive to assume a language would "win" on its own merit. Most of our software today is what it is due to path dependence. Was JavaScript a terrific language? No, it was a little doodle for bringing a little interactivity to websites, which were simple at the time. The web took off; thus JavaScript took off. If the web had never taken off, JS wouldn't be a thing. Same for C. What was so great about C, or its predecessor B? Nothing really. B was a minimal language designed to fit the constraints of a minicomputer. Unix happened, C was a natural evolution of B, Unix took off as a simple & cheap (even free) operating system for cheap computers. C got popular with Unix, and not due to anything revolutionary in its design. C++ rode the OOP hype wave and C's popularity. C#'s popularity is due to Microsoft's massive influence. Java similarly rode the OOP hype train and I guess Sun's marketing towards their many Enterprise customers (who also bought the "write once run anywhere" lie). Remember when PHP was popular? Was that because it was such an awesome language, or was it because it seemed easy and integrated well with this other popular thing that took off (the web)? (On a similar note, it's not clear at all that Linux would have become as popular as it is today if it weren't for the lawsuits looming over the BSDs in the 90s) Of course I'm oversimplifying and glossing over a lot of history but in the decades between Unix and C#, there have been countless programming languages that could have easily challenged each language that I named on their own merit. But that merit does not matter, because that's not what makes a language take off. If anything, the programming community seems rather reluctant to consider different approaches, and when they do it, they would rather do it in the comfort of their existing languages and ecosystem of tools & libraries rather than jump to something new entirely. Lisp and Haskell never got mainstream despite their use in teaching, but I think most of the programming community today sees the value in functional thinking and immutability; thus various constructs that have been historically exclusive to functional programming languages have made it into mainstream languages. You couldn't take lambdas and map & reduce for granted in 2000 and the FP aficionados had a fight ahead of them to convince the mainstream that they aren't just trying to be clever and look smart. And on the topic of teaching, I'll have to point out that LISP has absolutely not been a teaching language across universities around the globe. MIT is not a representative example. Most unis and colleges just stick to what seems to be mainstream (20 years ago: C, C++, Java, ...; today C#, Java, JS..) or just easy to start with (Python) and languages like C and Haskell are now reserved for one-off/in-depth courses about specific topics. If anything, I find it surprising that LISP has as big of a following as it does today, but I guess its (limited) use in teaching plus writings from certain influential people (including the author of this very site) have had their effect. APL by contrast has faced challenges; it was considered too easy to be a teaching language. Other challenges include the symbols, but not because they look scary and alien! We might take the ability to type fancy glyphs for granted today but go back a few decades when computers were using 8-bit character sets, often wired to glass terminals or printers or framebuffers with a hardcoded character set.. you'll start to see the problem. You literally could not enter or view the APL symbols on a lot of computers available at the time. Interoperability with other character sets absolutely was a real challenge and probably alone sufficient to push APL mostly into obscurity for a long time. And indeed this issue was important enough that Iverson moved on from APL to create J. Even this site shows how reluctant people are to accept anything new and alien looking. Almost all postings about APL feature the usual knee jerk reactions to the weird looking syntax, tersity, and symbols. APL and its kin go directly against what's been preached as best practices in programming for so long now that it's not surprising that people are uncomfortable with it. Doubters are not going to judge APL on its merit, because they won't learn it. I think there's a lot to criticize about APL and its ecosystem (let's be clear that due to its relative obscurity, it has missed a lot of the potential evolution and progress that a vibrant community would bring with it), but I think few here are willing to look beneath the surface. Indeed most developers just need a language with mature tooling and libraries and big community, everything else is secondary.
- rak1507 5y agohttps://code.kx.com/q/ https://code.kx.com/q/ uses words for a lot of things. Instead of the APL ⌈/ you write 'max'. Instead of the APL ⌈\ you write 'maxs'. And so on. Personally, I much prefer the APL for a few reasons. If I tell you that +/ is sum, you can reasonably guess what product is. (×/). However, in q, if I tell you 'sum' is sum, can you guess what product is? Well, maybe. But it's prd. Would you have guessed that first try? This seems like it might not be that important, and obviously to the q developers it isn't. But it is a consideration that logically leads to terse symbols. If you had to write reduce(plus, arr) every time of course you'd rather have a word for 'sum', it's only because of the symbols that let you decompose larger problems into the smaller primitives without ending up with more verbose code than other languages.
- throwaway675309 5y agoWith modern day IDEs, auto suggestions would likely lead most developers to easily discovering the exact syntax for "product". Additionally, words that describe the inherent function makes reading the source A THOUSAND TIMES easier. If A new developer sees the word max/min/sum, they can almost assuredly guess the meaning versus a random pictograph. And even after learning that ‰ means reduce (for example), it's just one more thing that I have to remember.
- dzaima 5y agoin APL you have ~80 of such "pictographs" (and many you'd already know from regular maths). Sure, it's something you have to remember, but not much, really. Words can definitely help new english-speaking devs understand code, but, after getting used to the symbols, they just provide so much flexibility.
- nuclearnice1 5y agoIn practice, how do you type the pictographs when coding?
- razetime 5y ago
- Jtsummers 5y agoThe history of APL is helpful to consider. It, initially, was a notation for describing computer systems and programs, and its use as a programming language came later (though not greatly later). If you want something APL-like but without the symbol heavy nature, the nearest is going to be languages like Haskell that similarly promote tacit programming but without quite as heavy a reliance on symbolic notations, or descendent languages of APL like q.
- jodrellblank 5y agoIt wouldn't take much work to make a text editor that lets you switch this: if (username == "alice") { results[5] = true; } into this: if username valueequals STRINGaliceSTRING begin let results index 5 be true stop endif because symbols are incomprehensible, words are much clearer, and you don't care about saving "a couple of characters" and you don't like codegolf. Would you use it? If not, why not? How do you know the amount of symbols you use is the perfect amount and not merely the amount you are habituated to? > "Why not give the symbols more descriptive names and let people use those names For the same reason almost nobody wants {} to be BEGIN/END; the symbols are so ingrained, so well understood, so automatic and habitual that there's no benefit to trying to turn them back into words. Why not move towards doing the same for other common operations? Once you've used ⌊ as floor and ⌈ as ceiling, Math.Floor() feels like a drag. Once you're familiar with 4↑list to get the first 4 items, list[0..4] is a drag and it has more symbols! list.take(4) has more symbols and is no clearer. How do you stop a forever-expanding proliferation of symbols? I don't know, but APL seems to have done a surprisingly good job of general purpose computing in under ~80 symbols which has hardly grown in 70 years. > "APL seems to be designed for people who place an extremely, extremely high weight on code golf-level terseness." Would you be surprised that this is valid Dyalog APL for a function to find the highest value in an array of positive integers? result←findMax data max←0 :For i :In data :If i>max max←i :EndIf :EndFor result←max then findMax 5 1 2 3 5 6 3 1 6 Dyalog has keywords, classes, namespaces, methods, libraries, and they get laughed at because who wants :EndFor . It's a bit of a PR issue - if you head to APL it's largely because you like golf, because if that's not what you want you may as well use Python/etc. But once you get there even if APL remains too opaque to use for everything it becomes annoying to know a short way to express what you want that you are comfortable with and have to laboriously boilerplate it out in another language with many lines, and have those lines contain more symbols into the bargain. And we say that one of the hard problems is "naming things", symbols and tacit programming can help avoid putting a name to variables that only hold some intermediate state you don't actually care about but need for the next couple of lines.
- rajandatta 5y agoThe best way to think about this is that all of these variants exist: APL uses custom glyphs J uses symbols from an ASCII keyboard - its a big set of primitives Q from Kx systems uses words. The conceptual basis for the languages is very simple. As others have said - your experiences will guide where you feel most comfortable.
- rajandatta 5y agoCommenter here ... meant to say 'The conceptual basis for languages is very similar'.
- ronbrz 5y agoHaving been interested in APL, but never taking the plunge and learning it, I've seen this article "Notation as a tool of thought" (this is linked in the submitted article as well) thrown around: https://www.jsoftware.com/papers/tot.htm https://www.jsoftware.com/papers/tot.htm The paper kicks off with a quote by George Boole: "That language is an instrument of human reason, and not merely a medium for the expression of thought, is a truth generally admitted." Having a terse language in itself can lend itself to thinking about problems and playing around with them in your head more effectively. I know when I'm thinking about an algorithm to be implemented in something like java there isn't room for all the boilerplate in my head. Stuff like "public static void main..." gets fuzzed out when thinking about a solution, to be replaced the idea of "place where main method is". I like the idea of boiling down useful abstractions to the most simple symbols we can manipulate mentally, to be able to fit the most possible high level abstractions in our mind at the same time. This should make it possible to be able to play more with constructing solutions. Never feeling particularly locked down because you have to manipulate a lot of syntax and curly braces to implement or think about an idea. That you only have to switch around a few symbols for a change in semantic meaning. Having never learned something like APL myself, I can't speak personally about the effectiveness of this idea.
- jodrellblank 5y agoSomething I didn't think of earlier is function trains, which annoyingly won't make much sense without knowing some APL - they're a pattern which takes more effort to explain than they take to start using. But still, simple APL expressions run right to left so the example below pushes 3 into ⊢ which echoes it unchanged, that goes into + which is a no-op here on a positive integer, and then the 3 goes into ⍳ which makes the first 3 numbers: ⍳+⊢ 3 ⍝ the first 3 numbers 1 2 3 it behaves differently from the same thing in parens shown below, which triggers a function train pattern and slightly breaks the right-to-left execution by making the data able to feed into two functions, not just one. In the below code the 3 is pushed into ⊢ on the right which echoes it unchanged but it also jumps over and is pushed into ⍳ on the left to make the first three numbers 1 2 3, and these two results become (1 2 3 + 3) and the whole thing makes 4 5 6: (⍳+⊢) 3 ⍝ 3 plus the first 3 numbers 4 5 6 It's not the parens which make the difference, assigning it to a variable to make a named function also does it: f ← ⍳+⊢ f 3 4 5 6 Point being, there's something semantically meaningful happening but it has no symbol to turn into words. It's not the proximity of the functions being bunched together even, it's roughly an odd number of functions separated from their argument(s) but with some edge cases. The text editor would have to be parsing APL to detect it, and I don't know how it would describe what's happening in useful words. "iota plus self_right" might still let you recognise three things together, but does "enclose bind grade_up index self_right" look like a function train? Does "It's easier to spot the pattern with symbols, it's easier to have the pattern exist at all in a symbols based language. When the Dyalog IDE can show you: +,-,×,÷ ┌─┼───┐ + , ┌─┼───┐ - , ┌─┼─┐ × , ÷ to explain how the train is being interpreted, what does the text version of that say?
- max_ 5y agoYou might not believe this. But reading the symbols (if u know what they mean) is actually easier that reading words. For instance, | 3 2 1 0 is read as "reverse" the array "3 2 1 0". So | 3 2 1 0 gives you 0 1 2 3. It certainly seems easier to read than "reverse 3 2 1 0". – which assumes your a fluent english speaker.
- Zababa 5y agoThis link explains it well I think http://nsl.com/papers/denial.html http://nsl.com/papers/denial.html
- civilized 5y agoIn a lot of these APL discussions I see an obsession with terse implementations of simple standard library-type functionality. Who on Earth has to literally write a loop in the middle of their source code to find the max of a bunch of numbers? I would just call the appropriate standard library function, especially in languages like Python that have excellent general-purpose data structures and standard libraries for them.
- Zababa 5y agoI think you should reread the article. One of the point of the APL community is that terseness itself is a goal. > Who on Earth has to literally write a loop in the middle of their source code to find the max of a bunch of numbers? People that uses JavaScript or other language which have a really small standard library.
- civilized 5y agoNah, they could easily write a function for max if they really wanted or needed it. Maybe terseness just isn't that tremendously valuable to a lot of coders.
- Zababa 5y agoBut that function is precisely what they're writing? Add a "return max;" at the end and you have you function. It will still be longer than |/. > Maybe terseness just isn't that tremendously valuable to a lot of coders. That's the thing. The big difference between the APL community and the rest is the value they accord to terness. I'm not saying they are right or wrong, I'm saying that it is what defines them. Another point that goes with the symbols is that the symbols may not have the baggage that words have. Words can mean a lot of different things.
- yiyus 5y agoIt's not about terseness, it's about making easy to see patterns and what is going on. You probably learnt the distributive property in school: a*(b+c) = a*b + a*c Let's make that "more readable": equals(multiply(a, sum(b, c)), sum(multiply(a, b), multiply(a, c))) It's not about the terseness, I just don't see a clear pattern using the "readable" notation. But it is obvious when using symbols. You can find another interesting example at: https://wjmn.github.io/posts/j-can-look-like-apl/ https://wjmn.github.io/posts/j-can-look-like-apl/
- seppel 5y agoBut it is the switching from infix operators to prefix operator that is making the second example less readable (and the implicit precedence of the operators). Writing it as (a times (b plus c)) equals ((a times b) plus (a times c)) would be a fair comparison, which is much more readble than =(*(a, +(b, c)), +(*(a, b), *(a, c)))
- yiyus 5y agoFair enough, the change from infix to prefix was misleading. But do you (or anyone) find (a times (b plus c)) equals ((a times b) plus (a times c)) easier to read than a*(b+c) = a*b + a*c ?
- civilized 5y agoI like the idea that APL could provide this advantage but I just haven't seen any compelling examples. And that's my experience with a lot of APL stuff - beautiful theory that just doesn't quite seem to deliver on the promises. It feels like the Zen of APL is "symbols are a freaking great idea, let's do more of those!" when intellectual communities that are heavy on symbolic manipulation are generally quite conservative in the introduction of new symbols... let alone the dozens that APL introduces. To each his own and all, but APL might have to content itself with a small group of devoted fans.
- yiyus 5y agoI absolutely agree with you about the introduction of new symbols. Most glyphs have been there for decades now, and there is a high barrier to introduce new ones. There are Dyalog developers who experiment with new primitives that use new glyphs, and it takes years until they are actually introduced into the language, if ever. Very clever people have been working in array languages for more than 60 years, and there is a set of around 20-30 primitives that all of them agree are worth to have. Depending on the array language of choice, there are another 10-40 primitives more. Symbols have double use (monadic and dyadic), so that makes a total of 20-40 symbols to learn, and you already know many of those (+-×÷=<>, and probably a few more). To each his own indeed. But if you haven't, I would suggest you to give it a try. It makes much more sense once you start writing code.
- 082349872349872 5y agoTry using a mid-1960's i/o device: a cardpunch, a tape punch, a mechanical tty at what, 110 baud? (or less)