Как стать автором
Обновить

Комментарии 97

Немного не понял про трюки на clojurescript. В чем там именно трюки состоят? И причем тут clojurescript? В том, что для csp в clojure легче описывать сложные concurrency абстракции с помощью core/async, чем в go, или там что то другое подразумевалось? В любом случае, именно c clojureSCRIPT сравнение как по мне странное. И вообще, представляю как ОТР эрланга после такого думает «вот щас обидно было».

З.Ы. Со всем уважением к terraform от упомянутой в переводе hashicorp (которую я искренне люблю, как и go), все же ее наиболее популярный продукт — vagrant, написан на руби, и это не мешает ему «осуществлять революции в серверах».
Немного не понял про трюки на clojurescript.

Там референс к примеру из статьи, в которой есть фраза «I frequently use in ClojureScript code tricks like» и вообще, Качаев знатный функциональщик, и часто ругает Go, за то что в нём нельзя делать то, что можно в функциональных языках

все же ее наиболее популярный продукт — vagrant, написан на руби, и это не мешает ему «осуществлять революции в серверах»

С vagrant-а начался Hashicorp, Go тогда был ещё в зародыше и Хашимото выбрал наиболее подходящий на тот момент инструмент. Про будущее руби отдельно можно писать, но в целом утверждение «на руби тоже есть клевые серверный софт» никак не противоречит статье :)
А как vagrant относится к осуществлению «революции в серверах», если он де факто — development environment?
Так, что в нем есть команда push наверно. Не знаю правда подпадает ли это под «де факто».
Это не относится к серверной части инфраструктуры
Если вас разочаровывает невозможность использования трюков ClojureScript, то Go это не то, что вы ищете.
В статье по ссылке аргументированная критика языка с реальными примерами, а все что автор этой статьи из этого понял, что «нельзя делать как в ClojureScript»?
Сложилось впечатление, что язык хорош для крупных компаний, которые могут нанять больше человек и получить более-менее стабильный прирост производительности команды.
Сложилось впечатление, что язык хорош для крупных компаний, которые могут нанять больше человек и получить более-менее стабильный прирост производительности команды.

Это хороший поинт, и это действительно было одной из задач. Хотя главный пункт был всё же не в том, чтобы «добавить +N людей и получить +N% производительности», а в том, чтобы вновь пришедшие в проект очень быстро могли в него войти, понять и поддерживать без превращения кодовой базы в типичный для таких ситуаций ужас.

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

Ну а каждый минус мне в карму — это подтверждение частого утверждения, что переводить статьи для Хабра — гиблое дело. Не вопрос же :)
Про переводы: тут срабатывает логика уголовного кодекса: раз перевел, значит, согласен, значит, причастен и соучастник.
Возможно ) Но всё же это неадекват. Я ещё понимаю, если бы статья была в стиле «хейтерс гона хейт, критики до свидания» — но это, действительно, очень толковая статья, не банальный, свежий и меткий взгляд на long-term эффект дизайна языка на open-source комьюнити.

Взгляд at scale — даже если оно идет в разрез с твоими убеждениями, всё же заслуживает уважения. Ну или, как минимум, здоровой дискуссии, а не тупого минусования.

Подозреваю, что главный эффект тут производят референсы на другие критические статьи — но это, вобщем-то, тема статьи, и автор достаточно виртуозно на них ссылается :)
Я ещё понимаю, если бы статья была в стиле «хейтерс гона хейт, критики до свидания»


Позвольте, но ведь именно это тут и написано:
Вы опоздали на вечеринку. Некоторые могут жаловаться и плакать из-за этого


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

Ну и высказывания типа «Go блистает» с примерами каких-то noname-проектов вообще на грани слишком толстого тролллинга. Вот когда эта ваша CockroachDB подвинет если не Oracle, то хотя бы Redis, тогда можно будет говорить «блистает». Ну а на данный момент Go по популярности конкурирует с такими замечательными языками как EXEC, Forth и Icon
www.tiobe.com/index.php/content/paperinfo/tpci/index.html

TL;DR Автор так восхищенно истекает слюнями по поводу своего любимого языка, что это похоже на толстоватый троллинг
Docker — noname проект?
Ладно.
Вы используете CockroachDB, blevesearch или Vulcand?
Я использую Docker, косвенно использую go в: Youtube, сайтах, находящихся за Cloudflare, используюя mongo-tools и MMS, когда мой Google Chrome скачивает обновления, когда мой dropbox синхронизирует данные, когда я пишу в чате на Twitch или захожу на твиттер, когда что-то делаю со своими серверами на DigitalOcean.
Ок, прекрасно.
Когда вы используете практически любой linux-сервер очень вероятно, что там есть немало строчек на bash. Bash «большой игрок в мире серверного софта»? А кто бОльший игрок Go или bash?
Я вам перечислил не-noname проекты на Go, или включающие в себя существенные сервисы/микросервисы на go (привет 500px), которые я использую. А bash — везде и повсюду в серверах, это факт, и я с ним спорить не буду.

Что я хотел сказать:
Если использовать другие метрики, например, google trends или github stars, то ситуация с популярностью и ее ростом у go будет вам яснее.
Вы бы еще популярность applе так меряли, уж извините за сарказм.
Обновляю вашу ссылку — www.google.com/trends/explore#q=%2Fm%2F09gbxjr%2C%20python&cmpt=q&tz=
Если пользоваться такими же аргументами, как оппонент, то можно и такую ссылку привести:
вот такую вот.

Получаем, что go — язык богов, и на порядки превосходит по полярности все языки, придуманные до него и после.
Так я специально привел обобщенную ссылку, аналогичную той, что дал оппонент :)
Круто, спасибо.
Что ж действительно Go programming language побеждает Python programming language, змею-питона и Монти Пайтона вместе взятых. В битве на гугл-тренде побеждает боксер в синих трусах
Вы опоздали на вечеринку. Некоторые могут жаловаться и плакать из-за этого

На мой взгляд это просто констатация факта. Go 1.0 вышел в 2012-м году и тогда было сказано — всё, язык меняться не будет, «we're done». Но при этом, регулярно приходится читать статьи с вопросом «почему меня не слышат». Слышат, но есть некоторая объективная реальность, которую нужно принять.

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

Менеджер прийдет к Робу Пайку и скажет «нужно значительно переделать» и в Go поломают обратную совместимость? Хорошая у вас фантазия :)

Ну а на данный момент Go по популярности конкурирует с такими замечательными языками как EXEC, Forth и Icon

Вы неправы. Мы можем спорить про то, что на самом деле меряет индекс TIOBE, но если у вас не возникает когнитивного диссонанса во время сравнения распространения Go, Forth и (что это вообще за языки?) Exec и Icon, то, видимо, вам просто не интересен реальный расклад, и вы о чём-то своём сейчас.
Менеджер прийдет к Робу Пайку и скажет «нужно значительно переделать» и в Go поломают обратную совместимость? Хорошая у вас фантазия :)


Да, добро пожаловать в мир корпоративной разработки. У Пайка, конечно, может быть вариант не согласиться с этим и уволиться. энтузиасты могут сделать 15 форков, но go будет развиваться так как захочет корпорация добра.
но если у вас не возникает когнитивного диссонанса во время сравнения распространения Go, Forth и (что это вообще за языки?) Exec и Icon, то, видимо, вам просто не интересен реальный расклад, и вы о чём-то своём сейчас.

Ну, извините, что убиваю ваших идолов. Понятно, что когда вы пишете на gо и варитесь в этом котле, вам кажется, что все вокруг любят go и go уже почти победил.
Хотите еще больше жестокости?
Вот:
jobsearch.monster.com/search/golang_5? плюс jobsearch.monster.com/search/go-developer_5?
vs
jobsearch.monster.com/search/python_5?
Да, добро пожаловать в мир корпоративной разработки. У Пайка, конечно, может быть вариант не согласиться с этим и уволиться. энтузиасты могут сделать 15 форков, но go будет развиваться так как захочет корпорация добра.

Если бы подобные утверждения были на чём-то основаны, то был бы смысл спорить.

Ну, извините, что убиваю ваших идолов.

А вы извините, что разрушаю ваши иллюзии о том, что вы убиваете каких-то идолов :)

Хотите еще больше жестокости?

Не хочу вас расстраивать, но пока что в Go-коммьюнити преобладает ситуация, когда ищут Go-программистов, а все гоферы и так заняты.
Так вот в этом-то и проблема, что вам цифры-цифры-цифры, а вы в ответ слова-слова-слова и эмоции и «У меня и у моих друзей все работает»
Вы привели рейтинг tiobe, в котором популярность у D на порядок выше, чем у Go.
Затем привели ссылки на jobsearch.monster.com

Теперь я попрошу вас, для «consistency», привести запрос к jobsearch.monster.com, который покажет популярность D.
А еще заодно приведу разные метрики.
Go vs erlang vs d vs perl vs python vs ruby
Теперь я попрошу вас, для «consistency», привести запрос к jobsearch.monster.com, который покажет популярность D.

Я даже сформулировать такой запрос не могу. А что вы пытаетесь доказать в этой битве титанов? Я согласен, что Go, D, Rust еще примерно в одной весовой категории и кто победит — зависит от того, как измерять. Однако эта весовая категория — микроскопическая и выступать с заявлениями типа «Go/D/Rust уже победил и блистает» пока рановато.
Я вот тоже не смог сформулировать такой запрос. А доказать пытался не очень высокую репрезентативность tiobe в контексте ЯП go.

Go победил в битве за свою жизнь. Он выжил и развивается, его используют, популярность увеличивается если не экспоненциально, то линейно. D на мой взгляд — не смог. У Rust битва за жизнь в самом разгаре.

А «блистает» — довольно субьективная характеристика. Для меня блистает, для Александреску блистает D, а go — не нужен.
Слово «блистает» в статье использовано в очень четком контексте с описанием аспектов open-source мира, в которых Go «блистает». Человек увидел два слова «Go» и «блистает» в одном абзаце и понесло :)
Go победил в битве за свою жизнь.

Да, справедливо. Эта фраза могла бы быть использована как заглавие заметно более объективной статьи про Go
Вы ищете цифры, чтобы оправдать своё негативное отношение к Go — ок, на здоровье.
Я и еще тысячи людей и компаний по всему миру, благодаря Go уже не первый год делем качественный софт, рубим бабло и получаем от этого удовольствие.
Каждому своё. Никакой проблемы нет :)

На этом дискуссию с вами прекращаю, извините уж.
Какого-то смысла обижаться на объективные цифры нет, иначе однажды выход из уютного мирка, где Go «блистает» и «уже победил» будет весьма болезненным
НЛО прилетело и опубликовало эту надпись здесь
[ИМХО]
Единственно, чего не хватает в Go — generics. Хотя это, конечно, прямо соответствует идеологии упрощения читабельности (шаблонный код не всегда легко понимается).
[/ИМХО]
Стоп-стоп, так generics (обобщенное программирование) или templates (шаблонный код)?
Так, чтобы можно было реализовать строготипизированную работу с произвольными коллекциями без копипаста и с проверкой типов при компиляции (например очередь как в STL)
Ответы на подобные претензии обычно делятся на две группы, и обе достаточно справедливы:

1) Go не против generics — просто авторы Go, при всём своём колоссальном опыте и мозгах, не знают, как сделать generics так, чтобы это было не sucks, как в других языках и не убрало другие достоинства Go. И до сих пор никто не смог предложить адекватное решение.

2) У generics есть достаточно хорошо известные use-кейсы. Там где без женериков совсем плохо — да, Go не подходит. Но на практике — такие юз-кейсы — это доли процента от реальной практической надобности.
Вот взять даже ваш пример — «хочу очередь для произвольных типов». Если вы изучаете теорию языков программирования — то вам это кажется нужным и важным. Если вы пишете сетевой сервис или код для прошивки дрона, в котором вам нужно использовать очередь — как правило, вы её будете использовать для конкретных значений. В реальной практике реализовывать свои контейнеры для всех возможных типов как-правило не нужно. И это, кстати, тема для отдельной дискуссии — когда в языках с женериками, люди используют их к месту и без места, и считают, что это «более продвинутый стиль программирования».

Оба этих ответа дают понимание, того, почему в Go нет generics.

Вообще, на эту тему есть достаточно хороший документ, где собраны все реальные категории того, что подразумевается под словом Generics, известные способы имплементации, с плюсами и минусами — познавательное чтиво. По крайней мере после него будет неудобно сводить generics к темплейтам.
docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/edit#
Тут не в теории дело, а чисто в практике: когда пишешь код под int, а в соседнем проекте потребуется string но с аналогичными операциями, копипаст начинает злить и мешать
Возможно, но, что я вижу из своего опыта и то, что читаю регулярно в подобных обсуждениях — что это отнюдь не частый кейс.

Вот серьезно, не примите за придирки, но могли бы вы описать хотя бы 5 последних ситуаций, где вам пришлось реализовывать свой контейнер сначала для int, а потом для string? Просто интересно, что за софт вы пишете, где регулярно встречается такая ситуация.
Я легко могу понять разовые отдельные подобные случаи, но если это возникает на практике регулярно — то даже интересно, почему такой частый паттерн или контейнер не учтён.
Софт: бэкенд веб сервисов, «умный дом», прикладная часть драйверов и т. п.. Проекты совсем разные (в т.ч. и заказчики).
Пример:
В одном проекте: сервис, обменивающийся данными по сети с полезной нагрузкой в виде строки (авторизационый сервис).
В другом: схожий сервис, но данные не строковые, а различные числовые данные (int, uint, float и другие результаты замеров).
В будущем третьем: сервис уже с пользовательским типом (драйверная обертка).
Конечно, так или иначе это можно сделать. Но очень много одинаковых компонентов, отличающихся только типом в аргументах функций.
Ну то есть обобщенного программирования. Не понимаю, в чем там проблемы с читаемостью в таком случае.
Я вот не знаю Go, но после статьи задумался.
Пройдите Go Tour и 90% языка вы уже будете знать.
У него действительно очень легкий период входа, и это killer feature.
Спасибо за перевод. По теме статьи скажу следущее: можно прочитать эту статью мысленно заменяя Go на название любого другого языка — ничего не изменится. Общие слова ничем не подтверждённые.
Я решил эту статью перевести именно потому, что озвученные в ней вещи действительно важны, и совпадают с моими наблюдениями. Только с Go у меня вошло в привычку читать код других проектов — просто потому что в 90% случаев он читабельный, понятный и доступный, только с Go у меня появилось вот это ощущение «если написано на Go — то это сразу +20 к карме проекта», и только с Go я стал опен-сорсить проекты, которые писал для себя.
Автор статьи просто в яблочко попал, на самом деле.

По вашему совету заменил Go на C++, и как-то совсем не идёт :)
Хорошо) Буду думать, что в Го есть некая загадочная читаемость, достигаемая компромисами и практичностью.
Нет никакой загадочности. Напишу, как это вижу лично я.

Вот самый примитивный пример — ternary operator. Удобная вроде штука, во всех развитых языках есть. Выразительно, кратко — сила, одним словом.
Но на практике это приводит к тому, что в 50% случаев ternary operator используют так, что код сложнее прочитать и понять, а иногда из :? творят откровенную лапшу на десятки строк. Да, можно винить программистов и говорить — вы просто плохие программисты. Но если пытаться ответить на вопрос «как получить качественный код?», а не, «кто виноват?», то решение «выпилить ternary operator вообще» в итоге в среднем приведет к более читабельному и понятному коду.

И так практически со всем — от отсутствия эксепшенов до чувствительности к регистру имён переменных.

Эффект «большЕй читабельности» не загадочный, он вполне очевидный.
То есть вы считаете, что с помощью if/else нельзя написать такой же лапши на десятки строк, а необходимость при условных выражениях всегда разделять объявление переменной и присвоение ей значения — не понижает читаемость?

Но вообще, конечно, мне интересно, как именно вы (объективно) измеряете читаемость.
Можно написать всё. Вовпрос в том, стимулирует язык это делать или нет.
Вот такое (это реальный код) написать с помощью if/else будет очень сложно, и мозг банально из-за лени среагирует на поиск другого решения.

Читабельность не измеряется «объективно», это достаточно субъективная вещь. Но всё субъективное, будучи умноженное на миллионы человеко-часов дают возможность выделить «более правильное» и «менее правильное», хорошие и плохие практики.
А что вы будете умножать на миллионы человеко-часов? На основании чего вы будете выделять?

(А в вашем примере есть очень высокая вероятность дублирования кода между разными ветками type is x, что может привести к ошибкам другого рода. Хотя код, конечно, пахнет.)
Я перестаю понимать ваши вопросы.

Вы вообще не согласны с тем, что код может быть более или менее читабельным? Или вы пытаетесь узнать у меня формулу определения читабельности кода? :)
Я согласен с тем, что код может быть более и менее читабельным. Я не согласен с тем, что для устоявшейся (в мейнстриме) функциональности можно однозначно сказать, что ее невключение в язык гарантированно повысит его читабельность.

Проще говоря, я считаю, что богатство языковых примитивов языка не может ухудшить его читабельность — на фоне общего синтаксиса и семантики это пренебрежимое отклонение.
Видимо Вы никогда не разбирали лапшу из
.map(?:?: rescue) rescue

Завидую Вам
Разбирал. А теперь скажите мне, что именно вы можете сделать с этим языком, чтобы избежать этой ситуации, и при этом не ухудшить читаемость в правильных применениях того же синтаксиса?
Банально не писать в одну строку подобный код.
А для того, что бы его не писали, в конечном итоге язык не должен содержать конструкций, которые позволяют так писать. В этом случае Go — хороший язык, в нем нет подобных конструкций

Да, и для «добивания» удобочитаемости в комплекте к компилятору Go идут gofmt + govet + golint, которые не только помогут отформатировать код согласно гайдлайну, но и проведут статический анализ (приятный бонус)
А почему вы думаете, что это не ухудшит читаемость в случаях правильного применения? Вообще же, это мне напоминает вечную дискуссию terse code vs sparse code.

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

(Пример был общим, с некоторым уклоном в ruby)
Понимаете, вы с водой выплескиваете ребенка. Вы запрещаете в языке выразительную конструкцию, и тем самым ухудшаете читаемость кода, написанного хорошими программистами.
«выразительная конструкция», которая даже 50% случаях превращает код в месиво — это вредная конструкция.
Любая конструкция в 50% случаев превращает код в месиво. Тупо потому, что большая часть кода, который мы все регулярно видим (конечно, если это не наш код) — месиво.
Покажите мне месиво в etcd
(Возможно, он просто из меньшей части?)

Но вообще, конечно: github.com/coreos/etcd/blob/master/etcdserver/etcdserverpb/etcdserver.pb.go#L66-L390

(я в курсе, что это кодогенерация, но кого это волнует?)
Вы что, издеваетесь?
Нет. Я просто показываю, что на любом языке можно породить месиво. Если это может сделать робот, то это может сделать и человек (потому что я видел людей, которые пишут так, что лучше бы это был робот).
Код там более-менее читабельный.
Хотя он и не предназначался для чтения и тем более модификации живыми существами.

Вы бы еще результат обфускатора какого-нибудь использовали как аргумент.
А это и не аргумент, это t0pep0 попросил показать пример месива из etcd. Я не очень понимаю, зачем к моему исходному комментарию аргументы, мне казалось, он более-менее самоочевиден.
Любая конструкция в 50% случаев превращает код в месиво.

lair, чуть выше я спрашивал, считаете ли вы, что код не бывает более или менее читаемым. Вот эта фраза равозначна ответу «да».
Ваша позиция ясна — вы считаете, что авторы Go неправы в том, что убрали различные конструкции из языка, потому что в долгосрочной перспективе они никак не влияют на читабельность кода.

Ни я, ни автор статьи, ни авторы Go c вами не согласны, и на этой ноте предлагаю этот, уже зашедший в тупик (а демонстрация кода автогенераторов — это тупик) тред закончить. Мы не сможем вам доказать «долгосрочный эффект по повышению читабельности» просто потому что это сложная вещь для доказательства — отдельный труд нужно писать и разрабатывать методологию исследования. Я лично для себя справедливость и правильность решения авторов Go ощущаю на ежедневном опыте на собственном и чужом коде. До Go, последние лет 5, для меня «читать код стороннего проекта» практически 100% означало «столкнуться с говнокодом/»персональным" стилем/сложночитабельными конструкциями". В Go это стало приятным ежедневным развлечением, только и всего. Я вам это не могу доказать и нарисовать графики, вы можете лишь поверить или не поверить, что я честен перед собой в своих оценках и абсолютно искренен с вами.
lair, чуть выше я спрашивал, считаете ли вы, что код не бывает более или менее читаемым. Вот эта фраза равозначна ответу «да».

Я, насколько помню, ответил вам что код бывает менее или более читаемым.

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

Нет, я считаю, что позиция «мы уберем эту конструкцию из языка, потому что она плохо влияет на читабельность» может быть ошибочной (потому что оценка long-term effects находится за пределами практически любой компетенции). Я, заметим, ничего не имею ни против Go, ни против принятых в нем design decisions — просто потому, что лично мне не хватает опыта программирования на этом языке.

До Go, последние лет 5, для меня «читать код стороннего проекта» практически 100% означало «столкнуться с говнокодом/»персональным" стилем/сложночитабельными конструкциями". В Go это стало приятным ежедневным развлечением, только и всего.

А вы уверены, что это свойство языка, а не сообщества?

PS. Seriously.

map[bool]int{true: a, false: b}[a > b]
Даже не совсем так. Не «мы уберем эту конструкцию из языка, потому что она плохо влияет на читабельность», а «есть программисты, которые пишут с помощью этой конструкции говнокод, поэтому мы ее уберем». Вот этот подход меня сильно настораживает.
Против Go ничего не имею, но, по моему мнению, это самый нелепый аргумент (причём, это касается всех кто так думает — что это, не программист криворукой, а синтаксис языка настолько плохой). Проблема в том, что плохой программист будет писать говнокод на любом языке, а вот профессионалу все эти «ограничения» будут мешать писать по-настоящему хороший код. Вы говорите что «язык стимулирует это делать», но скорее всего, это лень, невежество, дедлайн, маленькая зарплата, землетрясение или всё что угодно, но только не язык программирования.

И потом, посмотрите следующею функцию (я взял её из официального источника где учат новичков что «такое Go»):
func sum(a []int, c chan int) {
	sum := 0
	for _, v := range a {
		sum += v
	}
	c <- sum
}


Не знаю как Вы, но я не вижу тут «загадочную читаемость» про которую Вы говорите. Также, как не вижу её в следующем фрагменте кода:
c := (map[bool]int{true:a,false:a-1})[a>b]
Не знаю как Вы, но я не вижу тут «загадочную читаемость» про которую Вы говорите

Ладно, похоже, придется копнуть глубже.

Итак, про «читаемость».
Что такое «читать код»? Это понять, что собственно, этот код делает — «скомпилировать»/«запустить» его у себя в голове. Очевидно, что этот навык (чтения кода) может быть как нулевым, так и это может быть супер-натасканный 10-ти летним опытом программист, который беглым взглядом на код STL будет понимать как и что будет исполняться.

Давайте этот навык примем за некоторое число, скажем X. Распределение этого навыка среди людей, в общем случае, описывается гауссианой, с пиком где-то посрединке (среднячок). «Сильные программисты» — это меньшинство, они действительно могут очень быстро «читать» сложные конструкции. И одна из упомянутых в статье ссылок, как раз про критику об этом — мол я, «сильный программист», хочу писать крутой шифрокод, который я могу мгновенно читать, но Go мне говорит, что такой код сложночитаемый -> значит Go считает меня за лоха. Там практически так и писалось, мол Go не дает мне показать, какой я сильный программист.

Но весь поинт в том, что в Google, как и в мире open-source большинство программистов (гауссиана же) не будут в состоянии также моментально и правильно понимать те конструкции, на которые вы натаскали свой мозг. Им, для правильного понимания и дешифрования вашего кода, придется потратить больше усилий, и, потенциально, совершить больше ошибок, прежде чем, строка будет правильно прочитана. Это потери реального рабочего времени, реальные причины реальных ошибок, и стимулы для всевозможных плохих практик. И это мы говорим — о примере одной строки. Умножьте этот эффект на тысячи строк и тысячи рабочих дней и разница и потери станут более понятными.

Поэтому, в интересах авторов Go (с которыми я, к примеру, целиком согласен из своего практического опыта), чтобы, код был легкочитаем для вот той «серединки», для большинства. Чтобы любой человек, который захочет законтрибьютить в мой проект, мог это легко сделать, без того, чтобы иметь за плечами 10+ опыта горьких страданий и ошибок.

Ну отдельно можно расписать то, что плотность кода всё-таки влияет на то, как легко и быстро из него вычленит паттерны ваш неокортекс. Но так как я не читал тут никаких специальных научных исследований, а просто это чувствую на собственном опыте, то, пожалуй, не буду расписывать. Но для меня кажется очевидным, что «проскочить» или «не заметить» или «спутать» один символ в череде очень разнородных символов — гораздо проще, чем в структурированном, разбросанном на несколько строк коде. По крайней мере весь мой эмпирический опыт говорит именно это — я такое «незаметил»/«пропустил» очень много натерпелся в С++.
Извините, но Вы всё усложняйте, и, кажется, слишком глубоко «копнули». Вы написали столько букв про читаемость кода, но кажется Вы даже не читали/поняли мой комментарий. Читайте ещё раз мой комментарий и сообщение на которую я ответил — и заметите, пожалуйста, как и почему я написал слово «читаемость».

Также, прошу заметить, что я приводил две сниппеты написанные на Go, которые, по-моему, Ваши «гауссианы» точно не смогут их моментально понять, как и эту конструкцию go sum(a[len(a)/2:], c), которая, также взята из официального источника. А приводил я эти сниппеты не потому что считаю их говнокодом, а лишь потому что для меня странно видеть людей которые ненавидят тернарный оператор, но очень легко принимают совершено «необычные конструкции», и при этом считают что язык программирования стимулируют писать говнокод.

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

Замысел ваших сниппетов не слишком очевиден, но последний комментарий проясняет. Вы почему-то автоматически мне приписали, что я на любой Go-код вешаю ярлык «читабельный код», и приводите в пример не самый красивый в этом плане сниппет, ещё и обвинили в «ненависти к ternary operator-у».

Постараюсь ответить кратко — речь не идёт о бинарном делении на «читабельный» и «не читабельный», речь о статистической вероятности.

Я понял ваше несогласие с тем, что «та или иная фича способствует её неправильному использованию», но тут я даже не знаю что вам возразить. Мое убеждение в том, что авторы Go не с потолка взяли эти утверждения слишком сильно кореллирует с моим личным опытом. Мне хотелось бы, чтобы такие важные в разработке вещи, как «читабельность кода» можно было легко измерять и формализировать, но пока что это увы не так.
Замысел ваших сниппетов не слишком очевиден, но последний комментарий проясняет.
Да, мне тоже показалось что стоит объяснить почему я этого сделал.

Вы почему-то автоматически мне приписали, что я на любой Go-код вешаю ярлык «читабельный код»
Но разве это не Вы сказали что код Go в 90% случаев читабельный, понятный и доступный? Я не знаю откуда Вы взяли эти цифры, но допустим что это так. Однако, именно данная фраза послужила одной из причин приписывать, как Вы сказали, «ярлык читабельный код».

и приводите в пример не самый красивый в этом плане сниппет
Я взял 2 сниппеты из официального урока, чтобы показать что, даже без тернарного оператора в Go есть другие конструкции из-за которых код также становится не очень читаемым. И если в официальном уроке используются такие сниппеты, что же происходит в «закрытых» продуктах? Неужели там код пишут лучше? Не верю!

Заметите, я не взял просто «не самый красивый в этом плане сниппет», я взял сниппеты которые показывают людям насколько этот язык хорош и, пам-пам, гибкий. Но что же получается — они убрали тернарный оператор, но добавили куча новых конструкций, которые далеко не всегда делают код более читаемым. И разве тернарный оператор не делает ЯП более гибким?

ещё и обвинили в «ненависти к ternary operator-у»
Может я не использовал подходящее слово, но, сначала Вы пишите что в 50% случаев (опять используете какие-то загадочные цифры) тернарный оператор «это плохо» и говорите, что нужно его выпилить если хотим получить качественный код. Далее интереснее — Вы приводите пример кода чтобы доказать что тернарный оператор «это очень плохо» и что язык программирования стимулирует так писать. И наконец, t0pep0 говорит что «Go — хороший язык, в нем нет подобных конструкций». Я могу ошибаться, но раз Вы не видите другие странные конструкции кроме тернарного оператора, я подумал, что вы точно не любите его.

речь не идёт о бинарном делении на «читабельный» и «не читабельный», речь о статистической вероятности.
Если вспомнить историю, то статистика подсказывает почему сейчас на Go написан так мало говнокода. А всё очень просто — сейчас, по сравнению с другими языками, Go используют только немногие и как я заметил, большинство из них действительно профессионалы. Но что будет, когда неопытные программисты (или индусы) будут переходить к Go? Вы думаете, отсутствие тернарного оператора будет сдерживать их написать говнокод? Или, может быть они больше не будут использовать по 1000 строк if/else вместо простой функции или цикла?

Я понял ваше несогласие с тем, что «та или иная фича способствует её неправильному использованию», но тут я даже не знаю что вам возразить. Мое убеждение в том, что авторы Go не с потолка взяли эти утверждения слишком сильно кореллирует с моим личным опытом.
Что бы не говорили авторы языка Go, я никогда не поверю что в Go отсутствует говнокод поскольку он не поддерживает тернарный оператор (также как в других ЯП много говнокода из-за того что он поддерживается). Можно посмотреть на том же govnokod.ru, вряд-ли там так много примеров с использованием тернарного оператора. А вот чтобы подискутировать насчёт «потолка» — нужно открыть новую ветку комментариев, ибо, как мне кажется, тернарный оператор не используется в Go совсем по другой причине :)

Мне хотелось бы, чтобы такие важные в разработке вещи, как «читабельность кода» можно было легко измерять и формализировать, но пока что это увы не так.
Полностью согласен с Вами. И я очень рад за это.
Но разве это не Вы сказали что код Go в 90% случаев читабельный, понятный и доступный? Я не знаю откуда Вы взяли эти цифры, но допустим что это так.

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

Касательно приведенных сниппетов. Первый (sum()) — это очень понятный и прямолинейный код. Его сложно прочесть или интерпретировать неправильно, он оставляет мало места для ошибочной трактовки, даже если вы плохо знаете язык, в нем сложно «пропустить» одну букву и неверно истрактовать. Это хороший и идиоматический для Go код.
Второй сниппет — я не знаю откуда вы взяли, но это образец того, как не нужно делать, и я лично такой код не встречал.

Я могу ошибаться, но раз Вы не видите другие странные конструкции кроме тернарного оператора, я подумал, что вы точно не любите его.

Тернарный оператор служит хорошим примером того, какими ценностями руководствовались авторы Go, для достижения целей, описанных в начале статьи. Да, я не спорю, что:
foo := bar ? 1 : 0

выглядит приятнее, чем
foo := 0
if bar {
  foo = 1
}

Но из многолетней практики очевидно, что ternary operator используется не только для таких случаев. Он используется и тогда, когда if/else действительно должен быть более читабельным, и для вложенных проверок, и как аргумент функций и как возвратное значение, и как угодно ещё, делая код — по общему консенсусу хуже. Приведенный чуть ранее пример — лишь демонстрация этого.
И логика авторов Go звучит примерно так: «плюсы от возможности написать в 10% случаев чуть более краткий код, не перекрывают минусы от того, что в 90% код будет становиться хуже».

Но что будет, когда неопытные программисты (или индусы) будут переходить к Go?

Мне понятен ваш песс… реализм, основанный на опыте с другими языками, но такое опасение было бы действительно обоснованным, если бы Go концептуально не отличался от тех языков, которые прошли через подобное. Я не помню на своей памяти, язык, который бы хвастался тем, что у них меньше всего фич и он проще всех.
Эффект тут такой, что в Go уже повалило много людей, которые поняли, какие они получают плюсы и бенефиты, без того, чтобы становится бородатыми хардкорщиками. У Пайка есть даже статья о том, почему С++-программисты неохотно переходят на Go, и основной приток гоферов — с языков вроде Ruby, Python и PHP. Так что в Go уже большая часть комьюнити — это народ далеко не гении PLT, хотя действительно умных людей тоже немало.
Скажу так — Go позволяет легче делать production level код, и быть в нём уверенным. Для того, чтобы выдать качественный код на Go не нужно «5+ лет опыта» и 5 прочитенных «Библий Go».

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

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

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

Во-вторых, цифры должны быть подкреплены фактами. Я уважаю Ваше мнение, но когда речь идёт о таких цифрах как 90% или 50% — мне кажется что они взяты из «потолка»

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

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

И так, первый у нас docker*:
if !MatchesContentType("application/json", "application/json") {
	t.Fail()
}

if !MatchesContentType("application/json; charset=utf-8", "application/json") {
	t.Fail()
}

if MatchesContentType("dockerapplication/json", "application/json") {
	t.Fail()
}


Потом syncthing*:
case "setup":
	setup()

case "install":
	pkg := "./cmd/..."
	var tags []string
	if noupgrade {
		tags = []string{"noupgrade"}
	}
	install(pkg, tags)

case "build":
	pkg := "./cmd/syncthing"
	var tags []string
	if noupgrade {
		tags = []string{"noupgrade"}
	}
	build(pkg, tags)

case "test":
	test("./...")

case "bench":
	bench("./...")

case "assets":
	assets()

case "xdr":
	xdr()

case "translate":
	translate()

case "transifex":
	transifex()

case "deps":
	deps()

case "tar":
	buildTar()

case "zip":
	buildZip()

case "deb":
	buildDeb()

case "clean":
	clean()

case "vet":
	vet("./cmd/syncthing")
	vet("./internal/...")

case "lint":
	lint("./cmd/syncthing")
	lint("./internal/...")


Далее идёт сам golang*:
const exitstr = "exitcode="
cmd := `export TMPDIR="` + deviceGotmp + `"` +
	`; export GOROOT="` + deviceGoroot + `"` +
	`; export GOPATH="` + deviceGopath + `"` +
	`; cd "` + deviceCwd + `"` +
	"; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") +
	"; echo -n " + exitstr + "$?"
output := run("shell", cmd)


И последний которого посмотрел, gogs*:
case "":
	priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits"))
case "P224":
	priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
case "P256":
	priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
case "P384":
	priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
case "P521":
	priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)


Я прекрасно понимаю, что ни один язык программирования не идеален и плохой код существует везде. Но, повторюсь ещё раз — то что некоторые пишут говнокод это не проблема языка. И то, что на других языках написано больше плохого кода, чем на Go, никак не связано с отсутствием/наличие тернарного оператора.
Да ничего, на самом деле с Вами интересней всего из всех комментаторов тут было общаться.

Насчёт «Go не так популярен, как мне кажется» — мне не кажется, и я думаю, что достаточно объективно вижу картинку. Go достаточно уверенно занимает свою основную нишу (системный/серверный софт) и постепенно осваивает новые ниши — и мне важно то, что уже написанного софта и библиотек достаточно, чтобы не упираться в отсутствие каких-то важных библиотек, и что лично я для всех моих задач (а я, в основном, серверным софтом занимаюсь) получаю благодаря Go результат.

Тоесть фразы вроде «Go не так популярен» или «вот посмотрим на него, когда он вытеснит все другие языки» — мне просто не релевантны. Go для меня уже состоялся и экономит массу времени, которое для меня есть синонимом к «деньги» :)

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

А все приведенные ваши примеры — это не говнокод. Это то, что Брукс в своем знаменитом труде «No silver bullet» называл "essential complexity" — та составная сложности задачи, которая происходит из области проблемы, а не от выбранного инструмента. От этой сложности не уйти, каким языком её не решай. Если вам нужно поддерживать N алгоритмов генерации ключей — нет такого языка, где вы все N вариантов напишете одной командой. Зато вторая составная — "accidental complexity" — которая привносится инструментом, вот эти все обертки/классы/расходы на ручной менеджмент памяти и декодинг фичастых конструкций — это то, что можно и нужно уменьшать. Вообще эта тема отдельной статьи заслуживает.
Надо написать, спасибо за идею :)
В слепом фанатизме нет ничего хорошего.
Не задумывались, что язык Go создавался большими компаниями, которые подразумевают большую текучку? Для того чтобы программисты программировали и особо не возникали. Хочешь ЗП побольше — иди отсюда, мы наймем студента, которые будет писать за хлеб? Вы, наверное, такого хотите для себя, да?
Кстати, автор добавил небольшое обновление к статье.
И потом, посмотрите следующею функцию (я взял её из официального источника где учат новичков что «такое Go»):

Простите, а что здесь не понятного?
Также, как не вижу её в следующем фрагменте кода:

Да, согласен, код пример того, как писать не надо.
Если вам станет легче, то такой код нужно заменить на
c := a - 1
if a > b {
  c = a
} 

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

Если захотеть, можно написать обфускатор на go и пропускать через него все свои коммиты, специально отстреливая себе ногу вместе со всем остальным телом. Самое смешное, что и сгенерированный код для бездушных машин (protobuff), и вещи

c := (map[bool]int{true: a, false: a - 1})[a > b]
// причем именно так оно выглядит после go fmt, а то что вы привели - неизвестно откуда.

выглядят относительно адекватно, хотя подобную конструкцию я вижу первый раз (а пишу на go я уже больше года в продакшене, и с 2012 — вообще)

Но go fmt этот обфусцированный код сформатирует по-человечески, а go vet не пропустит достаточно много.

P.s. немного промахнулся с тем, кому отвечал, извините
> Вот такое (это реальный код) написать с помощью if/else будет очень сложно

Легко, надо просто написать соответствующие if/else в одну строчку. Если у писавшего это человека мозг из-за лени не пошел искать другое решение — у меня для мозга плохие новости…
А не надо было отделять :? от if else. И вообще выделять statements и expressions.
Например Haskell читается замечательно, при этом допускает достаточно большие выражения.
ИМХО, конечно, но у Haskell читаемость как у Scala
В тему C++
Однажды я пытался создать list<map> и мои синтаксические ошибки подняли мёртвых из могил
http://habrahabr.ru/post/203276/
На Go написан etcd — уже одно это заставляет отнестись к Go серьёзно.
Автор говорит о суперчитабельности. По совету выше начал проходить Тур оф Го и вижу пример:

func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum — x
return
}

(код не форматируется у меня)

И читаю объяснение:

> Naked return statements should be used only in short functions, as with the example shown here. They can harm readability in longer functions.

Ну ведь сами понимают, что это снижает читабельность (лично для меня даже эта микрофункция уже не очевидна), нахера такое вообще вводить? Что, написав return x, y код как-то жутко усложнился?
Naked return statements should be used only in short functions, as with the example shown here. They can harm readabilit y in longer functions.

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

А в коротких функциях иногда и правда return без параметров бывает аккуратнее
З.Ы. В настоящее время сообщество работает над переводом тур оф гоу, надеюсь после этого будет меньше таких не понятных ситуаций
Эмм… лол. Я понял о чем там говорят, мне не нужен перевод.

> А в коротких функциях иногда и правда return без параметров бывает аккуратнее

Я не знаю что вы подразумеваете под «аккуратностью», но эти их нейкед ритёрн ухудшает читабельность и понятность любой функции — и большой, и маленькой, при этом никакого профита не дает. И не надо тут ничего выдумывать про какую-то там аккуратность.
Да-да, видел — хорошо кого-то зацепило :)
ни смотря ни на что

несмотря ни на что
Не смотря ни не что
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации