If that's true to an unlimited extent, IOCCC programs should be nearly self-debugging, with how short they are.

This is "they all look the same to me" prejudice. IOCCC code relies on abusing undefined behaviour and clever tricks and edge cases, terse code like the OP link and the array languages relies on composing high level abstractions and using them over and over in learnable patterns. That aside, IOCCC programs wouldn't be "self-debugging" with this argument, they would "have fewer bugs". It shouldn't be too hard to accept that a given program written in 5k lines, 50k lines, and 500k lines would take different amounts of debugging effort. Whether it's a significant enough trade off of harder-to-code vs saves-much-debugging is a better question.

Throwing code away doesn't hurt my feelings.

And your feelings are the only potential cost involved in rewriting code, there's no time involved?

I can't rewrite what I can't read.

Of course you can? This is so common it's a programming trope "this is garbage code, nobody can tell what it's doing, let's rewrite it". Although I'm not sure that arugment works in my favour - Netscape's rewrite of Navigator which dragged on for years; was that because they /couldn't/ read the code to rewrite it, or because they couldn't rewrite it better while being bug-for-bug compatible?[1] Even then, writing one function and thinking "I could do this better" and rewriting it, then thinking "I could do this better" and rewriting it, is a cycle which gets much worse the longer the code is to rewrite.

Writing documentation based on LoC count is deranged.

But also necessary, unless you either a) admit that the extra LoC isn't saying anything important (so you have a poorly expressive language which forces you to write lots of boilerplate that isn't worth talking about) or b) you want to leave more of the code undocumented.

Lisp macros allow me to zoom out like that by letting me factor out common patterns more easily

"My way of writing dense composable code which outsiders hate and consider unreadable is great tho!", lol. LISP goes towards climbing an abstraction tower of code-which-writes-code, to get more done with less code, rather than simply /writing less code/. But this way, at least you agree that "less code is better" by factoring out common patterns? So why don't we push for common patterns which are shorter and achieve more, in normal languages (like we changed for loops to map in popular languages, eventually).

But, and here's the big sticking point for me, I can do all that without variable names which look like line noise.

Exactly what variable names do you think would make the code in the OP link "readable"?

Great. That doesn't preclude meaningful variable names.

It rather does; it's possible to give functions names, but when you have small functions and compose them together, it quickly gets to the stage where there's no meaningful English name to give them which helps clarify what's happening. In an APL example:

⊂ ⍝ left shoe encloses (nests) an array into a scalar

, ⍝ ravel unravels an array into a vector

⊃ ⍝ right shoe (NARS2000 APL) discloses a nested vector into a matrix

The pattern

⊃,⊂ 1 2 3

is common, it turns a 1D vector of 1 2 3 into a 2D matrix where the first row is 1 2 3. What would you name the pattern ⊃,⊂ that clarifies what it does and doesn't get in the way?

Once you've decided on that name, what do you name the data which goes into it and comes out of it, in a way that usefully explains what state it's in, without getting in the way? "matrix_of_grade_indices_into_data_array"? But you can see that from the way it's ⊃,⊂⍋data those words are what that combination of symbols says, only more precisely.

By the time you've written and read all those English words, you've hidden what the code does and covered it over with much less precise verbiage. The pattern is common because you can do different things to a 2D matrix than to a 1D vector, and the pattern is so short that you can inline it when you need it:

2⌿ 1 2 3
2⌿ ⊃,⊂ 1 2 3

these are different, writing it out in terms of

(first_axis_replicate
2
(disclose (ravel (enclose '(1 2 3))))))

isn't clearer it simply expresses the same thing in more code, and

nested_demo_nums_scalar = enclose(1 2 3)
ravelled_demo_nums_vector = ravel(nested_demo_nums_scalar)
demo_num_matrix = disclose(ravelled_demo_nums_vector)
result_demo_num_dupes = first_axis_replicate(2, demo_num_matrix)

isn't clearer either. And you can say I'm making up stupid variable names to obscure it, but what variable names wouldn't obscure it? How doesn't this terse style lead away from "English word variable names"?

The C style code which I can't read, I am strongly suspecting that what it does is this kind of code-block combining, not IOCCC style compiler abuse, and in that case it won't help anyone with the skill to work on it, to rename "x" to "pointer_to_first_function_argument_in_backwards_compatible_adjusted_scope", because at the point where such a person understands the code, they can see that's what "x" is, because that's what "x" always is and besides there's only a page of code to see it in, in the same way that a loop index variable is easily read without needing a long name in "for (int i = 0" code.

[1] https://www.joelonsoftware.com/2000/04/06/things-you-should-...