Determining an Election in K
leahneukirchen.org
leahneukirchen.org
v: 10400 3400 6200
s: 15
quotients: ,/v%\.5+!s
labels: s/!s*#v / list of 15x 0, 1, 2. arbitrary; could instead be party names
top: s#>labels!quotients / k dicts can have duplicate keys; can sort items by key(^) or val(<>)
seats: `freq@!top / count appearances of dict's keys
The ability to transform a dict's values while keeping the labels (keys) unchanged - sort, arithmetic, etc - is really powerful.This answer is longer when minified, but it's faster in 2020.03.27:
\t:100000 +/s>(#v)^<>,/v%/.5+!s ⇒ 1494
\t:100000 `freq@!s#>(s/!s*#v)!,/v%\.5+!s ⇒ 691 \t:100000 `freq@!s#>(s/!s*#v)!,/v%\.5+!s
941
\t:100000 `freq(s/!s*#v)s#>,/v%\.5+!s
901I'm similarly pleased to have found a correspondence from K's ' (also present in Klong) to J, where it ends up being "0 in this instance.
r=. v&%"0 (0.5+i. s)
+/s>($r)$/:\:,/rIf you can tolerate the learning-curve though.
For comparison, I do appreciate that many (most?) Linux shell utilities and command-line programs in general have adopted standard conventions for arguments (-f for short, --full for verbose) which make it easier for people new to a program to take a cryptic command-line and look-up the full-versions of the abbreviated commands to see what's going on - PowerShell does the same thing with its strict aliasing of cmdlets. Unfortunately I can't see that K (or many other programming languages really) do the same thing, where a a short, cryptic program can be syntactically expanded to one using verbose syntax with no changes in program semantics (unless you count VB.NET vs C# equivalence, heh).
Is there any automated explainer tools for the K language for beginners?
I think q is a better starting out point than k. Most functions in q have readable names (each in q vs ' in k, for example). Also it comes with a richer library of functions.
Not entirely an answer to your question, but J provides introspection/help in a pretty direct way via two distinct means, the first is ;: ("words") which will show you the parse of a J phrase (here, a pretty direct translation of the algorithm in the article):
;:'+/s>(s,#v)$/:\:,/v&%"0 (0.5+i.s)'
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬──┬──┬─┬─┬─┬─┬─┬─┬─┬─┬───┬─┬──┬─┬─┐
│+│/│s│>│(│s│,│#│v│)│$│/:│\:│,│/│v│&│%│"│0│(│0.5│+│i.│s│)│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴──┴──┴─┴─┴─┴─┴─┴─┴─┴─┴───┴─┴──┴─┴─┘
Which shows the tokens of the phrase, which can be helpful if you are unsure of where a symbol or diacritic is being used. Inside the J IDE you can get context sensitive help by pressing Ctrl-F1 on a symbol, if you were interested in /: for example, you are directly linked here[2].I am unaware of a similar tool in K, which should not be taken to mean it doesn't or can't exist. One of the reasons I'm interested in J has been the tooling and documentation available.
[0]: https://wjmn.github.io/posts/j-can-look-like-apl/
I think this is a good point.
In an interactive environment: you can iteratively build the expression up, and you have the right chunks of context in working memory as you do it. You'd still need to learn what the different functions/operations are; but in a one-line REPL the use of symbols would allow you to fit more on a line than using more traditional identifiers.
That avoids many of the things I'd be concerned about for writing code like this if I had to come back and read or modify it months later.
Still neat as a toy exercise using what seems like a fun little micro-language.
Although I'm not a K programmer (I've done some J in the past), the point that K programmers make is that the code IS readable once you get used to it. One of the benefits commonly mentioned is that you can keep the whole program in your mind at once. I can't do that with my own Go and Python programs :)
Doing low-level file I/O, socket I/O, handling low-level HTTP and FTP code for each one that needs it, parsing XMLs from scratch five dozen times, doing all those integrations without abstractions... how is that an improvement?
And reducing line count by a mere 10x would do nothing for keeping it all in the head at one time. Even if you could get it down by 1000x, I don't think you'd accomplish much because the logic still has to be there.
With our bloated stacks, the most used CPU instructions that our binaries use are the ones moving data. We are not using the computers to compute, but just to move data around. That just feels wrong. K, APL, Forth and the likes are living proofs that there are other ways to solve complex problems.
That is because moving data around is a very useful thing.
In fact, our entire product is almost entirely about moving data.
Using it, our customers don't have to move data by hand. They don't have to look at invoices and fill in forms with a pen, put those in an envelope and send it to the government.
Instead our product can do that. And it can be smart about which data to move, when to move it, and where to move it. That's where the small bit of computation comes in.
Both R and APL/K are great for data science and have great tools. I wouldn't call either a toy (not sure if you were just referring to this particular task or the technology in general). K is commonly used in kxsystems's kdb+ product and deep pocketed quants pay top dollar for it.
The article shows some nice k idioms that I find much more readable written in a concise form. For example, I find |^... easier than reverse(sort_ascending(...)), or <>... easier than grade_down(grade_up(...)). I guess the solution in other languages would be to define more functions for all these common operations, but then you will need much more documentation for all these extra functions and learn them, so I don't see it as an improvement.
At difference of most golfing languages, the set of k primitives is very small. Many people who criticize k forget that property, but it's a very important one. It would be interesting to see the R version and compare the amount of documentation you need to read to completely understand what each of the programs is doing (ie. to read the program). That would be, in my opinion, a better measurement of readability than a subjective opinion (unfortunately, the k9 documentation is too scarce at this point to make this exercise in a proper way).
[1] There's a handful of two-character primitives, as well as some special callable symbols (eg `freq @), but they don't come up nearly as often as the base set.
No, but it took me 12 years of school education to get to that point. Question is, for a large code base how many symbols are you willing to remember? At some point it hits diminishing returns, doesn't it?
The symbols you have to remember are the ASCII symbols (most of them are used in other programming languages too), with two operations for symbol, plus a few special cases and a bunch of extra functions. In total, less than 50 primitives. I think that any programmer can easily handle that.
There are many people who do not agree with this, but there is objective data (see the papers by Iverson about his efforts to teach mathematics using APL) that say it is easy to learn. In all these threads, most people with experience in array languages say it is not so hard as it looks, although there are some exceptions.
You may prefer other kind of languages or other kind of notation. There certainly is some subjective factor here. But I suggest everyone to give it a try before forming an opinion.
_q+(s-+/_q)><>q-_q:s*v%+/v
would be longer, but it would also probably be more readable.