Hacker News

Top stories

Live mirror
30 storiesupdated just nowView source snapshot
  1. Android 17 is the first since 3.x to add new APIs without releasing to the AOSP(grapheneos.social ↗)
    330comments
  2. San Francisco Onion Futures Company(onionfutures.com ↗)
    6comments
  3. Science Is Open Software(jepedersen.dk ↗)
    15comments
  4. SDCC – Small Device C Compiler(sourceforge.net ↗)
    7comments
  5. Cloudflare Quick Tunnels(cloudflare.com ↗)
    266comments
  6. Saving another 100TB of RAM(cloudflare.com ↗)
    58comments
  7. How OpenAI Used Its Own LLMs to Design Its Jalapeño Chip(ieee.org ↗)
    69comments
  8. How to Write with an LLM(sockpuppet.org ↗)
    299comments
  9. Show HN: Seal – Letters and passwords that open for your family after you die(github.com/jasonepage ↗)
    discuss
  10. Why building a Rust LSP is hard(rust-glancer.github.io ↗)
    11comments
  11. Typesafe-computer-use drives a Mac toward a goal for 1/50th of a cent per step(github.com/awlevin ↗)
    2comments
  12. Xcode 27.1 Beta Release Notes(developer.apple.com ↗)
    75comments
  13. Harm Laundering in GPT Models: Gender Discrimination Transformed Rather Than(arxiv.org ↗)
    discuss
  14. The first new cat species discovered in 100 years(nationalgeographic.com ↗)
    80comments
  15. Show HN: Cactus Needle 3: 8-29MB automation models can match DeepSeek V4 Flash(cactuscompute.com ↗)
    81comments
  16. Photon-Emission-Guided Laser Fault Injection Enables RP2350 Secure Debug(ledger.com ↗)
    61comments
  17. OpenJev(openjev.com ↗)
    250comments
  18. The Farnese letter(simonklee.dk ↗)
    5comments
  19. Cache-to-Cache: Direct Semantic Communication Between LLMs (2025)(arxiv.org ↗)
    12comments
  20. Goroutine Leak Profiles(go.dev ↗)
    1comments
  21. LispBM is a concurrent Lisp for microcontrollers with message passing(lispbm.com ↗)
    3comments
  22. Cyclomatic Complexity in C#(ndepend.com ↗)
    16comments
  23. Claude Code now reads AGENTS.md if there is no Claude.md(claude.com ↗)
    208comments
  24. Minimal Phone 2(minimalcompany.com ↗)
    199comments
  25. Show HN: LiveWorld – Every 24/7 YouTube live camera on one globe(liveworld.info ↗)
    32comments
  26. Alibaba open-sources AI model that can detect cancer and nearly 150 conditions(scmp.com ↗)
    9comments
  27. Warez: The Infrastructure and Aesthetics of Piracy (2021)(archive.org ↗)
    39comments
  28. Inside ZCode: Silently uploading your Git history to the cloud(ferstar.org ↗)
    94comments
  29. Flock Offers Employees Buyouts as Customers Flee(wired.com ↗)
    3comments
  30. How SpaceX streamlined the Raptor engine(construction-physics.com ↗)
    55comments

K7 Tutorial

198 pointsby 7y agocs.nyu.edu
83 comments
7y agoHN ↗

The mentioned gitlab repo doesn't seem to exist anymore. One would have to download kdb+ from kx, but I am not sure if this wouldn't be K4 only. Alternatively, one could play with oK (K6) which would also give you the nice graphical iKe.

7y agoHN ↗

I didn't really follow that development, what led to the creation of Shakti?

7y agoHN ↗

Not really sure... people started talking about it on the mostly dead /r/apljk subreddit last week which caught my attention. It appears Arthur Whitney left Kx Systems and started his own company again. I'm immediately suspicious when I see "blockchain" in something, but Arthur is a bit of a legend. I don't fully understand why it is bundled as an Anaconda (scientific and data analysis oriented distribution of Python), but I assume a library is utilized there for machine learning or something like that (hopefully someone can comment and tell us what). You can type in "/" in the REPL to bring up the help menu showing the various symbols and what they mean monadically (when taking one argument) or dyadically (taking two arguments). As usual though, their website seems to have virtually zero documentation like they want to stay obscure. I'd love if someone in the industry that can afford to use these products can tell me what Shakti looks like it would be used for. Is it the same as kdb+ mostly with a few added features?

7y agoHN ↗

According to the Google Group, Alexander Belopolsky (involved in pyq) is a member of Shakti. That would explain the Python relation.

7y agoHN ↗

Yeah, the mere mention of blockchain/crypto was also the reason why my interesting in Red waned suddenly...

Still waiting for kOS, too.

7y agoHN ↗

Haha. Same here for Red. I understand why they did it (it seems like they wanted blockchain and crypto currency to be their killer app), but I'm worried it was just a costly detour. That is their decision of course though and best of luck. The other thing they're doing (if I understand correctly) is creating a second code optimizer that is a paid product. So the default compiler created slower code than the commercial one I think.

I'm also still waiting on kOS, but I'll never be able to afford it, so not sure why I'm waiting on it.

7y agoHN ↗

Anaconda (scientific and data analysis oriented distribution of Python)

While that was the original and still by far most common use case of Anaconda, it has greatly expanded over the past couple of years into a more general purpose software environment packaging tool.

7y agoHN ↗

I think the reason it's in anaconda is they're trying to go after the python crowd? Regain some of the data analysis market share that stuff like numpy took from APL.

7y agoHN ↗

I see a lot of niche languages like Dyalog APL doing the same thing (building bridges to Python), but if I really have to use Python, I'll just use Python. Not a hybrid of the two. Maybe that's just me though.

7y agoHN ↗

Think about it as an extension to e.g. K/Q's strengths. What if you would like to visualise certain aspects of quote/trade data? It could take a very long time to process the data in Python and it is difficult to visualise data from within kdb+. Seems to be a good match.

7y agoHN ↗

What's important is that APL language family isn't a domain-specific one, suitable for some particular tasks in a narrow niche. To the contrary, they are languages of computations, allowing rather short paths from thought to implementation of an algorithm, compared to other languages.

I'm sure K knowledge and experience ensure the practitioner powerful tools for wide variety of problems in many areas.

7y agoHN ↗

Still, for me it is quite hard to imagine what would I create with APL.

Usually, when trying a language, my instinct is to implement a web-service. Or a simple gui-app, with some library.

With APL, I am looking at it and wonder. I looks powerful. But what should I do with it? Make a compiler? A database? How does I/O even work there?

7y agoHN ↗

In K, usually the I/O primitives you have are the "colon" operators, stuff like 4:.

7y agoHN ↗

J and K are different languages. They are similar in that both use standard ascii keys and are in the APL family of languages. The author of K "Arthur Whitney" wrote part of a prototype with Roger Hui for the J interpreter or so I think. The primary author of J is none other than Ken Iverson (the Turing award winner and designer of the original APL) who wanted a free version of APL for the masses where people wouldn't complain about the weird non ASCII APL symbols. It also primarily uses a tacit function train style of programming like data flow languages where you don't even necessarily need variables (pretty cool). This tacit coding style has since been added to Dyalog APL where you can see folks like Aaron Hsu build some pretty cool applications using it. I'd imagine K is more performant though than J and the source is famously small (just a few C files). J has a lot more stuff baked in like Qt support. They both have a database library Jd (for J) and Kdb+ (for K). Kdb+ is a fancy SSD based database which uses K and a SQL like DSL called Q. Its performance is pretty darn good and used in Finance. I don't know enough about Jd.

7y agoHN ↗

This comes up a lot in these discussions and I believe Arthur better understands 6 pages of code written like that than someone else can comprehend 30 pages of the equivalent idiomatic code. He writes APL/K for a living, so making the C fit closer makes more sense in my eyes as it matches his thought process better. I sympathize with hating scrolling in how it hurts your ability to see everything at once.

7y agoHN ↗

I get the same gut reaction as you, but I tried reformatting the code a little bit and it's not _that_ terrible.

From the very little APL I've learnt, I know that operators always have either one parameter (named ω) or two (named α and ω), and their inputs and outputs are always arrays.

If you need to write a lot of such functions, it makes sense to define some macros to help you:

    #define V1(f) A f(w)A w;      // create one-arg function
    #define V2(f) A f(a,w)A a,w;  // create two-arg function
    #define DO(n,x) {I i=0,_n=(n);for(;i<_n;++i){x;}}

iota is the APL equivalent of Python's range function:

    V1(iota) {            // Define one-arg function iota.
        I n = *w->p;          // Get the value of the ω argument.
        A z = ga(0, 1, &n);   // Allocate output array.
        DO(n, z->p[i] = i);   // Assign increasing integers.
        R z;                  // Return the result.
    }

The plus function adds two arrays:

    V2(plus) {            // Define two-arg function plus.
        I  r = w->r,          // Get the rank of ω.
          *d = w->d,          // Get a pointer to ω's data.
           n = tr(r,d);       // Get tne size of ω's data.
        A z = ga(0, r, d);    // Allocate output array.
        DO(n, z->p[i] = a->p[i] + w->p[i]);
                              // Add corresponding values of α and ω
        R z;                  // Return the result.
    }

Personally I cannot tolerate the lack of whitespace, but the APL guys are known to like to see their entire programs in one screenful. I can understand that some people like to write code like this.

7y agoHN ↗

Off topic, but is it just me, or do you also dig the simple text format of the website? -- so easy to read!

7y agoHN ↗

Wish it didn't have manual line breaks, though; it's kind of terrible on mobile.

7y agoHN ↗

Can any comment how this compares to R? Seems to have similar capabilities.

7y agoHN ↗

The syntax seems vaguely similar, but I don't really see other commonalities. R's strength is it's incredible ecosystem.

7y agoHN ↗

The language looks generally good for its goal, except these two operators

     |/y / maximum
 
     &/y / minimum

Those two characters have no connection with the operation they stand for and seem to be randomly picked from the available symbols on the keyboard. Why not simply max y and min y, which anybody can read and understand?

7y agoHN ↗

At least for boolean operations, | (or) can be thought of as the maximum of a vector of 0s (false) and 1s (true). Likewise, & (and) is the minimum of a vector of 0s (false) and 1s (true).

But I don't know if that was the motivation / justification for naming these operators / functions.

7y agoHN ↗

if you squint a bit, `x or y` returns the one that's greater, i.e. `0 or 1 == 1`; and `x and y` returns the one that's smaller, i.e. `0 and 1 == 0`. so min/max kind of are a generalization of and/or

7y agoHN ↗

Those are “or”=max, “and”=min. They are use sometimes in Mathematics (I have used them) but with the “low angle” and “up angle”. Not too frequently though.

7y agoHN ↗

Paraphrasing

  fold[max] y  # maximum
  fold[min] y  # minimum

Those two characters have no connection with the operation they stand for

  | — logical-or,  min
  & — logical-and, max

    0|1
  1
    1|42
  42
7y agoHN ↗

Sure they do, in most C-like languages || is OR and && is AND.

For OR, from

1 | 0 = 1

It's a small step to generalise to

N | 0 = N (~max)

and then

N | N-1 = N (max)

The same goes for &

7y agoHN ↗

max and min are also available as keywords in k7/shakti

7y agoHN ↗

Note that |/y is | (or) over y. Hence, max.

7y agoHN ↗

I liked the example of 1 line of code generation a table of random stock data.

But, this is not free or open source?

7y agoHN ↗

It’s not a port, it’s a separate implementation. The difference in meaning between these two words is sufficiently important that it’s worth pointing out IMO.

Porting software means to adapt an existing piece of software to a different computing environment.

Ports are based on source code and/or assets from the original piece of software that is being ported.

As such a port would be derivative work, meaning that the authors would not be able to release their software without permission from the copyright holder(s) of the software that was being ported.

7y agoHN ↗

Trying to learn how to use A+ from aplusdev.org to do some simple work for my personal use. A previous language designed by Arthur Whitney and GPL also. Included in Debian derived distros btw.

7y agoHN ↗

I would highly recommend GNU APL over A+.

GNU APL is a full-fledged, modern implementation of the official ISO APL 2 standard, supporting things like Unicode and modern terminals, and is currently maintained by very friendly people. While A+ is a very old, partial implementation of APL that requires a dedicated font and 8-bit encoding to work, and has not been maintained for decades. (IIRC)

Documentation for APL 2 can be found online, but I would recommend getting a second hand copy of the classic Gilman Rose book. I bought mine online for a few dollars.

7y agoHN ↗

Is there a particular edition of the Gilman Rose book you would recommend?

7y agoHN ↗

Sorry for the late reply. I seem to have the 1976 edition (I didn't think of checking the edition before buying mine! DOH!) I would say it was good enough for learning the language, although the references to mainframes and terminals are obsolete. (Picturesque, if you like that sort of thing, but obsolete.) If you can get the latest edition (1991) it's probably better.

I ended up buying that book because from all the online resources I was able to find at the time, I failed to understand the gist of the language, or how you are supposed to think in order to solve problems in APL. Which is profoundly different from all other languages, and which the book taught very well. I've also been using paper books to learn programming since forever, so it's a workflow I'm used to.

That being said, there are some free resources that you could try first:

http://misc.aplteam.com/robertson/APL1&2.pdf - http://misc.aplteam.com/robertson/APL3&4.pdf - https://www.dyalog.com/uploads/documents/MasteringDyalogAPL....

The latter is about Dyalog APL, a dialect of APL, so not all of it will be applicable to GNU APL.

About the font, any Unicode font will do, but for graphical consistency I would recommend downloading this one. You can use it with any modern terminal application:

https://www.dyalog.com/uploads/files/download.php?file=fonts...

About the keyboard, if you are on Linux you can just add one of several APL variants to your existing national keyboard. You will have to designate an APL key (eg. the useless menu key) to use as a special alt-like key to input APL symbols. If you're not comfortable typing blindly, you can buy a keyboard with APL symbols on it, or alternatively buy or print stickers to apply to yours.

I spent an entire summer learning APL for fun (that was way before GNU APL existed, so I had to struggle with various proprietary interpreters, either freeware or demoware, on top of the weird language + font + keyboard!) I then went on to compete in Code Golf challenges and other random things using it and had a blast!

I still miss APL. IMHO none of the successors (J, K) come close to the beauty of its symbols. It's also a very different way of writing algorithms (sometimes called "multi-dimensional array programming") that is not found in modern programming languages.

Feel free to contact me (username + gmail) for any questions you may have.

7y agoHN ↗

It's a very good tutorial (it's not easy to find information about k7), but it is a bit outdated. For example, % is inverse and not sqrt now, and it is not possible to evaluate parsed trees with !. I am sure the differences are small, but be prepared to be surprised with some descriptive error messages like: 'nyi

7y agoHN ↗

And that's very obvious once it's been pointed out, but how long would it take a beginner to figure that out?

7y agoHN ↗

A beginner is going to have a bad time with any language. Sure, 'nyi is not very descriptive, but an error message is not the place to teach total beginners. Unless you put some effort into learning a language (or already know something similar), compiler errors will be difficult to figure out anyway.

The most blatant example is the infamous "discards qualifiers" error but, for example, in a programming language with nice and descriptive error messages like Go, you will have a hard time figuring out what a interface type error is about until you actually read the manual and learn what an interface is.

7y agoHN ↗

A good error message doesn't have to be descriptive, but if it isn't, it absolutely must be Googleable -- i.e. unique enough so that someone who doesn't understand what it means can paste it into a search engine and find out.

If I Google "'nyi", I get a bunch of results about the New York Islanders hockey team. Not helpful. If I try to be more specific and Google "'nyi k7", the closest thing to a helpful result I get is a link to this discussion on HN.

7y agoHN ↗

Any good programmer should be able o learn to program k7 at the level of this tutorial in two hours.

7y agoHN ↗

K7 like it's ancestor APL is extremely powerful language, whit great signal to noise ratios. However it is kind of "write-only" language.. When trying to read a code not written by you (or written by you couple of monthes ago) you struggle to understand it...

7y agoHN ↗

I think that this is a matter of practice. I write k/q almost daily, and don't struggle to read other people's code, or my own.

Most code isn't clever oneliners, and is quite readable.

7y agoHN ↗

Agree with this. The problem is that there's no widely adopted style guide with k or q. A lot of code you find on the web is written in a minified fashion. At least put a new line and indent whenever you can.

7y agoHN ↗

K is interesting in that unlike something like Java the hard part is not remembering the standard library. You start to learn idioms for how to do certain things as you use it more. Then you pattern match different parts of the code and it can be very readable.

7y agoHN ↗

The fact that every function/operator has multiple meanings, often very different, depending on the actual data passed to it doesn't help readability. It tries too hard to use only symbols, which are limited on an normal keyboard, and so it crams multiple functionalities into the same symbol.

7y agoHN ↗

A concept in K that I wish more languages had is indexing with a list of indices. It always blows peoples' minds when I tell them how sorting works in K. You use grade (<) to return the indices that will sort the array if indexed in that order. Then you pass in that list as the indices to the list. They do it in the string examples in this tutorial.

7y agoHN ↗

Sorting a list by getting the sorted indices (permutation) and then applying them might seem a bit roundabout at first glance. Then you realize that you can apply the permutation to something else. For example, to sort a table by the values of a column, you get the column, "sort" the column, then apply the permutation to the original table (all columns of the table).

7y agoHN ↗

How does grade work? Can you customize how it ranks results?

7y agoHN ↗

If you want to rank results differently, you'd apply a function to each element of the original vector that computes the rank / weight of that element. Then you sort by weights, and apply the result to the original vector. Something like:

input[<{...compute weight of element x...}'input]

7y agoHN ↗

This is also how filtering works, you map a function that returns 0 or 1 over the list. Then you can call where (&) and it will give you the indices where the function evaluates true. Index by that and you'll filter a list.

7y agoHN ↗

A related operator is group (=), which creates a map between the unique elements of a list to their locations.

     x: 10 ? `a`b`c
     x
    `a`c`c`c`c`a`b`a`a`c
     =x
    a|0 5 7 8  
    b|,6       
    c|1 2 3 4 9
7y agoHN ↗

Another great concept is that function application and array indexing has the same syntax.

    a.map(f)

is basically† just:

    f[a]

and:

    a.map(x => m[x])

is still just:

    m[a]

†: Rank notwithstanding. If that bothers you that f might take an atom, pretend I said f@/:a and m@/:a instead.

7y agoHN ↗

I was hoping we'd finally get proper lexical scope in this version of K. Alas, seems to not be the case.

7y agoHN ↗

There are a few expected (or, better said, rumored) features that have been left out. Some of them will eventually come (views), some of them probably don't (like using the unicode symbol for sqrt). I was surprised when I saw in nsl a shift-reduce parser that took into account operator precedence, but it looks like it is not being used. I'd like to have lexical scoping too, but due to how function values work, I see it very unlikely.

7y agoHN ↗

Unlikely due to how they're implemented, or their semantics?

7y agoHN ↗

What are the financial applications that this is used for? Does anyone have specific examples?

7y agoHN ↗

In the 1990s Morgan Stanley's full suite of fixed income portfolio management and trading applications were written in APlus which was another of Arthur Whitney's APL variants. When I joined, MS was moving away from it, but the developers who'd been using it were very much in the "you'll take APlus from my cold, dead fingers" camp.

7y agoHN ↗

Not K7, but KDB+ is the de-facto time series store for financial data. It's faster than anything open source by orders of magnitude and extremely expressive. However, it's extremely expensive. If KDB had a much more user-friendly licensing scheme they would have seen much more adoption.

7y agoHN ↗

For curious, several facts i noticed by running anaconda distributed shakti:

1) k7 implementation obviosly is completely different codebase from current kdb+. I ran the following query on kdb+ and k7

  a1:1000000?1000000;b1:1000000?1000000;
  \t select #a by b from (+`a`b!(a1;b1));

And difference seems to be in order of magnitude (k7 is 650 msec, kdb+ is 77 msec), also on k7, time increases for subsequent execution of same query ==> memory leak? Looks like it's very early stage.

2) null number (0N) and infinity are now represented as non-ascii symbols Ø and ∞, also parsed as such.

3) type operator (@) returns symbols (`i, `j) for ints and longs etc, was returning shorts before. Interesting how do we distinguish arrays/scalars now.

4) default numeric type (e.g. 12345) is now int, was long.

5) entering overflow numeric literal returns Ø, was throwing exception.

6) k in anaconda is not stripped 675K linux x64 executable, stripped is 220K, while kdb+ is 657K as sold.

7y agoHN ↗

One might add that by typing "\", the K7 description gets printed (similar to the description on kparc.com).

7y agoHN ↗

Perhaps the performance difference is due to resource limitations in the Shakti trial?

7y agoHN ↗

3) type operator (@) returns symbols (`i, `j) for ints and longs etc, was returning shorts before. Interesting how do we distinguish arrays/scalars now.

Upper/lower case:

   @1
  `i
   @1 2
  `I
   @`a
  `n
   @`a`b
  `N
7y agoHN ↗

I saw that, but how do you make simple check if it is uppercase?

7y agoHN ↗

I guess you can check the ASCII value of the char:

   li:{(*$@x)within "AZ"}
   li 1
  0
   li 1 2 3
  1

Or can have a list of uppercase chars as names & check with 'in':

   li2:{(@:y)in x}[`$,:'`c$"A"+!26]
   li2 1 2 3
  1
   li2 1
  0

'li2' seems to be considerably faster:

   \t:10000 li 1 2 3
  13
   \t:10000 li2 1 2 3
  6

There may well be a better way though

7y agoHN ↗

this seems not to be in the spirit of language. Testing if type is array or not is so common, and adding this function (li, li2) to "standard library" would introduce "standard library". Maybe we overlooked some other obvious solution.