diff options
Diffstat (limited to 'hidden/2020-04-01-j-sorting.md')
| -rw-r--r-- | hidden/2020-04-01-j-sorting.md | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/hidden/2020-04-01-j-sorting.md b/hidden/2020-04-01-j-sorting.md new file mode 100644 index 0000000..2bc0bae --- /dev/null +++ b/hidden/2020-04-01-j-sorting.md @@ -0,0 +1,173 @@ +--- +title: Hello, J! Sorting Some Strings +route: /j-sorting +date: 2020-04-01 +description: We'll learn a few fun features in the J programming language by sorting some strings. +--- + +<!-- Inconsolata monospace doesn't work too good with J's unicode boxes --> +<style>pre code {font-family:monospace}</style> + +Following my previous [(1)](/j-fibonacci) posts [(2)](/j-pascal) on a fun little language called J (http://jsoftware.com/), I thought I'd do a quick writeup for some source code I provided in the [Khan Academy Alumni](https://www.khanacademy.org/about/alumni) slack channel. + +([They're](https://www.khanacademy.org/careers) hiring! [Stripe](https://stripe.com/jobs) is too!) + +Over the next few paragraphs we're going to sort some strings by length, and end up with a function that is 5 characters in length: `\:#&>` (really!) + +``` + (\:#&>) ;: 'sorting strings by length' +┌───────┬───────┬──────┬──┐ +│sorting│strings│length│by│ +└───────┴───────┴──────┴──┘ +``` + +## Boxes of strings + +We can use the [`;: Words`](https://www.jsoftware.com/docs/help804/dictionary/d332.htm) verb to get a list of words in a string. + +``` + 'a'; 'tall'; 'cat' +┌─┬────┬───┐ +│a│tall│cat│ +└─┴────┴───┘ + ;: 'a tall cat' +┌─┬────┬───┐ +│a│tall│cat│ +└─┴────┴───┘ +``` + +The fancy characters around each word represent the fact that they are "boxed." + +We can [`> Open`](https://www.jsoftware.com/docs/help804/dictionary/d020.htm) boxes. + +``` + > ;: 'a tall cat' +a +tall +cat +``` + +We can get the number of items in a list (or a string - which is a list of characters) using the [`# Tally`](https://www.jsoftware.com/docs/help804/dictionary/d400.htm) verb. + +``` + # 1 3 5 +3 + # 'hello' +5 +``` + +We can compose these two operations with [`& Bond`](https://www.jsoftware.com/docs/help804/dictionary/d630n.htm) conjunction, which takes two verbs and returns a single verb. + +``` + # & > ;: 'hello world' +5 5 + #&> ;: 'a tall cat' +1 4 3 +``` + +Now we are able to get the number of characters in each string. + +## Sorting and ranking + +[`\: Sort Down`](https://www.jsoftware.com/docs/help804/dictionary/d432.htm) is a powerful verb which sorts the left argument using the right argument for scoring (in descending order). + +For example, we can rearrange "hello" by giving `l` and `h` a score of 1 and 2 respectively, and giving `e` and `o` a score of 11 and 10 (respectively). `e` will then appear at the front of the result as it received the highest score. + +``` + 'hello' \: 1 11 2 2 10 +eollh +``` + +We can use this to sort our list of words, using the length of each word as its score. + +``` + #&> ;: 'a tall cat' +1 4 3 + (;: 'a tall cat') \: 1 4 3 +┌────┬───┬─┐ +│tall│cat│a│ +└────┴───┴─┘ + (;: 'a tall cat') \: #&> ;: 'a tall cat' +┌────┬───┬─┐ +│tall│cat│a│ +└────┴───┴─┘ +``` + +## Making things shorter + +We've successfully used the `;:`, `\:`, `#`, `&`, and `>` operators to piece together a working sort mechanism, but there's one flaw - we have to repeat `;: 'a tall cat'` twice 😱 + +To alleviate this, we can use one of J's strongest features, [hooks](https://www.jsoftware.com/docs/help804/primer/hook.htm). + +In the following example, we'll take a list of numbers and add 7% to each of them. We may be inclined to write it like so: + +``` + 10 40 55 + 0.07&* 10 40 55 +10.7 42.8 58.85 +``` + +Which reads, take the list `10 40 55` and apply `0.07&*` (remember [bond](https://www.jsoftware.com/docs/help804/dictionary/d630n.htm)?) to each item. Add the result to the list `10 40 55`. + +(Author's note: we also may be inclined to just multiply by 1.07 but that requires math). + +Hooks allow us to simplify this by simply leaving off one of the arguments. + +``` + (+ 0.07&*) 10 40 55 +10.7 42.8 58.85 +``` + +How does this work? J recognizes that we have two verbs within our parentheses (`+` and `0.07&*`) and combines them into a "[hook](https://www.jsoftware.com/docs/help804/primer/hook.htm)." When we place a single argument at the end, J **automatically applies it to both sides of the hook**. + +Put another way: `(f g) x <=> x f g x` for any two verbs `f` and `g` (don't forget your parentheses!) + +So, the following expressions are equivalent: + +``` + 10 40 55 + 0.07&* 10 40 55 +10.7 42.8 58.85 + (+ 0.07&*) 10 40 55 +10.7 42.8 58.85 +``` + +Let's circle back to our sorting mechanism before and see where we can apply this. + +``` + (;: 'a tall cat') \: #&> ;: 'a tall cat' +┌────┬───┬─┐ +│tall│cat│a│ +└────┴───┴─┘ +``` + +Spot it? Between our two instances of `;: 'a tall cat'` we have two verbs: `\:` and `#&>`. Let's hook 'em. + +``` + (\: #&>) ;: 'a tall cat' +┌────┬───┬─┐ +│tall│cat│a│ +└────┴───┴─┘ +``` + +Lastly, we can eliminate some whitespace and build our custom verb. + +``` + sort =. \:#&> + sort ;: 'a tall cat' +┌────┬───┬─┐ +│tall│cat│a│ +└────┴───┴─┘ +``` + +## We did it! + +I hope this was a decently short and pleasant introduction into some fun features of the [J programming language](https://www.jsoftware.com/#/README): + +- [`& Bond`](https://www.jsoftware.com/docs/help804/dictionary/d630n.htm) +- [`\: Sort Down`](https://www.jsoftware.com/docs/help804/dictionary/d432.htm) +- [Hooks](https://www.jsoftware.com/docs/help804/primer/hook.htm) + +I encourage you to download J and play around with it. Hooks and forks and [other trains](https://www.jsoftware.com/docs/help804/dictionary/dictf.htm) pop up in all sorts of places and may make you think differently about the code you write everyday. + +Also consider [following me on twitter](https://twitter.com/jdan). + +Thanks for reading ✨ |