Алексей Гладких: «Возможно, в будущем Ruby станет мейнстримовым языком»
Программист-полиглот рассказал о том, как и почему менял стеки, а также о недостатках Go и C# и перспективах Ruby и Rust.
Иллюстрация: Teddy / Rawpixel / Annie для Skillbox Media
В интервью Алексей рассказал:
- о главных недостатках С# и Go;
- почему Python настолько трендовый инструмент, а Rust — самый недооценённый язык в низкоуровневом программировании;
- о перспективах Ruby на IT-рынке.
С# и Go: в чём недостатки творений Microsoft и Google
— В твиттере ты довольно радикально высказал своё отношение к C# и Go. Чем вызвана такая нелюбовь?
— В профиле у меня действительно всё несколько категорично — по большей части из-за юмористической составляющей. Всё не настолько плохо — в каждой шутке есть доля шутки :)
На самом деле C# был моим первым настоящим языком в работе. Всё, что было до, представляло собой школьное и студенческое баловство. А уже профессиональным программистом я стал именно с C#.
Сам выбор языка, по большому счёту, был продиктован условиями рынка города, в котором я живу, — Уфы. В середине 2010-х у нас медленно развивалось IT — долгое время сектор представляли только госконторы, которые и взяли на вооружение C# (там очень популярен софт Microsoft). Когда я искал работу, С# казался наиболее востребованным. В конечном итоге я его выучил и устроился в Транснефть, где проработал два года.
Мне не столько не нравится сам С#, сколько стеки, с которыми неизбежно приходится сталкиваться шарпистам. Я не могу назвать себя большим фанатом Microsoft. В добавок мне не нравятся все эти «церемониальные» языки, когда надо многое описывать и строчить кучу бойлерплейта. Хочется больше тратить времени на фичи, поэтому в какой-то момент я понял, что это немного не моё. Хотя в целом язык хорош. С С# я ушёл на Go.
— С Go по тем же причинам не сложилось или уже что-то другое?
— Нет, с Go другая история. За очень редкими исключениями Go противоречит всему тому, что я считал хорошим и правильным. В Go есть несколько классных вещей, которых мне не хватает в других языках, — в частности примитивы для работы с многопоточностью. Однако этот язык не очень согласованный.
Например, возьмём Python. В нём есть парадигма, общепринятый подход, путь, как что-то делать, и вытекающая из всего этого философия. За счёт этого любой популярный язык и развивается — многие нововведения происходят органично и соответствуют духу языка.
А вот в Go я, к сожалению, так и не смог прощупать эту философию. Сложилось впечатление, что ничего, кроме навязанного примитивизма, язык, в общем-то, не предлагает. Например, если сказать, что Go рассчитан для конкурентного программирования, тогда почему он не поддерживает иммутабельные структуры данных? Очень очевидная вещь для конкурентных программ, как мне кажется.
Меня также до сих пор раздражают срезы Go, которые сохраняют в себе ссылку на строку, а не копию строки, из-за чего можно получить очень интересные, скажем так, побочные эффекты. Какие-то вещи на Go получаются гораздо длиннее, чем на том же Python.
— Стоп, длиннее? А как же его хвалёная читабельность?
— Популяризаторы Go говорят, что код на этом языке очень читабельный, но… это не так :) Разумеется, что-то действительно легко воспринимается, но пиар-плакатики о том, что чуть ли не менеджер будет читать и понимать код, — крайне далеки от правды.
В этом плане Go гораздо ближе к Java, чем к Python. Многие говорят, что Go — это как Python, только компилируется. Но это тоже довольно красочное преувеличение. Если сравнить код этих двух языков, то можно понять, что уровень читабельности у Python в большинстве случаев будет гораздо выше.
В общем, по этому ряду причин в Go я задержался ненадолго. Но, так или иначе, я не жалею об этом — подобный опыт заставляет в целом смотреть на программирование более объективно, с разных углов.
Python и Rust: почему Python так популярен, а Rust — самый крутой низкоуровневый язык программирования
— Ты не раз упомянул Python. Сейчас работаешь преимущественно на нём?
— Да. Причём Python я начал изучать ещё в университете, и уже тогда безумно полюбил этот язык. Более того, на старом месте работы с С# я был одним из тех, кто внедрил этот язык программирования. По сути, я был питонистом, который вынужденно работал на С#. Это сейчас благодаря удалёнке можно легко устроиться даже в зарубежный проект, а пару лет назад это были единичные случаи.
— То есть на Python ты вернулся в период пандемии?
— Нет. Это произошло немного раньше. Я ушёл с С#, когда зарплатные цифры в резюме стали достаточно высокими. Да и сам я тогда сильно вырос профессионально — стал увереннее на интервью, мог что-то предлагать сам. Поэтому, даже несмотря на фактическое отсутствие «официального» опыта на Python, мне удалось устроиться в одну из уфимских контор, которая тогда уже взяла язык на вооружение.
В каком-то смысле это был не возврат, а моё становление как Python-разработчика. Я всегда считал себя питонистом. Даже когда кодил на Go и C#. Просто путь получился очень извилистым :)
— Чем уникален Python, что ты так сильно его полюбил?
— Python очень крут в возможности компактно перенести мысли в код. Пожалуй, среди мейнстримных языков Python — самый выразительный и простой. То, что на Go я напишу в 20 строчек, на Python уместится в одну. При этом оно не будет выглядеть как какое-нибудь непонятное регулярное выражение в Perl, которое напоминает незнакомый иностранный язык. И дело не только в эстетике. Короткий код проще читать. Скажу вот что:
Не всякий короткий код просто читать, но всякий код, который просто читать, — короткий.
И это очень важно для разработки в целом. Если код легко читать, то в нём — внезапно — будет меньше ошибок: их проще избежать, находить и править. Это делает код более надёжным, ускоряет весь процесс разработки, да и вообще работать со всем этим получается комфортнее и продуктивнее.
Ко всему прочему, мне безумно нравится роль Python в бизнесе. Я всегда отшучиваюсь знакомым-предпринимателям: «В любой непонятной ситуации заводи себе питона» :)
Этот язык может практически всё. Python — это некий суперклей, который соединяет буквально всё в высокоуровневой обёртке. Даже тот же С++. Хотя я, если честно, не такой большой фанат сишек. Кажется, что со многими низкоуровневыми задачами Rust справляется гораздо лучше. Поэтому я и выбрал его в пару к Python, что очень советую попробовать другим.
— Интересный микс. А почему именно Rust?
— Как я уже сказал, Python — это язык-клей. Почти всегда то, что на Python работает хорошо, где-то под капотом написано на условном С. То, что пишется на голом питоне, обычно не всегда работает на том же уровне — оно обычно банально медленнее. То есть на практике часто берутся несколько сишных библиотек и клеятся питоном в одно целое.
У всего этого есть большая проблема. Если мне надо написать что-то своё, то мне надо писать на С. А писать на С — это ад и погибель; а на С++ — это ад и погибель ++ :) Поэтому я и начал присматриваться к другим языкам.
В своё время я даже изучал такой малоизвестный язык, как D. Но попытки создателей языка сделать что-то понятное и системное, к сожалению, так и не увенчались успехом. D получился языком со сборкой мусора, что очень плохо для языков системного программирования. Тогда же я обратил внимание на Go и вот Rust.
Rust меня очаровал тем, что, делая какую-то низкоуровневую вещь типа сетевого протокола, я могу это выразить через систему типов так, чтобы любая вещь, которую мне сложно представить, работала точно правильно. То есть в Python я делаю всякие высокоуровневые вещи (для них он идеален), а если нужно спуститься пониже, то беру Rust.
Система типов Rust, кстати, очень похожа на Haskell, который я в своё время выучил из спортивного интереса, потому что все говорили, что он сложный. В Rust можно многое выразить так, чтобы максимально исключить возможность ошибки — этим он и хорош.
— Почему многие всё равно предпочитают сишки?
— В Rust используется много концепций, которых в мейнстримных языках вообще нет — в частности аффинные типы. Это какая-то сущность, которая в коде может использоваться только один раз, и мы можем статически это проверить. Например, возможность закрывать файл.
Я никогда не был экспертом в низкоуровневом программировании, но тем не менее какое-то представление о том, как работает та же операционка под капотом, имею. Поэтому позволю себе судить и заявить, что практически нет задач, с которыми тот же C++ справляется лучше Rust. Но!
Очень многие штуки, которых нет в Rust, уже существуют в сишках. Ещё, помимо какой-то нехватки фреймворков и библиотек на Rust, дело может быть в банальной привычке. Например, сфера, из которой C++ вряд ли уйдёт в ближайшие десятилетия, — геймдев. Там столько всего наворочено, что у Rust вряд ли есть какие-то перспективы.
— Как думаешь, у Rust есть шансы где-то полностью вытеснить сишки?
— Смотря где. Если с геймдевом всё очень сложно, то вот, например, в реализации драйверов, серверов и протоколов Rust намного круче сишек практически во всём. Он невероятно страхует программистов от ошибок. Лучше, чем все высокоуровневые языки.
Из-за того, что С низкоуровневый, в нём очень легко накосячить в памяти. Rust тоже низкоуровневый, но в нём сложнее ошибиться, чем даже в Java или Python. Но этому есть высокая цена — порог вхождения (кстати, ещё одна причина, почему Rust не популярен).
Про Rust не так много образовательного контента, но то, что есть, — сделано очень качественно. Rust-book (eng, ru) — наверное, лучшая вводная книга по языкам программирования, которую я видел. Но вот берёшь оттуда программу, вводишь — работает; чуть-чуть меняешь — не работает. Приходится постоянно воевать с компилятором. Он параноик, который не даёт сделать даже гипотетически неправильные вещи. Это отпугивает новичков.
Про Rust даже шутят, называя его compile driver development. Если программа скомпилировалась, то она правильная.
— Чем же хорош такой компилятор?
— Rust взял на себя всё, что происходит в программе на этапе компиляции. В Rust нет runtime, а сам компилятор очень строгий и не позволяет делать очень многие вещи. Поэтому типичная ситуация вроде той же гонки данных в Rust не возникает. Почему?
Например, представим, что у нас есть два потока. Если мы создаём объект и он мутабельный, то мы не можем обращаться к нему сразу с двух объектов (я называю объектами для упрощения — в Rust другая терминология), — он просто не скомпилируется. То есть это не выяснится в процессе: вот у нас runtime error и мы не можем обращаться сразу с двух объектов. Он просто изначально не будет компилироваться.
Если очень коротко, то в Rust многие процессы контролируются на уровне компиляции — это избавляет программиста от многих лишних действий. То есть в целом компилятор Rust — это скорее плюс, чем минус. Просто к нему надо привыкать.
Кстати, другая классная штука Rust — система отслеживания ошибок. Rust возвращает ошибку как return, но делает это через тип данных result или error (в случае ошибки). И вот этот result мы должны проверить. Как следствие, у нас не может возникнуть ситуации, когда мы не обработали исключение. Кое-где статические проверки помогают не ошибиться.
— А есть ли в Go или С# что-то такое, чего тебе безумно не хватает в Python или Rust?
— Безусловно. Оговорюсь, что выбор языка сильно зависит от самого человека и его задач. Я не считаю, что тот же Go — это абсолютно бесполезный инструмент. Просто конкретно мне и под мои задачи подходят больше Python и Rust.
В Python точно не хватает быстродействия и многопоточности (она есть, но сделана так, что проще сказать, что её нет). Парадокс, но в Go лучше реализован один из ключевых принципов дзена питона: «Должен существовать один и желательно только один очевидный способ сделать это».
Сейчас в комьюнити питона существует проблема: многие вещи люди делают по-разному и нет какого-то общепринятого подхода. В этом плане Python стал напоминать JavaScript на бэкенде. Думаю, связано это с тем, что в какое-то время питонисты начали гнаться за трендами конкурентности, не совсем продумав свой путь. Go в этом плане гораздо лучше — многое стандартизировано и более понятно.
Сейчас Ruby, который отстаёт от Python в вопросах конкурентности, асинхронности и многопоточности, двигается по гораздо более перспективному пути. И за счёт этого у него даже может произойти новый рассвет.
Ruby — будущее IT-рынка?
— В твиттере ты пишешь, что изучаешь сейчас Elixir и Ruby. Это как-то связано с возможным «рассветом» Ruby?
— Не совсем. Эти два языка мне в первую очередь просто понравились. С Ruby я познакомился через Elixir, на котором тоже долгое время всерьёз думал стать разработчиком.
Ruby обворожил меня тем, что он очень похож на Python, с той разницей, что многие вещи, которые мне нравятся в Python, в Ruby ещё круче. Но есть одно «но».
То, что я люблю в Python, в Ruby сделано лучше, но то, что мне не нравится в Python, в Ruby сделано ещё хуже.
Такие вот забавные крайности :)
— А в чём это проявляется?
— Ruby ещё медленнее. Про многопоточность, асинхронность и конкурентность я уже говорил — в будущем, возможно, Ruby превзойдёт в этом Python, однако пока он отстаёт.
Но при этом синтаксис Ruby ещё более высокоуровневый. Когда я работал на Python, я думал, что это самый высокоуровневый язык, но чемпионом оказался Ruby. И это очень большой козырь в современном программировании.
Я повторюсь: дело не только в эстетике. Когда ты видишь весь код на одном экране с невероятной логикой, его проще читать, проще править, проще что-то заметить. Это позволяет придумать больше за меньшее время.
— Не было ли мысли полностью перейти на Ruby?
— Нет. Python сейчас слишком передовая технология. Да и язык в любом случае мне также импонирует. Хотя отмечу, что перспективы у Ruby огромные, причём даже с точки зрения рынка труда.
Из-за того, что сейчас рулит удалёнка, соотношение вакансий к соискателям условно стало общим для всего мира. Да, Ruby не популярен, мало кто на нём работает, но Ruby-разработчиков ещё меньше :)
Как результат, можно найти кучу вкусных предложений — зарплата рубиста нередко выше зарплаты питониста или джависта. Такие офферы, кстати, могут стимулировать и интерес к языку со стороны других программистов.
Ну, и не стоит забывать, что Ruby не слишком теряет позиции с точки зрения популярности. Он просто стагнирует. Есть ещё один занимательный факт. Наверняка многие слышали, что почти 80% интернета — это PHP. Так вот, у Ruby почти 6% — внезапно больше, чем у Python (1,4%) и JavaScript (1,8%).
— Стоп. Как так получилось?
— Огромный толчок Ruby дала популярная ныне площадка Shopify, которая, по сути, является сейчас второй CMS в мире по популярности. Shopify написана на фреймворке Ruby on Rails :) В Америке вообще бизнес, особенно стартапы, любят Ruby.
— Почему тогда никто не бежит учить эту тёмную лошадку?
— В этом и суть. Да, Ruby круче Python как высокоуровневый язык, но в то же время у его синтаксиса есть нюансы, к которым дольше нужно привыкать. Да, офферы на Ruby часто увесистее, чем на JS и Python, но и требования обычно мидл+.
То есть Ruby — это не самый лучший язык для новичков: мало образовательного контента и вакансий для входа с нуля. Это язык для опытных разработчиков, к которому нужно прийти осознанно. Звучит так, что рубисты — это прям какие-то серые кардиналы IT-мира. Но я действительно думаю, что, возможно, в будущем Ruby станет мейнстримовым языком :)
— C#, Go, Python, Rust, Elixir, Ruby… Тяжело ли держать это всё в голове?
— Выучить язык программирования не так сложно. Я вообще стараюсь каждый год учить новый язык, чтобы вдруг не упустить какую-то важную технологию или тренд. Ко всему прочему, это:
- качает мозги;
- заставляет думать нестандартно в рамках основного языка;
- открывает больше возможностей с точки зрения рынка.
Смена стеков также очень помогает с выгоранием, когда какой-то язык изрядно осточертел — очень рекомендую мидлам и сеньорам.
Разумеется, поддерживать на профессиональном уровне знания всего и сразу невозможно. Что-то будет неизбежно просаживаться, поэтому всегда стоит держать в резюме стек, в котором есть твёрдая уверенность.
— Напоследок — какой язык ты бы посоветовал изучать?
— Как я уже говорил, всё очень индивидуально. Кого-то воротит от TypeScript, а кому-то нравится разбираться в синтаксических джунглях С++. Но если давать универсальные советы, то новичкам лучше входить через Python или JavaScript — куча вакансий и образовательного контента. А Python один из самых простых языков программирования.
Опытным разработчикам, в особенности питонистам, посоветовал бы присмотреться к Ruby. Через несколько лет с ним можно запросто оказаться востребованным специалистом там, где пока толком нет специалистов :)