Re[6]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 19.03.23 10:50
Оценка: -1
Здравствуйте, vsb, Вы писали:

vsb>И как предлагается этим пользоваться? На каждый чих писать отдельный тип с кучей операторов? Ещё тип для смещений этого типа. Не очень понятно. Звучит как маразм или я что-то не понимаю.


Добро пожаловать в Раст Коммьюнити!
Ах, да, ты ничего не понимаешь, потому что у тебя Primitive Obsession. Писать простой код, который тупо складывает два числа — это Primitive Obsession. Надо обмазываться кастами и чекед методами, при этом чем длиннее и непонятнее выглядит код, тем лучше.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 19.03.2023 11:02 T4r4sB . Предыдущая версия .
Re[7]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 19.03.23 10:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Тогда

S>
S>var a = (position)5 + (offset)5 - (offset)3;
S>

S>даст a == (position)8, а
S>[cs]

(position)8 это паника в рантайме

Забыл сказать, что разные числовые типы складывать нельзя.
А ещё если ты скастишь только одно слагаемое к типу другого, то получишь панику, потому что тип другого не вмещает в себя все значения типа первого. То есть тебе надо не забывать всё кастить именно к более широкому типу. Напонимаю, что изначально всё хранить в широком типе — это Primitive Obsession, хипстота из раст коммьюнити тебя засмеёт за такое.
А ещё если тебе надо сложить два разных смещения, то тебе надо заранее учесть, что 7+7 не влезает в тип смещения, и если ты забудешь заранее скастить к инту, то компилятор тебе ничего не скажет, но ты получишь панику в рантайме.
Короче вместо a+b тебе придётся писать (a as int).checked_add(b as int).
И даже если частный случай сложения позиции и смещения ты инкапсулируешь в виде специального случая, то такую хрень тебе придётся прописывать каждый раз когда тебе нужна хоть какая-то арифметика, не предусмотренная всеми частными случаями, которые ты описал до этого. Маразматики из Раст коммьюнити говорят "воспринимай этот как чёрный ящик и пиши отдельный приватный метод для каждого случая, когда нужны вычисления с промежуточным кастом в более широкий тип".
При этом гораздо более простое, очевидное и менее склонное к внезапным паникам решение "хранить всё в инте изначально" считается антипаттерном Primitive Obsession.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 19.03.2023 11:08 T4r4sB . Предыдущая версия .
Re[7]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 19.03.23 11:00
Оценка: +1 :)
Здравствуйте, Sinclair, Вы писали:

S>А насколько часто у вас встречаются диапазонные типы? Ну, так, если по-честному?


На Русте какой-то идиот ввёл для размера массива тип usize, мотивируя это тем, что ограничение >=0 "соответствует специфике домена", при этом на вопрос что делать если надо вычитать два размера, мне сказали "мне никогда это не надо было делать". Дальше разгорелся срач, я привёл пример с шахматной доской 256х256, и спросил, реально ли они ради дебильной идеи сраных доменов будут использовать u8, понимая, что тривиальные операции будет делать крайне геморройно, и они сказали что да.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 19.03.2023 11:13 T4r4sB . Предыдущая версия .
Re[8]: Антипаттерн, противоположный Primitive Obsession
От: CreatorCray  
Дата: 19.03.23 11:08
Оценка: +2
Здравствуйте, T4r4sB, Вы писали:

TB>На Русте какой-то идиот ввёл для размера массива тип u32, мотивируя это тем, что ограничение >=0 "соответствует специфике домена"

А что не так? Лимит в 32 бита конечно неправильно, надо size_t

TB> при этом на вопрос что делать если надо вычитать два размера

И в чём проблема?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 19.03.23 11:16
Оценка: +1
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, T4r4sB, Вы писали:


CC>А что не так? Лимит в 32 бита конечно неправильно, надо size_t


Ой, я опечатался. Короче, там ввели usize, а должно быть isize. Страуструп тоже так считает: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf

TB>> при этом на вопрос что делать если надо вычитать два размера

CC>И в чём проблема?

Проблема в том, что я должен вручную отдельно разбирать случай, когда a<b. Если я забуду это сделать, то получу некорректно работающий код, то есть либо сразу программа свалится в дебаге, либо будет неверное значение в релизе. Никакой проблемы бы не было, если бы изначально был знаковый isize. Когда я спросил, нахрена создавать программистам проблемы, мне сказали что это потому что usize это более "домменно-ориентированный тип". Ок, я тоже подрочил на это красивое слово, но ненужный геморрой не исчез.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[4]: Антипаттерн, противоположный Primitive Obsession
От: Кодт Россия  
Дата: 19.03.23 20:41
Оценка: +3
Здравствуйте, T4r4sB, Вы писали:

TB>А как этот долбаный фанатик собирается писать банальную задачу "прибавить к позиции шахматной фигуры смещение и проверить валидность результата"? Ведь согласно его идеям позиция шахматной фигуры должна иметь тип [0..8), а смещение должно иметь тип [-7 ..7], и складывать их нельзя, и любая попытка скастить одно к другому вызовет исключение в некоторых случаях.


Эта штука называется "зависимые типы". К позиции 0 можно прибавлять смещение 7, а к позиции 1 — уже нельзя.
Ну, некоторые языки такую штуку поддерживают. Но это хардкор функциональщина.
Либо её можно попытаться протащить в вычисления времени компиляции — например, в плюсах это всякие constexpr и магия на шаблонах.

Либо её можно протащить ограниченно. Размерности, роли, иногда — флажки (конечный набор состояний), — вот это всё делается через фантомные типы.
Практика распространённая, и ничего ужасного в ней нет. Кроме одного: от разработчика требуется написать исчерпывающую обвязку, если компилятор не умеет делать её сам, или делает неправильно.

Те же chrono.
По большому счёту, там только time_point<???> и duration<???>, и очевидно, нужно сделать всю арифметику между всеми типами time и всеми типами duration, плюс какие-то удобные приведения, — чтобы у пользователя вообще не возникало желание что-то там хакнуть, выковырять внутреннее представление и надругаться напрямую.

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

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

Или библиотеки геометрических преобразований, у которых есть как минимум три сущности, записанные 3-мерным (или 4-мерным) вектором: точка (три реальных координаты / плюс фиктивная 1 в четвёртой компоненте), расстояние (фиктивный 0) и поворот (эйлеровы углы / кватернион).
Долбаный хипстер ввёл Point, Vector и Rotation, а людям расхлёбывать, да? А может, людям за чистотой своих рук последить, прежде чем Point+Point или Point+Rotation делать, не?
Перекуём баги на фичи!
Re[5]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 19.03.23 20:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Эта штука называется "зависимые типы". К позиции 0 можно прибавлять смещение 7, а к позиции 1 — уже нельзя.


В том же русте не так. Ты можешь сложить числа 100 и 200, но если оба аргумента имеют тип u8, то компилятор тебе ничего не скажет. Типа всё ок. Но ты получишь падающую программу, из-за чего матерясь полезешь явно кастить оба аргумента к i32. Ну и нахрена оно надо, изначально-то чего в i32 не хранится? Нахрен мне нужно ограничение, при котором предполагается, что промежуточный результат будет иметь те же ограничения, что и сами данные, если это вообще даже близко не так? И тогда зачем вообще ограничивать тип, когда проще все эти проверки делать в сеттере поля?

К>Те же chrono.

К>По большому счёту, там только time_point<???> и duration<???>, и очевидно, нужно сделать всю арифметику между всеми типами time и всеми типами duration, плюс какие-то удобные приведения, — чтобы у пользователя вообще не возникало желание что-то там хакнуть, выковырять внутреннее представление и надругаться напрямую.

И получаем либу, с которой невозможно работать без часового курения документации. А по факту было бы достаточно одной-единственной функции, возвращающей число наносекунд с начала эпохи в виде примитивного типа i128 (знаковый, чтоб можно было вычитать два момента и не париться). Если нужны даты и дни недели — то отдельными функциями, которые берут это самое i128 дальше сами там всё считают.
А ещё с этими ограничениями я не могу написать так:
class C {
  C(int128& time): time(time) { time -= std::chrono::now(); }
  ~C() { time += std::chrono::now(); }
  int128& time;
};

(после работы этого кода значение time увеличится ровно на то время, когда жил класс C)
Конечно это всё можно обойти, и для случая когда надо просто сложить-вычесть, легко это написать по-другому. Но операции над теми же векторами бывают посложнее.

К>Долбаный хипстер ввёл Point, Vector и Rotation, а людям расхлёбывать, да? А может, людям за чистотой своих рук последить, прежде чем Point+Point или Point+Rotation делать, не?


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

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


Пример с размерностями матрицы — это положительный пример внедрения гарантий времени компиляции. Полагаю, с таких примеров и начались хорошие идеи по возможности проконтролировать что-то заранее на уровне системы типов. Но заставь дурака богу молиться, и он сделает систему, в которой очень трудно написать что-то полезное.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Отредактировано 19.03.2023 20:59 T4r4sB . Предыдущая версия .
Re[10]: Антипаттерн, противоположный Primitive Obsession
От: Кодт Россия  
Дата: 19.03.23 20:58
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Ой, я опечатался. Короче, там ввели usize, а должно быть isize. Страуструп тоже так считает: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf


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

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

Кстати, целочисленные переполнения — это отдельный котёл ада. Вот, можно почитать и поужасаться. https://github.com/Nekrolm/ubbook/blob/master/numeric/overflow.md

Так что переделать API векторов на знаковые размеры и смещения — это просто сместить проблему немножко вперёд-назад по клиентскому коду.
Перекуём баги на фичи!
Re[11]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 19.03.23 21:05
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Мысль Страуструпа — в том, что "давайте делать неопределённое поведение более понятным".

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

В Расте ещё интереснее. В С++ при вычитании двух индексов ты с вероятностью 1/2 получишь очень большое число. А в Расте с вероятностью 1/2 программа просто упадёт.

К>Ну извините. Секретное знание о том, что на входе конструктора или субскрипта должно быть заведомо неотрицательное число — с одной стороны, позволяет делать более агрессивную оптимизацию


Это секретное знание можно дать компилятору в виде ассертов, которое в релизе превращается в ассьюм.

К>Кстати, целочисленные переполнения — это отдельный котёл ада. Вот, можно почитать и поужасаться. https://github.com/Nekrolm/ubbook/blob/master/numeric/overflow.md


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

К>Так что переделать API векторов на знаковые размеры и смещения — это просто сместить проблему немножко вперёд-назад по клиентскому коду.


Это передвинет её из "регулярно огребаю" в "огребаю раз в сто лет на экзотическом наборе данных", вроде не это называется повышением надёжности? Разумеется, я не говорю о случае, когда программа пытается как можно дольше скрывать ошибку, вызванную заведомо некорректными данными. Проблема в том, что беззнаковые числа любят валить программу на валидных данных. в Расте сразу, в С++ попозже.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[10]: Антипаттерн, противоположный Primitive Obsession
От: CreatorCray  
Дата: 19.03.23 22:00
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Ой, я опечатался. Короче, там ввели usize, а должно быть isize.

Схренали размер объекта должен быть isize? Он не бывает отрицательным никогда.

TB> Страуструп тоже так считает: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf

И? Это не имеет физического смысла. Ещё дробным сделайте, вообще офигенно будет.
У нас такие идиоты тоже сделали LBA знаковым в протоколе. Столько гемору вылезло из за этого потом — вбыв бы!
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[6]: Антипаттерн, противоположный Primitive Obsession
От: Кодт Россия  
Дата: 19.03.23 22:03
Оценка: 2 (1) +1
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, Кодт, Вы писали:


К>>Эта штука называется "зависимые типы". К позиции 0 можно прибавлять смещение 7, а к позиции 1 — уже нельзя.


TB>В том же русте не так. Ты можешь сложить числа 100 и 200, но если оба аргумента имеют тип u8, то компилятор тебе ничего не скажет. Типа всё ок. Но ты получишь падающую программу, из-за чего матерясь полезешь явно кастить оба аргумента к i32. Ну и нахрена оно надо, изначально-то чего в i32 не хранится? Нахрен мне нужно ограничение, при котором предполагается, что промежуточный результат будет иметь те же ограничения, что и сами данные, если это вообще даже близко не так? И тогда зачем вообще ограничивать тип, когда проще все эти проверки делать в сеттере поля?


Ну так руст — это не идрис, он не умеет в зависимые типы.

А числовые переполнения — это штука очень дискуссионная, и в разных языках к ней разные подходы.
Почему компилятор должен догадываться, что вот здесь u8+u8 = u8, а вот здесь уже = u9? А последующий u9-u8 — это u8, u9 или i10?
Для этого и пишутся спецификации по языку, — что делается по умолчанию, а что требует рукодельщины.

В сях и плюсах есть правила продвижения — (меньше-или-равно int) + (меньше-или-равно int) = int. Это тоже дискуссионная штука, потому что результат арифметики, продвинутой до int, в попытке запихать обратно в маленький тип, может тоже быть не тем, что хотел сказать автор. Вся эта трахотня с char, например.
Если в русте договорились, что тип результата не продвигается без явных указаний, — ну, делай указания.

Если есть сущность "смещения только в пределах шахматной доски", то — возможно, автору библиотеки или тебе лично, — придётся завести и сущность "расширенные смещения без гарантии, что они влезли в доску".
Опять же, разрядность этих смещений — "мамой клянусь, i32 мне за глаза и за уши", а вдруг "возьму-ка я float64"?

К>>Те же chrono.

К>>По большому счёту, там только time_point<???> и duration<???>, и очевидно, нужно сделать всю арифметику между всеми типами time и всеми типами duration, плюс какие-то удобные приведения, — чтобы у пользователя вообще не возникало желание что-то там хакнуть, выковырять внутреннее представление и надругаться напрямую.

TB>И получаем либу, с которой невозможно работать без часового курения документации. А по факту было бы достаточно одной-единственной функции, возвращающей число наносекунд с начала эпохи в виде примитивного типа i128 (знаковый, чтоб можно было вычитать два момента и не париться). Если нужны даты и дни недели — то отдельными функциями, которые берут это самое i128 дальше сами там всё считают.


А по факту, i128 в большинстве случаев люто избыточно.
Если наносекунды с начала эпохи влезают в i64, а ты будешь буферные 64 бита всюду таскать и складывать нули с нулями.

Что касается "час курить документацию", — то в случае с временем это, к сожалению, необходимое дело. Хоть с std::chrono, хоть с сишными примитивами.
И не потому, что авторы библиотек упоролись, а потому, что предметная область упоротая, — о чём клиенты не подозревают.
Все эти универсальное время, системное, монотонное... это всё разные сущности. Физически разные.
std::chrono прямо заставляет тебя сдать экзамен по метрологии, прежде чем ты пойдёшь кодить, — это правда.

TB>А ещё с этими ограничениями я не могу написать так:

TB>
TB>class C {
TB>  C(int128& time): time(time) { time -= std::chrono::now(); }
TB>  ~C() { time += std::chrono::now(); }
TB>  int128& time;
TB>};
TB>

TB>(после работы этого кода значение time увеличится ровно на то время, когда жил класс C)
TB>Конечно это всё можно обойти, и для случая когда надо просто сложить-вычесть, легко это написать по-другому. Но операции над теми же векторами бывают посложнее.

К>>Долбаный хипстер ввёл Point, Vector и Rotation, а людям расхлёбывать, да? А может, людям за чистотой своих рук последить, прежде чем Point+Point или Point+Rotation делать, не?


TB>Point+Point это нормальная операция, не надо её запрещать. Point+Rotation конечно может привести к неприятностям, но я слабо представляю себе, как можно даже случайно так написать. В случае же разделения вектора и точки на два типа получаем код, которым очень трудно пользоваться, причём геморрой от борьбы с тараканами хипстера намного превышает вероятность потенциального бага, который к тому же легко обнаружить и исправить.


А какая физическая природа у суммы двух точек?
И как к ней, например, аффинные преобразования применять?

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


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


Дурак любую вещь доведёт до греха — хоть с primitive obsession, хоть с контрактами повсюду!
Перекуём баги на фичи!
Re[12]: Антипаттерн, противоположный Primitive Obsession
От: Кодт Россия  
Дата: 19.03.23 22:09
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Это передвинет её из "регулярно огребаю" в "огребаю раз в сто лет на экзотическом наборе данных", вроде не это называется повышением надёжности? Разумеется, я не говорю о случае, когда программа пытается как можно дольше скрывать ошибку, вызванную заведомо некорректными данными. Проблема в том, что беззнаковые числа любят валить программу на валидных данных. в Расте сразу, в С++ попозже.


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

Вот раст — другое дело. Он обещал.
Перекуём баги на фичи!
Re[7]: Антипаттерн, противоположный Primitive Obsession
От: vsb Казахстан  
Дата: 20.03.23 06:46
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Добро пожаловать в Раст Коммьюнити!

TB>Ах, да, ты ничего не понимаешь, потому что у тебя Primitive Obsession. Писать простой код, который тупо складывает два числа — это Primitive Obsession. Надо обмазываться кастами и чекед методами, при этом чем длиннее и непонятнее выглядит код, тем лучше.

Ну я так никогда не делал, поэтому мне сложно оценить осмысленность этой идеи.

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

Поэтому тут в любом случае нужен баланс между этими крайностями. Где он в этом примере с числовыми типами я пока не знаю. Если я могу сказать type Money = Decimal, получить автоматом тип для Money.offset, Money.power(2) (деньги в квадрате), со всеми автоматом выведенными и корректно работающими операторами, так, чтобы преобразования между числами и деньгами были только на входе и выходе из алгоритма, грубо говоря, 3 строчки на 1000, тогда может и нормально будет. А если мне надо написать 100 строк вспомогательного кода, только чтобы потом написать 20 строк основного, ну это не очень.
Re[8]: Антипаттерн, противоположный Primitive Obsession
От: vsb Казахстан  
Дата: 20.03.23 06:57
Оценка:
Здравствуйте, T4r4sB, Вы писали:

S>>А насколько часто у вас встречаются диапазонные типы? Ну, так, если по-честному?


TB>На Русте какой-то идиот ввёл для размера массива тип usize, мотивируя это тем, что ограничение >=0 "соответствует специфике домена", при этом на вопрос что делать если надо вычитать два размера, мне сказали "мне никогда это не надо было делать". Дальше разгорелся срач, я привёл пример с шахматной доской 256х256, и спросил, реально ли они ради дебильной идеи сраных доменов будут использовать u8, понимая, что тривиальные операции будет делать крайне геморройно, и они сказали что да.


Моё имхо: для указателя/размера массива нужно использовать некий спец тип 0 .. 2^63 — 1 (для 64 битов). Можно назвать его u63. При этом при вычитании должен получаться i64. Ну и можно складывать u63 + i64 = u63. Это почти все проблемы бы решило, как мне кажется. То бишь тот самый offset. А адреса 2^63 .. 2^64 — 1 пометить как невалидные, чтобы при попытке обращения к ним всё падало (в идеале вообще добавить в процессор специальные операции, которые будут вызывать прерывание сразу после вычисления неправильного адреса).
Re[11]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 20.03.23 07:19
Оценка: -1
Здравствуйте, CreatorCray, Вы писали:


CC>Схренали размер объекта должен быть isize? Он не бывает отрицательным никогда.


Против подобных идиотских мыслей я и борюсь. А на два шага вперед посмотреть?. Если он сам по себе не бывает меньше нуля, то это не значит что тебе не понадобятся промежуточные представления с отрицательным результатом. И если понадобятся то у тебя программа упадет. И придется код засирать кастами. И всего этого бы не было если бы изначально был знаковый размер.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[5]: Антипаттерн, противоположный Primitive Obsession
От: no_ise  
Дата: 20.03.23 07:42
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, T4r4sB, Вы писали:


TB>>А как этот долбаный фанатик собирается писать банальную задачу "прибавить к позиции шахматной фигуры смещение и проверить валидность результата"? Ведь согласно его идеям позиция шахматной фигуры должна иметь тип [0..8), а смещение должно иметь тип [-7 ..7], и складывать их нельзя, и любая попытка скастить одно к другому вызовет исключение в некоторых случаях.


К>Эта штука называется "зависимые типы". К позиции 0 можно прибавлять смещение 7, а к позиции 1 — уже нельзя.

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


Все это хорошо про "зависимые типы", Lof Type Theory, но, получается парадокс.
Т.е. внизу у нас Тюринг-комплит система, скажем, C или там С++, и сверху мы начинаем
сильной типизацией городить Тюринг-комплит метауровень.

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

Для хардкорного доказательства теорем это может быть круто. А для сложения-умножения точек
в каком-нибудь GDI кажется будет перебором.
Re[7]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 20.03.23 07:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, T4r4sB, Вы писали:


TB>>Здравствуйте, Кодт, Вы писали:


К>А числовые переполнения — это штука очень дискуссионная, и в разных языках к ней разные подходы.

К>Почему компилятор должен догадываться, что вот здесь u8+u8 = u8, а вот здесь уже = u9? А последующий u9-u8 — это u8, u9 или i10?

Ну ок, компилятор не должен догадываться. Пусть будет результат u8. А я возьму инт и не буду про это думать? Можно? Нет, нельзя.

К>Если в русте договорились, что тип результата не продвигается без явных указаний, — ну, делай указания.


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

К>Если есть сущность "смещения только в пределах шахматной доски", то — возможно, автору библиотеки или тебе лично, — придётся завести и сущность "расширенные смещения без гарантии, что они влезли в доску".


Да можно. Только эти хипстеры забыли что не надо плодить сущности без необходимости. А необходимости нет — на простых интах жилось ьы намного проще.

К>Опять же, разрядность этих смещений — "мамой клянусь, i32 мне за глаза и за уши", а вдруг "возьму-ка я float64"?


Переход на плавающие числа это уже радикальное изменение которое требует переписать почти все.

К>А по факту, i128 в большинстве случаев люто избыточно.

К>Если наносекунды с начала эпохи влезают в i64, а ты будешь буферные 64 бита всюду таскать и складывать нули с нулями.

А я не знаю, влезают ли в i64? Там запаса почти нет вродь. Ну если и его хватит то можно и его. Зато голову морочить не надо.

К>Все эти универсальное время, системное, монотонное... это всё разные сущности. Физически разные.

К>std::chrono прямо заставляет тебя сдать экзамен по метрологии, прежде чем ты пойдёшь кодить, — это правда.

Когда я пользовалсяGetTickCount(), time(), rdtsc() и QueryPerformanceCounter() то как то обходился без экзамена. Правда один раз огреб с GetTickCount когда у компа аптайм превысил ограничения типа

К>А какая физическая природа у суммы двух точек?

К>И как к ней, например, аффинные преобразования применять?

Сумма это промежуточный результвт операции "полусумма" у которой есть смысл.
Конечно можно записать это в виде a+(b-a)*0.5, но не всегда. Например тебе надо миллион точек прополусуммировать с данной. Тогда заранее вычислить a*0.5 было бы проще.
А пользы от данной идеи не вижу. Защииа он неверных значений не имеющих физического смысла типа (a+b)*0.6? Ну так если я напишу a+(b-a)*0.6, то мне станет не легче от того что результат сиал гдето примерно посередине a и b
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[8]: Антипаттерн, противоположный Primitive Obsession
От: night beast СССР  
Дата: 20.03.23 09:11
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Вообще я всегда, когда вижу, как люди увлекаются перекладыванием на систему типов всё большего функционала, вспоминаю, что рядом есть люди, которые пишут на JS и питоне.


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

в общем, "здесь не все так однозначно"
Re[6]: Антипаттерн, противоположный Primitive Obsession
От: so5team https://stiffstream.com
Дата: 20.03.23 09:49
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Ну ок, у тебя есть position, который [0..8) и offset который [-7..7]. Если ты применишь оператор (position, offset)->position к паре (5,5), то у тебя будет паника и прога упадёт.


Возмущение понятно. Не очень понятно что именно предлагается взамен. Отсутствие какого-либо контроля на уровне типов? Т.е. пусть все представляется int-ами, а если к position=5 добавят offset=-7, то что? Пользователь обязан проверить результаты своих операций перед тем, как эти результаты как-то использовать? Делать какие-то проверки на входе в функции, которые ожидают position?

Т.е. могли бы вы описать как вам бы хотелось работать с подобными значениями?
Re[7]: Антипаттерн, противоположный Primitive Obsession
От: T4r4sB Россия  
Дата: 20.03.23 10:15
Оценка: 2 (1)
Здравствуйте, so5team, Вы писали:

S>Т.е. могли бы вы описать как вам бы хотелось работать с подобными значениями?


Как с интами. Ну и валидацию только в самом конце когда ставим фигуру на доску.
Опционально валидацаю в сеттере set_coords. Вроде это намного проще чем кастовать на каждый чих.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.