50 Years of APL Datatypes (2016) [pdf]
sudleyplace.com
sudleyplace.com
https://news.ycombinator.com/item?id=13565743
https://news.ycombinator.com/item?id=13638086
We'll probably do that this weekend. (The intention was for 13638086 to be that discussion, but we dropped the ball, so we're going to do a retake.)
Edit: planned for Sunday at 11am PST!
Not sure what to make of it other than thinking that perhaps it is different enough that it still generates interest from time to time but few are using it professionally.
There are still places where APL is actively used. This is mostly in the financial services arena. I think it's sort of like companies that use massive Excel files for internal "secret sauce" and they just can't pull away from it.
Not saying APL has run it's course, but, after using it for so long (and still do just to play around) it was easy to see the language needed yet another revision to remain useful and viable for widespread real-world projects.
If you can believe it, I still have a 1980's era original IBM PC in the garage with a real IBM APL keyboard (they used to sell keyboards with the APL character set on the front of the keycap) and both IBM and STSC interpreters installed and running. One of these days I need to see about creating a virtual machine out of those drives (20 MB hard disks!).
http://sigapl.org/Archives/waterloo_archive/apl/apl-11/QL_Si...
A recent version that has gone through many iterations can be found at
https://github.com/PlanetAPL/openAPL
If you google "Ken Thompson APL\11" you will find several links, including ancient archived versions of the code.
I'm doing a bit of shameless advertising here, since I'm the author of gnu-apl-mode[2] which adds support for GNU APL to Emacs.
If anyone have questions about this, I'll be happy to answer them here.
[1] https://www.gnu.org/software/apl/
[2] Available on MELPA, but you can also find the source here: https://github.com/lokedhs/gnu-apl-mode
In fact, I do believe GNU APL is the youngest APL implementation out there, having had its initial release just a few years ago.
I personally use it for working on data sets such as working on performance data from, say, vmstat. I'm also using it for casual calculations. It's very good for this since the syntax is so terse, I can do a lot of computation with very little code.
And of course, I use it because it gives me some degree of satisfaction. For example I did one of the tasks in last year's Google Code Jam in APL.
I have had performance problems at several million rows, but it all depends on what you do.
Hopefully it can still be helpful: https://www.youtube.com/watch?v=yP4A5CKITnM
When using it, you can type C-c C-k which will open a quick help that shows they keymap.
2nd ed covered the differences between STSC, APL2 and Sharp, which were the main implementations that people used to encounter. Later they issued an edition with a 3rd author, Brown, that used APL2 exclusively.
For learning the language, I've found the freely available "J Tutorial and Statistical Package"[0] to be a great approach. You learn J by building up a package of basic stats functions. The author also has a variety of other interesting J papers.[1]
[0] https://webdocs.cs.ualberta.ca/~smillie/Jpage/jtsp.pdf [1] https://webdocs.cs.ualberta.ca/~smillie/Jpage/Jpage.html
Nested Arrays weren’t without controversy as there were two competing designs called Floating and Grounded which differed in many ways, but fundamentally on whether the enclose of a simple scalar produced a new array or the same array.
What's 'enclosing' (is it something like boxing?) and what does it mean to produce a new or the same array?
⎕ ← 1 + 2
will yield 3, and ⎕ ← 1 9 5 + 2
will yield 3 11 7. Of course, you can have complex arrays as well: (2 3) (5 4 2) in APL will be an array with two elements: the first element having two sub-elements, and the second having three sub-elements. The question then, is what about (2)? Should that be an array inside an array? Or just an array? That is my understanding of that paragraph.I don't think the question of "which is best" here can be answered without a lot of practical experience trying both methods. If you like APL, I think this is a good tutorial: http://www.zerobugsandprogramfaster.net/essays/5b.html
Way cool to play with...
Now, with this design, how do you manage a collection of strings? Turns out you can't, so what old software used to do was so have a two-dimensional array of characters. This works reasonably well, except that this means that all strings have to be the same length. You can work with this, but can be very annoying.
What APL2 introduced was the idea that you can not only put scalars inside an array, but also other arrays. This is of course how pretty much every other programming language works, but at the time (as far as I know, this is way before my time) this was seen as very controversial since it made the language less clean, or "elegant".
To go into some details, you can consider a scalar as an array of dimension zero:
⍴⍴5
0
(⍴⍴ returns the dimension of the argument to the right[1])Once you have nested arrays, you can also wrap an array inside a scalar. This allows you to more easily treat arrays as single objects:
s ← 'hello' ⍝ Assign the string "hello" to s
⍴⍴s ⍝ Confirm that s is a one-dimensional array
1
s2 ← ⊂s ⍝ The ⊂ wraps its argument as a scalar, assign the result to s2
⍴⍴s2 ⍝ The result now has 0 dimensions
0
[1] To go really deep into the technical details, it returns the dimensions of the dimensions of the argument. A scalar has no dimensions, do ⍴5 returns an empty array. The second ⍴ returns zero because an empty array has zero elements.Is this a divergence between APL2 and Sharp implementation? I used to work (a long time ago) with a lot of ex-Sharp people from Toronto who were always harping about the superiority of Sharp.
As far as I know, Sharp APL was "old style" in the sense that it did not support nested arrays. Some people may like that style, but I have a hard time seeing that it is "better", since the nesed arrays are backward compatible with the non-nested style.
Note that you can also use the ⊂ and ⊃ functions to convert between nested and recursive arrays. For example, assuming you have an array of strings:
a ← 'here' 'are' 'some' 'strings'
⍝ a is now a single-dimensional array of 4 elements
⍴a
4
⍝ The ⊃ function converts the nested array into a two-dimensional array
⊃a
here
are
some
strings
⍝ The array is two-dimensional with 4 rows and 7 columns
⍴ ⊃a
4 7This greatly simplified the entire language - both semantics and implementation.
(From what I could understand with floating you are actually adding a scalar element to the array, with grounded you are creating a 1-element array containing the scalar, and adding this to the original array, which is an array of arrays - but I might have completely misunderstood)
In the early 1980’s, a number of APL vendors almost simultaneously introduced a new concept into APL - the nested array. Each element of a nested array can itself be any other (nested) array. A new monadic primitive function, called enclose, was introduced that took any array as its argument and returned a scalar enclosed array. This scalar (rank zero) array could then be inserted in place of any scalar element of any APL array.
Unfortunately there were two inequivalent approaches; grounded arrays as proposed by Ken Iverson [...] and floating arrays as proposed by Jim Brown [...] In the grounded system, enclosing a simple scalar produces an enclosed scalar, whereas in the floating system, enclosing a simple scalar leaves it unchanged.
So enclose(x) is always a scalar, but the two schemes disagree about whether enclose(s) == s for a scalar s.
I was horrified when I learned FORTRAN: I have to write a do-loop to add two arrays together? Why? (No array fortran back then.)