среда, 26 апреля 2017 г.

[prog.thoughts] Вероятно, наступило время языков, на которых можно "просто педалить код"...

У меня в блоге давно не было псевдофилосовских рассуждений на тему языков программирования и тенденций их развития. Тому есть свои причины. Мне самому уже, в силу возраста, не так интересно тратить время на пустое сотрясение воздуха. Блог живет уже достаточно давно и в нем подобные темы уже поднимались неоднократно. Плюс к тому, текущие дела и заботы заставляют больше смотреть в сторону проблем маркетинга и позиционирования на рынке, а проблемы технологий и языков программирования при этом отходят на второй, третий или даже четвертый план.

Тем не менее, есть ощущение, что такие языки, как JavaScript и Go (в особенности Go), становятся все более и более востребованными в нашей индустрии... Ну, если и не восстребованными, то одними из самых обсуждаемых. Хочется разобраться, почему так происходит и, если получится, понять, чем это грозит и, может быть, придумать, как этим можно воспользоваться.

Итак, вот есть язык Go. Который, на первый взгляд, выглядит очень простым и практичным. Я бы, правда, сказал, что он примитивный и убогий, ну да я старый маразматик, мои слова все равно ничего не изменят ;) Вот только на второй взгляд, выясняется, что в Go так же есть приличное количество своих косяков и неоднозначностей. Так что мифы о простоте Go, наверное, несколько преувеличены. Тем не менее, большое количество людей Go пользуется, пользуется с удовольствием и, что удивительно, не особо хочет чего-то другого.

Недавно у меня возникло ощущение, что я таки окончательно понял, почему именно так.

В какой-то момент все само собой разложилось по полочкам и стало понятно, почему с Go происходит именно так. Ключевым моментом стала увиденная где-то (возможно, в Facebook-е) заметка, в которой разработчик на Go троллил разработчиков на других языках программирования многократно повторяя, что на Go можно "просто педалить код". Мол, пока Java-программисты спорят о том, какие паттерны они будут задействовать и сколько абстрактных фабрик им придется построить, Go-программисты просто педалят код.

Не смотря на то, что заметка носила троллинговый характер, ее автор явно узрел в корень и написал чистую правду: язык Go нужен для того, чтобы просто педалить код.

Это заставило меня вспомнить свое впечатление от знакомства со средствами работы с базами данных времен начала 90-х. Были такие вещи, как dBase (FoxBase, FoxPro) и язык Clipper. Очень активно использовались для разработки прикладного софта, вроде бухучета, складов, картотек и т.д. По сравнению даже с Pascal, не говоря уже про C и C++, это были ну очень ограниченные по своим выразительным возможностям языки. Но вот что важно: для своих предметных областей они позволяли педалить код гораздо быстрее, чем на том же самом Pascal-е (про C вообще можно было не говорить).

Сдается мне, что языкостроение давным-давно разделилось на несколько направлений. Из которых в контексте данного разговора интересно только два. Первое направление -- это разработка заточенных под специфическую предметную область специализированных языков программирования. Вот тех же самых ForBase или Clipper. Языки эти могут быть весьма убогими, не сильно продуманными, напоминающими лоскутное одеяло, сшитое из совершенно разных кусочков... Но зато они отлично закрывают свою узкую прикладную нишу. Беря такой язык ты просто педалишь конкретный прикладной код и понимаешь, что вряд ли какой-то другой язык мог бы дать тебе такую же скорость разработки и качество результата (за те же деньги, по крайней мере).

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

Ну вот, например, нужен вам графический редактор уровня Photoshop или Corel DRAW. В голом C или даже в голом C++ нет никаких готовых средств для создания графического редактора. Однако, и C, и C++ позволяют разработчику сформировать набор специализированных библиотек, на базе которых задача становится уже вполне себе решаемой. При этом, правда, такие библиотеки могут оказаться совершенно бесполезными для написания, скажем, СУБД уровня MSSQL или Oracle. Но это уже проблемы разработчиков СУБД :)

Так вот, целью универсальных языков программирования является предоставление разработку такого набора низкоуровневых примитивов, из которых разработчик сможет создать нужные ему строительные блоки. Возможно, даже несколько слоев этих самых строительных блоков (например, на базе C++ строится STL, на базе STL строится Boost, на базе Boost-а -- еще какой-то более приближенный к прикладной задаче слой и т.д.). Поэтому с 1970-х годов и до недавнего времени универсальные языки программирования развивались так, чтобы становиться все более и более выразительными. На моей памяти примерами этого стали такие языки, как Ada, которая оказалась мощнее и выразительнее Pascal и Modula-2, под влиянием которых она и создавалась. Или C++. Или Eiffel.

Особенно показателен в этом плане пример Java. Там изначально под флагом "мы выбросили из C++ все самые опасные фичи" создали такой куцый язык, что сейчас даже страшно вспомнить. Но затем в Java пришлось добавлять вещи, которые реально упрощают жизнь программисту. И современная Java, к счастью, сильно ушла от Java времен 1995-го года. А авторы C#, имея перед глазами пример Java, прошли этот путь гораздо быстрее.

Однако, вернемся ближе к телу. Развитие универсальных языков шло по пути их усложнения. Ada была гораздо сложнее в изучении, чем Pascal и Modula-2. Про сложность C++ и говорить не приходиться. Даже Eiffel, весьма продуманный и, я бы сказал, довольно минималистичный язык, не так уж и прост и требует изрядного перестроения мозгов и взглядов на то, как нужно проектировать и реализовывать программы. Как сказано выше, современная Java уже совсем не так проста, как Java 1.0. Собственно, тоже самое можно сказать и про современный C#. Ну а Scala всегда была сложной :)

Эта сложность универсальных языков программирования, имхо, полностью оправдывается, когда универсальные ЯП используются для создания инфраструктуры. Т.е. сложность C++ вам нужна, когда вы пишете свой аналог STL для специфических условий или же пишете собственную NoSQL СУБД. Но эта сложность совершенно не нужна, когда вам нужно просто раз в 10 секунд прочитать значение какого-то датчика и записать полученное значение в определенный MQ-шный топик.

И вот тут оказывается (да, я тормоз, для меня это "внезапно"), что за минувшие 25-30 лет огромное количество инфраструктурных задач уже было успешно решено тем или иным способом. И еще более огромное количество задач сейчас лежит в области именно прикладного программирования. Когда задачей обычного разработчика является написание прикладного "клеевого кода". Т.е. реализация взаимодействия с другими компонентами по типу: нас дернули отсюда, взяли параметры запроса, проверили, если вот это, то спросили вот у этой подсистемы, а если вот это, то вот у той.

Т.е. за последние годы сформировался набор прикладных ниш, для которых нужны не универсальные языки общего назначения, пусть даже и снабженные большим количеством прикладных библиотек, а современные аналоги dBase и Clipper-а. В хорошем смысле этого слова :)

Почему же нужны специализированные языки, а универсальные не подходят? Главная причина в человеческой тупости, ибо количество разума на планете есть величина постоянная, а население-то растет. Ну причин много, полагаю. Наиболее важные -- это более высокий порог входа. Изучить Go все-таки проще, чем какой-нибудь Eiffel, Rust или C++. А изучать придется, т.к. абстракции все-таки текут и когда прикладному разработчику приходится заглядывать в потроха используемых библиотек, то ему минимального знания языка программирования явно не хватит. Плюс к тому, чем меньше способов решить проблему, тем лучше. Когда у разработчик выбирает бросить ли ему исключение или вернуть Option, это это проблема выбора. Таких проблем быть не должно. Плюс к тому, заточенный под предметную область язык не должен давать возможность писать мудреный код, требующий знаний каких-то специфических особенностей языка программирования (вроде ADL в C++ или специализаций шаблонов).

Получается, что специализированный язык в принципе должен быть избавлен от средств повышения выразительности, которые специально закладываются в универсальные языки программирования. Ведь сложность -- это проблема для специализированного языка. Поэтому специализированные языки должны двигаться в противоположном направлении и должны избавляться от всего, что может усложнить жизнь среднестатическому прикладному программисту. Что мы, собственно говоря, и видим на примере языка Go.

Какой же сухой остаток можно выделить из всего вышесказанного?

А вот фиг его знает :(

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

В этом сужении "инфраструктурного программирования" плохо то, что зарабатывать на такого рода задачах будет все сложнее и сложнее. Поскольку сюда же нужно добавить и тенденцию разрабатывать OpenSource продукты, за которые большинство пользователей просто не платят. Но хорошо то, что у людей, не боящихся сложных универсальных языков программирования, конкурентных преимуществ должно быть побольше. В этой нише.

Есть ощущение, что Go -- это всерьез и надолго. В ИТ с каждым годом вливается все больше и больше народу. Объективно, для изрядной части даже современная Java -- это уже over complicated. А Go -- в самый раз. Будем посмотреть, как все это повлияет на ИТ в перспективе 5-10 лет. Хотя есть ощущение, что ИТ сейчас настолько сегментировано, что тенденции в одном сегменте вряд ли оказывают влияние на другой сегмент. Только вот про сегментацию постоянно забываешь, ибо на слуху самые горячие темы -- вроде front-end-а на JavaScript и back-end-а на Go. И складывается ощущение, что кроме этих горячих тем ничего больше нет. Что совершенно не так. Но это уже совсем другая история.

PS. Думается, что Erlang -- это еще один пример специфического прикладного языка, который взлетел именно тогда, когда появилась насущная необходимость в решении определенного рода прикладных задач в Web-е и коммуникациях через Интернет.

Комментариев нет: