Здравствуйте, alpha21264, Вы писали:
Pzz>>Причем помогает даже не от случайных ошибок, а помогает читать код. Например, когда хочешь понять, кто поднасрал в сложную структуру, внутрь функций, которые получают ее, как указатель на константу, можно не заглядывать.
A>Ну вот... фигня. A>Нормальный программист знает, что не надо менять входные параметры, и как правило не меняет.
А куда ему деваться, если основной выразительный механизм в Си — это функции, которым передаются указатели на структуры, с котороми они что-то делают?
A>Поэтому с моей точки зрения нужно маркировать не константные аргументы, а изменяемые аргументы. A>Таким образом в правильно написанной программе хлама не будет.
Ну в принципе, да. Лучше иметь константность по умолчанию и явно задаваемый признак того, что переменная может меняться. Но это — очень радикальное измненение по сравнению с Си. В Rust, не отягощенном совместимостью с Си, вроде так и сделано
A>А сейчас хлама столько же, сколько полезной информации или даже больше. A>Это не правильно.
Раздражает микс, когда в проекте имеется полно функций, параметры которых по сути константные, но таковыми не размечены.
A>Другой маразм, который никто не знает, и который любят спрашивать на собеседованиях - A>в зависимости от положения слова const может быть константный адрес или константное содержимое адреса.
На собеседованиях любят спрашивать всякую фигню.
У Си есть неочевидные нюансы, но никто в своём уме не будет использовать их в боевом коде.
Мой любимый пример: x = (flag ? sin : cos)(y); Опыт показывает, что эта простая конструкция приводит многих собеседователей в тупик, в диапазоне от "а что это значит?" и до "а что, так можно?".
Здравствуйте, Pzz, Вы писали:
S>>Хотелось бы видеть что-то в качестве демонстрации возможностей Go.
Pzz>Похоже, под нетривиальностью ты имеешь ввиду размер программы.
Нет. Но в вас я вижу человека, которому думать, скажем так, тяжело.
Pzz>Ядро Linux, правда, на сишечке написано.
Ну хоть что-то.
S>>Пока что со стороны кажется, что Go делали для людей, для которых даже Java -- это "слишкам сложно". И, вероятно, людьми, которые даже Java в силу своего "крутого" бэкграунда не освоили.
Pzz>Ты видишь в Go язык, созданный идиотами для идиотов.
Для идиотов -- да. Про умственный уровень создателей я не говорил.
Pzz>Я вижу что за Go стоят люди, которые подарили миру UNIX и Си — проекты, определившие направление развития индустрии на десятилетия.
Т.е. для вас важнее авторитеты? Ну OK.
Pzz>С учётом всего этого, Go — это такой C 2.0, прямое продолжение цепочки C -> Alef/Limbo -> Go. Созданный с учётом всего этого опыта и со многими исправленными ошибками Си.
Вы так говорите, как будто это что-то хорошее.
Вообще странно, когда Go сравнивают с Си. Но, в вашем случае опять же нужно делать скидку на, скажем так, особенности мышления.
Безопасный язык со сборкой мусора сравнивать с Си, в геноме которого полная свобода программиста с минимумом контроля. Внушаить, да.
Pzz>Детский какой-то вопрос. А можно ли переписать LibreOffice с нуля на Go? Ну можно, наверное.
А может быть и нет. Языки программирования эволюционировали в сторону усложнения не просто так. Например, Ada сразу создавалась как сложный язык, а потом еще и обрастала возможностями. Аналогично и Eiffel. Аналогично и Java c C#. Про С++ и говорить не приходится. И это мне еще не приходилось сталкиваться с миром функциональщины (Scala, OCaml, Haskell и вот это вот всё).
Ряд вещей, от которых некоторые отмахиваются (вроде const-ов или даже пространств имен) как раз предназначались для борьбы со сложностью, которая возникает из-за размера проекта. И это даже не беря в расчет сложность самой предметной области.
При этом вышеозначенные языки в большей или меньшей степени позволяют разработчику создавать недостающие инструменты под задачу.
В Go, например, каналы сделали частью языка. Сомнительно, но окай.
Только вот зачем это нужно, если язык и так достаточно выразительный, чтобы сделать тоже самое посредством библиотек?
И что делать в языках вроде Go, когда потребуется что-то, что авторы языка не удосужились туда упихнуть?
В то время как для технически продвинутых языков это не проблема.
Поэтому нетривиальные задачи на C++, C# или каком-нибудь Haskell решаются. Как будет с Go... Есть сомнения.
Pzz>Что в этоге получится? Ну, видимо, LibreOffice, переписанных на Go
Только вот вопрос будет как в цене разработки, так и в тормознутости и ресурсоемкости результата.
PS. Дяденька, судя по тому, что и как вы пишете, вы лет на 5-10 постарше меня. Неудобно такие вещи говорить старшим, но складывается ощущение, что голова у вас для того, чтобы в нее есть. А не думать.
Здравствуйте, Pzz, Вы писали:
S>>>Такое ощущение, что вы продолжаете жить в 1980-х. Уже к середине 1990-х такое стало моветоном.
A>>Я знаю. Я действительно не стильно-модно-молодёжный.
Pzz>При чём тут модность-молодёжность?
При том, что в программистском мире тоже есть религиозные проповедники, которые проповедуют свою религию.
Да, религии бывают разные, можно верить в непорочное зачатие, а можно верить в модификатор const.
Поскольку мне за всю мою жизнь не встречались проблемы, которые лечит модификатор const, то я считаю его лишним.
Pzz>У человеческой головы ограниченная пропускная способность. И как-то глупо тратить столь ценный ресурс на то, чем вполне мог бы заняться компилятор.
Компилятор не будет читать и понимать программу. Компилятор программу компилирует.
А читает программу программист. И когда программа удлиняется всяким мусором, программу становится читать сложнее.
Если прототип функции не умещается в строке, мой глаз воспринимает такой текст гораздо хуже.
Pzz>Предупреждения помогают. Просто надо уметь их готовить.
Ну вот gcc-шники не умеют. Полезное предупреждение тонет в массе бессмысленных и ненужных.
Это как сказка про пастушка, который кричал "волки-волки" до тех пор, пока его не перестали слушать.
Здравствуйте, so5team, Вы писали:
Pzz>>Похоже, под нетривиальностью ты имеешь ввиду размер программы.
S>Нет. Но в вас я вижу человека, которому думать, скажем так, тяжело.
Трудно разговаривать с человеком, который через слово дураком обзывается.
Сам дурак!
Pzz>>Я вижу что за Go стоят люди, которые подарили миру UNIX и Си — проекты, определившие направление развития индустрии на десятилетия.
S>Т.е. для вас важнее авторитеты? Ну OK.
Нет. Культурный контекст.
Pzz>>С учётом всего этого, Go — это такой C 2.0, прямое продолжение цепочки C -> Alef/Limbo -> Go. Созданный с учётом всего этого опыта и со многими исправленными ошибками Си.
S>Вы так говорите, как будто это что-то хорошее.
Я не вижу большого смысла комментировать оценочные суждения.
S>Вообще странно, когда Go сравнивают с Си. Но, в вашем случае опять же нужно делать скидку на, скажем так, особенности мышления. S>Безопасный язык со сборкой мусора сравнивать с Си, в геноме которого полная свобода программиста с минимумом контроля. Внушаить, да.
В 70-е Си воспринимался, как лютое ограничение свободы, по сравнению с ассемблером, на котором тогда нормальные люди и писали операционные системы. Примерно как сейчас Go.
S>А может быть и нет. Языки программирования эволюционировали в сторону усложнения не просто так. Например, Ada сразу создавалась как сложный язык, а потом еще и обрастала возможностями. Аналогично и Eiffel. Аналогично и Java c C#. Про С++ и говорить не приходится. И это мне еще не приходилось сталкиваться с миром функциональщины (Scala, OCaml, Haskell и вот это вот всё).
То же самое, наверное, можно сказать и про операционные системы.
Сколько там системных вызовов в венде? Последний раз, когда я интересовался, я слышал число 3500. Сейчас, наверное, уже 5000. Линукс как-то обходится 350-ми, и это прям много, но по историческим причинам разросся, увы.
Кучерявость интерфейса не говорит о его "выразительной мощности". А скорее говорит о его плохой продуманности. Простые интерфейсы с ясной и лаконичной метафорой, стоящей за ними, проектировать сложнее, чем вытащить все кишки наружу, пусть пользователь сам разбирается.
S>Только вот зачем это нужно, если язык и так достаточно выразительный, чтобы сделать тоже самое посредством библиотек? S>И что делать в языках вроде Go, когда потребуется что-то, что авторы языка не удосужились туда упихнуть?
Затем, чтобы люди охотно пользовались каналами и гороутинами. Люди предпочитают те механизмы, которые синтаксически выглядят легковесно, а не те, которые на самом деле просто устроены под капотом.
Вот арифметику указателей специально сделали синтаксически тяжеловесной.
S>В то время как для технически продвинутых языков это не проблема.
S>Поэтому нетривиальные задачи на C++, C# или каком-нибудь Haskell решаются. Как будет с Go... Есть сомнения.
Смешно.
Уж насколько Go прост, Haskell проще его в разы. За Haskell-ем стоят непростые идеи, но сам язык очень простой.
Очень странный список для сравнения. Примерно, как и ваш предыдущий список "нетривиальных" проектов. Не потому ли вам так сложно задать нетривиальные проекты их свойствами, а не перечислением, что вы сами не очень понимаете, что имеете ввиду?
Pzz>>Что в этоге получится? Ну, видимо, LibreOffice, переписанных на Go
S>Только вот вопрос будет как в цене разработки, так и в тормознутости и ресурсоемкости результата.
Говорят, гошный библиотечный http-сервер по производительности сравним с nginx. При этом nginx очень гордится своей производительностью. А гошный библиотечный сервер написан довольно-таки в лоб (и мог бы быть существенно ускорен за счёт уменьшения числа аллокаций, приходящихся на запрос, но ценой усложнения API).
Это к вопросу о производительности...
S>PS. Дяденька, судя по тому, что и как вы пишете, вы лет на 5-10 постарше меня. Неудобно такие вещи говорить старшим, но складывается ощущение, что голова у вас для того, чтобы в нее есть. А не думать.
Здравствуйте, serg_joker, Вы писали:
_>Нет, не получим.см. здесь, например. Добавление std::unrechable() убирает предупреждение и никаким иным образом на выхлоп не влияет.
какой unreachable? До него уже столько кода написано Кстати это такой же костыль наподобие "мамой клянусь" который вы критиковали. Если мы на него нарвёмся получим тот же UB. И в чём цимес? В том что прокомментировали более явно свои намерения? Ну ок, в принципе тоже аргумент.
_> Ну или приведите пример, где получим, не гипотетически, а на практике, у меня не получилось, может плохо старался.
я считал очевидным вернуть Type::unknown.
switch (flag & 3){
case 0: return Type::_1;
case 1: return Type::_2;
case 2: return Type::_3;
default: return Type::Unknown;
но это ломает оптимизацию и добавляет лишние 3 инструкции (раньше у меня получалось больше на 2, но сейчас видимо звёзды по другому встали)
parse(int):
and edi, 3
xor edx, edx
lea eax, [rdi+1]
cmp edi, 3
cmove eax, edx
ret
Здравствуйте, Pzz, Вы писали:
Pzz>Нет. Культурный контекст.
ХЗ что под этим подразумевается, т.к. тот же UNIX за прошедшее время сильно эволюционировал.
Это как ссылаться на Вирта рассуждая о современном FreePascal или Delphi.
Pzz>>>С учётом всего этого, Go — это такой C 2.0, прямое продолжение цепочки C -> Alef/Limbo -> Go. Созданный с учётом всего этого опыта и со многими исправленными ошибками Си.
S>>Вы так говорите, как будто это что-то хорошее.
Pzz>Я не вижу большого смысла комментировать оценочные суждения.
Ну так перестанье сами их распространять.
Pzz>В 70-е Си воспринимался, как лютое ограничение свободы, по сравнению с ассемблером, на котором тогда нормальные люди и писали операционные системы. Примерно как сейчас Go.
Мы не в 1970-ых. А в 2008 или 2007-ом ситуация была другая. Можно было и не изобретать велосипед. Тем более, такой своеобразный.
Тогда как в 1970-х выбора-то особо и не было.
S>>А может быть и нет. Языки программирования эволюционировали в сторону усложнения не просто так. Например, Ada сразу создавалась как сложный язык, а потом еще и обрастала возможностями. Аналогично и Eiffel. Аналогично и Java c C#. Про С++ и говорить не приходится. И это мне еще не приходилось сталкиваться с миром функциональщины (Scala, OCaml, Haskell и вот это вот всё).
Pzz>То же самое, наверное, можно сказать и про операционные системы.
Только вот речь не про операционные системы.
Pzz>Кучерявость интерфейса не говорит о его "выразительной мощности". А скорее говорит о его плохой продуманности. Простые интерфейсы с ясной и лаконичной метафорой, стоящей за ними, проектировать сложнее, чем вытащить все кишки наружу, пусть пользователь сам разбирается.
К языкам программирования сия сентенция как относится?
S>>Только вот зачем это нужно, если язык и так достаточно выразительный, чтобы сделать тоже самое посредством библиотек? S>>И что делать в языках вроде Go, когда потребуется что-то, что авторы языка не удосужились туда упихнуть?
Pzz>Затем, чтобы люди охотно пользовались каналами и гороутинами.
Либо потому, что они специально делали язык, в которых собственные каналы с гороутинами фиг напишешь.
Pzz>Очень странный список для сравнения.
В этом списке в основном языки, с которыми имел дело (а про Scala/OCaml/Haskell есть отдельное примечание). Я не рассуждаю о вещах, в которых не разбираюсь.
Pzz>Не потому ли вам так сложно задать нетривиальные проекты их свойствами, а не перечислением, что вы сами не очень понимаете, что имеете ввиду?
Представляете, да. Нетривиальный потому и нетривиальный. См. определение "нетривиальный" в толковом словаре.
В качестве некоторого далекого приближения можно было бы написать что-то вроде: код (или проект) сложность которого находится либо на самой грани технических возможностей существующих инструментов либо вообще за их гранью.
Но это неважное определение к которому можно доколупываться, поэтому я избегаю прямого ответа.
А примеры вполне себе нормальные.
Pzz>>>Что в этоге получится? Ну, видимо, LibreOffice, переписанных на Go
S>>Только вот вопрос будет как в цене разработки, так и в тормознутости и ресурсоемкости результата.
Pzz>Говорят, гошный библиотечный http-сервер по производительности сравним с nginx. При этом nginx очень гордится своей производительностью. А гошный библиотечный сервер написан довольно-таки в лоб (и мог бы быть существенно ускорен за счёт уменьшения числа аллокаций, приходящихся на запрос, но ценой усложнения API).
Pzz>Это к вопросу о производительности...
Только вот гошный библиотечный http-сервер по своему функционалу далеко не nginx.
Вы опять говорите вещи, на которые только и остается, что сказать: очередная дурость.
PS. На счет говнокода и Go. Случайный файлик из списка проектов на который вы сослались. Функция на 200 строк из которых изрядный процент как раз if-ы с return err. Красота.
Здравствуйте, Pzz, Вы писали:
S>>Нет. Но в вас я вижу человека, которому думать, скажем так, тяжело. Pzz>Трудно разговаривать с человеком, который через слово дураком обзывается. Pzz>Сам дурак! S>>PS. Дяденька, судя по тому, что и как вы пишете, вы лет на 5-10 постарше меня. Неудобно такие вещи говорить старшим, но складывается ощущение, что голова у вас для того, чтобы в нее есть. А не думать. Pzz>Голова у меня, чтобы на дураков ругаться.
Бесконечно долго можно смотреть на огонь, на воду и на срач интеллигентных людей
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, sergii.p, Вы писали:
SP>а тут уже начинается интересный пласт вопросов.
Некоторые ЯП ответили на этот пласт вопросов. Скажем в java компилятор имеет правила что когда выходит и т.п. Например "while(true){...}" — компилятор понимает, что цикл бесконечный и после него unreachable, но если есть break — то уже конечный. А так же логика exhaustive switch-case и т.п.
Вот это пусть и компиляторщиков голова болит как это всё проверять, а не у меня, как разработчика.
SP>Доказать, что функция не на всех возможных путях вернула значение (что как я догадываюсь, теоретически невозможно)
Так а зачем в принципе писать такой код, который даже теоретически невозможно доказать корректность? Тем более в таких тривиальных случаях... Жопсекьюрити что-ли?
SP> if((flag & 1) == 0){
SP> return 1;
SP> }
SP>}
SP>не будем придираться к самой функции. Поколения криворуких программистов могут сделать и не такое.
Так ведь в данном случае — лишь потому что компилятор по кривым ручкам не бьёт. А может. Но вместо этого, как обычно, стреляет в ногу!
SP>Тут формально return нет и clang честно пишет предупреждение control reaches end of non-void function но в asm генерирует абсолютно корректный код. То есть компилятор признал что код с душком,
А вот надо придраться! Код пишется для человеков, а не для компилятора. Мне, как человеку, хочется видеть надёжный очевидный код. Я предпочитаю, чтобы было тупо — скомпилировалось, значит работает. Я слишком тупой, чтобы на ходу выполнять битовые операции и в голове представлять что где может быть пропущено.
В случае если очень надо, то есть std::abort/std::unreachable — их видно явно и становится понятно, что тут нечто особенное на что стоит обратить внимание.
SP>но полез делать маленькие оптимизации из предположения что это корректная программа и смог дойти до правильного ответа. SP>А теперь представим, что у нас не такой синтетический пример, а что-то реальное с закрученной логикой листов на 5.
Именно. Как ты с логикой на 5 листов поймёшь, что ничего не пропущено? Особенно когда смотришь PR и никаких warnings не видишь.
SP>p.s опять же UB тут по ветке по-моему понимают несколько привратно. Дескать если компилятор видит UB, он может делать любую дичь. Но он как раз предполагает, что в программе UB быть не может и делает оптимизации из этого предположения. То есть если в программе на какой-то ветке нет return, да, для компилятора это сигнал что тут UB. Но он сделает предположение, что программа туда просто не дойдёт или в этом случае никто результат проверять не будет. То есть в runtime всё сложится так, что в конечном коде UB исчезнет. SP>Что произошло у ТС — не понимаю. Возможно, это бунт разработчиков компилятора, их следует признать еретиками и сжечь на костре.
Сабж как раз о том, что раньше всё работало, а потом ВНЕЗАПНО стало падать в рантайме. Мой поинт — должно падать в компайл-тайме!
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, sergii.p, Вы писали:
SP> Может у него раньше стоит проверка и сразу делается вывод об ошибке. Зачем ему явно обрабатывать невозможный сценарий?
Беда в том, что код меняется. Если в момент написания этого кода parse звался из места, где стояла проверка, а через год эту же функцию позвали из места где проверку написать забыли.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, sergii.p, Вы писали:
SP>я считал очевидным вернуть Type::unknown. SP>но это ломает оптимизацию и добавляет лишние 3 инструкции
Как я понимаю, это потому что числа отличаются. Если unknown переместить вниз, то асм вообще упрощается. Вот так надо оптимизировать, а не через UB.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alpha21264, Вы писали:
A>Ну вот... фигня. A>Нормальный программист знает, что не надо менять входные параметры, и как правило не меняет. A>Поэтому с моей точки зрения нужно маркировать не константные аргументы, а изменяемые аргументы. A>Таким образом в правильно написанной программе хлама не будет. A>А сейчас хлама столько же, сколько полезной информации или даже больше. A>Это не правильно.
Можно случайно напортачить. const же не даст это сделать.
И входные параметры не менять? Это очень спорно.
A>Другой маразм, который никто не знает, и который любят спрашивать на собеседованиях - A>в зависимости от положения слова const может быть константный адрес или константное содержимое адреса. A>Никогда не мог запомнить надо слово const ставить слева или справа. A>Наверное для англоязычных людей это привычно, когда смысл слова зависит от расположения, A>но я такое запомнить не могу.
Видимо, поэтому const вообще и не используешь
На самом деле это просто. const char *pstr, char const *pstr — указатель на константу, char * const pstr — константный указатель.
Здравствуйте, m2user, Вы писали:
F>>Дык сборка должна быть warning free (-Werror, /WX) — как раз чтобы не терять важное среди "трёх экранов бессмысленной выдачи".
M>И всякие относительно безобидные warnings (типа unused variable) будут ошибкой. Это неудобно.
Это не безобидные варнинги, в некоторых случаях они позволяют увидеть смысловую ошибку.
А если уж "так и задумано", то [maybe_unused]] или старые добрые хакерские эквиваленты вида (void)name
M>Всякие там выходы из фунцкии по std::abort или throw не препятствие к тому, чтобы требовать обязательный return в коде.
Хорошо, когда у возвращаемого типа какой-то простенький конструктор (например, тривиальный). А если нет?
Здравствуйте, sergii.p, Вы писали:
_>>Нет, не получим.см. здесь, например. Добавление std::unrechable() убирает предупреждение и никаким иным образом на выхлоп не влияет. SP>какой unreachable? До него уже столько кода написано Кстати это такой же костыль наподобие "мамой клянусь" который вы критиковали. Если мы на него нарвёмся получим тот же UB. И в чём цимес? В том что прокомментировали более явно свои намерения? Ну ок, в принципе тоже аргумент.
В том, что компилятор в код пальчиком тыкнет — и программисту придётся проверить этот кусок кода более внимательно, обратить внимание на потенциалную проблему — и принять решение: это баг или так и задумано.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alpha21264, Вы писали:
Pzz>>При чём тут модность-молодёжность?
A>При том, что в программистском мире тоже есть религиозные проповедники, которые проповедуют свою религию. A>Да, религии бывают разные, можно верить в непорочное зачатие, а можно верить в модификатор const. A>Поскольку мне за всю мою жизнь не встречались проблемы, которые лечит модификатор const, то я считаю его лишним.
Попробую еще раз объяснить.
У меня такое ощущение, что ты воспринимаешь предупреждения, как такую ненужную тебе защиту от случайностей. Ну, типа, передали функции строку, она
туда сдуру писанула. А со словом const не сможет. Но ты таких дурацких функций никогда не пишешь, поэтому тебе такая защита не нужна и только мешает.
Я же пытаюсь рассказать, что этот механизм можно и более интеллектуальным способом использовать.
Допустим, у меня есть некоторый тип. Ну, скажем, распарсенный HTTP URL, чтобы пример был простым, но уж не слишком.
HTTP URL, это не такая простая штука, как кажется, поэтому я хочу оставить себе свободу в выборе (и будущем изменении) его внутреннего устройства. Поэтому я представляю его интерфейс как opaque структуру с набором функций-аксессоров (или в виде класса с приватными полями и доступом через публичные методы, если мы про C++, не к ночи он будет упомянут).
Часть этих методов просто возвращает информацию. Ну, например, схему или hostname или TCP-порт. Они не модифицируют структуру. А часть модифицируют. Например, добавляют или удаляют IPv6-зону к адресу, или меняют путь или чего еще.
Так вот, const в данном случае помогает выразить некоторые вещи относительно семантики операции, да еще и компилятор за мной присматривает, что я не наврал. Это куда как удобнее, чем описывать семантические детали в виде комментариев и из методов контроля иметь только чистую совесть и внимательность разработчика.
Когда применяешь этот подход систематически, через некоторое время обнаруживаешь, что на языках без контроля типов, например, на Питоне, писать очень тяжело, приходится головой всё время думать о том, о чём бы мог подумать компилятор.
Pzz>>Предупреждения помогают. Просто надо уметь их готовить.
A>Ну вот gcc-шники не умеют. Полезное предупреждение тонет в массе бессмысленных и ненужных. A>Это как сказка про пастушка, который кричал "волки-волки" до тех пор, пока его не перестали слушать.
Ну, понимаешь, в нормальном проекте предупреждений 0. И он собирается с -Werror. Поэтому когда предупреждения вдруг появляются, они не тонут в шуме.
Да, иногда приходится тратить некоторое время, чтобы загасить предупреждение, возникшее без нужды. Например, почему-то на убунте компилятору очень важно, чтобы я обязательно проверял значение, которое вернул вызов write и подобные ему, и даже общепринятый метод (void) write(...) ее не берет. А на федоре gcc плюс-минус той же версии так себя не ведёт.
Но в целом, такая хрень встречается нечасто и много времени не занимает.
Здравствуйте, so5team, Вы писали:
Pzz>>Нет. Культурный контекст.
S>ХЗ что под этим подразумевается, т.к. тот же UNIX за прошедшее время сильно эволюционировал.
Культурный контекст — это та среда, это та среда, в которой происходит коммуникация и взаимодействие между людьми, и которая определяет их ценности, убеждения и нормы.
Это определение не я придумал, а гуглёвый поисковик. Но я с ним согласен.
S>Это как ссылаться на Вирта рассуждая о современном FreePascal или Delphi.
Мне трудно рассуждать о Паскале и его производных, а с ними мало знаком.
Pzz>>>>С учётом всего этого, Go — это такой C 2.0, прямое продолжение цепочки C -> Alef/Limbo -> Go. Созданный с учётом всего этого опыта и со многими исправленными ошибками Си.
S>>>Вы так говорите, как будто это что-то хорошее.
Повторюсь относительно бессмысленности оценочных суждений.
S>Либо потому, что они специально делали язык, в которых собственные каналы с гороутинами фиг напишешь.
Почему не напишешь? Гошный рантайм написан на Go, с незначительными ассемблерными вставками. Не будет красивого синтаксиса в виде ключевого слова go и операторов <- и ->, а в остальном всё будет.
Кроме того, оператор for ... range уже умеет итерировать не только встроенные типы, но и пользовательские типы, которые реализуют соответствующий интерфейс. Не удивлюсь, если и с каналами так когда-то будет ("всё есть канал, если реализует интерфейс канала").
S>Представляете, да. Нетривиальный потому и нетривиальный. См. определение "нетривиальный" в толковом словаре.
S>В качестве некоторого далекого приближения можно было бы написать что-то вроде: код (или проект) сложность которого находится либо на самой грани технических возможностей существующих инструментов либо вообще за их гранью.
Я боюсь, у нас разное представление о нетривиальности.
Скажем, на мой взгляд, алгоритм построения ДКА из регулярного выражения нетривиален. Хотя, безусловно, может быть реализован на любом вменяемом языке программирования.
S>Но это неважное определение к которому можно доколупываться, поэтому я избегаю прямого ответа. S>А примеры вполне себе нормальные.
Я не пытаюсь доколупываться. Но хорошо бы иметь общую терминологию, а не догадываться, что имеет ввиду оппонент.
Pzz>>Говорят, гошный библиотечный http-сервер по производительности сравним с nginx. При этом nginx очень гордится своей производительностью. А гошный библиотечный сервер написан довольно-таки в лоб (и мог бы быть существенно ускорен за счёт уменьшения числа аллокаций, приходящихся на запрос, но ценой усложнения API).
Pzz>>Это к вопросу о производительности...
S>Только вот гошный библиотечный http-сервер по своему функционалу далеко не nginx.
Речь шла о производительности.
Библиотечный http-сервер по своему функционалу очень хорош. Просто он не является коробочным продуктом, а является полезной запчастью, которую можно к чему-нибудь приделать.
Причём Go очень гибок в плане приделывания запчастей друг к другу. Поскольку библиотечный http-сервер оперирует на TCP-сокетами, а интерфейсами net.Conn и net.Listener, его можно приделать к тому, что и сетью-то не является. Например к USB.
Или, например, любая библиотечная функция, которая умеет читать из файла, с таким же успеком будет читать из тела HTTP-ответа, причём без промежуточной буферизации, потоком. Практически напрямую из сокета, если ответ никак не закодирован, или через gunzip и chinked decoder, если формат ответа подозревает это. Прозрачно для себя и автоматически.
S>Вы опять говорите вещи, на которые только и остается, что сказать: очередная дурость.
Повторюсь: сам дурак.
S>PS. На счет говнокода и Go. Случайный файлик из списка проектов на который вы сослались. Функция на 200 строк из которых изрядный процент как раз if-ы с return err. Красота.
Такой код совсем немного сложнее писать, но зато значительно проще читать и отлаживать, поскольку всё эксплицитно.
Здравствуйте, sergii.p, Вы писали:
P>какой unreachable? До него уже столько кода написано
Помнится, когда вводили область видимости для переменных, объявленных в заголовке for (С++ 98), тоже стоны были, мол, столько кода написано, где переменная используется после цикла. А ничего, код починили (и я свой код в том числе), и он стал лучше почти всегда. При этом, случаев, где переменная цикла была переиспользована для следующего цикла или для других целей было точно сильно больше, чем кода, где есть ветки без return.
Вот так же нужно починить код, где был возможен провал в ветки без явного возврата.
P> Кстати это такой же костыль наподобие "мамой клянусь" который вы критиковали. Если мы на него нарвёмся получим тот же UB. И в чём цимес? В том что прокомментировали более явно свои намерения? Ну ок, в принципе тоже аргумент.
Именно. Когда компилятор увидит std::undefined, то он будет "знать", что программист не забыл возврат, а именно гарантирует письменным заявлением, что в эту ветку мы не попадём, и берёт всю ответственность на себя, текстом через код.
Более того, когда я буду делать ревью пулл-реквеста, пойму то же самое. Когда я загляну в код через год-два-десять,то не буду не угадывать ход мыслей автора, а буду видеть его выраженным в написанном контракте. Исходный код — это не только предусловие к генерации кода машинного, но и способ выразить мысль.
_>> Ну или приведите пример, где получим, не гипотетически, а на практике, у меня не получилось, может плохо старался.
SP>я считал очевидным вернуть Type::unknown.
<cut>
Но это же не соответствует модели мысли автора кода. Автор подразумевал, что 3 невозможно, просто в коде это не было выражено. std::unreachable/abort выразит эту мысль явно... Да, старый поломанный код придётся явно и одномоментно починить и это может быть неприятным, но см. пример с for. При использовании std::unreachable сгенерированный код не становится хуже относительно изначального.
Возврат Type::unknown нужно делать, если таки есть сомнения в невозможности 3, и тут уж рост бинарного кода никакого значения не имеет. Вы же не будете писать код без этой ветки, понимая, что 3 таки может прилететь, даже понимая, что добавление обработки неожиданной тройки приведёт к росту бинаря?
Т.е. автору (ну или мейнтейнеру, если не повезло такой код поддерживать) придётся, под давлением компилятора, явно выбрать, что во что мы верим: или таки в то, что в ветку без return мы не попадём, или всё-таки что при неудобных обстоятельствах попадём и нужно решить, какого поведения мы хотим в таком случае.
Здравствуйте, serg_joker, Вы писали:
_>Помнится, когда вводили область видимости для переменных, объявленных в заголовке for (С++ 98), тоже стоны были, мол, столько кода написано, где переменная используется после цикла.
Да-да, было дело. Помнится, мы вот такую поделку мастырили, чтоб ограничить область видимости:
#define for if(1) for
А иногда даже вот такую:
#define for if(0); else for
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, serg_joker, Вы писали:
P>>какой unreachable? До него уже столько кода написано _>Помнится, когда вводили область видимости для переменных, объявленных в заголовке for (С++ 98), тоже стоны были, мол, столько кода написано, где переменная используется после цикла. А ничего, код починили (и я свой код в том числе), и он стал лучше почти всегда. При этом, случаев, где переменная цикла была переиспользована для следующего цикла или для других целей было точно сильно больше, чем кода, где есть ветки без return.
Я тогда на MSVC 6 лабал, и на BC 5.5, в одном можно было переиспользовать переменную после цикла (вроде MSVC), в другом было строго, поэтому привык заводить переменные до цикла, если надо было переиспользовать (а это было в большей части кейсов).