Монокультура в программировании — это использование одного стека для решения всех возникающих задач. Она существует не только на уровне конкретного человека и его предпочтений, но также часто встречается на уровне компаний. В таких компаниях, как правило, все делается с использованием одной технологии.
В далеком 2011 году в Ульяновске я начал создавать филиал широко известной в узких кругах компании Undev, той самой, которая писала софт для трансляции выборов президента, проведения ЕГЭ и многих других мероприятий. Основным стеком компании на тот момент был Ruby. Как известно, в регионах рубистов крайне мало, и на тот момент во всем Ульяновске это был десяток человек, которых все знали по именам.
Наша стратегия заключалась в том, чтобы брать ребят с других стеков и переучивать их, а также набирать зеленых студентов. По сути, это был обучающий центр при производстве. Занимался я этим примерно 4 года, за которые было выращено более 70 разработчиков только внутри Андева, не считая активностей, направленных на развитие среды (за это время в городе появилось еще несколько филиалов Руби-ориентированных компаний, и многие начали использовать Руби в дополнение к своим основным направлениям).
Первоначально идея развития состояла в том, что мы используем Руби почти везде (и js, конечно). Ведь это дает столько возможностей:
- Легко заменять людей и перебрасывать их между проектами
- Быстрый вход в любой проект
- Отработанные схемы обучения
- Большая экспертиза по Ruby, которая «шарится» между всеми командами
В каком-то смысле это верно. Действительно, для бизнеса мысль о том, что можно легко восполнять потери и не бояться, что некую часть проекта невозможно поддерживать в виду отсутствия специалистов внутри компании, кажется очень притягательной. Мы успешно работали по такой схеме около двух лет, а потом система начала давать сбой.
В это время в компании появилось множество программистов, которые кроме Ruby в своей жизни не видели практически ничего. Все они были обучены внутри. Кроме того, сложность самих продуктов стала выше, а Москва стала нам доверять все более сложные части сервисов.
Подписывайтесь на канал Кирилла Мокевнина в Telegram — чтобы узнать больше о программировании и профессиональном пути разработчика
Проблемы начали проявляться сразу, как только приходилось писать что-то вне стандартного флоу «рельс». Практически любая библиотека или самостоятельный модуль были написаны в худших традициях ruby:
- Метапрограммирование — основной способ написания программ. Все, что можно сгенерировать программно, генерируется программно. Даже если вы не знакомы с этой концепцией, то представьте себе программу, в которой невозможно найти GREP определения функций.
- Манкипатчинг как основной способ расширить функциональность
- Активное использование глобального состояния
Я уже не говорю про то, что код при этом часто оставлял желать лучшего сам по себе. В разговорах выяснялось, что многие решения были продиктованы исключительно ограниченностью кругозора и отсутствием понимания принципов программирования. Ребята не могли их дифференцировать от самого языка. Любую ситуацию они рассматривали с точки зрения конструкций Руби. Например, несмотря на то, что Руби декларируется как полностью ООП-язык, те задачи, которые требуют использования полиморфизма включения (через инверсию зависимостей), решаются через манкипатчинг и глобальное состояние в классах (которые сами — глобальные объекты).
И это происходило на фоне того, что я очень активно развивал инженерную культуру. Мы вовсю использовали практики экстремального программирования, писали большую часть кода через тесты, в каждом кабинете у нас висели мониторы с дашбордом интеграционных серверов. Ребята читали книги, изучали операционные системы и активно делились знаниями друг с другом.
В то время я познакомился с небезызвестным Львом Валкиным, одним из самых авторитетных для меня людей в программировании. Человеком, который приобщил десятки тысяч людей к функциональному программированию. В то время он занимался ныне не существующей компанией Echo, а позже и филиалом компании Machinezone. Хотя Лев уже давным-давно живет в Долине, в те годы он довольно часто приезжал на малую родину, как раз тогда мы (ульяновские айтишники) запускали конференции nastachku.ru и ulcamp.ru.
Вот что обычно написано в вакансиях компаний, которыми руководит Лев:
Сейчас используем в основном Python, Erlang, Haskell, C, C++, Docker, Vagrant, AWS, Git, Centos, Bash. Но ничего не мешает нам расширить или сократить этот список. Главное, чтобы для решения задачи был подходящий инструмент.
Каждый раз когда мы встречались, моно- и поли- культуры были предметом обсуждения. Я отстаивал точку зрения удобности монокультуры для бизнеса, Лев придерживался противоположной идеи, что монокультура вредит. И немного примеров:
Выдержка из статьи на лурке:
Далее, насчет именно функциональных языков программирования. Из семейства ML OCaml действительно самый практичный. Пользователей у него больше, чем у остальных диалектов ML, библиотек, соответственно, тоже гораздо больше. Инструментарий, пусть и довольно скудный, опять же богаче. Да, если отвлечься от ML, то у того же Haskell пользователей и библиотек еще куда больше, но Haskell по заявлению самого Пейтон-Джонса не предназначен для продакшен. Да, его используют там, но Пейтон-Джонс позиционирует и развивает его как именно исследовательский язык. Ну и, что куда важнее, как язык Haskell гораздо сложнее, порог вхождения в него гораздо выше. Оба языка достаточно маргинальны, чтоб легко найти разработчиков на них, но тот же Лев Валкин вполне себе набирает просто толковых людей себе в команду, а там за пару недель на OCaml оные начинают вполне себе писать.
Статья в блоге Льва, как у них появился clojure: https://lionet.livejournal.com/125495.html
Кстати, тот самый Тонский, который постоянно светится в подкастах, пропагандирует clojure, clojurescript, react, сделал datascript и firacode, вышел из echo Льва, как и многие другие крутые разработчики.
Тогда мне стало понятно, что выбранная схема обучения программистов в Андеве готовит не программистов, а Rails-программистов. Проблема расширения кругозора усугублялась еще тем, что уровень автоматизации и интегрированности инструментов в Rails настолько высок, что ребятам было крайне сложно вытащить себя куда-то еще. Любая задача решается с помощью фразы “поставь гем”. Все сделано до нас, только найди и используй. Я уже не говорю про то, что такие разработчики с трудом могут понять границу применимости привычного инструмента и подобрать более подходящее решение под задачу.
В 2013 году я резко изменил курс. Вместо обучению Rails, мы начали учить фундаментальным основам информатики. Основным языком на время обучения стал Clojure. Основным источником вдохновения - SICP. Внутри самой компании начались перемены и сдвиг парадигмы в сторону расширения спектра используемых технологий и языков. Сразу оговорюсь, что это не было расширение ради расширения. Все было обосновано с точки зрения бизнеса, главное, что мы сняли табу на это расширение. В арсенале появились такие языки как go, python, а сейчас, в restream (ex-undev) пишут на всем подряд
Положительный эффект наступил практически сразу. Хорошее понимание идей и применимости функционального программирования, понимание важности менеджмента состояния, абстракций, полиморфизма и многого другого позволило отвязаться от языка и общаться на более высоком уровне. Код стал менее зависим от языкового влияния. Ребятам стало просто и комфортно переключаться между разными языками. И понятно, что я стал приверженцем поликультуры.
Я считаю крайне важным, чтобы человек, который учится программировать, делал это не на том языке, на котором он будет (планирует) писать код за деньги. Причем не менее важно то, что язык должен быть совсем другой. Если вы писали в университете на c#, а на работе пишите на java, то для вас мало что поменялось. Переход с динамического на статический язык (или наоборот) дает гораздо больше для общего развития, еще лучше, если этот язык из другой парадигмы.
В те годы я сам начал активно писать на Erlang, Clojure, Python и даже немного OCaml с Haskell, а сейчас ввожу в рацион typescript. Сильно ударился в ops тему, а так же разработку на frontend. Все это сейчас можно увидеть в наших курсах, статьях, вебинарах и других материалах.
Кстати, в том же 2013 году я познакомился с Рахимом на конференции Happydev в Омске, и выяснилось, что у нас примерно похожий взгляд на то, каким должен быть разработчик. Чем эта история закончилась — вам уже известно :)
Примерно полгода назад я приехал в Санкт-Петербург как консультант в компанию Петер-Сервис, с которой и по сей день сотрудничаю. Меня пригласили как человека, который поможет наладить инженерные практики и посмотрит свежим взглядом на код и то, как ведется разработка. Честно скажу, что сам я в такого уровня сложности проектах не работал никогда: огромный биллинг, более 70 команд, тысячи людей и продукт, который должен работать как часы. Было даже немного страшно, что мой уровень окажется недостаточным для каких либо изменений. В целом оказалось, что напрасно.
Жизнь показала, что проблемы у всех одни и те же. В компании ярко выраженная монокультура. Большая часть команд, с которыми я работал, пишет исключительно на одном языке, чаще это Java. Причем, многие ребята либо всегда писали на Java, либо уже давно не видели ничего другого. Когда мы стали разбираться с конкретными проблемами, на которые наталкиваются ребята, стало понятно, что многие из них давно и успешно решены в Rails гораздо более удобными способами. Для некоторых команд отличным решением было бы использование React вместо jsf. Причем сам jsf был выбран, потому что «архитектор его знал», а попробовать js никто бы не решился. Нет соответствующей экспертизы и никто не готов брать на себя эту ответственность (оно и понятно). Также мало кто использовал принципы автоматного программирования, что приводило к трудноподдерживаемому коду (как минимум одна команда полностью переделала архитектуру одного из ключевых сервисов, связанного с платежами, после того, как мы «копнули» в сторону автоматов). На стачке будет доклад про то, как ребята переделали архитектуру проекта в соответствие с этой парадигмой.
Главная проблема монокультуры в том, что даже если ваша экосистема предлагает отличные решения для повседневных задач, то даже теоретически она не может предложить лучшее решение для всех возникающих задач. Более того, люди склонны путать понятия легкий и простой. Когда на деле оказывается, что решение то, хоть и легкое (привычное), но совершенно не является простым.
Кроме того, отсутствие опыта работы с разными парадигмами делает программистов очень зашоренными. Вместо того, чтобы увидеть суть проблемы, он сразу представляет себе диаграмму классов. Особенно ярко это проявляется на собеседованиях. Когда при разговоре об общих концепциях программист может рассуждать только в терминах конструкций конкретного языка и на вопрос о том, как бы он сделал, если бы у него был другой набор примитивов, человек не может дать ответ. Как грустно шутил Задорнов, специалист по правому уху ничего не понимает в левом.
Собирая все вместе
- Учите программирование сразу через несколько разных языков
- Не будьте <язык>-программистом, различайте суть и реализацию
- Постоянно смотрите по сторонам (достаточно фоловить в твиттере правильных людей и аккаунты).
- Если вы писали только на статических языках, обязательно выучите динамический.
- Если вы писали только на динамических языках, обязательно выучите статический.
- Изучайте парадигмы программирования
- Старайтесь использовать в повседневной практике хотя бы два языка (с учетом засилья js это не так сложно)
- Если не получается предыдущий пункт, заведите себе хобби-проект на отличном от рабочего стеке