Is there any benefit that can't be gained from using a minifier or transpiler?
Is there any benefit that can't be gained from using a minifier or transpiler?
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.
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.
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.
# 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...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.
Like how you might find f(x)=2x+1 easier to read than double_and_increment(some_number) = 2 * some_number + 1.
Yes, it makes it much simpler!