The opening paragraphs about how people enamoured by a shiny gadget will overlook a terrible interface brings immediately to my mind the modern day LLMs.
One can appreaciate striving for simplicity (a programming language that can be taught and explained with pen and paper), but one must also consider that computers are meta-devices.
Before computers, we could write things only on paper, either with our hands or a typewriter. So, naturally, when computers came about, the way of thinking about programming was very text-driven, with an emphasis on what a typewriter could represent.
But then, code could be written directly with computers, opening up more typesetting possibilities thanks to keyboards not being bound anymore by the mechanical limitations of typewriters. You could add keys and combinations to your heart's desire, and they would be natively digital and unlimited.
Now, with graphics, both 2D and 3D, and a myriad or other HIDs, shouldn't we try to make another cognitive jump?
We've had paper and pencil permitting unfettered symbolic representations for centuries. The reason we settled on text is not some accidental bottleneck caused by typewriters.
We settled on dense and terse modes of symbolic reasoning and typewriters and computers just reflect that.
The dream of unleashing cognition by breaking free of these constraints is backwards. The friction and the constraints are why and how we can do things, not what impedes us doing things. If we were all floating on high dimensional frictionless spaces we would be able to represent anything and do nothing.
I wonder if EWD would have had the same opinion if he were alive today, with every Unicode font having the APL characters immediately available on the screen.
Did he feel the language design was bad, or would having TTF fonts being able to show "rho", "iota", "grade up" have removed one or more of his objections?
APL is the only language I've ever dreamt about writing (as in: I could see the characters); I'd dreamt about programming in the past, but those dreams were usually what I would categorized as a nightmare—desperately trying to fix a bug that I couldn't figure out.
Due to my affinity for the language, and my wish to have worked in its heyday (would love to have an APL gig someday), I have been exposed to various writings and recordings of Ken Iverson. I've also been exposed to a few of Dijkstra's thoughts on APL.
I have to say that Iverson generally comes across as a very generous and curious individual while Dijkstra seems to have been a miserable ass. Maybe, given the lens, I've not given Dijkstra a proper chance to demonstrate a more positive attitude, so I'm open to any suggestions of writings where he doesn't seem like such a grump.
I often see a lot of folks here on HN who are too eager to pass judgement on Dijkstra without having read and understood his writings nor giving much thought to the context and times which shaped his thinking. All of his opinions should be thought over and appropriately adapted for use in our context. He was a wide-ranging polymath philosopher (technical and non-technical) with a laser-like focus on exactitude using Mathematics. Radical approaches must be pushed, particularly when they are hard/difficult to learn and understand. If his language was biting, then it was so much the better for promulgating his cause viz. "correctness over easy", "mathematical reasoning underpinning everything", "structure in aid of the previous", "proper language syntax/design in aid of the previous" etc.
As an example; read EWD 1036: On the cruelty of really teaching computing science (https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD103...) in entirety and carefully. The thesis is that computing is "radically novel" from other forms of human endeavour and hence it cannot be taught by simplifying to known analogues and adhoc procedural operations. You need the rigor and exactitude of Mathematical Logic to build a "Scientific" basis.
Excerpts:
... What is a program? ... I prefer to describe it the other way round: the program is an abstract symbol manipulator, which can be turned into a concrete one by supplying a computer to it. After all, it is no longer the purpose of programs to instruct our machines; these days, it is the purpose of machines to execute our programs.
So, we have to design abstract symbol manipulators. We all know what they look like: they look like programs or —to use somewhat more general terminology— usually rather elaborate formulae from some formal system. It really helps to view a program as a formula. Firstly, it puts the programmer's task in the proper perspective: he has to derive that formula. Secondly, it explains why the world of mathematics all but ignored the programming challenge: programs were so much longer formulae than it was used to that it did not even recognize them as such. Now back to the programmer's job: he has to derive that formula, he has to derive that program. We know of only one reliable way of doing that, viz. by means of symbol manipulation. And now the circle is closed: we construct our mechanical symbol manipulators by means of human symbol manipulation.
...The point to get across is that if we have to demonstrate something about all the elements of a large set, it is hopelessly inefficient to deal with all the elements of the set individually: the efficient argument does not refer to individual elements at all and is carried out in terms of the set's definition.
...
Back to programming. The statement that a given program meets a certain specification amounts to a statement about all computations that could take place under control of that given program. And since this set of computations is defined by the given program, our recent moral says: deal with all computations possible under control of a given program by ignoring them and working with the program. We must learn to work with program texts while (temporarily) ignoring that they admit the interpretation of executable code.
Another way of saying the same thing is the following one. A programming language, with its formal syntax and with the proof rules that define its semantics, is a formal system for which program execution provides only a model. It is well-known that formal systems should be dealt with in their own right, and not in terms of a specific model. And, again, the corollary is that we should reason about programs without even mentioning their possible "behaviours".
He liked to make fun of emerging CS, it was his thing, and he did it pretty well. He wasn't "miserable ass", he was a man of different culture. "Positive attitude" as you used it is a late americanism FWIW. In many parts of the world we often bring our criticisms in similar caustic manner, and we enjoy it while being resilient and optimistic.
It doesn't mean that he was always right, of course.
Dijkstra's go-to language (pun intended) was Algol 60 (& Pascal) – everything else was shit in his view. Some of his comments:
FORTRAN — "an infantile disorder"
COBOL — "the use of COBOL cripples the mind"
BASIC — students exposed to it are "mentally mutilated beyond hope of regeneration"
PL/I — "the fatal disease"
APL — "a mistake, carried through to perfection"
He liked his languages and programs to be easily traceable with pen & paper. He always wrote programs on the paper (and proved correctness) and only then into computer. REPL-driven development (what APL pioneered) was a foreign concept to him. He would be so appalled by LLM code generation.
I wrote a lot of APL for my undergraduate Senior Project in 1978/1979.
I really enjoyed it because it was fun. You could do an incredible amount of work in a single line of code.
The only problem was, that line would then be almost impossible to read and understand! It could easily be used as a "write-only" language even without a separate obfuscation step.
When I become a professional programmer right after college, I never used it again, and learned to write code that was readable above all else.
APL suffers from the same apparent problems as Perl: They have friction coming from an unconventional syntax that's hard to understand without knowing the language beforehand, and when faced with competition, people went with the path of least resistance.
* Out of all people, and especially in the newer generations, it is increasingly uncommon to find someone with a desktop or even a laptop.
* Out of them, very few decide to do anything with it besides checking mail, social media, the web or play games.
* Out of them, very few decide to learn a programming language.
* Out of them, very few decide to learn anything besides Javascript or maybe Python.
* Out of them, very few decide to learn anything besides Java/C#/C++, learn algorithms, or learn tools like Vim or Emacs.
* Out of them, very few decide to learn anything besides Rust/Go/Haskell/Lisp/Scheme or even Fortran.
* Out of them, very few decide to learn a language with an alien, symbolic notation that resembles a code golfing language, and which, too, requires them to possibly learn a completely new keyboard layout to type with proificiency.
Not trying to discredit APL's contributions to functional programming and the like, but from the letter, it is pretty obvious Djkstra had little respect for friction. Not saying that he's right to dismiss it outright, though.
IMO, Perl's downfall was mostly Perl 6, not the language.
Plenty people wrote plenty of Perl long ago. Yeah, the whole $ business is maybe a bit unintuitive, but it's the least of the problem really. It's easy to get past it.
IMO, the first part of Perl's downfall is that it didn't evolve fast enough. It was good enough that people tried to do big things in it and then it turned out it wasn't a good idea. Perl's OO for instance is kind of a neat hack that turns into a horrible mess with large projects. Large projects also increasingly need verification and safety because the debug costs rise higher and higher, and Perl is paradoxically safer at small scales. "use strict" works great in toy scripts and is nigh useless in OO-laden large projects where "strict" does nothing to check your $this->{foo}->{bar} hash trees. Yes, solutions sort of exist but they're all adhoc and you have to plan for them, and module writers don't use them, and...
That could have been survivable with the right improvements, but:
The second part is that Perl 6 was terribly planned and took bloody ages to get anywhere. People stopped writing Perl 5 expecting Perl 6 was around the corner, so why invest too much effort when it was clear 6 was going to be incompatible even early on? And it kept not coming out, so Python quickly ate its lunch.
APL was the first language to have operators for "do this to all that stuff".
They were headed for functional programming. But the syntax was too weird.
As if medieval math notation was not weird enough, people decided to invent APL to be even more bizarre. As a proud Perl5 dev, I totally don't buy it. Neither do I buy into Raku's brave use of all possible Unicode symbols. Perhaps I'm ageing.
It has been a long time since I used APL (in college)
We had APL terminals which had APL keys and would print APL characters. It was significantly more immersive that way.
Looking at this letter i start to vaguely recall things.
Decades later, I recall the output operator, not shown anywhere here.
⎕←<something>
which would print whatever <something> was. (was I misremembering?)
I do recall using matrix operations in a similar way to the math classes I was taking at the same time. matrix multiplication, inversion, dot products seemed to be more "math oriented" than other computer languages.
In other computer languages, you had to adapt to the language. For example:
x = x + 1
y = mx + b
in these two statements, one only makes sense in math class, one only makes sense to increment a variable in a computer language.
21 comments
[ 2.5 ms ] story [ 48.1 ms ] threadBefore computers, we could write things only on paper, either with our hands or a typewriter. So, naturally, when computers came about, the way of thinking about programming was very text-driven, with an emphasis on what a typewriter could represent.
But then, code could be written directly with computers, opening up more typesetting possibilities thanks to keyboards not being bound anymore by the mechanical limitations of typewriters. You could add keys and combinations to your heart's desire, and they would be natively digital and unlimited.
Now, with graphics, both 2D and 3D, and a myriad or other HIDs, shouldn't we try to make another cognitive jump?
We settled on dense and terse modes of symbolic reasoning and typewriters and computers just reflect that.
The dream of unleashing cognition by breaking free of these constraints is backwards. The friction and the constraints are why and how we can do things, not what impedes us doing things. If we were all floating on high dimensional frictionless spaces we would be able to represent anything and do nothing.
Did he feel the language design was bad, or would having TTF fonts being able to show "rho", "iota", "grade up" have removed one or more of his objections?
Due to my affinity for the language, and my wish to have worked in its heyday (would love to have an APL gig someday), I have been exposed to various writings and recordings of Ken Iverson. I've also been exposed to a few of Dijkstra's thoughts on APL.
I have to say that Iverson generally comes across as a very generous and curious individual while Dijkstra seems to have been a miserable ass. Maybe, given the lens, I've not given Dijkstra a proper chance to demonstrate a more positive attitude, so I'm open to any suggestions of writings where he doesn't seem like such a grump.
I often see a lot of folks here on HN who are too eager to pass judgement on Dijkstra without having read and understood his writings nor giving much thought to the context and times which shaped his thinking. All of his opinions should be thought over and appropriately adapted for use in our context. He was a wide-ranging polymath philosopher (technical and non-technical) with a laser-like focus on exactitude using Mathematics. Radical approaches must be pushed, particularly when they are hard/difficult to learn and understand. If his language was biting, then it was so much the better for promulgating his cause viz. "correctness over easy", "mathematical reasoning underpinning everything", "structure in aid of the previous", "proper language syntax/design in aid of the previous" etc.
As an example; read EWD 1036: On the cruelty of really teaching computing science (https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD103...) in entirety and carefully. The thesis is that computing is "radically novel" from other forms of human endeavour and hence it cannot be taught by simplifying to known analogues and adhoc procedural operations. You need the rigor and exactitude of Mathematical Logic to build a "Scientific" basis.
Excerpts:
... What is a program? ... I prefer to describe it the other way round: the program is an abstract symbol manipulator, which can be turned into a concrete one by supplying a computer to it. After all, it is no longer the purpose of programs to instruct our machines; these days, it is the purpose of machines to execute our programs.
So, we have to design abstract symbol manipulators. We all know what they look like: they look like programs or —to use somewhat more general terminology— usually rather elaborate formulae from some formal system. It really helps to view a program as a formula. Firstly, it puts the programmer's task in the proper perspective: he has to derive that formula. Secondly, it explains why the world of mathematics all but ignored the programming challenge: programs were so much longer formulae than it was used to that it did not even recognize them as such. Now back to the programmer's job: he has to derive that formula, he has to derive that program. We know of only one reliable way of doing that, viz. by means of symbol manipulation. And now the circle is closed: we construct our mechanical symbol manipulators by means of human symbol manipulation.
...The point to get across is that if we have to demonstrate something about all the elements of a large set, it is hopelessly inefficient to deal with all the elements of the set individually: the efficient argument does not refer to individual elements at all and is carried out in terms of the set's definition.
...
Back to programming. The statement that a given program meets a certain specification amounts to a statement about all computations that could take place under control of that given program. And since this set of computations is defined by the given program, our recent moral says: deal with all computations possible under control of a given program by ignoring them and working with the program. We must learn to work with program texts while (temporarily) ignoring that they admit the interpretation of executable code.
Another way of saying the same thing is the following one. A programming language, with its formal syntax and with the proof rules that define its semantics, is a formal system for which program execution provides only a model. It is well-known that formal systems should be dealt with in their own right, and not in terms of a specific model. And, again, the corollary is that we should reason about programs without even mentioning their possible "behaviours".
... a program is...
It doesn't mean that he was always right, of course.
FORTRAN — "an infantile disorder"
COBOL — "the use of COBOL cripples the mind"
BASIC — students exposed to it are "mentally mutilated beyond hope of regeneration"
PL/I — "the fatal disease"
APL — "a mistake, carried through to perfection"
He liked his languages and programs to be easily traceable with pen & paper. He always wrote programs on the paper (and proved correctness) and only then into computer. REPL-driven development (what APL pioneered) was a foreign concept to him. He would be so appalled by LLM code generation.
I really enjoyed it because it was fun. You could do an incredible amount of work in a single line of code.
The only problem was, that line would then be almost impossible to read and understand! It could easily be used as a "write-only" language even without a separate obfuscation step.
When I become a professional programmer right after college, I never used it again, and learned to write code that was readable above all else.
* Out of all people, and especially in the newer generations, it is increasingly uncommon to find someone with a desktop or even a laptop.
* Out of them, very few decide to do anything with it besides checking mail, social media, the web or play games.
* Out of them, very few decide to learn a programming language.
* Out of them, very few decide to learn anything besides Javascript or maybe Python.
* Out of them, very few decide to learn anything besides Java/C#/C++, learn algorithms, or learn tools like Vim or Emacs.
* Out of them, very few decide to learn anything besides Rust/Go/Haskell/Lisp/Scheme or even Fortran.
* Out of them, very few decide to learn a language with an alien, symbolic notation that resembles a code golfing language, and which, too, requires them to possibly learn a completely new keyboard layout to type with proificiency.
Not trying to discredit APL's contributions to functional programming and the like, but from the letter, it is pretty obvious Djkstra had little respect for friction. Not saying that he's right to dismiss it outright, though.
Plenty people wrote plenty of Perl long ago. Yeah, the whole $ business is maybe a bit unintuitive, but it's the least of the problem really. It's easy to get past it.
IMO, the first part of Perl's downfall is that it didn't evolve fast enough. It was good enough that people tried to do big things in it and then it turned out it wasn't a good idea. Perl's OO for instance is kind of a neat hack that turns into a horrible mess with large projects. Large projects also increasingly need verification and safety because the debug costs rise higher and higher, and Perl is paradoxically safer at small scales. "use strict" works great in toy scripts and is nigh useless in OO-laden large projects where "strict" does nothing to check your $this->{foo}->{bar} hash trees. Yes, solutions sort of exist but they're all adhoc and you have to plan for them, and module writers don't use them, and...
That could have been survivable with the right improvements, but:
The second part is that Perl 6 was terribly planned and took bloody ages to get anywhere. People stopped writing Perl 5 expecting Perl 6 was around the corner, so why invest too much effort when it was clear 6 was going to be incompatible even early on? And it kept not coming out, so Python quickly ate its lunch.
Is this a horrible sideswipe or do people think it was intended frankly?
https://www.reddit.com/r/apljk/comments/uccbd6/russ_cox_solv...
We had APL terminals which had APL keys and would print APL characters. It was significantly more immersive that way.
Looking at this letter i start to vaguely recall things.
Decades later, I recall the output operator, not shown anywhere here.
⎕←<something>
which would print whatever <something> was. (was I misremembering?)
I do recall using matrix operations in a similar way to the math classes I was taking at the same time. matrix multiplication, inversion, dot products seemed to be more "math oriented" than other computer languages.
In other computer languages, you had to adapt to the language. For example:
in these two statements, one only makes sense in math class, one only makes sense to increment a variable in a computer language.