Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Reading awc (akamayu-ouo.srht.site)
60 points by secwang on June 6, 2024 | hide | past | favorite | 20 comments


While APL-styled C may be one extreme, I've noticed that average code has taken an uncomfortable shift in the other direction especially within the past decade, and I find it irritating to work with a lot of the "modern" stuff as it's far too verbose and needlessly indirect. I suspect the rise of strongly lowest-common-denominator lame coding standards and the desire by corporations to make programmers easily replaceable dunces is to blame for that insipidness.

(Aside: odd domain names like the one in this article I normally ignore in search results since they're usually full of SEO'd spam, but if one makes it to HN it's usually worth a look.)


Srht (Sourcehut) is a github-like service well-covered by HN.


Reading code like this makes me better understand how the Shin Megami Tensei authors came up with the idea that a computer could channel demons.


I though that having undefined behavior in a programming language would be sufficient for that.


I made some ~25 changes to the code[0], to show how some making some pretty minor changes can really improve readability, while still staying extremely tight. I don't need everything spelled out for me, and in fact I prefer a horizontal style--I hate scrolling too. But Arthur Whitney's code is deliberately obfuscating and IMO it tarnishes the positive aspects of the style.

[0] https://github.com/saulpw/ksimple/commits/main/a.c


I find both your version and the original you forked from to be nigh unreadable. Do y'all have broken spacebars or something? Are you writing to 720k floppy disks and don't want to "waste" space on identifiers longer than a few characters?

Unfortunately I can't RTFA, as the site appears to be down.


Here's an attempt to make the code in the first link [1] slightly more readable by replacing the most frequently occurring identifiers with visually distinctive Unicode characters :)

https://i.imgur.com/F27ZNfk.png

At least it's now much easier to spot multiple occurrences of the same identifier. All these unicode characters are still valid in C identifiers, by the way.[2]

[1] https://www.jsoftware.com/ioj/iojATW.htm

[2] I say 'still' because C23 is set to follow C++ and take them all away by restricting identifiers to XID_Start/XID_Continue. I find the whole XID_Start/XID_Continue idea unmotivated, both philosophically speaking and from a practical point of view, but what can I do. I just hope languages like Julia, Swift, Racket, and Clojure don't follow this trend anytime soon...


While the code may be elegant like the author suggests - I have never understood the coding style of not using descriptive variable and function names?

Is there any benefit that can't be gained from using a minifier or transpiler?


There's this general idea that I've found quite illuminating, where physical code size in itself can cross a certain limit and suddenly take more time to read.

Something like (+ 5 (* 3 2)) is, IMO, an easier think to parse than add(5, multiply(3, 2)). 5 + (3 * 2) obviously wins some points from being what we get taught for a decade.

So if you have these sorts of idioms that are meant to be within other idioms, stuffing them all in one line means there's less place for issues to hide, without paying size costs.

The real thing of course, is less the above example and more things like:

results = [2 * x for x in data]

turning into:

results = [] for x in data: results.append(2 * x)

Where in one version I immediately pattern match on a comprehension, so I can immediately determine cardinality and other properties, where the other one I gotta do a _touch_ more work mentally. This feels like it doesn't matter, but it all adds up!

Terseness is a quality, especially if everyone messing with the code speaks the same vocabulary.


> 5 + (3 * 2) obviously wins some points from being what we get taught for a decade

It also has the benefit of having an obvious starting point: on the left, and moving to the right compared to "on the right but inside all of the parentheses, but don't ignore them because they're needed!" Where it fails is the implicit assumption of operator precedence, which breaks the "left to right model". If anything though, I'd argue that eliminating precedence rules and requiring parentheses for anything other than strict left-to-right order would be _more_ intuitive, and the fact that we were all taught about the "order of operations" is the only reason it isn't obvious that it's probably not better for anything other than writing polynomial expressions, which is not something that most people will ever do outside of the specific educational context where we're taught the precedence rules in the first place.


Of course that would also just be written as results = 2*results in array languages


Or indeed just results*:2


I had the same question as the person you replied to, and these excellent examples really made it click for me. Especially the second one. Thanks for sharing.


If you nest a pair of "for" loops in a C program and use "i" and "j" as the loop counters, few reviewers would bat an eye. In this context, used consistently, the single letter carries semantic meaning.

In K, lambdas use the variable names "x", "y", and "z" for arguments by default. If you see an "x", it is the function's first argument. If you see a "y" but no "z" in a short definition, you know it's a dyadic (arity 2) function. Removing unnecessary degrees of freedom in this manner (among other conventions and stylistic choices) makes it much more likely that two K programmers will arrive at character-for-character identical solutions to problems. The uniformity and consistency makes idioms and repetition stand out.

Arthur-style C is built on the same basic concept: remove unnecessary degrees of freedom, focus on internal consistency. A very short name can still be descriptive if it is always used to mean the same thing.


Sometimes, particularly in mathematical code, I want the focus to be more on the operators than the variables. I see this style all over the place on Shadertoy.

    # hyperbolic and contrived example in fake c
    for (int i = 0; i < len(a) - 1; i++) {
        s += a[i] ^ 2 + a[i+1] ^ 2;
    }
    # vs
    for (int index = 0; index < len(array) - 1; index++) {
        sum += array[index] ^ 2 + array[index + 1] ^ 2;
    }
Arthur's style takes this way past my comfort levels, and it make sense he'd prefer array languages! Check out his Game of Life implementation:

    a:{3=s-x&4=s:2(+-1+/':)/x}
https://web.archive.org/web/20220926225051/https://kparc.com...


It's worth keeping in mind that most production k code tends to be short, like even just a few dozen lines. It's not an application programming language and you are typically not modelling business rules. Most of the code is math-adjacent, and there may not even be any clear descriptive name for the variables involved.

The point is basically to put more code on the screen, so that you can think about what the code itself does, and basically maximize expressivity.

I do personally think Arthur is taking it a bit far, and it's turned into code colf for the sake of it, but at the same time, I don't think the idea is entirely without merit, at least in some circumstances.


Not defending it, but I imagine they find it more readable.

Like how you might find f(x)=2x+1 easier to read than double_and_increment(some_number) = 2 * some_number + 1.


This is a kind of "false dichotomy". Not using single-letter variable name doesn't ncessarily mean using long verbose variable name. A variable name can be one word or two words that explains well while not using much space. Things usually need balance instead of extreme.


energy = mass * light_speed ^ 2

Yes, it makes it much simpler!


Is there a way to read this style of C, without prior knowledge of APL, J, or K? Can people with prior knowledge read this more easily? I'm asking this because this is the first time I took the time to read that `j.c` and it wasn't really any more readable than normal C code. I was expecting to "read the C source in chunks" but that didn't really happen.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: