Пользователь
121,5
рейтинг
16 ноября 2015 в 16:46

Разработка → Лучше или хуже перевод

Перевод статьи «For Better or For Worse» разработчика из компании DataDog Inc. Статья посвящена вопросу дизайна языков программирования и связи дизайна с попытками оценок качества языков. Частично является ответом на недавно переведенную тут эту статью.

В программистской тусовке возникает мем об “объективном качестве” дизайна Go. Буквально на днях я встретил его в статье про выбор языков от Honza, где он был очень хорошо виден:
Учтите, язык объективно очень плохо спроектирован. [...] И, при этом, Go гораздо более популярен, чем Haskell, если верить GitHub. При этом, уже столько отличных проектов, написанных на Go, вроде Docker, InfluxDB, etcd, Consul, Prometheus, packer и других.

Я думаю, что это крайне интересный набор противоречий, и автор с этим согласен.

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

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

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

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


Чем хуже, тем лучше


Это современная манифестация того, что Ричард П. Гэбриел описал в своём классическом эссе “Чем хуже, тем лучше”. В нём, Гэбриел озвучивает 4 главных ценности дизайна системы, которые могут быть в противоречии: простота, правильность, логичность и полнота. Далее он описывает две конкурирующие философии: подход MIT, ставящий выше правильность и логичность, и подход Нью-Джерси, ставящий выше простоту реализации.

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

Простота стала вероятно ещё более признанным приоритетом с момента написания эссе в 1990, по мере того, как мир компьютеров разительно изменился.

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

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

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

Природа качества


Несмотря на тренд в сторону простоты, обсуждения языков программирования, как правило, проходит во фрейме MIT-подхода. Это было так успешно и популярно, что это уже незаметно и даже неочевидно.

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

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

Подход Go был в том, чтобы начать с C, затем выкинуть вещи, которые было сложно использовать правильно, и заполнить промежутки, пока не останется ничего достаточно простого или достаточно ортогонального, чтобы добавить. Взять известный набор компромиссов, известную точку на континууме между простым и усложнённым, и сделать небольшие изменения, основанные на дюжинах аккумулированных лет практического опыта разработки в реальном мире. Это непростительно прямолинейный инженерный подход к построению систем.

Безусловно, вы не можете положить всё на алтарь простоты. Многие низкоуровневые байткод- и ассемблерные языки легко написать и портировать, но их интерфейсы слишком сложны для использования программистами. Необходимо достичь баланса между количеством фич и простотой языка.

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

Чтобы узнать, что же решат присяжные насчёт Go, могут понадобиться годы. Нет простых и ясных способов измерить насколько “хорош” язык, так что это, в итоге, определяется по тому, насколько популярные системы процветают, а не популярные вянут и умирают. Вопреки своим очернителям, популярность Go продолжает расти благодаря своим сильным сторонам, а это значит, что он заслужил больше времени для оценивания. Если же его кажущиеся слабости реальны, мы непременно увидим их в реальном мире, по мере того, как созданные на нём системы достигнут зрелости, но пока что перспективы очень хорошие.

Зато что мы видим, так это то, что Go выбирают проекты, которые ещё лет 5 назад даже не представлялись возможными из-за ужасной ситуации с инструментарием в их нише. Даже если Go в конечном счёте провалится, чем дольше он будет расти, тем более вероятно, что следующие поколения языков будут начинать с Go, точно так же, как Go начал с C, и, учитывая родословную последнего и остающуюся силу, я бы сказал, что это будет огромный успех.
Перевод: Jason Moiron
divan0 @divan0
карма
128,0
рейтинг 121,5
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (94)

  • +4
    Я так и не понял, о чем эта статья ;) Никаких аргументов ни за, ни против. Куча ссылок на другие ресурсы и лирическое отступление в прошлое.

    Разумеется, претензии к переводчику не имеют отношения. За перевод — плюс.

    Но я так и не понял, почему Go плохой или хороший. Кстати, он плохой или хороший? ;)
    • 0
      Хороший
      • +4
        Всё равно его не брошу — потому что он хороший (с)
    • +21
      Это очередной пост для срача. Человека просили писать интересные практически статьи, но похоже это не входит в интересы и пиар кампанию.
      • –4
        Отнюдь. Это отличная статья, которая получила заслуженное одобрение в англоязычном сегменте интернета. Лично я считаю её более чем интересной и познавательной.

        И мне не сильно понятна ваша фамильярность. Помимо лично ваших «просьб писать» что-то, у меня есть собственные соображения о том, что писать и/или переводить, а также мнения других людей, кроме вас.
  • +8
    Такие споры давно уже пора закончить тезисом «лучше то, что удобнее использовать конкретному человеку». Кому-то просто физически нужны средства для построения более высоких абстракций, кто-то любит обходится более простыми инструментами. Крики «СЛОООЖНА» не менее смешны, чем «отстой, застрявший в каменном веке».

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

    Многие говорят, правда, что при разработке на более «сложном» языке понадобится меньше программистов) Но мне тут трудно судить.
  • +13
    Когда люди с таким видением пытаются объяснить популярность Go, они неизбежно приходят к парадоксу. Если Go настолько плох, почему он так популярен?

    1. РНР гораздо лучше Go
    2. Миллионы мух не могут ошибаться

    А всё из-за двух ошибок:
    1. популярность и хорошесть коррелируют, но не очень.
    2. хорошесть относительна и контекстно-зависима.
    • 0
      В случае с PHP немалую роль сыграл фактор низкого порога вхождения.
      • +1
        Плюс сайтостроение тогда развивалось семимильными шагами. PHP угораздило попасть в очень восстребованную нишу, имея достаточный набор характеристик дял успешного последующего развития.
        Кстати, так как у Go немного другая ниша (хотя и частично пересекающаяся), то не стоит сравнивать их популярность напрямую.
      • +5
        Как и с Go, как и с Go.
        • 0
          Я наверное не слишком одарен, но никогда не понимал что значит эта фраза. А куда тяжёлый?
      • +3
        Откуда взялось это расхожее мнение про низкий порог входа для PHP? Низкий по сравнению с чем?
        Только не приводите в пример С++ — я на нём много лет программлю. Начать на плюсах принципиально проще.
        • +1
          Хех, я, по сути, программирование начал с плюсов. Бейсик и паскаль в школе не считаю как-то, но реальное программирование началось на С++. И, скажу я вам, это было не сложно, хотя программа включала все от и до. И как же я рад, что я начал с этого. Начинать с PHP — мне кажется, что там слишком много инфраструктуры надо понять, прежде чем войти в него. Веб-сервер, хтмл, файловая система хоста, кто и как это все запускает, куда девается это все после закрытия странички, что это за сессии и прочее и прочее. Я сам просто помню все эти вопросы, когда я с этим всем знакомился — это ж совершенно не традиционная модель исполнения кода.
          • 0
            Не надо ничего понимать, надо в html написать <?php print «hello» ?>. И дальше инкрементально.
            • +2
              Написал всё в точности как вы сказали. Открыл файл в браузере. Что я делаю не так?

              image

              И могли бы вы пояснить что в данном случае вы подразумеваете под «инкрементально»?
              • 0
                Да, конечно. Вы как раз продемонстрировали очень хороший пример. У вас не установлен сервер, который будет обрабатывать php.

                Предвижу вашу реакцию — чего за сервер, мне что его ставить, почему всё так сложно? Нынче есть много пакетов, которые ставят всю инфраструктуру в один клик и такой пакет вам, скорее всего поставит старший товарищ. Или вы сам по мануалу.

                Это, кстати, часть инкрементального обучения — узнать, что для php нужен сервер. Следующим шагом будет выводить вместо hello текущую дату. Потому ещё что-нибудь такое. Потом вам расскажут, как делать пункты меню.

                Потом вам захочется выводить на странице то, что ввёл пользователь в какое-нибудь поле. И так далее.

                • 0
                  Меня друг попросил написать ему интернет-магазин, я подумал что это действительно очень просто. Хнык :`(

                  Это стёб, если что. Попытка демонстрации того, что порог вхождения в РНР не такой уж низкий. Во всяком случае не ниже, чем в go, где по крайней мере веб-сервер с сервером приложений ставить не надо. И да, там не только в веб-сервере дело. Кавычки-то не настоящие! И насчёт инкрементальности в этом контексте тоже шутить можно много. Какой язык программирования можно изучить «не инкрементально»? Всё «инкрементально» в этом мире. Кроме того, спустя некоторое время оказывается, что дело вобще не в конкретном языке программирования, а в эфемерных «опыте», «пряморукости», «голове», «архитектуре» и прочей чепухе. А язык… французский лучше.
                  • 0
                    Ну я понял, что стёб. И я также согласен, что реально для того, чтобы писать на php надо знать очень много — что такое http, что такое сервер, как это всё работает и т. д… Всё так.

                    Только деньги с php можно начать получать уже после того, как понял что можно написать <?php pring «hello» ?> и научился заливать это на ftp. Деньги будут платить уже за незначительные правки существующих незначительных сайтов. Для того, чтобы получить деньги с С++ надо учиться ещё долго. Вот что я имею в виду, когда говорю про низкий порог вхождения.
                    • –1
                      А вот это уже очень интересный момент. Получается, с точки зрения потребителя-разработчика проекта РНР действительно намного лучше Go, т.к. существенно проще в плане подержки, читаемости, понятности и т.п. И с точки зрения потребителя-владельца проекта тоже лучше, т.к. разработчики дешевле (не нужно быть супер-героем, чтобы разобраться в коде).
                      • +1
                        Почти. Большиство задач, которые нужно решить потребителю-владельцу очень просты и поэтому для их решения можно обратиться к низкоквалифицированным программистам на php, а php в свою очередь позволяет низкоквалифицированным программистам быстро и дёшево решать простые задачи.

                        С ростом сложности задачи использование php становится всё менее и менее оправданным. Пока в один прекрасный момент система не разрастается до такого размера, что для продолжения работы требует специалистов с очень высокой квалификацией. За решения задачи такого рода с помощью, например, java можно было бы заплатить существенно меньше денег. Но переписывать уже поздно. Вот такая инкрементальность.

                        Но php всё равно очень популярен потому что:
                        1. Большинство систем не разрастается до такого уровня.
                        2. Язык развивается давая разработчикам средства для решения всё более сложных задач.
              • +1
                Написал
                #include <iostream>
                
                int main ()
                {
                    std::cout << "Hello, world!" << std::endl;
                }
                


                Сохранил как program.exe, программа почему-то не запускается, что я делаю не так?

                Тулчейн везде нужен.
                • 0
                  А кто вам советовал так программы писать? Я не советовал. И не утверждал, что куда-то там низкий порог входа.
                  • 0
                    Просто аналогичный аргумент применим к любому языку, как я уже сказал. «кто и как это все запускает, куда девается это все после закрытия странички программы» так вообще практически, как видите, без изменений применимо.

                    Но у PHP всё-таки кривая обучения немножко более пологая.
                    • 0
                      Просто аналогичный аргумент применим к любому языку

                      Совершенно верно, именно это я и хотел продемонстрировать. Получается, порог входа в РНР как минимум по этому фактору уже не такой уж низкий. Тогда в чём он низкий?

                      Насчёт кривой обучения РНР затрудняюсь оценить. Наверное да, она не сильно крутая (если я правильно понимаю этот термин). А вот авторы Go, видимо, хотели сделать эту кривую очень короткой. А получилось так, что помимо простого синтаксиса и довольно небольшого количества сущностей, надо вбить себе в голову еще некоторое число противоестественных и/или непривычных концепций, чтобы этим можно было хоть как-то пользоваться не «для поиграться».
                      • 0
                        Тогда в чём он низкий?

                        Вот скажите сами, только честно-пречестно, если Вас попросят написать простенький веб-сайт — Вы возьмете C++ или PHP?

                        Или даже проще — сайт уже есть, а Вас просят написать дополнительный скрипт (слово скрипт тут не означает что от Вас требуют конкретную технологии, это просто обработчик фиксированного урла, а /counter.cgi это или /counter.php — роли не играет) — счетчик посещения страниц, или ссылок…
                        Ваш выбор? C++ или PHP? И почему?
                        • 0
                          PHP, конечно же. Он понятнее, читабельнее, проще и дешевле в разработке и поддержке.
                          • +2
                            Ну вот Вы сами ответили на свой вопрос )
                            Если отвлечься от факторов, одинаковых для C++ и PHP (т.е. иметь понятие о протоколе HTTP, принципах работы HTML и т.д.) — то на PHP получить требуемую функциональность (сейчас речь о веб-программировании, разумеется, а не вообще-вообще) можно существенно проще, чем на C++, можно иметь более низкую квалификацию. Если это не называется «более низкий порог вхождения», то я уже и не знаю, что тогда называется.
                            • +1
                              Чтобы спаять схему, что вы выберете — молоток или паяльник? Конечно паяльник. Вывод: у паяльника более низкий уровень вхождения.
                              • 0
                                У Вас пример неудачный — молотком схему не напаяешь.
                                Я ж не прошу Вас писать скрипты на SQL.
                                Веб-скрипты можно писать как PHP, так и C++, но при прочих равных выбирают PHP, потому что на нем это сделать проще.
                            • 0
                              Это называется специализация, а не низкий порог вхождения. Зато вот какой-нить сервер на кастомном протоколе я бы начал писать на плюсах, а не PHP. Сокеты, thrift и вперед.
                              • 0
                                C++ это универсальный язык программирования, и PHP не сильно от него отстает — множество вещей (где не требуется низкий уровень) можно реализовать на обоих языках.
                                Возьмем пример, под который PHP не заточен — написать демона хостинговой панели, который будет случать порт, ловить команды по кастомному протоколу и выполнять их. Вы можете со мной не соглашаться, но я считаю, что PHP программист получит требуемый функционал быстрее, и квалификация от него будет требоваться ниже, чем для C++ программиста. И ещё не факт, что в PHP версии будет больше уязвимостей, чем в C++ (это я про потенциальные переполнения буффера и прочие прелести таких низкоуровневых языков как C++).
                              • +1
                                Именно в этом и заключается мой изначальный посыл. Нельзя говорить хуже-лучше, проще-сложнее, дешевле-дороже в отрыве от контекста, от задачи, от требований и т.п. РНР стал популярным из-за популярности задач, которые он решает. Но это не сделало его простым языком и не понизило требования к разработчику.
                • 0
                  О тулчейне можно узнать много позже. Обычно изучение С++ начинается с популярной среды разработки, которая ставится в два клика, в которой вы пишите этот маленький код и нажимаете >> (запустить) и всё работает.
                  А что там под капотом происходит — до поры до времени знать не нужно.
                  • 0
                    У меня в 11 лет так не получилось. Была какая-то книга, там был компакт-диск с каким-то проектом для какой-то вижуал студии. Что за проект и зачем он нужен? Что за вижуал студия? Я тут $gamename поставил, у меня теперь в Панели Управления есть Microsoft Visual Studio Redistributable, это оно?

                    Это потом повезло потыкать в BC++3.1, где никаких проектов не нужно, и повезло попасть на удачную книгу без всяких вижуал студий, а потом уже стало более-менее понятно, что вообще такое компиляция и так далее.
                    • +1
                      В 11 лет это действительно сложно без посторонней помощи. У нас в школе с 6 класса преподавали сначала Quick Basic потом Turbo Pascal. Знал оба.
                    • 0
                      Что-то вспомнились из моего детства 4 дискеты, принесенные из института старшим братом моего друга, со словами «Это С++! Самый крутой язык в мире!» И тоненькая жёлтая книжка, сразу начинавшаяся с сакрального «Объект — это инкапсулированная абстракция, которая включает информацию о состоянии и чётко определённое множество протоколов доступа». Что это такое я понял только несколько лет спустя. :)
        • 0
          Я начинал с JS (снежинки в браузере, суровый 2001-й, мы развлекались, как могли), потом был PHP, потом был C++, да. Не могу сказать, что на них начать принципиально проще.
          • 0
            Вот в JS действительно порог низкий — не нужен веб-сервер со всей инфраструктурой.
            • +1
              Так он и в PHP низкий, об этом думать особо не пришлось. Ну или мне так уникально повезло купить нужный номер то ли Каскепа, то ли Подводной Лодки, где на компакт-диске был то ли Xitami, то ли Denwer (помню, оба тыкал, не помню, где из них был PHP), который разворачивался в три клика.
      • –1
        Можно подумать, у Go он большой.
    • 0
      Я бы добавил еще 1 момент, что фреймворки и CMS — это уже по-сути новые системы (и часто языки там свои). И вопрос не том, насколько популярен PHP, а насколько вовремя появились Wordpress и Joomla, и без альтернатив в других языках.
  • +14
    Собственно и Go набрал популярность не потому тому, что он такой весь из себя идеальный, а благодаря вере людей в то, что именитый чел из крупной конторы фигню не сморозит. А все недостатки легко обращаются в достоинства ввиду различных когнитивных искажений. Очень «приятно» потом за такими людьми разгребать «очень простой код», написанный в процедурном стиле методом копипасты.
    • +2
      Если Вас не затруднит — можете уточнить один момент? Про «разгребать код» это Вы написали про собственный опыт сопровождения Go проекта после других программистов?
      • –2
        Нет. Это про собственный опыт разгребания «очень простого кода», где сложность не инкапсулируется в абстракциях, а выпячивается наружу и приводит к копипасте да кодогенерации.
    • –3
      Но ведь это же неправда. Никто никогда не выбирает язык из-за «именитых челов». Писать-то программисту, а не челу.
      • 0
        Правда состоит в том, что язык, платформу и фреймворк выбирает не рядовой программист, а техдир, который не всегда достаточно компетентен. А критерии выбора включают в себя множество не относящийся к языку вещей: стоимость и число свободных программистов (чем язык сложнее, тем сложнее найти хорошо знающего его программиста и тем больше он попросит за свою работу), перспективность (если язык продвигает большая контора, то вероятность, что она забросит его через год ниже, чем если никто за ним не стоит), компетентность существующих сотрудников (время на переобучение — не бесплатно, качество кода после переобучения — не гарантировано).
        • +2
          Ну вы своим комментарием и подтвержаете мой, вероятность, что техдир выберет язык по крутости, создавшего его «чела» равна примерно нулю. Хаскель тоже не последние люди в индустрии написали и не из самых маленьких компаний, однако его применение ограничивается энтузиастами.
          В общем вы написали
          Собственно и Go набрал популярность не потому тому, что он такой весь из себя идеальный, а благодаря вере людей в то, что именитый чел из крупной конторы фигню не сморозит.

          и вторая часть предложения это неправда и будет неправдой для любого языка.
          • +3
            При определённой интерпретации применение многих языков будет ограничиваться лишь энтузиастами.

            Ну и да, про Роба Пайка можно сказать, что вот, он Юникс пилил, десятилетия опыта продакшена, всё такое, фигни не сморозит (что и говорят). А с Haskell что там? Ссылки на кучи публикаций и академический ресёрч выглядят не так эффектно для среднего программиста, выбирающего себе язык.
          • +1
            Именитость чела влияет на то, будут ли к особенностям языка относиться как косякам или как к откровению. А вот выбирают язык в частности из-за того, что за его плечами стоит крупная контора.

            • 0
              Забавно, что ваш ход мыслей в статье упомянут :)
        • 0
          а техдир, который не всегда достаточно компетентен.
          В конторах, доросших до существования техдира, решения о выборе платформы принимаются обязательно с участием компетентных людей. Иначе такие конторы до появления техдиров не дорастают.
          Впрочем в чем-то вы правы. Сам участвовал в проекте, где «сверху» навязали СУБД MSSQL, как корпоративный стандарт для потенциальных клиентов. Это сильно усложнило проект. Впрочем внутренний заказчик был предупрежден об усложнении и сознательно на это пошел.
          • +1
            Нельзя быть компетентным во всём. Да и техдирами становятся далеко не только разработчики языков программирования. Я бы разделил всех техдиров на две категории:
            1. Используем все новые модные трендовые технологии
            2. Используем привычные хорошо знакомые технологии

            Ходят слухи, что есть ещё и третий тип:
            3. Постоянно развиваемся, изучая что-то новое, объективно оцениваем достоинства и недостатки, и можем аргументированно о них рассказать

            Но я таких не встречал :-)
            • 0
              4. Давайте поставим задачу разработчикам подобрать технологию под задачу. И обосновать её использование.

              Техдиру не нужно быть компетентным во всем, его работа — руководить тех.специалистами.
              • –1
                Это у вас менеджер получился, а не техдир :-)
                • +2
                  Я может вам тайну открою, но даже тимлид — менеджер. В изначальном смысле этого слова, управляющий. Его основная задача — управлять людьми.
                  • 0
                    Ну что ж, откровенность за откровенность. Дизайнер — тоже инженер, а не художник :-)
  • +12
    В ходе чтения на вопрос «Если Go настолько плох, почему он так популярен?» как-то сам собой возник ответ «потому что миром правит посредственность». Похоже, автор статьи дал тот же ответ, только немного завуалированно и более мягко, что ли.
  • +22
    Перевод:
    Даже если можно поспорить, является ли подход Нью-Джерси пост-фактум описанием Unix-философии, то совершенно точно можно быть уверенными, что создатели Go явно продвигали простоту, как ведущий элемент их философии.

    Оригинал:
    Even if the New Jersey method was a post facto straw-man description of the Unix philosophy or that of its creators, make no mistake that there has been an explicit endorsement of simplicity as a guiding philosophy from Go's creators.

    Как по-моему правильно:
    Даже если подход Нью-Джерси и оказался пост-фактум доведённым до абсурда описанием философии системы Unix или её создателей, без сомнения имело место явное продвижение простоты как руководящей философии создателей Go.

    Общий смысл фразы у переводчика сохранён и я не стал бы его поправлять, если бы этот абзатц не был ключевым во всей статье. Статья в той или иной степени является ответом на древнюю публикацию Гэбриэла Worse is Better.

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

    В случае с языком программирования простота использования — это показатель, определяющий насколько просто писать программы на данном языке, а простота реализации — это насколько просто написать для него компилятор.

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

    И когда автор опускает тот факт, что речь о простоте использования против простоты реализации — он кривит душой и создаёт ложное впечатление что о философии MIT, что о Go.

    По честному, в контексте статьи Worse is better, процитированный в начале абзац должен бы выглядеть вот так:

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

    Совершенно другое впечатление, не правда ли?
    • –6
      Впечатление то другое, но не стоит ставить знак тождества между философиями New Jersey (или MIT) и Go. Простота действительно является одним из важнейших концептов языка, но все же основой является именно простота использования. И только уже как следствие простоты концепций языка получаем простой и быстрый компилятор.

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

        Я же хочу сказать, что пример с дженериками красноречиво демонстрирует, что по краней мере в случае с ними, простотой использования сознательно поступились в пользу простоты реализации.
        • –2
          Тем не менее, не стоит считать единичный пример с дженериками обобщающим )
          От их реализации, кстати, не отказались, а скорее — отложили на некоторые время. Вопрос их реализации в будущих версиях пока что открытый.

          Отсутствие дженериков не отменяет основных целей дизайна (другой вопрос, насколько эффективно они реализованы), таких как держать язык простым (для использования), где это не мешает эффективности.
          • +4
            Пока что я вижу в Go только один вид простоты — если ты долго писал на Си — Go понятен и прост. В нём решены очень многие проблемы этого языка и решены как раз в стиле, который симпатичен программистам, знающим и любящим этот язык. Они не теряют вообще ничего, а приобретают много. Если ты всю жизнь писал на Си, но тебе надоели драйвера и хочется веба — тебе дорога в Go.

            С точки зрения тех, кто пишет например на Java — Go не прост, но понятен. Они потеряли дженерики и исключения, но приобрели быструю компиляцию, быстрый рантайм, структуры, которые можно передавать по значению и понятную многопоточность. Джава очень долго не развивалась, те кто на ней программируют привыкли к бойлерплейту как к данности. Обнаружив, что может быть бойлерплейт, но без тормозов и при этом со сборщиком мусора, который к тому же отрабатывает за гарантированное время они испытывают трепет, близкий к священному. Ради такого отсутствие дженериков можно потерпеть, тем более, что их всё равно когда-нибудь добавят, как добавили в Джаву.
            • +2
              Кстати, Ваше замечание относительно простоты Go для C программистов объясняет и разные точки зрения по поводу Go — просто люди с разным бекграундом одни и те же особенности воспринимают по разному. Скорее всего многие хейтеры Go никогда не имели дела с С кодом.
              • +3
                Имел дело с C, являюсь нелюбителем Go. Правда, я и нелюбитель C при этом.
                • –1
                  Пользуясь случаем, спрошу — а зачем вы, раз не любите Go, ходите во все посты про Go и доказываете, какой он плохой?
                  Я вот просто не могу представить на себе, что должно мной двигать, чтобы мне захотелось ходить в посты про языки, которые мне не нравится и оставлять там комментарии, что-то кому-то доказывая про то, что я не люблю и не знаю.
                  Проясните эту загадку? )
                  • +7
                    Я вообще во многие посты хожу. Многие языки вот недолюбливаю, а почитать интересно. Я не люблю Python, но почитать про внутренности интерпретатора интересно. Я не люблю C# (вру, C# хороший язык, я не люблю экосистему, да и вообще, просто не сложилось как-то), но почитать про него интересно. И с Java то же, например. Вот, статьи про GC тамошний недавние вполне любопытно было почитать, особенно последнюю, про конкурентные GC.

                    А Go… Ну, Go — это вот как Оберон в начале этого лета, кажется, помните? Там тоже весело было. Практически одна философия и хвалебные оды.
                    • 0
                      Ну, Go — это вот как Оберон в начале этого лета, кажется, помните?

                      Ну, если не выглядывать за пределы комментариев Хабра, то, наверное две статьи про Оберон таки похожи. Ну ладно, раз это профессиональное, то вы ответили на мой вопрос.
        • +1
          Мне кажется, что добавление generics заметно усложнило бы язык, его семантику. Да, возможность сделать параметрический список или другую подобную структуру данных — это очень удобная штука, но она обяжет проработку языка для всех «краевых случаев» параметризации, т.е. здесь проявится эффект видимой части айсберга.
  • –5
    Все же «когнитивная нагрузка» есть ключ к пониманию всего.
    Низкая нагрузка — пишут в основном дебилы — софтом невозможно пользоваться, вроде бы все есть, но через жопу, архитектура говно, сложные реализации очевидных вещей, не очевидное поведение и т.д…
    Это если упрощенно и простыми словами. Так что ретроспективно по качеству софта можно судить о языке. У го в этом плане хорошего и красивого софта просто нет.
  • +5
    Основное преимущество Go, по моему скромному мнению, заключается в его крутом runtime и goroutin'ах, а отнюдь не в синтаксисе языка. На Go можно очень легко написать масштабируемые и весьма производительные сетевые демоны, которые, к тому же, стабильно работают в продакшене.

    Go сильно облегчает написание эффективных асинхронных демонов, причём позволяет ещё и легко масштабироваться по ядрам, в отличие от libev-подобных библиотек. Если от Go оставить только его синтаксис и убрать runtime, то желающих писать на таком языке, я думаю, сильно бы поубавилось, и вряд ли он смог получить такую популярность, как сейчас.
  • +2
    Простота реализации это чётко сформулированная позиция как в самом языке, так и в библиотеках, и этот явный приоритет простоты над логичностью вшит в язык.

    Простите, но я не понимаю. Как может быть простой вещь которая не логична!? Логичность это и есть составная часть простоты.
    • +2
      Очень просто. Смотрите, вот даже на примере Go.

      Объявление переменной типа T и типа «указатель на T»:
      var foo T
      var fooPtr *T = &foo
      

      Паттерн понятен, теперь, на тип Т повесим метод Bar():
      func (T) Bar() {}
      

      Пока что всё логично. А теперь, как бы было бы «логично» вызывать этот метод для foo и fooPtr? Метод Bar ведь определен только для T, значит логично будет разыменовать fooPtr:
      foo.Bar()
      (*fooPtr).Bar()
      

      Но это дополнительная нагрузка на программиста. Проще будет писать:
      fooPtr.Bar()
      

      а разыменование будет делать компилятор автоматически.

      play.golang.org/p/hgcyQKW4-j

      Это не так логично, но это плюс в сторону простоты. Если бы логичность была выше простоты, такого бы не было.
      • –1
        Вот у меня простой вопрос — как понять где нужно использовать указатели, а где нет?
      • +2
        Неожиданная автоматика в языке, который ставит явное выше неявного :-)

        И не менее неожиданная префиксная нотация для разыменовывания указателя в языке, где не побоялись воспользоваться постфиксной для объявлений типов.
        • –2
          Неожиданная автоматика в языке, который ставит явное выше неявного :-)

          Так вот статья именно об этом.
          Ну и если бы все было «ожиданным», то ничего нового и не появлялось.
      • +3
        Если бы логичность была выше простоты, такого бы не было.

        Если бы здесь была простота, то не было бы вообще разделения на значение и указатели, пришедшее из мира совсем не простых С/С++. Все указатель и вперед, как в тех же C# и Java. Либо более радикально, никаких указателей и совместного владения, только передача владения объектом. Существенно упрощает как язык, так и правила работы с ним. Вместо этого в Go мутные правила, когда же нужны указатели, а когда значения. В особенности это касается методов. Мне, честно, не понятно, зачем было введено это усложнение. В Go выглядит несколько неуместным. В некоторых местах у Go есть такие вот шероховатости, которые сильно печалят.

        Как вот меня при парсинге печалил такой вот случай
        a, err := read(); err != nil {
            return err;
        }
        

        Когда результат кладешь в переменную, то все красиво. Обе переменные не надо объявлять заранее, просто пишешь код. Как только вместо «a» возникает поле структуры, то err приходится объявлять где-то сверху и использовать обычное присвоение, ":=" не совместим с полями структур. Это логично, но было бы проще это сгладить и позволить писать тот же самый код, а не вспоминать времена С, когда в начале функции у тебя пачка локальных переменных.
        • –2
          Если бы здесь была простота, то не было бы вообще разделения на значение и указатели

          Ну это вам так кажется. Но даже в статье это написано, что в языке важен баланс между необходимыми фичами и простотой, а не «простота любой ценой».

          ":=" не совместим с полями структур

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

          • +4
            Мне не видна вообще ценность этого усложнения языка, однако я по всему интернету вижу вопросы, а что же мне и когда использовать. Это мутная тема Go, указатель или нет в методе структуры — ведь авторы не дают прямо четких наставлений, а так, если структура большая, то все же используйте указатели, даже если метод не модифицирует объект, ибо копирование много кушает. Убрать бы вообще это и не пудрить людям мозг. Его применением видится лишь чем-то вроде const методов из С++, но выглядит скорее таким же бесполезным и вносящим лишнюю путаницу из-за своей же примитивности (в C++ хотя бы есть всякие константные указатели и ссылки). В С++ к этому все привыкли, а видеть такое в Go странно — интересно, задавал ли кто вопрос о причине такого решения. Потому что вполне реально, что объективных причин держать эту фичу кроме как совместимость может и не быть. Как то, именованные возвращаемые значения — фича, которую авторы хотели бы убрать, ибо она лишняя и только усложняет язык, но уже поздно. И таких не одна. С объявлением переменных тоже есть желание убрать лишнее.
            • –3
              Убрать бы вообще это и не пудрить людям мозг.

              Если вы примете тот факт, что авторы Go занимаются кое-чем другим, чем желанием запудрить вам мозг, мне будет проще отвечать на ваши многочисленные комментарии.
              Вы предлагает убрать вообще указатели? Очень круто. Давайте посмотрим — в Go при передаче параметров, всегда происходит копирование. Всегда. Даже если это указатель — он копируется, но поскольку это всего лишь информация об адресе в памяти, то код, работающий с переданным указателем, имеет доступ к нужному объекту. Давайте, по вашему мудрому наставлению, «уберем вообще это и не будем пудрить мозг». Как теперь изменять значения, переданные в функции? Отказываться от подхода «все копируется» и переделывать дизайн языка и компилятора?
              • +5
                Если вы примете тот факт, что авторы Go занимаются кое-чем другим, чем желанием запудрить вам мозг, мне будет проще отвечать на ваши многочисленные комментарии.

                Опять дурака валять начинаете. Вы не отвечаете на мои комментарии, я опять вижу приход слепой веры в праведность и полное непонимание причин дизайна языка. Только то, что так надо и все. Но вы все продолжаете мне отвечать, не давая никакой полезной информации и ответов на вопросы.

                Вы предлагает убрать вообще указатели?

                Я вообще-то предложил не это, научитесь читать уже посты. Я предложил сделать все указателями как это в Java и C#. Только там разработчик вообще не думает, указатель это или нет. Ему это не важно. У него есть объект, он его передает, вызывает у него методы. Функция может его модифицировать. Все просто и ясно. Можно просто писать код, а не гадать — а не лучше бы мне здесь было указатель всунуть. Не это ли философия языка Go — писать код и просто решать задачу. Выбор это прерогатива С и С++, где с помощью этих больших возможностей решаются задачи, для которых Go вообще не предназначен. В философии Go в этом месте выбора вообще быть не должно — есть один вариант и все. Тоже самое авторы ответили насчет возвращаемых значений — не нужно два варианта, нужен один и все. Таков Go, но уже поздно — 1.0 вышла, код сломается.
                • –6
                  Опять дурака валять начинаете.

                  научитесь читать уже посты.

                  Ясно. Желаю вам найти других собеседников, разделяющих ваше убеждение, что Go придумывали идиоты, а вы знаете как надо было, потому что в Java и C# не так. Мне не интересно на такое «общение» время тратить.
                • 0
                  Я предложил сделать все указателями как это в Java и C#.

                  Только вот в Java указателями сделаны объекты и больше ничего. И тот факт, что на объект можно только получить указатель иногда неслабо убивает перформанс.

                  А в С# есть структуры, которые указателями не являются. И есть ссылки, с помощью которых можно модифицировать и передаваемые в функцию примитивные переменные и структуры. Это очень удобно.
                  • 0
                    А при чем тут другие языки? Я про них это все знаю. Речь о простоте Go и внезапно взявшейся низкоуровневой фиче как то передача структур по значению или ссылке. Мой изначальный посыл — это выбивается из философии языка. Тут нужно одно, скорее всего только указатели, что разом решит мутные вопросы, из синтаксиса уйдет лишнее, а минусов мы не получим. Язык нас подталкивает так работать, что это все не нужно просто напросто — есть просто заноза в заднице, когда же использовать в методе указатель. И пачка разных методов создания переменной, что сами авторы хотели бы тоже упростить. Тоже самое C# — ref там используется по праздникам и обычно не от хорошего дизайна изначально. А если еще и структуры с помощью них модифицировать, то вообще караул — кому-то надо вспомнить, что это не С++. Язык подталкивает к оперированию объектами, где вопросов о ссылках не появляется. Структуры больше фенечка и объективных преимуществ в рамках платформы и ее специфики в основном не несут. Заменил на класс с правильными свойствами и ничего сильно не изменилось. Но это и не Go, это громадный язык с кучей возможностей, там это кажется лишним скорее с точки зрения философии управляемых языков — эдакий привет из C++.
                    • 0
                      А при чем тут другие языки?

                      При том, что вы предложили сделать всё указателями, как там.
                      Я про них это все знаю.

                      Тогда непонятно, почему вы предложили всё сделать указателями, как там, ведь там не всё сделано указателями.
                      Тут нужно одно, скорее всего только указатели, что разом решит мутные вопросы, из синтаксиса уйдет лишнее, а минусов мы не получим.

                      Мы получим невозможность сделать массив структур, компактно расположенный в памяти, что в некоторых случаях плохо скажется на производительности. Вы, кстати постоянно забываете уточнить, что указателями хотите сделать не всё, а только объекты.
                      Структуры больше фенечка и объективных преимуществ в рамках платформы и ее специфики в основном не несут.

                      Отсутствие этой фенечки не позволяет писать код, который учитывает наличие процессорного кеша.
                      • 0
                        При том, что вы предложили сделать всё указателями, как там.

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

                        Тогда непонятно, почему вы предложили всё сделать указателями, как там, ведь там не всё сделано указателями.

                        Потому что к словам придираетесь. Обобщение оно тут от лени расписывать каждую несущественную деталь, которая к сути отношения не имеет. Можно еще про boxing вспомнить, че уж тут.

                        Мы получим невозможность сделать массив структур, компактно расположенный в памяти, что в некоторых случаях плохо скажется на производительности. Вы, кстати постоянно забываете уточнить, что указателями хотите сделать не всё, а только объекты.

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

                        Отсутствие этой фенечки не позволяет писать код, который учитывает наличие процессорного кеша.

                        Поэтому я уточнил про специфику — C# не об этом и подавляющее большинство софта на это плюет. Собственно, почему практически нигде ref не встретишь, а если встретишь, то явно кто-то костыль нагородил. Как и структуры, собственно, тоже редкость. Учет процессорного кеша означает работу со множество вычислений, которые сильно зависят от кэш промахов. Слишком узкий кейс в рамках дотнета. Об этом могут заботиться джетбрейнс, но не разработчики бизнес-приложений на аспнете. И например то, что за каким-нить DateTime на самом деле стоит структура — кому это интересно? Да никому. Кто от этого что-то выигрывает? Да никто. Он выглядит как класс, создается как класс, применяется как класс. Замени его на класс и мир не заметит. Низкоуровневое программирование это вон к плюсам — там рады поговорить о выравнивании, кеш линиях, кеш промахах, раскручивании циклов, предсказаниях переходов и еще много чего я тоже могу умного вспомнить, потому что это то, для чего он нужен многим многим многим разработчикам и без чего язык этот собственно и не нужен. Но они решили оставить структуры, потому что так захотелось. Могли не оставлять и ничего бы существенного язык не потерял. А так, да, греет душу — можно на кеш оптимизироваться. Интринсики еще надо для полноты картины.
                        • +1
                          Они всего лишь пример реализации, больше ни для чего эти языки я не упоминал. Что видит программист — вот что важно. В этих языках он не видит этих деталей, они ему не нужны.
                          В Java программист эти детали обязан знать. Обязан знать, что объекты представлены переменными, в которых на самом деле находится указатель, а примитивные значения хранятся в памяти непосредственно. Обязан знать, почему в дженерик можно поставить параметром только класс. Обязан знать, как работает сборщик мусора. Это нужно ему для того, чтобы писать корректно работающие программы.

                          Кого это беспокоит? Кто об этом будет думать? Разработчик Go? Да не в жизни. Я говорю о философии языка и забота о кеш френдли структурах там никаким местом. Для таких целей есть другие языки.
                          Больше всего в Джаве раздражает, что иногда единственный ответ на вопрос как что-то сделать — сменить язык. Наличие структур — фича важная не только для кэша. Также это позволяет делать типы данных, которые по умолчанию передаются по значению, что важно уже не для оптимизаций, а для создания хорошего кода.

                          Какие там структуры данных, когда у нас рантайм одна большая магическая коробка, в которой происходит что-то, о чем никто кроме самого рантайма не знает.
                          Что в Java, что в C# что, наверное, в Go рантайм магической коробкой не является. Программист, повторюсь, обязан знать, хотя бы в общих чертах, как оно устроено внутри. Какие гарантии даёт рантайм, а каких он не даёт. Как можно писать код, а как нельзя. Если вы считаете, что это не так — пересмотрите свои взгляды, это сильно поможет в работе.

                          Go сделан для создания микросервисов, это прям вот вся его суть.
                          Go сделан для серверного бэкенда — это несколько шире, чем просто микросервисы. И это пока нет графических библиотек. Консольный софт на Go пишется только в путь — посмотрите на platinum searcher.

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

                          И например то, что за каким-нить DateTime на самом деле стоит структура — кому это интересно? Да никому. Кто от этого что-то выигрывает? Да никто.
                          Это интересно каждому, кто хочет знать, можно ли как-то изменить DateTime, переданную в качестве параметра. И интересно тем, кто хочет обрабатывать как можно больше DateTime в секунду.

                          В общем что я хочу этим всем сказать. Отсутствие структур в стиле С# уже оказало медвежью услугу Джаве. Кейсов, когда это нужно в программировании сервер-сайд — достаточно много. В программировании вообще — гораздо больше. Я как программист, в обмен на возможность обрабатывать эти кейсы, не меняя язык, готов смириться с тем, что мне иногда придётся думать что передавать — указатель или всю структуру целиком.
                          • 0
                            Обязан знать, как работает сборщик мусора. Это нужно ему для того, чтобы писать корректно работающие программы.
                            Это вы загнули. Понимание работы GC нужно для написания эффективных программ, корректность от этого зависит слабо. Вот JMM, который вы не упомянули, java middle знать обязан.

                            А в остальном +1.
                            • 0
                              Про JMM не сказал, потому, что настолько очевидно, что даже не вспомнил :). Знание GC конечно очень помогает с эффективностью, но ещё помогает избежать OutOfMemory.
      • 0
        Но это дополнительная нагрузка на программиста. Проще будет писать:

        Как то не поворачивается язык назвать «упрощением», не очевидное решение, сохраняющее всего 3 символа в строке.
        К слову (*fooPtr).Bar() всё же сработает или свалится в ошибку?
    • 0
      Вот пример — оператор === в PHP. Просто! но без чтения мануала интуитивно понять как это работает сложновато.
      • 0
        Так а откуда заключение, что это просто, если это понять сложновато :)

        «Просто использовать» != «просто набирать на клавиатуре»
        • 0
          Я понял о чем вы. Просто понять != просто использовать. Все верно.
          • +2
            Так, что же имел ввиду автор? Первое или второе?
  • +1
    -

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.