Зато до этого большинство статей только о том, какой это прекрасный язык. Как это обычно бывает со всеми новыми IT игрушками. Тот же docker какой прекрасный распрекрасный нам рисовали все время. NoSQL как нам рисовали, помнится. Правильно люди на конференциях Go говорят — перед знакомством с языком надо опустить свои ожидания, которые из-за хайпа вокруг него завышены очень сильно. Тогда язык не будет казаться непонятной хренью непонятно для чего.
Что тогда есть поддержка Unicode, если не возможность хранения и манипулирования unicode строками на уровне стандартной библиотеки? Да, там это не очень удобно делать, в основном из-за многочисленных устаревших API, которые умеют только char. Но все же есть.
у Go очень подробные трейсы, если у вас получилось что не обработали ошибку сильно не в том месте где упало, смотрите на это как на стимул обрабатывать ошибки.
А вот исключение покажет мне конкретное место, кто его выкинул. Как-то нагляднее и полезнее, чем копаться и искать, что же завалило мой Go код. И то и то стимулирует обрабатывать ошибки, но по несколько разным причинам. Случай с Go напоминает классическую ошибку с порчей кучи — что-то где-то упало, зато стимул аккуратнее работать с памятью.
Подход с ошибками можно описать просто — я вижу метод с ошибкой и сразу пишу, что мне делать, что там за ошибка мне в принципе не очень то и важно.
В этом вся и проблема ошибок Go для меня. Он подталкивает писать код, который ничего не делает с ошибками. Пишем на best case scenario, а если ошибка, то всем nil вернуть и фиг с ними.
99% ошибок в go это errors.New(«some text»)
Стандартная библиотека содержит множество типизированных ошибок или переменных-ошибок на уровне пакета. Они сделаны для того, чтобы кто-то смотрел на тип и реагировал соответственно.
какой use case, что именно вы смотрите кроме текстовки и как на это реагируете?
Вам придумать use case, когда от ошибки зависит дальнейшее поведение программы? Вы никогда не писали демонов, которые должны сами восстанавливать соединение, повторять то, что завершилось с ошибкой? Куча use case, когда некому и нечему читать сообщения, нужно реагировать и восстанавливаться. И это зависит от того, какая конкретно ошибка вернулась.
В существующем же дизайне API, пользовательский код таким образом выглядит более естественным: сначала пройтись до конца по токенам, а потом проверять и волноваться об ошибках. Обработка ошибок не прячет поток управления.
Вот здесь мне говорят, что один вариант лучше другого.
Под капотом всего этого, конечно, происходит следующее — как только Scan обнаруживает ошибку ввода-вывода, она сохраняет ошибку и возвращает false. Отдельный метод, Err, её возвращает, когда клиент запросит
Вот здесь мне говорят, что лучше пробежаться потенциально сотни и миллионы итераций с no-op
Вы вправду верите, что Go делали, руководствуясь такими соображениями?
Приходится, потому что объективных причин нет
Выдерживают.
Одна из основных идей отказа от исключений в Go в том, что последние подталкивают к коду, который просто игнорирует ошибки. Пустой try/catch и в релиз. Ага, при этом в Go игнорирование ошибки это поведение по-умолчанию. Нет объективных преимуществ у Go ошибок. Напротив, видны объективные недостатки, которые проистекают от того, что Go использует всего лишь немного приукрашенные C ошибки, которые никогда не были удобными и всегда вели к страшному и сложному коду, который и можно видеть в статье. Это кстати одна из причин, почему goto таки очень нужная вещь именно в C коде и ему подобных. Иначе получается страх и ужас как в статье с тучей err != 0 по всему коду.
Опять 25. Panic — именно та ситуация, когда произошла неотвратимая ошибка, и нужно завершить программу и вывалить стек.
Да что вы говорите. Вы блоги то читаете? Panic рекомендуется использовать в тех же библиотеках, есть даже конкретный паттерн, который приводится в пример. И самый явный пример это парсерсы, которые активно пользуются этими уродливыми исключениями. Что не советуют — это вываливать panic наружу, а выдавать error.
Это ваши неверные догадки. Не знаю, почему вы не хотите разобраться в истинных причинах.
После «вставка в середину массива уролива, чтобы показать сложность операции» у меня нет причин думать иначе. Это похоже философия языка, делать уродливым и сложным то, что делать не рекомендуется. И защитники Go это активно проповедуют, судя по всему. Таких маленьких деталей в языке достаточно, которые намекают — так не делай. Тот же рандомизированный select — явно намекают, что не надо тебе надеяться, чтобы кто-то будет первый. Ты лучше архитектуру поменяй, чтобы этого не требовалось. Ну или делай вложенные select, что, о боже как неожиданно, уродливо.
Это в других языках извращение. В Go исходники всегда доступны в godoc и это вопрос миллисекунд. Попробуйте, прежде чем судить.
Но вообще, хорошую идею подали. Хотя подобная ситуация никогда в практике не была проблемой, но это интересный кейс для статического анализа.
Я пробовал, не надо за меня додумывать. Я пробовал, я писал и я плевался. Для чего нужная документация? Как ни странно, чтобы описать, что делает функция, что она принимает, что она возвращает в случае успеха, что она возвращает в случае ошибки. Так делают ВСЕ. Что делает официальная документация Go? Она просит лезть в исходник. Это извращение и никак иначе. И то, что люди привыкают лезть ради таких вещей в исходник, делает только хуже. Можно похоже уже не писать документацию — лезь в исходник, че, нафиг тебе еще объяснять поведение функции.
Вам так не говорят. В статье рассматривается конкретный пример.
И на основе него мне говорят прямым текстом «надо не сразу получать ошибку и ее обрабатывать, а пробежаться все сотни и миллионы итераций с no-op, чтобы потом в конце узнать, что оказывается на первой итерации была ошибка».
Мне прямым текстом говорят, что один вариант плохой, а другой хороший. Так что, еще раз, как иначе понимать статью, если не так? Вы уже который комментарий ходите вокруг да около, кидаете какие-то намеки, но так конкретно и не говорите, как же надо понимать то, что написано черным по белому в статье.
Эм, а как тогда понимать код в статье? Мне говорят, что надо не сразу получать ошибку и ее обрабатывать, а пробежаться все сотни и миллионы итераций с no-op, чтобы потом в конце узнать, что оказывается на первой итерации была ошибка и мой цикл в пустую делал работу. Это херота какая-то и ужасный просто совет. Я удивлен, что такое советуют в официальном блоге. Ошибка должны быть обработана в том месте, где она произошла. Если код из-за этого становится страшным, то, ну не знаю. Вроде бы давно ясно, что обработка ошибок многословна. Либо надо таки как-то рефакторить код. Но не делать костыль как в статье.
Каким образом совет в статье связан с «программирование с использованием значений ошибок» решительно не ясно.
Дизайн ошибок в Go конечно очень странный и таки не выглядит лучше того, что есть у других. Такое ощущение, что сделали лишь бы чтобы было по-другому. Все аргументы, что он чем-то лучше исключений и как-то способствует лучшему коду, не выдерживают критики. Более того, исключения таки, объективно, больше способствуют написанию кода, который обрабатывает ошибки и правильно на них реагирует, и банально более функциональны:
1. Исключение без try/catch сразу завалит программу, а таки пустой try/catch вокруг каждого куска кода никто не ставит. Ошибки Go можно банально игнорировать и это является поведением по-умолчанию, в отличие от исключений. Самый прикол сразу в hello world — мало кто подозревает по первости, что банальный Println возвращает ошибку. Кто ее обрабатывает? Да никто. Это прям как коды ошибок в C.
2. Исключения имеют контекст по-определению — стек вызовов. Если go код упадет из-за необработанной ошибки, то где и как искать злосчастное место? Да никак. Panic и recovery не более чем костыль, который выглядит как try/catch, но похоже намерено сделаны уродливыми и неудобными, чтобы их по-меньше использовали.
Но все таки в итоге, ошибки в Go наверно ни лучше и ни хуже исключений. Просто другие и не дают никакого реально выигрыша. Так захотелось создателям языка.
У меня вот вопрос к опытным гуфам. Допустим, работаю я с пакетом net. Вижу, что метод Listen может мне вернуть ошибку. Естественно возвращают мне интерфейс error, тут все ок. Вопрос, как мне узнать, а какой конкретно тип может иметь эта ошибка? В net пакете пачка этих ошибок разных, но в документации ни слова о том, какие из них может вернуть Listen. Опять же, исключения обычно (а в том же msdn для .net всегда) оговорены конкретно для каждой функции. Как мне вот быть, может я совсем ослеп и где-то таки эта информация есть? Я понимаю, что можно посмотреть исходник, но это, извините, полное извращение. Или же это очередная уникальная особенность экосистемы Go?
А вот и пошли аргументы в стиле «сначала добейся».
Чето все мелочи всякие обсуждаем. Может начать тему того, что в го отсутствует система управления зависимостями и намеченное решение выглядят как большой такой и страшный костыль, который все равно ее не решает. Такой то системный язык для больших команд и проектов. Благо хоть создатели осознают, что это большой фейл и надо с ним что-то делать. Жалко, что сами они не хотят с этим ничего делать.
Мне кажется это, как тут уже говорили, имидж языка, который вот такими статьями и создается. Язык вроде и не плох, и есть чем ему похвастать против остальных, но вот такое вот комьюнити создает враждебную атмосферу, когда уже на любых защитников языка кидаются с уверенностью, что это наверняка очередной фанатик, который дальше своего Go видеть разучился, аргументов внятных предоставить не может кроме «Пайк сделал, значит правильно». И ведь много таких в комментариях даже здесь. Напротив, хейтерства именно я вижу мало. Я вижу людей, которые обсуждают то, что им не нравится. А против них обычно фанатик, который внятно свою позицию обозначить не может. Просто слепая вера какая-то в святость путей, избранных Go.
А Go нет никакой возможности нам еще доказать, что он чем-то лучше этих языков «приводящих к тоннам багов и ужасного неподдерживаемого кода в дикой природе». Go новомодная штучка, все его достоинства пока что существуют в большинстве на словах и в мечтах авторов некоторых статей. Когда дорастет, то приходите, обсудим, во что превратился некогда такой прекрасный язык.
Статья же автора о том, что дизайн языка «плохой» — это, к сожалению, не более, чем попытка привлечь к себе внимание
Не берите на себя слишком много. Написали статью для самоуспокоения — замечательно. Но прошлая статья прекрасно описывала те проблемы, с которым, например, столкнулся я и долго плевался. И что-то подсказывает, что я далеко не один. Статья написана в том числе для привлечения внимания, но ее суть и основные тезисы описывают фактические проблемы языка, которые некоторые отказываются видеть и выдумывают тысячу отмазок вроде «так сделали, значит так надо и правильно», «это не нужно, приведите примеры, когда это нужно» и прочие попытки успокоить себя, не более того.
И? Оно что-то крадет? Оно что-то делает, что не позволено ему? Оно вообще запускается или лежит мертвым грузом, ожидая превью программы? Просто так дампить весь этот список не имеет никакого смысла. Хотите верить, не основываясь ни на чем — пожалуйста. Для меня это не убедительно ввиду отсутствия объективных фактов.
Этот синтаксис показывает программисту, что операция которую он совершает, не простое присваивание, а ресурсоемкая задача.
Ох е. И вы действительно в это верите? Есть другая причина — разработчики языка не продумали эту сторону, и мы имеем неоптимальное, некрасивое, неудобное решение. И ваши оправдания тому, что это нормально, выглядят нелепо. Ресурсоемкость задачи программисту должна говорить документация, но никак не монструозный синтаксис, который вообще никак с ресурсоемкостью не коррелирует и не связан. Есть плохой синтаксис и есть примитивная операция как то вставка в произвольное место массива. Это примитивная операция и не надо пытаться доказать обратно в надежде, что это сойдет за оправдание Go.
Расслабьтесь и наслаждайтесь жизнью в сторонке от Go.
А давайте вы лучше будете жить спокойнее в сторонке от тем, который так вас подрывают. Нравится — ок. Нам не нравится — извольте нам дать свободу для обсуждения. На любой язык ругаются и это позволяет сделать их лучше. На Страуструпа с плюсами жалуются — получаем новые стандарты. На команду C# жалуемся — получаем новые версии языка. Авось и до команды Go дойдет, что дизайн языка таки не блещет. В нем много хорошего, но достаточно проблемных мест, которые никак не подорвут его философию.
А кто сказал, что это сложная задача? Даже на С она решается тривиально и я даже осмелюсь сказать, что получится читабельнее этого месива из скобок и точек. Это не говоря о том, что в современных языках это обычно входит в стандартную библиотеку.
Почему бы не сделать это в виде библиотечных функций, как это везде повсюду? Как же знаменитый code-reuse? Из языка вырезали так много, что приходится обратно все туда руками заталкивать. И это будет не стандартный API, а велосипед, который все и каждый делают заново. Это — плохо продуманный язык. Кто-то слишком фанател идеей о «спорной нужности операции».
Только вот я это читаю и просто диву даюсь — да это ж пересказ всего того мата, который был у меня, когда я начинал писать на Go. Простая примитивная программа из-за тех же слайсов и чехорды между [n]int и []int превращается в такое убожество, что страшно. Язык простой, да, но код на нем получается совсем не простой.
А вот исключение покажет мне конкретное место, кто его выкинул. Как-то нагляднее и полезнее, чем копаться и искать, что же завалило мой Go код. И то и то стимулирует обрабатывать ошибки, но по несколько разным причинам. Случай с Go напоминает классическую ошибку с порчей кучи — что-то где-то упало, зато стимул аккуратнее работать с памятью.
В этом вся и проблема ошибок Go для меня. Он подталкивает писать код, который ничего не делает с ошибками. Пишем на best case scenario, а если ошибка, то всем nil вернуть и фиг с ними.
Стандартная библиотека содержит множество типизированных ошибок или переменных-ошибок на уровне пакета. Они сделаны для того, чтобы кто-то смотрел на тип и реагировал соответственно.
Вам придумать use case, когда от ошибки зависит дальнейшее поведение программы? Вы никогда не писали демонов, которые должны сами восстанавливать соединение, повторять то, что завершилось с ошибкой? Куча use case, когда некому и нечему читать сообщения, нужно реагировать и восстанавливаться. И это зависит от того, какая конкретно ошибка вернулась.
Вот здесь мне говорят, что один вариант лучше другого.
Вот здесь мне говорят, что лучше пробежаться потенциально сотни и миллионы итераций с no-op
Приходится, потому что объективных причин нет
Одна из основных идей отказа от исключений в Go в том, что последние подталкивают к коду, который просто игнорирует ошибки. Пустой try/catch и в релиз. Ага, при этом в Go игнорирование ошибки это поведение по-умолчанию. Нет объективных преимуществ у Go ошибок. Напротив, видны объективные недостатки, которые проистекают от того, что Go использует всего лишь немного приукрашенные C ошибки, которые никогда не были удобными и всегда вели к страшному и сложному коду, который и можно видеть в статье. Это кстати одна из причин, почему goto таки очень нужная вещь именно в C коде и ему подобных. Иначе получается страх и ужас как в статье с тучей err != 0 по всему коду.
Да что вы говорите. Вы блоги то читаете? Panic рекомендуется использовать в тех же библиотеках, есть даже конкретный паттерн, который приводится в пример. И самый явный пример это парсерсы, которые активно пользуются этими уродливыми исключениями. Что не советуют — это вываливать panic наружу, а выдавать error.
После «вставка в середину массива уролива, чтобы показать сложность операции» у меня нет причин думать иначе. Это похоже философия языка, делать уродливым и сложным то, что делать не рекомендуется. И защитники Go это активно проповедуют, судя по всему. Таких маленьких деталей в языке достаточно, которые намекают — так не делай. Тот же рандомизированный select — явно намекают, что не надо тебе надеяться, чтобы кто-то будет первый. Ты лучше архитектуру поменяй, чтобы этого не требовалось. Ну или делай вложенные select, что, о боже как неожиданно, уродливо.
Я пробовал, не надо за меня додумывать. Я пробовал, я писал и я плевался. Для чего нужная документация? Как ни странно, чтобы описать, что делает функция, что она принимает, что она возвращает в случае успеха, что она возвращает в случае ошибки. Так делают ВСЕ. Что делает официальная документация Go? Она просит лезть в исходник. Это извращение и никак иначе. И то, что люди привыкают лезть ради таких вещей в исходник, делает только хуже. Можно похоже уже не писать документацию — лезь в исходник, че, нафиг тебе еще объяснять поведение функции.
И на основе него мне говорят прямым текстом «надо не сразу получать ошибку и ее обрабатывать, а пробежаться все сотни и миллионы итераций с no-op, чтобы потом в конце узнать, что оказывается на первой итерации была ошибка».
Мне прямым текстом говорят, что один вариант плохой, а другой хороший. Так что, еще раз, как иначе понимать статью, если не так? Вы уже который комментарий ходите вокруг да около, кидаете какие-то намеки, но так конкретно и не говорите, как же надо понимать то, что написано черным по белому в статье.
Каким образом совет в статье связан с «программирование с использованием значений ошибок» решительно не ясно.
1. Исключение без try/catch сразу завалит программу, а таки пустой try/catch вокруг каждого куска кода никто не ставит. Ошибки Go можно банально игнорировать и это является поведением по-умолчанию, в отличие от исключений. Самый прикол сразу в hello world — мало кто подозревает по первости, что банальный Println возвращает ошибку. Кто ее обрабатывает? Да никто. Это прям как коды ошибок в C.
2. Исключения имеют контекст по-определению — стек вызовов. Если go код упадет из-за необработанной ошибки, то где и как искать злосчастное место? Да никак. Panic и recovery не более чем костыль, который выглядит как try/catch, но похоже намерено сделаны уродливыми и неудобными, чтобы их по-меньше использовали.
Но все таки в итоге, ошибки в Go наверно ни лучше и ни хуже исключений. Просто другие и не дают никакого реально выигрыша. Так захотелось создателям языка.
У меня вот вопрос к опытным гуфам. Допустим, работаю я с пакетом net. Вижу, что метод Listen может мне вернуть ошибку. Естественно возвращают мне интерфейс error, тут все ок. Вопрос, как мне узнать, а какой конкретно тип может иметь эта ошибка? В net пакете пачка этих ошибок разных, но в документации ни слова о том, какие из них может вернуть Listen. Опять же, исключения обычно (а в том же msdn для .net всегда) оговорены конкретно для каждой функции. Как мне вот быть, может я совсем ослеп и где-то таки эта информация есть? Я понимаю, что можно посмотреть исходник, но это, извините, полное извращение. Или же это очередная уникальная особенность экосистемы Go?
А вот и пошли аргументы в стиле «сначала добейся».
Чето все мелочи всякие обсуждаем. Может начать тему того, что в го отсутствует система управления зависимостями и намеченное решение выглядят как большой такой и страшный костыль, который все равно ее не решает. Такой то системный язык для больших команд и проектов. Благо хоть создатели осознают, что это большой фейл и надо с ним что-то делать. Жалко, что сами они не хотят с этим ничего делать.
Не берите на себя слишком много. Написали статью для самоуспокоения — замечательно. Но прошлая статья прекрасно описывала те проблемы, с которым, например, столкнулся я и долго плевался. И что-то подсказывает, что я далеко не один. Статья написана в том числе для привлечения внимания, но ее суть и основные тезисы описывают фактические проблемы языка, которые некоторые отказываются видеть и выдумывают тысячу отмазок вроде «так сделали, значит так надо и правильно», «это не нужно, приведите примеры, когда это нужно» и прочие попытки успокоить себя, не более того.
Ох е. И вы действительно в это верите? Есть другая причина — разработчики языка не продумали эту сторону, и мы имеем неоптимальное, некрасивое, неудобное решение. И ваши оправдания тому, что это нормально, выглядят нелепо. Ресурсоемкость задачи программисту должна говорить документация, но никак не монструозный синтаксис, который вообще никак с ресурсоемкостью не коррелирует и не связан. Есть плохой синтаксис и есть примитивная операция как то вставка в произвольное место массива. Это примитивная операция и не надо пытаться доказать обратно в надежде, что это сойдет за оправдание Go.
А давайте вы лучше будете жить спокойнее в сторонке от тем, который так вас подрывают. Нравится — ок. Нам не нравится — извольте нам дать свободу для обсуждения. На любой язык ругаются и это позволяет сделать их лучше. На Страуструпа с плюсами жалуются — получаем новые стандарты. На команду C# жалуемся — получаем новые версии языка. Авось и до команды Go дойдет, что дизайн языка таки не блещет. В нем много хорошего, но достаточно проблемных мест, которые никак не подорвут его философию.