60 comments

[ 8.3 ms ] story [ 123 ms ] thread
You can pry C from my cold, dead hands.
No one's asking you to get rid of C; Arthur (the guy who wrote this article) actually wrote his own C compiler a few years ago!

Ever-elegant, it does away with precedence, which makes for much prettier code.

http://www.kparc.com/b/

Holy shit, this is the craziest C code I've ever seen!
Is it? I find it quite beautiful. Have you read the ngn/k source?
I'm not a fan of it. It looks like minified code. Every variable 1 or 2 letters, very long lines with everything jammed together as much as possible.

I would rather have more descriptive and memorable names, and whitespace that aids in understanding the program structure.

Short variable names are features, long lines are good (more horizontal pixels than vertical pixels on modern monitors so you keep it all on one screen). Brief and small. Hard to find another C compiler that you can fit in your head, especially one faster/better at generating binaries than LLVM/GCC.
Well, it's not real C, and simplifying a language makes things a lot more easier than having to stick to a lengthy, detailed standard. Not that the compiler ever argues that it does something different than that, it's named "B" after all (never mind the name clash with the original lobotomized BCPL)

Some simple Algol-/Pascal-ish compilers used for instruction aren't that much more complicated. Sure, they don't fit in that many lines, but if you consider tokens on a x/y axis, it's not that different. Wirth's Oberon-7 would be a good example for something not toy-like.

I do appreciated the terseness, though. APL/K often operate in a specific domain and/or are used interactively, where this is of a big benefit.

It does make me wonder how lengthy interleaved string messages would interfere with this. Would a terse language suffer more from the "context switch" between short identifiers and long strings than one where functionsAreWrittenLikeThis in the first place? Probably calls for more variables, otherwise the actual parts of the code are spread too far apart.

I've been seeing K mentioned a lot around here recently. Fostering interest in any array language is a good thing imo, but I'm curious about what draws people to K over J in particular. They're both ASCII based with APL heritage, but afaik J is free software and K isn't.
Performance, KDB+, simplicity.

I've heard it said that J is for people with brains too big for K. J can be difficult with its hooks, forks, trains, and other complex function application constructs.

Job prospects too. K is heavily used in the financial sector (even YC has postings for K jobs in its monthly listings) and pays extremely well for what is basically a database developer.

Thanks for the info. I think J's implicit combinators have made me a better tacit programmer, but over reliance on them can make things frustratingly ambiguous.

The monadic/dyadic overloading in all these langs doesn't always help either. I recall somebody here recently writing a K implementation where there was explicit syntax for the uh... adicity(?) of operators, but I forgot to bookmark it. Anybody know what I'm talking about?

k (well, some version of it) has something along those lines:

> [the] `:` in `|:` is used to force the verb `|` to be interpreted as a monad, as by default ambiguities are resolved in favour of dyads.

http://www.math.bas.bg/bantchev/place/k.html

> adicity(?) of operators

You will often hear it referred to as the valence of the operator or function from APL people (don't forget niladic too).

Other CS people will call it the arity.

https://t3x.org/klong/

> Klong is an array language, like K, but without the ambiguity. If you know K or APL, you may be disappointed by Klong. If you don't know any array languages, it might explode your brain. Use at your own risk!

?

To expand on this a little:

J was what Iverson did after APL. ('arcfide has called it a "stopgap," but I don't think that's right: it does a lot of things better than even Dyalog does.) In that way, it's a bit more pure of an experience [compared to Dyalog APL], and in a way brings the notation a lot further, as long as you can ignore the ASCIIfication of it.

k was made explicitly as a stripped-down version of (primitive-)APL. This has many trade-offs. It does make performance optimizations a lot easier (which is partially why practically every non-toy k implementation is faster than Dyalog, which is fast in its own right, even if J is usually faster). It's also mildly easier to keep in one's head in most cases.

It's a lot more mainstream in comparison to J, both because of the performance optimizations and because it's a lot less of a leap from Lisp to k than it is from Lisp to J. If I remember correctly, Arthur is a bit more of a normal person on this: he prefers/preferred writing Lisp to APL, and k is definitely a lot easier to compare to conventional languages than J or APL.

J was designed as a way to spread notation to the masses, k was designed as a way to get incredibly small amounts of code to do very big things. Both are good at both, I think, though to varying degrees.

k, though, appeals to a core aspect of the programmer by design: small. And it's small in a way that can't be called code golfing, either, which is like cocaine to your average programmer. It's primitive, very shiny, and its bite-sizedness appeals to your average cascade of attention-deficit (mostly grown-up now) teenagers that make up these sort of spaces. It's basically bait, and in a really good way.

Another reason is because J doesn't have all of the cool little snippets that k people love posting; there's no "ray-tracer in 7 lines of J" text dump despite something similar being possible, just because of the community that's formed around k. In k you have a bunch of people like Stevan Apter who just live for cool programming languages. They devour that stuff and try and make the coolest things they can to show everyone.

The ray tracer in 7 lines of k:

http://nsl.com/k/ray/ray.k

The whole site http://nsl.com have some amazing code samples.

nsl stands for No Stinkin Loops - a reference to apl/k's implicit looping constructs.

(I miss using K)

That's not Arthur's version, which is also really cool! nsl.com/k/ray/raya.k
Thanks for this comment kick.

I wish I had a contextualized summary like this a few months ago when I first started to look into APL/j/k/q. Had a similar feeling when I first looked into Lisp and stumbled through the overwhelming amount of implementations and nuggets of information spread around the web & mailing list archives. Comments like yours really help (kinda like when you're lost in an RPG and after wandering around for a while & feeling lost you bump into this NPC who has the information you need to get further).

bookmarked

Always happy to talk about this stuff!

Have you read any of the essays/papers/anecdotes on jsoftware.com yet? They expand a lot on the history of APL, and it's pretty fascinating.

A fun quote that highlights how many years ahead APL and the companies built around APL were/are even decades later:

Working at IPSA, with its far-flung offices and its Mailbox, it was possible to “know” a person for years without ever meeting the person. Well into my IPSA career, I asked Lib Gibson, “Is Leslie Goldsmith a guy or a girl?”

https://www.jsoftware.com/papers/APLQA.htm

(IPSA was I.P. Sharp Associates, which long before that ran a huge amount of the APL in the world, remotely. Kind of like a primitive cloud, though then called time-sharing.)

I've noticed the term "low code" being mentioned more often lately, but never in relation to array programming languages. In my opinion languages like k, q, apl and j are the most flexible and expressive low code programming platforms on the market.
> K stands for “keys to the kingdom”.

Lol. It's actually just the letter after J, since K was supposed to be the next in the APL-ish family.

Arthur wrote the article :)
Ha, I didn't notice that. But I've heard it before on the K list. I think it is more of a backronym than a serious statement. This is a guy who names his source files a.c, b.c, c.c, ..., z.c.

I'm unsure why Ken Iverson named the J language that though.

Probably because A through I were already taken.
Interested to see what happens with Shakti, the newer iteration of Kdb
I wish their site said more.
Are you on the mailing list? It's a bit slow, but seriously cool to see random people bring up strange bugs and Arthur going "thanks! fixed in the next release." over and over again like clockwork.
No, but I might add myself.

Speaking of fast bug fixes. 8th is a commercial Forth-like language for embedded, desktop, server, and iOS/Android that is kind of like that. It is basically a small (few MB) binary that is a full REPL that can cross-compile your code into an encrypted binary. It has nice GUI, SQL, Rest, REPL,JSON/CSV/XML...etc support all built-in as well as a bunch of other goodies. Releases happen very regularly and reported bugs are fixed incredibly fast. There is a forum with a lot of activity from the fairly small user base. Probably not everyone's cup of tea, but I've had a blast playing with the free version. The professional version is like $250 and after your free upgrades wear out you can then upgrade for a reduced cost. Full source is also available in the Enterprise edition with an NDA. In some ways it has some similarities with K.

Long story short to see hundreds of posts requesting some obscure feature of edge condition and seeing a reply a few hours later with "fixed". It seems to be a pretty mature language for one person to build. I have not bought a professional edition yet as I'm having fun with the free one and this is probably not something big corporate IT would like. If I start building enough tools at home, I might go in that direction. Also, no affiliation with the project, they just seem to get a lot of my wish list right. I really wish it was a free/open source project as I bet it would catch on more.

Yeah, I've heard of 8th! Absolutely sucks that it's proprietary, it's seriously cool. It's one of my favorite examples of how single-man dev "teams" are the most efficient.
Yeah, you get some advantages with a large language, but there is no coherant harmonizing force even with a BDFL like in Perl and Python.

Arthur's work is seriously impressive and something to motivate me to write my own tools.

I work in the financial industry and code in K3 (among a number of other languages).

Things I like: highly orthogonal & minimalistic design (basically vectors and functions acting on vectors), easy C FFI, well documented, satisfying to minify production code, my inflated salary (+job security for some).

Things I dislike: proprietary, impossible to skim, APL/J/K "culture", over-marketed, functions/operators overloaded in very unintuitive ways, lack of lexical scoping, interpreted languages falling out of vogue.

Overall, I recommend every coder to try K (or J or APL) at least once. They compare favorably to NumPy/R in many respects.

> interpreted languages falling out of vogue

This would be for performance issue though. And K, even when interpreted, is still faster than most people's C code because the interpreter does very little and most of the time is spent in optimized loops.

Also, I heard rumors of a JIT (I've seen some of his compilation code and it is pretty amazing and small and even include SSE/AVX optimizations).

> include SSE/AVX optimizations

I would expect K in particular to benefit immensely from SIMD instructions, yes?

I think they were added about 5 years ago?
APL/J/K "culture"

What exactly is it about the "culture" which you dislike?

high brow. some people find it annoying:)
I used APL professionally for ten years. The only high-brow APL’ers I ever came across did almost nothing outside of APL.

I love the language but it is, in my opinion, not much more than an academically interesting paradigm now. I agree that every programmer should have non-trivial exposure to these ideas (also Forth and Assembly). And then they should move on.

The language stopped evolving some 20 to 30 years ago. Frankly, I am perplexed as to why it pops-up on HN so much.

The language is more relevant than ever, especially with things like the D programming language (not 'WalterBright's thing, John Scholes's thing). Have you seen co-dfns?
Co-dfns is interesting because I think it is the first compiler that has ever been written in a fully data-parallel style. But why does that make APL as a language particularly relevant, except that it was the implementation language?
I hesitate to answer this because I feel like 'arcfide's explained this much better than I can in one of his talks so maybe he'll see this and can point you to it, but if there's no response by the time I wake up tomorrow I'll give a detailed explanation on my views on this.
I'd love to hear your views, regardless of whether you can find arcfide's.
What's the typical background of professional array lang programmers? Are they recruited from a community of enthusiasts who are already familiar with the language, or are they trained up from a pool of clever people already working in the industry?

I don't think I've ever seen a J/K/APL job posting, but something tells me that maybe I'm not meant to see one.

Both; array languages are really easy to learn when you have someone teaching you, so you can train newbies in a couple of weeks. I think 'RodgerTheGreat has a few anecdotes you can find using HN search on that.

But it definitely helps to know it beforehand. APL/J/K job postings are pretty common, although less common than C or Rust postings. Just keep an eye out and you'll see one eventually (and if you do your stuff in public, you'll probably get an offer from one of the usual suspects).

Exactly how inflated of a salary are we talking about?
There was a comment about Q / kdb+ some years ago including the language "if you enjoy making furniture out of stacks of cash".
k3; 1010data? If so, I'm really curious: has the k3 fork you guys have bifurcated far enough that it no longer resembles k3? It makes me really curious, because substantially modified k doesn't really seem like k much at all anymore.

Things I dislike: [...] APL/J/K "culture",

Ow. It cuts like a knife. Right in the heart! Is it the silly jokes? The bad memes in almost every presentation? That we think our approach is better than everyone else's because it produces better code, faster? That we like math?

In what ways is the code better?
Imagine that you could write something that executed 10x faster, that required half the effort it'd take for you to write something in whatever language you're using right now, that you could reasonably be sure was bug-free, and that would reduce the complexity of your program by an order of magnitude.

None of that is exaggerated; I think most of the comparisons usually have a far higher disparity between Iverson's family of languages and everything else.

There are a few very plausible/simple/not at all "out there" reasons for all of this that I'll explain if you want.

1010er here. I don't think Arthur would have trusted us with a fork if that was even a remote possibility. I find it true to the design and aesthetic of k3--you'd never notice if you didn't use the new features and they seem quite natural.
Thank you so much for answering! That's fascinating! I hope that at some point someone expands on what features have been added.
We used K/KDB at my first job out of college. One one hand, it was fast and terse.

The downside was that the code was nearly impossible to read by anyone but the original author, and for some reason they encouraged one-letter variables. This actually propagated to the rest of the code base (com.a.x).

Single letter variables are actually a feature, not a bug. (I think you'll be able to find some passionate defenses of it if you use HN search, better than I can do certainly.)
> v: 3 4 /a vector, i.e. a list of 2 atoms.

> v+'v /v plus EACH v, i.e. (3+3;4+4).

> 6 8

How is for EACH working here? Adding v (a 2-vector) to each element gives a 2-vector, so why isn't the result a 2-vector of 2-vectors?

It applies element-wise across both arrays. What you're describing is more like an each-right (+/:) or each-left (+\:).

    2019-09-25 14:44:44 2core 3gb avx2 © shakti l test
     v:3 4
     v+v
    6 8
     v+'v
    6 8
     +'[v;v]
    6 8
     v+/:v
    6 7
    7 8
    
     +/:[v;v]
    6 7
    7 8
Indeed, that was my confusion, thanks!