Live data from Hacker News

Stages of Denial

beyondloom.com

81–90 of 119 posts

Re: Stages of Denial

#81

This is a category of cursed knowledge which causes psychic damage to the reader. When you go down certain rabbit holes you develop a fascination with obscure forms of programming and start to realize it has some powerful benefits of which you can never take advantage because it isn't widely adopted. To free yourself from this curse write ten regular for-loops in C and say a prayer to K&R while tighly holding your co…

I know it's a joke but I don't really agree that this area is cursed! It just delves way deeper into syntactical terseness than many programmers will tolerate.. even compared to assembler it's quite a different beast.

I think still potentially very interesting if you're keen on expressing the most computation using the smallest number of characters though!

Re: Stages of Denial

#82

This is a category of cursed knowledge which causes psychic damage to the reader. When you go down certain rabbit holes you develop a fascination with obscure forms of programming and start to realize it has some powerful benefits of which you can never take advantage because it isn't widely adopted. To free yourself from this curse write ten regular for-loops in C and say a prayer to K&R while tighly holding your co…

I developed this on a society scale. Every time I go to a place and people are using very wrong ways (from normale like using an old excel file as a collaborative dB or wilder like printing Excel sheets to write changes wih a pencil to edit the file later...) I go depressed.

Re: Stages of Denial

#83
> Does giving a K idiom a name make it clearer, or does it obscure what is actually happening?

There's a balancing act around that. It's called "abstraction".

At some point, you cannot afford to know what's actually happening. If you try, the entire problem won't fit in your head. So you cut the thing you're working with to a name and an interface, and forget what's "actually happening". You do that right in the K code, because you e.g. cut your understanding of `/` to "fold the array with the preceding operation", and totally don't think about the way it's implemented in the machine code.

This, of course, does have a cost; the simplest case is inefficiency, worse are circuitous ways to arrive to logically the same result, when a much simpler way exists.

I'd argue that `/` or `+` are very much names, of the same nature as `fold` or `add`, just expressed shorter. So if you prefer point-free style, you can likely do a very similar thing in, say, Haskell (and some people do).

I'd hazard to say that APL and J are DSLs for array / matrix numeric code. They allow to express certain things in a very succinct way. What APL traditionally had, mmm, less than ideal experience was I/O, because the language is not optimized for the branchy logic required to handle it robustly. K is a next step that allows to escape into "normal-looking" language with long names, explicit argument passing, etc when you feel like it.

Also, I love this idea: «APL has flourished, as a DSL embedded in a language with excellent I/O. It's just got weird syntax and is called Numpy.» (https://news.ycombinator.com/item?id=17176147) The ideas behind APL / J / K are more interesting than the syntax, and haven't been lost.

Re: Stages of Denial

#84
post #21

Earlier quoted context omitted.

The lens library has a reasonably consistent visual language baked into it: - Operators containing `%` apply a function to the target (mnemonic: % is "mod" in many languages). - Operators containing `=` have a `MonadState` constraint and operate on the monadic state. - Operators containing `~` operate directly on values. - Operators starting with ` - Operators starting with ` - Operators containing `@` operate on ind…

You wouldnt make it compact, so the new dreaming intern joining your codebase would be able to gloriously produce changes rapidly and get hired under the well intentioned smiles of the rest of the team. Instead, in the kdb team I joined recently (a one-letter, symbol heavy language used by quants), nobody can remember what things do, nobody has time to teach you the insanity of code older than 2 months, and you re in…

Look, the parent comment lays out a regular dictionary that allows to unpack a symbolic name into words, or pack words into a symbolic name.

In your case, the vocabulary is absent. (And yes, the custom of naming K functions with numbers, especially negative numbers, is sort of annoying.)

Re: Stages of Denial

#85
post #83

> Does giving a K idiom a name make it clearer, or does it obscure what is actually happening? There's a balancing act around that. It's called "abstraction". At some point, you cannot afford to know what's actually happening. If you try, the entire problem won't fit in your head. So you cut the thing you're working with to a name and an interface, and forget what's "actually happening". You do that right in the K co…

You certainly can do points-free programming in Haskell. It's the first place I ever heard of it.

Ironically, points-free programming in Haskell has a lot of '.' in it.

Re: Stages of Denial

#86
post #23

Just replace K and JavaScript with German and English to see the vacuity of this argument. Either of several possible representations can become native to one’s thinking. The question is which is a better aid in reaching some non-arbitrary goal. The only merit of K presented and emphasized here was the supposed brevity of its programs. Personally I’ve found the habitable zone somewhere that allows for more air betwee…

How about this: K is an interpreted language, but your whole program's source code plus the interpreter plus the whole database engine fits inside your server's L1 cache, so K programs tend to be faster than their C equivalents (in addition to all the array operations being highly optimized). And you don't get to waste time scrolling, your typical module's code fits on your single screen.

I know it's all been said before, but the performance take here is somewhere between misleading and wrong. K runs code quickly for an interpreter because it has a simple grammar and a small number of types, but you don't get up to compiled speed just by reducing overhead, so it will lose to C, Javascript, or LuaJIT in this regard. If you can concentrate the program's work in a few operations on large arrays (not always possible), then K might beat idiomatic C. I don't think I've ever seen an example of this.

Anything about the L1 cache and K is just wrong, usually. At 600KB the K4 database engine is much too large to fit in L1 (K9 from Shakti is somewhat smaller but still a few times too large). And L1 instruction cache misses aren't a bottleneck for other languages, so there's little benefit in reducing them even to the extent K does it.

The long version: https://mlochbaum.github.io/BQN/implementation/kclaims.html

Re: Stages of Denial

#87
post #14

{x#x{x,+/-2#x}/0 1} I'm sure if you used K for a year or so, that would be obvious and understandable at a single glance. But all I can think of is that I used to see that in my terminal session right after my modem got disconnected.

Is it that much worse than, for instance: kvPairs.reduce((acc, [k,v]) => ({...acc, [k]: v}), {}) (Which obviously has nothing to do with the K-Snippet but is the first thing that came to my mind that's equally as symbol-heavy)

Yes. I don't know what language that is, but I know what it means: take some key-value pairs, and reduce them with an accumulator, and make a new dictionary with the items from the accumulator, plus another entry mapping a list of the key to a value, starting with {}.

Alternatively:

  mut acc = {}
  for k, v in kvPairs {
    acc[[k]] = v;
  }
  acc
Am I much wrong?

Re: Stages of Denial

#88
post #14

{x#x{x,+/-2#x}/0 1} I'm sure if you used K for a year or so, that would be obvious and understandable at a single glance. But all I can think of is that I used to see that in my terminal session right after my modem got disconnected.

  fib = 0 fby ( 1 fby fib + next fib );
That's how this would look in a data-flow language.

"fby" means "flowed by". It constructs a stream.

So you can be quite terse without loosing the clarity just by using the right abstraction.

Example taken form:

https://en.wikipedia.org/wiki/Lucid_(programming_language)

Re: Stages of Denial

#89

Earlier quoted context omitted.

Is it that much worse than, for instance: kvPairs.reduce((acc, [k,v]) => ({...acc, [k]: v}), {}) (Which obviously has nothing to do with the K-Snippet but is the first thing that came to my mind that's equally as symbol-heavy)

Yes. I don't know what language that is, but I know what it means: take some key-value pairs, and reduce them with an accumulator, and make a new dictionary with the items from the accumulator, plus another entry mapping a list of the key to a value, starting with {}. Alternatively: mut acc = {} for k, v in kvPairs { acc[[k]] = v; } acc Am I much wrong?

Huh, no you're exactly right. (It's javascript, btw)

Re: Stages of Denial

#90
post #5

So are array languages polish notation? +/!100 feels like the opposite way you'd write it in some kind of RPN concatenative language 100 ! [ + ] /

In Polish notation all the operators are prefix operators.

In APL family languages there are infix operators and prefix operators.

Prefix operators take as their operand the result of everything to their right. Infix operators take as one operand everything to their right and take as their other operand the first thing on their left.

Post reply on HN