Изучение концепций программирования, погружаясь в глубину

Перевод | Автор оригинала: Pascal Hertleif

Есть много разных способов чему-то научиться; время от времени мне нравится то, что я бы назвал «прыжком в самый конец»: посмотрите на решение проблемы и изучите каждую из его деталей, пока не поймете все концепции.

Это контрастирует с обучением в стиле учебника, когда вы изучаете одно за другим и постепенно создаете более сложные вещи. Мне нравится подход «глубокого конца», потому что это очень личный стиль обучения. Это часто дает мне возможность самому открывать для себя интересные аспекты вещей, пытаться выяснить, как части работают вместе, и экспериментировать с материалом, пока я не пойму, как это работает. И хотя путь к пониманию может быть полон небольших разочарований и упущенных знаний, я считаю его очень полезным упражнением. (Или, может быть, я просто один из тех, кто любит разбираться в аккуратных концепциях.)

Недавно я столкнулся с такой задачей: подсчитать отдельные слова в заданном тексте. Решение, которое я нашел, показалось мне хорошей «глубокой проблемой». Он короткий, но в то же время полон разных концепций.

Вот что я бы написал (на 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 }
    )
}

Всего 8 строк! (Вы можете поиграть с кодом здесь.)

И вот концепции, которые вам следует изучить, чтобы полностью понять, что происходит (в произвольном порядке; я попытался добавить много ссылок):

Обратите внимание, что большинство этих концепций не являются специальными для Rust. Я только что написал это на Rust, потому что это язык, который я использую чаще всего в свободное время, а также потому, что это язык, который открывает вам множество интересных концепций.

Для сравнения, вот то же самое в JavaScript (поиграйте с ним на JSBin):

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

Спасибо за чтение.