There are many different ways to learn something; one that I enjoy from time to time is what I’d call the “jump in at the deep end”: Look at the solution to a problem and study each of its details until you understand all the concepts.

This is in contrast to a tutorial-style learning where you learn one thing after another and gradually build more complex things. I like the “deep end” approach because it’s a very personal learning style. It often gives me a way to discover interesting aspects of things myself, try to find out how parts work together, and play around with the material until I think I’ve got how it works. And while the road to understanding might be full of little frustrations and missing knowledge, I find it a very rewarding exercise. (Or maybe I’m just one of those people who like to geek out about neat concepts.)

Recently, I came across this task: Count the individual words in a given text. The solution I found seemed like a good “deep end” problem to me. It’s short and yet full of different concepts.

Here’s what I’d write (in Rust):

use std::collections::HashMap;

fn count_words(text: &str) -> HashMap<&str, usize> {
    text.split(' ').fold(
        HashMap::new(),
        |mut map, word| { *map.entry(word).or_insert(0) += 1; map }
    )
}

It’s just 8 lines! (You can play with the code here.)

And here are the concepts you should study to fully understand what’s going on (in no particular order; I tried to add a lot of links):


Note that most of these concepts are not special to Rust. I’ve just written this in Rust because it’s the language I currently use the most in my free time, and also because it’s a language that exposes you to a lot of interesting concepts.

Just for comparison, here’s the same in JavaScript (play with it on JSBin):

function count_words(text) {
  return text.split(' ')
    .reduce((map, word) => {
      map[word] = map[word] ? map[word] + 1 : 1;
      return map;
    }, {});
}