Здравствуйте, Marty, Вы писали:
M>>>А namespace'ы на что?
A>>Чтобы запутать себя и других.
M>Яс но. Вопросов больше не имею
Ну ты вообще слегка недогадлив.
И склонен к впаданию в ступор, если встретился немного нестандартный контекст.
Пересечение namespace'ов — это как раз на эту тему.
Здравствуйте, Nuzhny, Вы писали:
A>>Но у всего есть цена. Так давайте посмотрим на цену.
N>У европейцев спутник "Ариан-5" упал когда-то, с типом данных не угадали. Стоит ли работы программиста? N>Или сбой навигации у самолётов над Мёртвым морем, когда высота была отрицательной. N>Есть области, где стоит платить такую цену.
А есть области, где не стоит.
В данном случае это был видеоредактор для роликов Ю-туба.
Здравствуйте, alpha21264, Вы писали:
A>А есть области, где не стоит.
Ой ли?
Один из самых запоминающихся кранчей по поиску бага был связан с тем, что в типа "бизнес-приложении" на Java имя пользователя и пароль пользователя для доступа к БД задавались обычными String-ами. Команда из 6 человек потратила полдня на поиск совершенно тупой ошибки, когда username и password перепутали местами.
Этой ошибки не было бы в принципе, если бы:
* язык программирования поддерживал strong typedef из коробки. Ну или хотя бы предоставлял возможности для дешевой реализации strong typedef своими руками (вот Java в прошлом этой возможности не предоставляла, а может и до сих пор);
* у программистов была привычка пользоваться strong typedef-ами. У подавляющего большинства из виденных мной такой привычки нет.
Если добавить сюда, например, то, что в C++ и в Си есть автоматическое и неявное преобразование между типами, то такие бездны открываюся, что просто ахтунг. Встречался код, в котором у людей double неявно к std::size_t приводился. И, типа, норм...
Здравствуйте, serg_joker, Вы писали:
_>и есть у меня код: _>
_>if (s1 > s2) { ... }
_>
_>вот ты бы хотел, чтобы условие разворачивалось в (!(s1 < s2 ) || (s1 == s2)) с удвоением сложности? _>или чтобы нужно было писать gteaterthan(s1,s2) ?
Зачем? Имея два оператора: == и <, остальной набор операторов компилятор мог бы сгенерировать автоматически безо всякого удвоения сложности:
bool operator != (const T& a, const T& b) { return !(a == b);}
bool operator > (const T& a, const T& b) { return b < a;}
bool operator <= (const T& a, const T& b) { return !(b < a);}
bool operator >= (const T& a, const T& b) { return !(a < b);}
по крайней мере, для total и weak ordering.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Зачем? Имея два оператора: == и <, остальной набор операторов компилятор мог бы сгенерировать автоматически безо всякого удвоения сложности:
Здравствуйте, so5team, Вы писали:
A>>А есть области, где не стоит.
S>Ой ли?
S>Один из самых запоминающихся кранчей по поиску бага был связан с тем, что в типа "бизнес-приложении" на Java имя пользователя и пароль пользователя для доступа к БД задавались обычными String-ами. Команда из 6 человек потратила полдня на поиск совершенно тупой ошибки, когда username и password перепутали местами.
Вот этот пример какое имеет отношение к обсуждаемой теме?
Если для поиска такой тупой ошибки нужно 6 человек и полдня, то тут дело не в языке программирования.
Мне кажется, что у кого-то руки из жопы.
S>Этой ошибки не было бы в принципе, если бы...
Я подозреваю, что абсолютно в любой системе имя пользователя и пароль будут стрингами.
Не, если в команде заведётся какой-нибудь миссионер...
А вот есть такие ошибки, когда путают плюс и минус. Или икс и игрек.
Нет ли какого-нибудь продвинутого костыля для таких случаев?
Ну вот чтобы в формуле программист плюс и минус не перепутал.
Мне очень надо. Ну пожалуйста!
S>Если добавить сюда, например, то, что в C++ и в Си есть автоматическое и неявное преобразование между типами, то такие бездны открываюся, что просто ахтунг. Встречался код, в котором у людей double неявно к std::size_t приводился. И, типа, норм...
Не понимаю, что тебя расстроило. Плавающая точка всегда приводилась к целому.
Всегда — это с 60-х годов, когда плавающая точка вообще появилась.
Здравствуйте, alpha21264, Вы писали:
S>>Один из самых запоминающихся кранчей по поиску бага был связан с тем, что в типа "бизнес-приложении" на Java имя пользователя и пароль пользователя для доступа к БД задавались обычными String-ами. Команда из 6 человек потратила полдня на поиск совершенно тупой ошибки, когда username и password перепутали местами.
A>Вот этот пример какое имеет отношение к обсуждаемой теме?
Самое прямое. Это все вариации на тему strong typedef, его отсутствия и (не) желания его использовать.
A>Если для поиска такой тупой ошибки нужно 6 человек и полдня, то тут дело не в языке программирования.
Эту-то ошибку хотя бы нашли. А вот разработчикам Mars Climate Orbiter не повезло.
A>Мне кажется, что у кого-то руки из жопы.
Они таковы у 99.9(9)% разработчиков. Поскольку я лично не видел еще ни одного (может быть кроме вас) кто бы не совершал ошибок, в том числе и совершенно дурацких, когда по невнимательности путают аргументы местами.
S>>Этой ошибки не было бы в принципе, если бы...
A>Я подозреваю, что абсолютно в любой системе имя пользователя и пароль будут стрингами. A>Не, если в команде заведётся какой-нибудь миссионер...
То они стрингами, к счастью, не будут.
A>А вот есть такие ошибки, когда путают плюс и минус. Или икс и игрек. A>Нет ли какого-нибудь продвинутого костыля для таких случаев?
Strong typedef rules them all!
A>Ну вот чтобы в формуле программист плюс и минус не перепутал.
Полагаю, все типы ошибок ловятся тестами.
Но если использование строгой типизации в коде позволяет совсем исключить какой их процент, то зачем от этого отказываться?
A>Не понимаю
Это не удивительно. У меня есть сомнения, что вы вообще в программировании что-то понимаете.
A>Плавающая точка всегда приводилась к целому.
Округление в какую сторону при неявных преобразованиях double в size_t идет?
Актуально ли это для конкретной задачи или правильно делать округление в большую сторону? Или к ближайшему целому?
Вот какие вопросы должны волновать разработчика когда он вычисляет что-то в double, а затем неявно преобразует результат в size_t. И сам факт того, что эти преобразования делаются неявно в 99% случаев говорит о том, что разработчик об этом даже не задумывался.
Здравствуйте, so5team, Вы писали:
S>Один из самых запоминающихся кранчей по поиску бага был связан с тем, что в типа "бизнес-приложении" на Java имя пользователя и пароль пользователя для доступа к БД задавались обычными String-ами. Команда из 6 человек потратила полдня на поиск совершенно тупой ошибки, когда username и password перепутали местами.
Видел жавовые "приложения", представляю о чём речь. Дело там совсем не в стрингах.
Будь у них там стронг-тайпед дефс, то суммарные потери времени были бы куда больше. Ты смотришь только на эти 6 человеко-дней, а нужно смотреть на всю стоимость написания и поддержки системы. Так вот, там где перемудрили с тимпами, поддержка куда дороже чем в прямом си-стайл коде, особенно когда переборщили IoC. Там такие дебри бывают, что тупо полдня ищещешь, куда же искомая строчка в итоге отправляется. После такого кода плохеет от одного только слова "спринг". А спринг-бут чётко ассоциируется со словом "ПИДАРАС!".
Оверинженеринг, он такой!
зы: извините за крепкие выражения.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, so5team, Вы писали:
S>Один из самых запоминающихся кранчей по поиску бага был связан с тем, что в типа "бизнес-приложении" на Java имя пользователя и пароль пользователя для доступа к БД задавались обычными String-ами. Команда из 6 человек потратила полдня на поиск совершенно тупой ошибки, когда username и password перепутали местами.
Звучит как очень простой баг. Нарвался — быстро нашёл — покрыл тестом. Был бы специальный тип для логина и пароля — мудохался бы с преобразованиями весь срок жизни проекта
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Звучит как очень простой баг. Нарвался — быстро нашёл — покрыл тестом. Был бы специальный тип для логина и пароля — мудохался бы с преобразованиями весь срок жизни проекта
Не мудохался бы. Если у вас очень частые преобразования между типами Username/Password и String, значит что-то делается не так.
И да, я помню ваши стоны о том, что в Rust-е вы запарились с библиотеками обработки изображений у которых разные int-ы. Не самый убедительный пример, который говорит, скорее, о выразительных возможностях Rust-а.
S>И да, я помню ваши стоны о том, что в Rust-е вы запарились с библиотеками обработки изображений у которых разные int-ы. Не самый убедительный пример, который говорит, скорее, о выразительных возможностях Rust-а.
не знаю как в Расте, но это вообще много где геморойное дело, т.к. в языке как правило есть дефолтный целочисленный тип, и он шире одной цветовой компоненты пиксела, и неявное расширение до него немного похоже на минное поле
Здравствуйте, koenig, Вы писали:
S>>И да, я помню ваши стоны о том, что в Rust-е вы запарились с библиотеками обработки изображений у которых разные int-ы. Не самый убедительный пример, который говорит, скорее, о выразительных возможностях Rust-а.
K>не знаю как в Расте, но это вообще много где геморойное дело, т.к. в языке как правило есть дефолтный целочисленный тип, и он шире одной цветовой компоненты пиксела, и неявное расширение до него немного похоже на минное поле
Без подробностей предметной области сложно рассуждать, но есть ощущение, что в достаточно выразительном языке можно было бы делать "универсальный" тип с условным i64 внутри, с автоматической конвертацией в этот тип из исходных u64 и u32 со всеми нужными проверками внутри. И, если так уж хочется, с автоматической конвертацией к u64/u32 (опять же с нужными проверками).
Тогда бы получилось что в самой прикладной логике все делается с "универсальным" типом, а операции конвертации присутствуют только в местах использования сторонних библиотек.
Прямая аналогия -- это как сейчас в C++ с std::chrono. Очень часто достаточно использовать условный std::chrono::steady_clock::duration и все. Мест же, где этот самый duration получается из исходных единиц (секунд, миллисекунд) или преобразуется в целевые единицы (секунды, миллисекунды) оказывается сильно меньше и все они отлично видны в коде.
Правда, T4r4sB от std::chrono плюётся, но это, возможно, уже и не лечится.
Здравствуйте, so5team, Вы писали:
S>И да, я помню ваши стоны о том, что в Rust-е вы запарились с библиотеками обработки изображений у которых разные int-ы. Не самый убедительный пример, который говорит, скорее, о выразительных возможностях Rust-а.
Который говорит о том, что надо головой думать, а не пытаться пихать эти доменно-ориентированные типы в каждую щель, произнося "доменный" с религиозным придыханием.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, koenig, Вы писали:
S>>И да, я помню ваши стоны о том, что в Rust-е вы запарились с библиотеками обработки изображений у которых разные int-ы. Не самый убедительный пример, который говорит, скорее, о выразительных возможностях Rust-а.
K>не знаю как в Расте, но это вообще много где геморойное дело, т.к. в языке как правило есть дефолтный целочисленный тип, и он шире одной цветовой компоненты пиксела, и неявное расширение до него немного похоже на минное поле
В Русте нет неявного расширения, поэтому если автор библиотеки не дружит с головой и применил как ему кажется более подходящий u32 вместо наиболее широкого и удобного i64, то при работе с библиотекой ты будешь постоянно писать "ехал каст через каст". Самое дикое что там на уровне языка размер массива (метод len) это usize, а значит даже просто написать v.len()-1 нельзя, это потенциально опасная операция. Повышает это читаемость, удобство отладки? Нет, конечно. Зато слабоумные евангелисты считают что использовать беззнаковый тип для размера это круто потому что сразу показывает что размер не может быть отрицательным, а если тебе надо вычитать из размера единичку, то в их зумерской жизни такого ни разу не надо было, значит ты тоже что-то делаешь не так.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Который говорит о том, что надо головой думать, а не пытаться пихать эти доменно-ориентированные типы в каждую щель, произнося "доменный" с религиозным придыханием.
Пихать тоже нужно уметь, для этого думать нужно еще больше, чем рассказывать страшилки про то, как плохо иметь размер контейнера в виде беззнакового.
TB> то при работе с библиотекой ты будешь постоянно писать "ехал каст через каст".
хотя бы будешь писать
а не иметь загадочный баг неизвестно где — надо еще догадаться, что проблема в касте, а потом его найти при том что в сорцах его нет, а потенциально он может быть много где.
Здравствуйте, koenig, Вы писали:
TB>> то при работе с библиотекой ты будешь постоянно писать "ехал каст через каст".
K>хотя бы будешь писать K>а не иметь загадочный баг неизвестно где — надо еще догадаться, что проблема в касте, а потом его найти при том что в сорцах его нет, а потенциально он может быть много где.
1. Я написал v.len()-1, компилятор даже слова не скажет что так бывает нельзя
2. Я написал (v.len() as isize — 1) as usize, аналогично
3. try_into().unwrap() пишут только шизы свихнувшиеся на идеологической корректности
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте