K/simple: a tiny K interpreter for educational purposes by Arthur Whitney
github.com
github.com
https://www.jsoftware.com/ioj/iojATW.htm
(Discussed previously: https://news.ycombinator.com/item?id=25902615 )
There's something very satisfying about how this style seems to "climb the abstraction ladder" very quickly, but all of those abstractions he creates are not wasted and immediately put to use. I think much of the amazement and beauty is that there isn't much code at all, and yet it does so much. It's the complete opposite of the bloated, lazy, lowest-common-denominator trend that's been spreading in many other languages's communities.
it is by arthur whitney.
anything else?
no, that'd be fabrice bellard, who is actually a "realized" ioccc champ.
atw doesn't do obfuscated c. you are led astray.
He writes as most of us code-golf. Makes you wonder how good his golfing would be if he tries.
shakti.com has a suspiciously familiar looking snippet of javascript
was it him?
Did anything ever come of kOS?
https://gist.github.com/chrispsn/da00835bb122c42f429a084df83...
The kparc.com links are down though.
As far as I can tell they are best for data analysis but not for heavy numerical computation because most or all of them lack GPU support. is that right or have I got it wrong?
Are there any other use cases?
regarding use cases, see https://kx.com/resources/use-cases/
q is good with bulk operations on compact arrays; these are cache-friendly and the interpreter can utilize cache-level parallelism. and with q it's convenient to go from idea -> MVP in short time. it's a high-level language with functional features so expressing algos and complex logic is natural.
but it's interpreted and optimized for array ops. so really latency-critical (e.g. high-freq trading) or highly scalar logic will be done with C++. the trade-off is convenience of development.
There are a few intersecting truisms about coding that I believe: one is that people's working memory varies: some have an immense amount, some less. Humans definitely process spatially better than in time series (e.g. comparing side by side rather than turning over a page.)
This implies you should prefer succinct code and languages because they are less memory load for engineers working on them.
At the same time, a corollary is that a smaller standard library / language is generally better, in that less needs to be learned by an engineer for full coverage of the language.
Another truism is that some people's processing speed is higher than others, and in general I think of the combination of working memory + speed as roughly equivalent to "g", general intelligence.
K occupies this weirdo place though, because it's absolutely succinct, a very small language as counted by number of atoms supported by the interpreter, and also incredibly hard to scan.
One of the K intros I read mentioned that the language is designed to be something that takes down your thinking; essentially the idea is that the workflow is "drink coffee with fellow PhDs, annotate on the chalkboard, and then when ready, capture it directly." This seems about right to me with my own K/J/Q experiences -- the bulk of the time is spent thinking about structuring a problem solution.
I compare this to go, a language I love for its long-term readability and maintainability, where I spend a lot of time writing boilerplate and dealing with errors in-situ.
At any rate, somehow there's a sort of event horizon of terse solution making where you come out the other side and need a 170 IQ to feel comfortable, and Mr. Whitney lives where he lives, and I live where I live. :)
People complaining about how ugly the C code is here are definitely missing the point: he has bent C's preprocessor to his will in order to encapsulate how he thinks about coding: essentially functional, vectorized. It's using C to write a DSL for solving programming problems interesting to Arthur Whitney.
I think it's fascinating on those terms. In a world where you have to read 10,000 lines of code from 100 developers, the C is terrible, and hard to parse. In a world where you will mostly write code to a style you've honed over 40+ years, it's super expressive, minimal, pared down to what matters, and probably fits his brain perfectly.
I read that code like he got the expressivity benefits of a lisp macro system with close-to-the-metal C speeds in like 100 lines of code. I'm curious what else could do this.
you want a stack trace? tough luck, you'll get back:
`type
and that's it
at some point we might upgrade to java 8!
Non-titanic engineers accidentally generate bugs in these languages with high "floor" IQ requirements, and debugging someone else's K code is terrible. Debugging your own K code is terrible, not less because when you get help you will feel very, very stupid indeed :)
In your opinion, what would be a language that comes closer to K’s functionality but at the same time be understandable to mere mortals?
k and uiua are in different branches of the APL family.
It's not as powerful or concise as K, but it gives you some of the flavor of an array language tucked inside what resembles an ordinary imperative/functional scripting language.
Also, I am constantly amazed at how concise K is, easily rivaling not only conventional languages but also much larger array languages like APL or J. Arthur Whitney's taste in selecting primitives is out of this world.
This is super accurate, and interesting in the context of the repo. It’s clearly not the most accessible language or style - I wonder if someone who has hyper optimized for themselves in the way Arthur has can write an effective teaching language. It requires a theory of mind for minds that are probably quite different in the general case.
I'm not convinced that APL is "incredibly hard to scan" for someone who is familiar with it; it's just a matter of experience. While I'm by no means experienced in APL either, a visually similar thing I did frequently in my younger days was reading x86 instructions not in a disassembler nor hexdump, but displayed as CP437. It was not hard, and I can still remember ┤, PQRS, ═!, and ├ as "MOV AH", "PUSH AX; PUSH CX; PUSH DX; PUSH BX", "INT 21", and "RET" respectively. Here's an example:
ò║•═!├Hello world!$
Edit: looks like HN swallowed a byte, but you can sort of see what I mean.@& (filtering)
@< or @> (sorting)
@\: (folding)
,/ (flattening)
+\ (a running total)
etc.
It's also easy to notice, e.g. in K3, a reserved name like "_f" and immediately know you're looking at a recursive procedure.
Would you rather write/read:
DIVIDE X BY 5 GIVING Y
or
y=x/5; / this would be considered "noisy" by C programmers, relative to COBOL
The first is COBOL (designed to make code easier for "normal" people to read. The second is C/Java/Python/Javascript (which looks more like the math that we learn in grade school).
k/APL/J simple moves further in the direction of the algebraic notation you already know. The difference is more operations/algorithms.
When you read the one-character symbols in K as algorithms versus characters, it makes much more sense. In addition, you can read "faster" in k than in other languages, relative to the functionality being expressed.
When I review C/Java/C++, I print out the source code and write the equivalent k code in the margin. The compression ration is typically 10-20X. Doing so speeds up my work significantly when I go back over the reviewed code.
It's been years since Arthur started this other k-variant.
The feature split on the free / enterprise edition holds a lot back; my vibe on the free version was it was just enough to validate that shakti is performant, and then they want you to pay.
Additional examples at
https://github.com/louyx/aplus/blob/master/src/a/k.h
https://code.jsoftware.com/wiki/Essays/Incunabulum
How would you characterize that?
Heavy use of the C preprocessor and C defaults to embed a functional programming language. Language with a small number of core functions and ability to apply functions to lists of atoms. Aesthetically favoring short identifiers and minimal whitespace to create high semantic density. Eschew comments.
k always seemed like a bunch of those kids managed to become highly accomplished and brilliant engineers without ever breaking that terrible habit. Is there actually a reason to write these array languages (and interpreters for them, apparently) this way, or is it just a cultural difference?
They're more readable and less buggy that way. But unfortunately most programmers would rather spend 10 days reading 100,000 lines than 4 days reading 1,000 lines.
AW is known for kdb+ which is often used in finance due to its extreme performance properties and ability for quants to quickly explore ideas.
Personally, to get a better handle on how array languages worked, I implemented KlongPy which is a python implementation of Klong, which descends from K (which AW wrote).
You have to play with this stuff to understand it intuitively.
What it's really great for is that it's really neatly integrated into the q language, which is great for exploratory programming, and it's fast enough not to get in the way.
I'm not sure what an I$ issue is - any chance of a bit more explanation?
(also I'd love to hear about the tradeoff part in more detail but that's a bigger ask)
But seriously, if you haven’t given it a try you should. You won’t be disappointed.
I read that they are (K in particular) used in finance...would you reckon it would be easier to find job in that field having that in the CV? I know I cannot compete on the C++/Python side but maybe as a skilled K developer I could sneak in