Live data from Hacker News

The APL Source Code (2012)

computerhistory.org

41–50 of 61 posts

Re: The APL Source Code (2012)

#41

> Expressions in APL are evaluated right-to-left I find it more natural to evaluate left-to-right, because that's the order we read things in. For example, to read a file and sort its lines (in D): auto sortedLines = File("file.txt").byLineCopy.array.sort;

Isn't the assignment operator evaluated last, though? I don't know of any language that would support "true" left to right evaluation, though it would be neat! I suppose it would look like: File("file.txt").byLineCopy.array.sort = sortedLines; ...which by first blush, seems bananas, but if you were to read it as English, would make sense: "Load the file 'file.txt' into an array of lines, sort them, then assign it to…

> Isn't the assignment operator evaluated last, though?

Yes. Though one could use the . operator and a sink to make it completely left-to-right.

Re: The APL Source Code (2012)

#42

I like APL (and k/j). Problem is, outside trading (and even there it's a niche), it is just not popular enough. This also because most people dismiss it as line noise / write only programming language; that's usually only people who never used it or used it briefly saying that. But it's hard to promote anything that has a reputation like that. What is a fairly interesting observation (more people have made it, includ…

> This also because most people dismiss it as line noise / write only programming language

Not so. Anyone who says these things simply does not know APL. It's like saying musical notation is write-only. Sure, if you don't know it reading the darn thing is excruciating. Yet, if you do, you can see music on the page.

What APL is not is a low-skill, low-knowledge language. A casual glance at the language isn't enough to know it. Just as you can't internalize musical notation without dedication, work and experience.

Back in the '80's I used APL professionally for about a decade. From that context, it reads like music. To this day I can read it just fine (though not as quickly). Interestingly enough the same is the case musical notation, which I could read without thinking twenty years ago, when I was studying and playing classical guitar and piano with great regularity.

That said, I would not recommend anyone get serious about APL today. Study with some degree of dedication? Yes, I think that would be of value. Real projects? No. Definitely not.

Re: The APL Source Code (2012)

#43
post #6
post #4

> But APL programs are often cryptic and hard to decode. Some have joked that it is a “write-only language” because even the author of a program might have trouble understanding it later. So the original Perl?

Nope, not even close. I’ve written/read lots of Perl. APL is a completely different paradigm. Every now and then I get the urge to take a deep dive into APL or J but I really need a use case. Since they are array languages they seem like they might be good for machine learning?

Image processing is a fun use case. For example, here's a bit of Common Lisp using April and the Opticl library to create a mirrored meme image:

  (opticl:write-png-file 
   "~/out.png" (april-c "2 0∘{(x s)←⍺←2 0 ⋄ (⌽[x],[x]⊢)⌽[x]⍣s⊢⍵↓[x]⍨(1-2×s)×⌊2÷⍨x⊃⍴⍵}" 
                        (opticl:read-png-file "~/in.png")))
The 2 0 at the start of the APL line above controls the mirroring behavior. The second number can be set to 0 or 1 to choose which side of the image to mirror, while the 2 sets the axis along which to mirror. This will be 1 or 2 for a raster image but this function can mirror any rank of array on any axis.

April was used to teach image filtering in a programming class for middle-schoolers, you can see a summary in this video: https://vimeo.com/504928819

For more APL-driven graphics, April's repo includes an ncurses demo featuring a convolution kernel powered by ⌺, the stencil operator: https://github.com/phantomics/april/tree/master/demos/ncurse...

Re: The APL Source Code (2012)

#44

> Expressions in APL are evaluated right-to-left I find it more natural to evaluate left-to-right, because that's the order we read things in. For example, to read a file and sort its lines (in D): auto sortedLines = File("file.txt").byLineCopy.array.sort;

Isn't the assignment operator evaluated last, though? I don't know of any language that would support "true" left to right evaluation, though it would be neat! I suppose it would look like: File("file.txt").byLineCopy.array.sort = sortedLines; ...which by first blush, seems bananas, but if you were to read it as English, would make sense: "Load the file 'file.txt' into an array of lines, sort them, then assign it to…

It's the symmetry of the '=' symbol which creates the difficulty. Replace it by an arrow in the direction of the assignment and it doesn't look strange anymore. File("file.txt").byLineCopy.array.sort -> sortedLines;

Especially if you add the |> operator (from Erlang I believe) to 'pipe' the data.

File("file.txt") |> readlines |> sort -> sortedLines;

Re: The APL Source Code (2012)

#45
post #4

> But APL programs are often cryptic and hard to decode. Some have joked that it is a “write-only language” because even the author of a program might have trouble understanding it later. So the original Perl?

Way harder to read than Perl..

You can create obscure Perl as you can create obfuscated C as in any language, but if you think about the reader you can create 'easy to read' program in Perl, even by a beginner.

But creating 'not obfuscated' APL? That's really hard!

Re: The APL Source Code (2012)

#46
post #27

Earlier quoted context omitted.

If a string (or a file or whatever) is "just" an array (of bytes; characters, again: whatever), then yes.

If that means "you don't get much more than what C offers", then I'll take that as a no. I18N, Unicode, Regex, built-in string manipulation functions, character set conversions and efficient data structures are table stakes at this point.

APL is very decent at string manipulation. I could try to explain why, but I am afraid that you'll have to see for yourself to understand why what you wrote is both true and not very applicable to APL.

Re: The APL Source Code (2012)

#47
A modern version of APL here: BQN [1] [2].

Its introduction says: "Although it maintains the concept of array-driven computing and much of APL's array functionality, BQN discards all compatibility with other array languages and changes many fundamental concepts. It uses the based array model with dedicated array notation, distinguishes between data types and expression roles to give the language a context-free grammar with first-class functions, and uses a new set of glyphs with different primitive pairings."

[1] https://mlochbaum.github.io/BQN/doc/quick.html

[2] https://mlochbaum.github.io/BQN/tutorial/index.html

Re: The APL Source Code (2012)

#48

I like APL (and k/j). Problem is, outside trading (and even there it's a niche), it is just not popular enough. This also because most people dismiss it as line noise / write only programming language; that's usually only people who never used it or used it briefly saying that. But it's hard to promote anything that has a reputation like that. What is a fairly interesting observation (more people have made it, includ…

Ironically, APL has won as a programming language. Look at the SIMD instruction set - it's APL!

Vector instructions came around roughly at the same time as APL, though.

Re: The APL Source Code (2012)

#49
I'm skimming the source code, noting a few things that might help others do so. The "ADD NAME=" lines separate what would have originated as separate decks of punched cards. Each card is an assembler statement; each has an 8-digit sequence number in columns 72-80. You might note that sequence numbers are sometimes not consecutive. This reflects changes due to editing. As long as the deck could be sorted in correct order on the last 8 columns it was ok.

Each such source deck would have been assembled to make an object deck. There are assembler commands for formatting the printed assembly listing: TITLE to set a running title on the listing pages, PRINT OFF to avoid listing repetitive macros, PRINT ON, PRINT NOGEN to not print macro-generated statements, EJECT to start a new listing page.

A DSECT line introduces a data section, essentially a record. The pseudo-instruction USING tells the assembler which register contains the base address of a DSECT, so USING MKLOCLS,14 says, assume R14 has the address of the DSECT MKLOCLS. Reference to a name defined within that DSECT will generate an instruction using R14 plus the offset to that name.

A CSECT names a "control section" or named block of instructions. The linker handles CSECTs and DSECTs as units. A CSECT typically begins with USING *,15 or some other register, to inform the assembler that at run-time R15 will have the base address of this code. Local jump addresses will assemble as offsets from that register. A DROP statement tells the assembler to no longer assume that register is in use.

There are inside jokes: the code with TITLE 'THE AGORONOMIC ROUTINES' is memory management.

APL\360 managed memory on two levels. First, as a time-sharing system, it created a separate "workspace" for each logged-on user. A workspace was a contiguous block of memory (typically 32K as a practical size) that contained all of the user's current code definitions. There was not room in the typical 360 RAM for more than a few user workspaces at one time, so the system swapped whole workspaces in and out as it serviced each user. The code to do this operated the disk drives directly on a head and track level and was highly optimized. You'll see a number of references to "one-track workspace" as a special case; if a workspace fit on one track of the (2311 or 2315) disk, it could be read in or written out in minimum time.

On the user level, the interpreter while executing APL code is constantly creating and trashing values which are stored as memory objects within the current workspace. So there was memory allocation and garbage collection. Garbage collection was a simple sweep across the workspace moving all active objects to one end.

APL would be initiated as a normal job under OS/MFT and would immediately take control of the entire system, kicking the OS out and managing all aspects of the 360 hardware itself, including interrupt handling, storage protection and so on. This was before the day of hardware-supported virtual memory, so it didn't have that to deal with. See NAME=APLSAPLM and forward. I'm pretty sure in that code, TCB stands for Task Control Block, a dispatching object. APL had multiple internal tasks being time-shared, as necessitated by the fact that it had to handle asynchronous interrupts from both terminals and disk drives.

Post reply on HN