
Ode to J - lelf
https://zserge.com/posts/j/
======
eggy
I love J, APL and the array languages in general. I am always looking for
exercises to practice my J skills. I found this article by Tyler Limkemann
called "Modeling the COVID-19 Outbreak with J"[1].

I also follow tangentstorm and took some of this J-talks gui code[2], and
mashed it up with Tyler's as a J learning exercise. I just put this up on my
github. [3]

I highly recommend tangentstorm's YouTube videos too![4]

The concise J code, and the way it makes me approach a problem brings me joy!
Given all of my coding projects in J fit on one page, I can revisit them
later, and get right back in without worrying about having too many comments
or documents to understand my code. I like refining the code over time for fun
and learning even after it works, or somebody much smarter than myself shows
me a different way to look at it.

[1] [https://datakinds.github.io/2020/03/15/modeling-the-
coronavi...](https://datakinds.github.io/2020/03/15/modeling-the-coronavirus-
outbreak-with-j)

[2]
[https://github.com/tangentstorm/j-talks](https://github.com/tangentstorm/j-talks)

[3]
[https://github.com/rpherman/JLang/tree/master/COVID-19](https://github.com/rpherman/JLang/tree/master/COVID-19)

[4]
[https://www.youtube.com/user/tangentstorm](https://www.youtube.com/user/tangentstorm)

------
smabie
It seems like array languages are really picking up steam on HN lately; It's a
positive development. Every developer should learn at least one array
language. They sound absolutely crazy before you start, but then you start
writing some code and you realize there's a lot of wisdom in the coding style.
It's not something you can appreciate only from afar, though.

~~~
dunefox
Which of these languages has good materials and is suitable as an introductory
language?

~~~
smabie
My first one, which I learned for Advent of Code 2019 was kdb+/q. There's a
good book for it too: [https://code.kx.com/q4m3/](https://code.kx.com/q4m3/)

------
7thaccount
I've done a little J in the past and have been playing with APL a lot lately.

It is definitely a different way to think. My programs are taking a long time
to write as I train my brain to think in this domain, but the code is very
concise and generally not hard to follow afterwards. Everything is so
interactive it's a joy.

In particular, I enjoy how the poster broke the code down as I can only
understand some of C code. It's cool to think I could create my own little J
interpreter this quick.

------
jim-jim-jim
It seems like this blurb of code has appeared on HN quite a bit lately, and
it's cool to see a breakdown of it.

The next time I write C, I'm tempted to do it Whitney style like this. There
really is something to be said about seeing everything at once.

~~~
beagle3
Indeed. Be careful, though, many people find they can’t go back to the level
of verbosity they used to write (and which is often expected in a team)

~~~
moonchild
Dyalog and kx are hiring

------
scythe
Since this flurry of APL/J/K/A+/Q articles started, I've been wondering about
the relationship between APLs and literate programming.

They say that APL was developed to mimic mathematical notation, and I see the
resemblance. But real works of mathematics consist of one or two lines of
expressions separated by sentences and paragraphs explaining the goal of those
expressions.

So far in K "advertising" I only see the expressions and not the explanations.
The explanation is there, but it's not a comment in the codebase; it's in a
blog post that explains it. The code has many lines of expressions on top of
each other, and nobody writes math that way.

I feel like I'm missing something, basically. It's clear how to write K, but
what are the best practices for making a large codebase readable? I shouldn't
have to invent that myself, right?

~~~
7thaccount
Assuming you write your code for a certain domain, I think most of your
colleagues could follow along after learning a little k.

I wrote a toy simulator for the domain I work in using something like 6 lines
of APL code and sent it to someone good with APL. They replied back to the
email pretty quickly with some tips on how to improve it and could generally
get the gist of what I was trying to do while knowing nothing of the problem
domain. It was really an interesting experience. I think with zero doc, a
colleague of mine would immediately understand what I was doing after going
through a short APL tutorial. It isn't magic, but not nearly as cryptic as
people make it out to be.

Edit: people do comment their APL code. I think a million loc project would be
pretty difficult in APL, but the beauty is that you should be able to do some
pretty powerful work in a few pages I would imagine.

~~~
eggy
I think you're right. Aaron Hsu's work in APL is inspiring and awesome. The
source code to his data parallel compiler hosted on the GPU is 17 lines of
APL! Read the abstract to his paper here:

[https://scholarworks.iu.edu/dspace/handle/2022/24749](https://scholarworks.iu.edu/dspace/handle/2022/24749)

~~~
kd0amg
_The source code to his data parallel compiler hosted on the GPU is 17 lines
of APL!_

The co-dfns source I've seen[1] is much longer. Do you know if there's a
write-up somewhere of the differences between that and Appendix B from the
dissertation?

1: [https://github.com/Co-dfns/Co-dfns](https://github.com/Co-dfns/Co-dfns)

~~~
vchak1
I think its important to distinguish between something that is a core piece vs
all the other things that make the system usable. For example once you start
adding error handling, and good error reporting, the complexity goes up by an
order of magnitude. And in many cases the approach for the core does not
necessarily scale out to the other contexts.

~~~
eggy
The right tool for the job. If you are building a huge website with input
forms, videos, data collection, ML algorithms, yes then you wouldn't do the
whole thing in APL or J even if you could. Python is big in ML because
packages for working with data in array language ways were developed. Pandas
by Wes McKinney is one example, and he studied J or q, and even tweeted: IMHO
J is the best APL for data analysis because of its broad suite hash table-
based functions.

I like APL and J as a scratchpad where arrays are the basic unit and not
scalars. J is functional and it turned me on to that world before I touched
Haskell or F#.

Aaron Hsu has a lot of great videos that speak to a lot of the usability and
scaling out you mention:

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

I particularly like this one:
[https://www.youtube.com/watch?v=z8MVKianh54&t=2857s](https://www.youtube.com/watch?v=z8MVKianh54&t=2857s)

I am able to grasp concepts or own them after coding them in APL or J even if
the code isn't as fast such as how well APL applies to Convolutional Neural
Networks [1,2]. I really understood the mechanics of CNNs better after working
through this paper a lot more than books I had read on ANNs in general since
the late 80s/early 90s. By contrast, I have coded ANNs in C and Python, and I
get lost in the PL, not the concept, if that makes sense. Anyway, I am a
polyglot and find people criticize J/APL/k etc. from a brief look without
really trying to learn the language. I learned assembler and basic back in
1978 to 1982, and I felt the same way when I first looked at opcodes.

[1]
[https://dl.acm.org/doi/10.1145/3315454.3329960](https://dl.acm.org/doi/10.1145/3315454.3329960)

[2]
[https://www.youtube.com/watch?v=9vIZ7d3-GBw](https://www.youtube.com/watch?v=9vIZ7d3-GBw)

~~~
7thaccount
Bahaha. It's a small world fellow HN user. As soon as ACM opened their digital
library, I started looking for interesting APL papers and found that one and
thought it was beautifully done. My takeaway is that you can make purpose-
built AI in APL with very little code versus calling out to a large library
like Tensorflow and having no idea what's going on.

~~~
eggy
I think someone has translated this to J, but I am trying on my own to
practice my J-fu by implementing it in my own way. Then I usually open it up
to the J experts on the mailing list, and my learning takes off. There are
some awesomely smart people there who are generous with their time.

Yes, the takeaway is that with APL or J is that you can see the mechanics in a
paragraph of code, and it is not a very trivial example. If the libraries or
verbs are created to deal with some of the speed or efficiency issues, it is
promising as a way of understanding the concept better.

The dataframes of R and Python (Pandas) were always a thing in APL/J/k/q, so
it is their lingua franca or basic unit of computation upon which the
languages were built - arrays, not a library.

More importantly, almost along the lines of the emperor has no clothes, is a
tack to get away from the black box, minimal domain knowledge, ML or DL that
cannot be explained too easily - see newly proposed "Algorithmic
Accountability Act" in US legislature. Differentiable Programming and AD
(Automatic Differentiation)applied with domain knowledge to create a more
easily explainable model, and try to avoid biases that may creep into a model
and affect health care and criminal systems in a negative way [1][2].

And then there are those who use DL/ANNs for everything, even things that are
easily applied and solved using standard optimization techniques. Forest from
the trees kind of phenomenon. I have been guilty of getting swept up with them
too. I started programming ANNs in the late 80s to teach myself about this
new, cool-sounding thing called "neural networks" back then ;)

[1] [https://arxiv.org/abs/1811.10154](https://arxiv.org/abs/1811.10154)

[2] [https://arxiv.org/abs/1907.07587](https://arxiv.org/abs/1907.07587)

~~~
7thaccount
Neat and thanks for sharing!

------
okareaman
Am I weird because I have no interest in terseness that you have to tease
apart. It feels counter-productive. The programming golf (Code golf) contests
and obfuscated C contests just seem like a waste of time to me. The whole
point of programming languages is to allow humans to produce machine code
using a more natural language closer human language that we are all already
fluent in.

~~~
smabie
That's not the point of programming languages. The point of programming
languages is to be more productive, it has nothing to do with natural
language. In fact, natural languages are a poor fit for programming languages
(see Cobol).

~~~
ben509
Counterpoint: SQL is incredibly successful and its syntax uses natural
language structures quite heavily.

The problem Cobol has is that uses some natural structures, but then becomes
very verbose because it only uses a few, and they often can't be combined, so
it is very repetitive.

It's not natural to say,

    
    
        I will buy eggs at the grocery store.
        And I will buy ham at the grocery store.
        And I will buy cheese at the grocery store.
    

> The point of programming languages is to be more productive...

But you should be productive not only in initially writing the code, but also
in reading it later when you do maintenance.

And what you see with most languages is extensive commentary to help future
authors understand what's going on, and that's partly because terse languages
tend to be cryptic.

~~~
ken
In my experience, SQL is successful _despite_ its syntax, not because of it.
Wasn't it originally intended to be an end-user interface? It's failed at
that. Now even programmers choose to use an ORM to insulate themselves from
it. Even the programmers I know who don't use OO still use an abstraction
library to avoid the need to touch SQL directly.

SQL isn't even one language. It's a family of incompatible dialects. I've
never written more than the most trivial SQL that would even be valid (much
less the same result) on any other SQL dialect. Even though it has ISO and
ANSI standards, every database in the world requires proprietary rules and
conventions and extensions. How do you quote identifiers? Are strings case
sensitive? Is '' the same as NULL? How do you create an index? What data types
are there? We can't even agree on the most basic aspects of syntax.

It's "incredibly successful" in the same way that early HTML and JS was.
People wanted access to the underlying platform so badly they'll put up with a
nutty design and gratuitous incompatibilities. They don't really have a
choice, and many are going out of their way to build their own alternatives
because the vendors won't.

------
haolez
I like to play with array languages in my free time. I have a doubt regarding
readability:

For me, it's easier to read APL with the symbols than to read J/K. Does it get
better if you work a lot with J/K?

~~~
ThomasBHickey
Long ago I was doing some analysis on a Sigma 5/CP-V machine. One of the few
high level languages available was Xerox APL. For those without an APL
keyboard they provided ASCII replacements (I don't rember what they were, but
looked like $NDX, $ASG). After learning APL with the awkward mnemonics I was
never able to read it with the special characters! J does a much better
standard-character APL.

~~~
dunefox
Why don't these languages support latex-style symbols in the way Julia does?
Even in the Repl: type \alpha<TAB> and you get α. Even Σᵢ is possible. This
makes symbols accessible without a keyboard and the code is quite close to
mathematical notation.

~~~
clarry
Latex style is way too verbose, I would not want to type like that. And I
think the input method should be a problem for your editor/OS to handle, not
the language.

In any case, symbols were abandoned back in the day when everyone was still
using 8-bit encodings. [1][2]

Nowadays you have e.g. Dyalog APL which does use APL symbols and you have
short ascii-based sequences (easier to type than latex) for inputting them:

    
    
        `u`y gives you ↓↑
    

(You can try this online at [https://tryapl.org/](https://tryapl.org/))

[1] Remembering Ken Iverson
([http://keiapl.org/rhui/](http://keiapl.org/rhui/))

> For the first few months, the special APL characters and the ASCII spelling
> co-existed in the system. It was Ken who first suggested that I should kill
> off the special APL characters. I myself resisted for a few weeks longer,
> until the situation became too confusing, for reasons described in J for the
> APL Programmer.

[2] J for the APL Programmer
([https://www.jsoftware.com/papers/j4apl.htm](https://www.jsoftware.com/papers/j4apl.htm))

> J uses the 7-bit ASCII alphabet. It also makes non-essential use of the box-
> drawing characters in the 8-bit ASCII alphabet for display. Using ASCII
> avoids the many problems associated with using APL symbols. It allows J to
> be used on a variety of machines without special hardware or software, and
> permits easy communication between J and other systems.

------
kinleyd
Recently I've been dabbling in q and kdb+. Would there be any benefit to
dabbling in J instead?

~~~
anonu
Shakti seems to be the new flavor

~~~
7thaccount
The creator of kdb+, the k language, and the q-sql DSL sold his share of
Kxsystems (company that makes kdb+) to start a new venture called "Shakti"
with a new version of his "k" language. Kdb+ is still around and developing,
so I'd say they're forked at this point.

------
warthogschool
Does anyone know what the dyadic verb 'find' (dyadic '~') is supposed to do?
Its implementation seems to be empty in the little interpreter.

~~~
chrispsn
It's probably like k's find (`?`), which gets the indices of the found
elements, or else the length of the list (or null, depending on the dialect)
if not found:

    
    
         "abc"?"caz"
        2 0 3

------
antigirl
We did J in university. I hated it. We also did assembly and I much ordered
that instead

~~~
7thaccount
I think I would also hate J, APL, Prolog, Haskell, Forth, or Lisp in
University.

The problem is that those languages require a completely different shift in
software from the common imperative/OO style to something more declarative or
in Lisp's case, just a bit different.

In a typical university course, there isn't enough time to focus on learning
those things and you stay so shallow with the material that the language seems
useless. It seems like 1/2 of the Prolog subreddit is about homework
assignments on things like list reversal. If you can already do that in
Python/Java with a single method call, Prolog just seems like a really bizarre
and inefficient method. Now once you take another step and see how it can
figure out how to solve Sudoku without explicit instructions...that is cool.

It's really the same thing with electrical engineering when the professor is
trying to teach us microprocessors and assembly at the same time and it all
seems like a waste when C is much easier. The assembly method probably teaches
better, but I need more than just a few weeks to synthesize that information.
Especially when you're getting slammed by other hard classes like differential
equations at the same time. So perhaps you do hate J, then again, maybe you
just need to learn it on your own schedule and not to answer arbitrary test
questions about something you can already do in Java.

~~~
aidenn0
I don't know how it is in J, but having fielded Lisp questions from students
learning Lisp (usually 1/3 or 1/2 of a semester class on "Programming
Languages" or "Functional Programming"), the assignments tend towards
_terrible_ questions, to the point where I don't think I could come up with
questions that were better suited to making someone hate the language.

People come out of a class that used Common Lisp thinking that Common Lisp
lacks any looping construct (it has several). It looks like the professor took
a SICP (which uses scheme, not common lisp) based class as an undergrad, never
looked at any language in the lisp family again, and then 20 years later made
up a syllabus using the half-remembered information using Common Lisp because
they remember SICP had something to do with Lisp and taught it without
actually trying to do any of the exercises.

------
empath75
About halfway through reading that, I was thinking -- it would be fun to try
and write this in Rust, and then i got to the bottom, and he had aleady done
it. Much easier to read in rust.

~~~
RodgerTheGreat
The C version is 41 lines, and 1749 bytes. The Rust version is 295 lines, and
8289 bytes.

The point of the Incunabulum is not really what it does (it's a REPL with a
handful of half-implemented J verbs and no error checking), but the style it
demonstrates. I think that rewriting a similar program in another language
without even attempting to reproduce the style is rather missing the point.

If you're interested in Rust, why not figure out what a semantically-
compressed style looks like for it?

~~~
tomp
How much of that is due to the C preprocessor though? In theory, you could run
the same preprocessor for Rust code (if you figure out some sensible macro
shortcuts).

~~~
clarry
Not much at all.

It's a completely apples to oranges comparison, with the rust version having
some error handling, support for longer identifiers, tests, relatively
idiomatic style with line breaks and indentation where you expect it,
variables and type names longer than one or two characters, etcetra.

You could compress it massively before going for the preprocessor. In fact, a
few of the preprocessor macros just make the C version longer (when measured
in lines) than it would be without those macros if lines were allowed to be as
long as in the rust version (<70 chars vs 100 chars). The printf macro (used
only three times) actually makes the C code longer both in bytes and lines (or
equal length in lines if you retain the 70 column limit).

There's really only one macro (DO) that expands enough to save lines, but just
barely. The shorthand for return saves quite a few bytes (but not so many
lines) given that it's used everywhere.

------
klipt
Are there any open source compilers for J (and similar languages)?

~~~
vchak1
I'd also suggest looking at Pike's ivy as a simple example of an apl like
system in go. [https://github.com/robpike/ivy](https://github.com/robpike/ivy)

~~~
moonchild
I would argue that, being stylistically inconsistent with the way most apl is
implemented, that's actually not such a great resource. I found 'whitney c'
surprisingly approachable, with just a little patience; despite no prior
experience with it, I was able to make an apl-ish interpreter in 7kb and a few
hours. If you're curious about implementation details, that might be a more
worthwhile exercise. Be sure to check out the parsing section[1] of the J
dictionary.

1:
[https://www.jsoftware.com/help/dictionary/dicte.htm](https://www.jsoftware.com/help/dictionary/dicte.htm)

------
anthk
gets() wont compile today.

