
Klong: a Simple Array Language - kick
http://t3x.org/klong/
======
nprescott
I read the Klong book [0] and for me it "clicked" in a way that J/K never had.
The author did a really nice job paring down the language and cleaning up some
of the ambiguities in a way that made it approachable. Also, after reading it
I've found APL and J more approachable, which is encouraging.

If you'll forgive the style, I took a swing at implementing k-means clustering
in Klong a few months ago [1]. While I did find a few slow-downs with a
modestly sized data set (Fisher's iris data), I think Klong is built on a
Forth-like VM using the core of a scheme implementation (all of which the
author wrote!). It wasn't slow enough to really bother me, as I was more
interested in learning about array languages and algorithms.

I'm a fan of Klong -- it's just fun.

[0]: [http://www.t3x.org/klong/book.html](http://www.t3x.org/klong/book.html)

[1]: [https://idle.nprescott.com/2019/k-means-clustering-in-
klong....](https://idle.nprescott.com/2019/k-means-clustering-in-klong.html)

------
smabie
I’ve been using Q (built on K) for Advent of Code. It’s an amazing language
that has made me reconsider what a language and programming should be. I come
from a FP background and have always considered abstraction the heart of
powerful and expressive programming.

In Q, abstraction is wholly unnecessary. Libraries are unnecessary. I can fit
the entire language in my head and all code in the language is built out of
the fundamental building blocks of it. There’s no layer after layer of
abstraction, just a small base of operators and functions.

One might be tempted to compare it to other small languages, like Scheme. But
for Scheme it’s intended that you build higher and higher levels of
abstractions. With Q it’s both small and compact, and one rarely if ever feels
the need to actually build a library of utility functions or anything really:
it renders unnecessary the false prophet of code reuse.

I got interested in Q because some of my friends at other financial
institutions were using it for HFT and research on historical tick data. I
found it surprising at the time I that their software stacks could be so
simple, essentially just a single small executable that entirely fit in the
CPU cache that managed both the runtime and their entire database. At the time
I thought this was impossible, but now I realize how possible and eminently
reasonable this was. Instead of Kafka and Redis and SQL Dbs and Kubernetes and
god knows what else, you just have Q. No DevOps bullshit, no containers, no
complex shit to manage.

In the past 3 weeks I’ve had to rethink my philosophy of what software needs
to be and have concluded that most of us are doing things very very wrong:
we’ve created this unnecessary world of complexity that is tantamount to
masturbation.

Now let’s talk about the language itself. It may look complex, but it’s
actually quite simple. The only real data types are lists, dictionaries,
symbols, and numbers. And surprisingly, that’s enough. When programming in it
I have no desire for classes or objects or trees or whatever, in fact, just
using lists and dictionaries can usually solve the problem in a better way.

Also, while Q is interpreted, it’s so goddamn fast. I’ve done some benchmarks
against C and Q is about as fast, sometimes even faster. The optimizations the
interpreter does are just insane. Not even joking, a single line of Q can
accomplish somewhere between 100 to 1000 lines of what the equivalent C code
would look like.

Another plus is that editor tooling is unnecessary, I have no need for
autocomplete or inline docs because I can literally remember the entire thing.
And since Q is so compact, I can view an entire program on a single screen, no
scrolling, no jumping between files.

I’ve also noticed that I can remember the verbatim definition of my code. I
can almost perfectly remember my exact code for each Advent of Code solution.

Anyways, good luck on Klong, I’m going to check it out. I don’t like J and
wish there was a good open source K/Q like language. I don’t actually like K
because the overloads on function arity creates a lot of complexity (Q does
away with this), so Klong might be right up my alley!

For anyone who hasn’t tried an array based language, I highly recommend it. Q
has expanded my mind more than I thought possible at this point in my career.
My last really mind expanded experience in programming was when I picked up
Scheme and Haskell in high school. And now after using Q, those languages
aren’t that great anyways!

~~~
dkersten
> Instead of Kafka and Redis and SQL Dbs and Kubernetes and god knows what
> else, you just have Q. No DevOps bullshit, no containers, no complex shit to
> manage.

What if you need to scale beyond what one machine can handle? Or if you need
redundancy and failover? Transactional guarantees? Or need to talk to external
systems?

Its easy to build a single-executable no-DB no-container no-devops application
in most languages if you don’t care about the finer details of building a high
scale resilient system that can survive a machine going down or has to talk to
third party external systems.

~~~
shrubble
Please examine the specs and likely database performance of a Ryzen or
Threadripper system with 128gb RAM and several NVME ssds.

You can literally run the database for a multimillion dollar company on one
such server.

I don't know what transactional guarantees Q has though.

~~~
dkersten
What about redundancy and failover? Serious question, as I am not familiar
with KDB+/Q

------
chvid
From [https://t3x.org/klong/prime.html](https://t3x.org/klong/prime.html):

{&/x!:\2+!_x^1%2}

This is function that checks if the value given as first parameter x is a
prime by running through the numbers 2 to square root of x and applying the
function x modulus y, then it looks at the minimum of the resulting list and
see if it is 1 or 0. If it is one then x is a prime.

Written in a language with c-style syntax it would be something like:

x -> min((2 .. sqrt(x)).map(y -> x % y)) == 1

Why is Klong simple?

Is it easier to implement, parse and interpretate?

Or is the syntax somehow simpler once you get used to it?

The former maybe; but it doesn't seem to be a part of the language's pitch.

The latter is surely in the eyes of the beholder. I find it counter-intuitive
to have so many single character operators & ! : _ with uncommon meaning and
precedence rules.

~~~
yiyus
This is actually very standard syntax for array languages. Precedence rules
may be uncommon, but extremely simple: right to left, that's all; and finding
the meaning of each symbol just requires checking in a table. In your c-style
example, you are actually using different precedence for each operation (is it
(x -> ...) == 1 or x -> (... == 1)?), you have symbols like the dot which mean
different things depending on context, a function of two arguments like %
works totally different to another one (map), and so on.

The only reason you find the c-style version simpler is because that's what
you are used to. But while you have been able to interpret the Klong
expression with no experience at all, ask yourself if someone familiar with
array languages (and only array languages) would be able to understand the
c-style version in a few minutes without having to read an extensive tutorial.

I do not agree simplicity is in the eyes of the beholder. If a language can be
totally specified by a few paragraphs and a table, it is simpler than a
language that needs a long specification. However, this does not mean the
simpler language is simpler to use. That, indeed, is a subjective matter.

~~~
e12e
> The only reason you find the c-style version simpler is because that's what
> you are used to.

Well, yes. But we're taught infix notation early (x+y), and function
application quite early too (y=f(x) - and in combiation (also note short-hand
eliding multiplication): f(x) = 2x + 1).

I still find array languages to be too dense for me - but I do understand that
they are simple from a certain point of view.

~~~
smabie
I did too, but just try them out for a week, you’ll love it. Moreover array
based language like Q do have infix notation.

f(x)=2x+1

In Q is

f:{1+2*x}

You could call it with: f 5 or f[5]. It’s really not any different.

~~~
e12e
Hm, I could see myself playing with it - but I'm not quite seeing how I'd fit
it into my day job. I do occasionally work with some simple aggregation and
filtering - but usually in an sql db - and barring embedding an array
language, I'd have to fetch all the data into eg: klong first, then process.
It's hard to imagine a scenario where that would make sense.

Otoh, I'm still considering working through advent of code - such domains
should be well suited, I guess.

~~~
smabie
If you're writing business logic, I'm not sure how helpful array-based
languages are. The code would look very similar to a normal language, but
without the classes or methods or objects.

For advent of code, it really shines though. Read in some big chunk of data,
do a bunch of matrix and list operations to get the answer.

------
renox
Is the right to left order common to all array language? It sure doesn't help
onboarding..

~~~
beagle3
It is for APL and derived languages (APL, J, K, A, A+, Klong)

And .. well, if you want C or Java, use C or Java.

Quickly, which is higher precedence, "&" or ">" ? You may have memorized them,
but many people get it wrong often enough. APL has a very simple and
consistent rule: There is no precedence in an expression except paranthese,
and you go right to left.

And it may seem to not help with onboarding if you skim, but if you take the
time it clicks quickly for most people, especially if you consider that "right
to left" is actually "left of right", e.g. (note, a|b is the maximum of a and
b, not the bitwise or)

    
    
        1 + 2 * 3 + 4 | 5
    

is read and understood as:

    
    
        (1 + ...) applied to ((2 * ...) applied to ((3 + ...) applied to (4 | 5)))
    

read another way (note: using python syntax)

    
    
        def f(x): return 1+x
        def g(x): return 2*x
        def h(x): return 3+x
    

It is equivalent to

    
    
        f(g(h(max(4,5)))
    

But one argument K/APL functions need no parentheses, so you would have
written it

    
    
        f g h 4|5
    

But with "f", "g" and "h" inlined you get the original expression back.

It is different - but it is simple and consistent without any arbitrary
precedence and associativity rules.

Also, it's not a new idea; APL predates every other programming language still
in use except, perhaps, Fortran, Lisp and COBOL -- of which only Fortran uses
operator precedence and associativity in the modern C/Algol sense. Lisp is
also consistent (though with a different route than APL took). And I'm afraid
to describe COBOL in fear that cthulu will rise.

------
e12e
Is there something like kdb for klong? How does it preform vis-a-vis the
better known array languages?

~~~
kick
If you need performance, klong probably isn't for you.

------
tluyben2
Besides the discussion about the GDPR which is offtopic (and in my opinion
it's not handy to be openly political if you want uptake of your product as
it's not related to your product but it does taint it (as can be seen here);
maybe in the 'about' or 'privacy' it would fit, but that is a matter of
opinion), great work on Klong and I'll buy your book to read over xmas.

I have been playing (quite a lot; to the extend my wife got me a t-shirt with
some k on it for my birthday :) with Shakti(k7) for a few months now and been
working through the Dyalog tutorials.

Keep up (that part) of the good work!

Edit: bought the book and started reading

~~~
nils-m-holm
Thanks! Enjoy the book!

~~~
tluyben2
Can I mail you feedback if I have any?

~~~
nils-m-holm
I would appreciate it!

------
127
At this point Python/Numpy is really the array processing language I prefer to
use. You can even use libraries like Cupy to switch the backend from
BLAS/LAPACK to Nvidia CUDA libraries, which makes it lightning fast, often
improving performance by 100x. And the requirement for arcane runes in Numpy
is much less than APL or J.

Also the various libraries and functionalities that plug into Numpy is
countless and extremely powerful.

There's also [https://futhark-lang.org/](https://futhark-lang.org/) which
might be an improvement in writing array processing kernels.

~~~
korijn
> arcane runes

What does that mean?

~~~
conover
APL (and I assume J) uses a large range of special graphic symbols as part of
its syntax, which can be difficult to internalize for folks coming from other
languages. It can be easily construed as mysterious or magical lettering
(arcane rune). My favorite video to illustrate this is Conway's Game of Life
written in APL:
[https://www.youtube.com/watch?v=a9xAKttWgP4](https://www.youtube.com/watch?v=a9xAKttWgP4)

~~~
beagle3
J and K stick to Ascii (though recent K seems to accept a unicode "sqrt" sign,
and "pi" character with the expected meaning).

I do find some J choices questionable - e.g. '}' and '{' are used as
individual operators, rather than a parenthetical pair - which confuses
editors without a special J mode, and humans who switch between languages
often - but if you use it enough, it's easy to get used to; Also, K keeps ()
{} and [] as parenthetical pairs, like they are in C/Java/Python etc

------
yellow_postit
Found this disclaimer sad and reminiscent of the endless and useless cookie
prompts in the EU

 _Note: This text used to be interactive, but is no longer, thanks to the
General Data Protection Regulation (GDPR), which makes it virtually impossible
for small, non-commercal sites to "process user data" (like your input)
without contacting a lawyer first._

~~~
skrebbel
You could make a statement like that about any law.

Eg many EU countries also have laws against hate speech, but I saw nobody take
down their hobby hacks because of those.

~~~
nils-m-holm
> You could make a statement like that about any law.

If you can, you should. There are too many totally bogus laws!

