Hacker News new | ask | show | jobs
by razetime 1492 days ago
I hope you have taken some time to understand K's philosophy and goals before making this comment. A tutorial exists here: https://github.com/razetime/ngn-k-tutorial if you'd like to understand why this solution is good.
1 comments

It was just an honest question. I've just peeked at APL, J and K due to posts here on HN, and the sample code I've seen mostly reads as noise to me, so I was just curious if there were any array languages that would be approachable to me.

The tutorial does help a fair bit, though glossing through it, it doesn't really explain why it has to be so exceptionally terse.

I mean the matmul[1] sure is impressively short in the end, and with a background in computer graphics and simulations I can absolutely appreciate working on arrays rather than singular values. But I'm sure one could get the same computational result with a bit more approachable syntax.

[1]: https://github.com/razetime/ngn-k-tutorial/blob/main/c-think...

> the sample code I've seen mostly reads as noise to me ... But I'm sure one could get the same computational result with a bit more approachable syntax.

Chinese looks very strange to lots of people, but I think you should expect to get a strange look if you were to suggest Chinese reads like noise to you and then suggested, gee, you know, if they just used latin letters for everything, you would still "get the same computational result"

Where was I saying the Chinese should use latin letters?

And the fact that you can go on Google Translate and go from Chinese to English does indeed suggest you can generally get the same computational result from either language. Sure some things expresses better or more naturally in one or the other, that's to be expected.

> Where was I saying the [array languages] should use [more accessible symbols]?

I know you do not see these the same, but maybe that will help?

> you can go on Google Translate and go from Chinese to English

Yes yes. You can use arrays with python. Whoopdy-do. But you're mistaken if you think you understand what "叶公好龙" means just because you put it into Google Translate; This is Darmok and Jalad at Tanagra. You have no hope when you're decoding every character and translating it into "accessible symbols" you know, and even if you can put up with it and puzzle it out with a little extra googling, you already know you don't like to do that, so why are you doing it?

I'm telling you to put up with what you're calling "noise" and learn it anyway. Don't skim it and try to "pick it up as you go" like you've undoubtedly tried and been somewhat successful at in other languages. It won't work. You will have to change. Then at some point, you won't be decoding or deciphering or "working it out" anymore, you'll just be reading. It will be much easier to talk about the benefits/weaknesses of k's choice of symbols at that point.

If you want some ideas about how to go about learning this stuff, I'm happy to give some pointers if I know a little better about what you already know and where you're at.

Translating a K expression into something much more readable won't likely help you as the language is extremely compact. So for example, translating "ab",/:\:"cd" to ((each-left (each-right concatenate)) "ab" "cd") will still be inscrutable to you. But you can experiment with k, one expression at a time, play with its builtin operators and incrementally build up knowledge. Long before you get really proficient in it, you will start appreciating its compact syntax.

Without trying you wouldn't know if you are going to love it or hate it. But at the same time, there are far too many interesting things to learn so one has to pick and choose. Ignore what the cool kids of the day are doing or the latest fads. Just do what furthers your personal goals!

Well, yes, there's other languages like Julia, MATLAB and such if you want familiar, approachable syntax for array programming. Nial (https://nial-array-language.org/), which is inspired by APL, mostly uses words instead of symbols, which you may find more intuitive.

In K, terseness is part of the package, and it is considered good, because you can see the innards of your code at a glance, there's lesser text to change if you mess up, so on, so forth. Some time investment in the language may or may not help with this.

Or, or, and here me out here, you could learn the syntax in order to make a more informed assessment.

Do also seek out geocar’s posts. They are well written and to my mind convincing. https://news.ycombinator.com/item?id=27393682

> you could learn the syntax in order to make a more informed assessment

I'm fairly sure my assessment wouldn't change even if I did learn the syntax. It would still read like noise. The only difference would be that I could understand the noise.

I've read and worked on enough super-terse code in other languages to feel confident in that.

> Do also seek out geocar’s posts. They are well written and to my mind convincing.

I guess it comes down to how ones brain is wired then. For example, I have the exact opposite reaction to multiple pages of code vs terse one-liners compared to geocar[1]. I don't have trouble remembering what range() does because it says so right on the tin, unlike for example + in k (addition or, surprise, transpose).

[1]: https://news.ycombinator.com/item?id=27223086

> I guess it comes down to how ones brain is wired then.

Your brain is not wired. You can learn new things, including this.

> I've read and worked on enough super-terse code in other languages to feel confident in that.

To know you will fail before you try? What a great time-saver that must be. I simply would never believe it.

Listen, I don't think most k code is "super-terse" -- for sure, it is fun to play golf with k and think about ways to make it shorter, but you can do that in any language. That's not what's going on here.

Allow me to explain: I learned k because I saw someone do something with k I did not know how to do with C. That was it. That convinced me that there was value here, and so I learned k.

And then something magical happened: When I went back and read C, I was reading that faster. Not quite as fast as k, but substantially faster than I was reading C before.

That was so surprising and unexpected to me. I think I expected that if I took a break from C I would get rustier at C, not better. And so I talked to a few people about it, and convinced them to learn k, and you know what was really amazing? It made them better programmers too!

So I hear that you can't now, and that's okay, but I think it's worth learning. I don't know if everyone learns differently, but most everyone (myself included) struggles and struggles and struggles until one day, they just get it. And it's hard to know how far away you are from that point unless you go there, so if you're worried you're not smart enough to figure it out, you just need to trust that dumber people than you have figured it out and you just have to keep trying. I am telling you it's worth it.

There are other languages that actually try to look like noise, like brainfuck, where part of the challenge (or the treat) is figuring out how to say things we think of as simple using the most primitive of tools, but k is not one of them.

I remember the first thing that got me excited, was when I realized the implications of (intentionally!) confusing indexing from application. In k, f[x] means if f is a function, call it with x as an argument, but if f is an array, give us the value at index x. Just think of this pattern, in all the ways you see it:

    for(i=0;i<x.length;++i)f(g[x[i]]);
    x.forEach(function(a){f(g[a])})
    foreach($a as $x){f($g[$a]);}
    for i in range(0,len(x)): f(g[x[i]])
Now they're all just f g x; barely 10% of the typing and code! I just can't agree that f g x is "super-terse" that's just the normal way to write it. I also think it is easy to agree that it doesn't look like noise and couldn't possibly be anything simpler.

> I don't have trouble remembering what range() does because it says so right on the tin, unlike for example + in k (addition or, surprise, transpose).

Try to read a little more carefully what I am saying: I wasn't confused about what range() did, I was confused about whether it was the best way to do what I wanted to do.

Also, + is flip not APL's transpose operator.

> To know you will fail before you try?

I don't of course. But I don't have infinite time or resources, so I sadly have to prioritize. Hence why I was curious if there was something more accessible.

> I just can't agree that f g x is "super-terse" that's just the normal way to write it.

I agree that allowing indexing and function calls to have a unified syntax can be very useful. I've used this several times in my own code (through anonymous functions).

But I still think "f g x" is quite terse. For example, it's suddenly implied you're looping over all the elements of x, whereas if it was just function composition it would return a function taking an index.

Does it in itself look like noise? Not to me. But with the extensive use of symbols and tendency to do one-liners it adds up.

Anyway, appreciate the discussion. Maybe I can get a chance to crack the code, so to speak. Regardless of how I think it looks, it does seem like an interesting language to know.

> it's suddenly implied you're looping over all the elements of x,

One of the most mindblowing parts of array languages is that there are no loops. Everything is just arrays and operations composed to produce more arrays. A few weeks ago, I was firmly in your camp, and thought APLs were indecipherable, but they're really not. It's just a totally different philosophy of programming.

> implied you're looping over all the elements of x, whereas if it was just function composition it would return a function taking an index.

I think it's a mistake to make this assumption.

In C, if you saw:

    f(g(x));
you wouldn't expect to be able to make any assumptions about how many loops are going on in there. Python programmers are often overloading their functions too, so you can't even say anything about x+y in Python. I actually think it's the norm that you have to dig all the way down to understand what's going on, and it's the same thing happening here: Yes either f or g might be a loop. Or both. That's just life.

At the end of the day, the only thing I think that helps with that is having less code to read (in source-code bytes).

I think you’re right that if you’ve already decided what the outcome will be then it’s not worth your time but also think it severely undermines the value of your opinion for others.
I have a feeling it's a bit like being color blind. It doesn't help how much people try to explain just how different red and green look if I'm red-green color blind.

Ever since I got somewhat proficient at programming, I've been able to take a quick glance at some non-terse code with descriptive identifiers and get a feeling for what it's doing. Often very accurately, which makes it easy to mentally filter the code into what I need to focus on and what's irrelevant to the task at hand.

But if people write very terse code, this goes down rapidly. I have to spend a lot of time scanning for important symbols, unpacking what's going etc. When they stuff everything on as few lines as possible and use single-letter, non-descriptive identifiers it gets significantly harder to read for me. Now I really have to study the code, and remembering what things do gets harder due to non-descriptive names.

I've worked on a fair bit of really terse code, and I find it just doesn't allow me to be as productive as I am with less terse code.

This is why I doubt that learning k will completely change that, and given that I have very limited time and capacity for fun things like learning new languages, I was curious if there was something more approachable for me.

I think very few would argue that this style of coding doesn’t demand more of the developer, but the thinking is that the focus it demands is appropriate. Programs are written for running, ideally accurately. Without focus you can’t be 100% sure the code you glossed over wasn’t important. Hopefully though this style allows you to spend your valuable attention on the bits that matter.
> the sample code I've seen mostly reads as noise to me

Would you rather write/read:

DIVIDE X BY 5 GIVING Y

or

y=x/5; / this would be considered "noisy" per your definition, 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.

> so I was just curious if there were any array languages that would be approachable to me

q is a very wordy language that sits on top of K4. Some open source examples of libraries used in finance:

https://github.com/finos/kdb/tree/main/q

APL is pretty approachable. You just gotta put a few hours in. There is a tryAPL website that lets you type in some simple programs. It's funny, but I've only spent a few hours on APL, and can still remember the symbols I learned after putting it down for a year.