
APL Demonstration (1975) [video] - emersonrsantos
https://www.youtube.com/watch?v=_DTpQ4Kk2wA
======
agumonkey
Just in case, Aaron Hsu made a bunch of talks about APL

[https://www.youtube.com/results?search_query=aaron+hsu](https://www.youtube.com/results?search_query=aaron+hsu)

It's a bit caustic to the mainstream (beauty, terseness over ease and variable
names) but I personally find it tickles all my boxes.

~~~
nulldata
Aaron Hsu's work has truly inspired me, and expanded my horizon when it comes
to code and programming in general.

~~~
dang
He did a couple major discussions on HN a couple years ago:

[https://news.ycombinator.com/item?id=13565743](https://news.ycombinator.com/item?id=13565743)

[https://news.ycombinator.com/item?id=13797797](https://news.ycombinator.com/item?id=13797797)

~~~
agumonkey
Thanks I missed those

------
spectramax
The clarity, simplicity and minimal didactic approach towards making old
instructional videos is gone now. We have subscribe/hit-the-bell reminders,
annotations, background music, sponsorships, intro and exit greetings and all
kinds of unneeded bullshit in video production.

Commercialization of video has ruined this art form. Just compare early
Mythbuster episodes to something from 2016. Production quality has
horrendously degraded. The money is where the masses are and the masses want
entertainment, not education.

------
codesections
As cool as this is, APL has improved a _lot_ in the 34 years since that video
was made. Most notably, these days, APL has `direct functions`, which enable a
degree of concision and tacit-programming support unmatched in any other
programming language (yes, including Haskell).

As a minor taste of the power of direct fns, here's a naive implementation of
the Fibonacci sequence with one: `fib←{1≥⍵:⍵⋄(∇⍵-1)+∇⍵-2}`

~~~
kazinator
That's an example of what I call "stupid terse".

When comparing program length, we should count tokens, not characters.

We should give a penalty to excessively long tokens, of course, like
pointlessly_long_variable_or_function_names. Say, any token longer than 8
characters counts as two tokens. Any longer than 16 counts as 4 and so on,
exponentially. Pairing tokens like { } and ( ) can count as one for the pair.
In syntax like f(x, y), the () are essentialy one operator denoting function
application, spread out to enclose the arguments.

Your APL

    
    
      fib←{1≥⍵:⍵⋄(∇⍵-1)+∇⍵-2}
    

has 19 tokens. jodrelllblank's Python:

    
    
        def fib(n):
            if (1 >= n):
                return n
            else:
                return fib(n-1) + fib(n - 2)
    

has 27. There is a bit of verbiage with the colons, the else punctuation and
the explicit return commands.

TXR Lisp:

    
    
      (defun fib (n) (if (plusp n) n (fib (+ (pred n) (ppred n)))))
    

has 21 tokens (or, if you will, nodes in the syntax tree). Only two more over
APL, and provides a clear function definition from which we know it takes
exactly one required argument, which is given a name. It exhibits no
ambiguities.

~~~
jodrellblank
It's all very well to say your lisp is clear and unambiguous, how long did it
take you to realise it's wrong? It took me a good 20-30 minutes of writing a
reply about character count, before I tried to format your lisp onto three
lines and then noticed.

I think the Python code is very clearly a correct Fibonacci, it looks at a
glance like the layout of a procedural language doing a recursive call with a
base case and a recursive case. The APL is not as clear in that sense, but
knowing the diamond is a statement separator it breaks down into small pieces
and is fairly easy to read because there's so little of it to read. The Lisp
with 8 pairs of parens, 5 levels of nesting, and use of function names instead
of "n - 2", while still being a long run of code where there are almost no
symbols except alphabet letters and parens to make anything stand out, makes
it difficult for me to parse by eye to see what the intended nesting is, and
to make sure the parens are nested as intended.

You have it returning fib ((n-1) + (n-2)) instead of ((fib (n-1))+(fib
(n-2))), and I think you might have the condition the wrong way around, if N
is positive then the recursive calls should happen. That's not to say you or
Lisp can't write a correct Fib, it's to say that I think I would spot errors
in the Python much more easily, thus making it "more clear".

Which his another way of saying that I'm not convinced that counting
characters is automatically worse than counting tokens - characters are what
we type, what we have to read, they are what take up screen space and push
other code off screen, they push related bits of code further apart even when
it's all on-screen, and they are places bugs can hide. If they're not helping,
what are they doing?

Characters are the reason the APL could fit 3x in a single 80 character wide
line, and the Lisp code 1.3x in the same line, and the Python code 0.2x in the
same line. Not that I desperately want to read 80 characters of uncommented
APL, but that adds up quickly. The APL tends to be high level and more
declarative, which doesn't show up in Fibonacci, but makes a difference in
character count.

\----

APL functions in the dfn style (curly braces) can only take an argument on the
left and an argument on the right, both optional. The left one becomes alpha ⍺
and the right one becomes omega ⍵. That is to say, because you see omega in
the code, you know it too expects exactly one argument, that argument goes on
the right, and it has a name. The name is no less meaningful than "n",
although no more meaningful either.

The steep learning curve about APL code isn't "what does the code say, those
symbols are unreadable", they stop being scary quite quickly and just stay
dense, instead it's "how on Earth does that manipulation of arrays solve the
problem??"

~~~
kazinator
> _I think you might have the condition the wrong way around,_

Yes I do! I did this just minutes before rushing out the door, and didn't even
bother to run it.

Now, the funny thing is, I was focused on paraphrasing your Python expression
for expression, so that it calculates Fibonacci in exactly the same way with
the same conventions, so any size comparisons are fair. (Though obviously I
took advantage of the _pred_ and _ppred_ idioms.) I wasn't thinking "is this
correct Fib", but "does it match whatever the Python is doing".

So now I'm looking at: why did I transcribe the simple conditional backwards?
Taking a second look at the Python, I now clearly see the reversed convention
in 1 >= n that I read as n >= 1.

------
yeellow
I have a feeling that apl (or j) based calculator app (with buttons for all
fancy symbols) could be something. All those nice powerful one liners seem to
be suited for such app. I wonder if something like that is available. I know
there is j for Android, but having a nice closed interface focused on short
clever code would be fun.

~~~
agumonkey
I grew up with a HP48g and for some reason I never considered a handheld APL.
That would be the only thing to match HP RPL :)

~~~
jodrellblank
dzaima/APL is implemented in Java and can be built as an Android app; steps in
the readme here:
[https://github.com/dzaima/APL](https://github.com/dzaima/APL) and
downloadable APK and screenshots here:
[https://github.com/dzaima/APL/tree/master/AndroidIDE](https://github.com/dzaima/APL/tree/master/AndroidIDE)

(I think; I've never used it)

~~~
agumonkey
hehe, pretty nice

------
dang
A thread from 2014:
[https://news.ycombinator.com/item?id=7817593](https://news.ycombinator.com/item?id=7817593)

------
coldpresent
I find that his mentioning of "monadic" and "dyadic" instead of "unary" and
"binary" interesting, why did he mention those?

~~~
nprescott
As far as I know, this is a peculiarity of APL resulting from Iverson's stance
on the language as a "tool for thought"[0]. The best explanation I've heard is
that "binary" is most apt to number systems (or matrices!) - but a "verb" in
APL is not binary, it is dyadic. The language of verbs and nouns is a similar
reflection of the ideas that APL is primarily a _language_ (like English, more
so than Fortran) to express mathematics succinctly (with a minimum of
ambiguity or syntax).

This is (to me) even more apparent in his next language, J; where he sought to
"correct" deficiencies in APL and further expanded the "language" to include
things like "gerunds"[1] more explicitly, which are nominally (as defined in
an English dictionary):

> a noun formed from a verb, denoting an action or state

Which may be summarized somewhat unsatisfactorily as: "Because Ken said so".

[0]:
[https://www.jsoftware.com/papers/tot.htm](https://www.jsoftware.com/papers/tot.htm)

[1]:
[https://code.jsoftware.com/wiki/Vocabulary/GerundsAndAtomicR...](https://code.jsoftware.com/wiki/Vocabulary/GerundsAndAtomicRepresentation)

~~~
mjn
It's not _totally_ APL-specific terminology, although it's uncommon in other
areas of computer science. You can find it (predating APL) in areas like
mathematical logic, where a predicate over two terms is sometimes called a
"dyadic predicate". I'm guessing Iverson was familiar with that usage and
extended it to APL. I wouldn't read too much into it though. It's mostly just
Latin vs. Greek roots (unary, binary, ternary are Latin; monadic, dyadic,
triadic are Greek).

------
narrator
APL made a lot more sense in the era of 110 baud teletypes.

