Информация об изменениях

Сообщение Re[6]: Антипаттерн, противоположный Primitive Obsession от 23.03.2023 12:06

Изменено 23.03.2023 12:12 netch80

Re[6]: Антипаттерн, противоположный Primitive Obsession
Здравствуйте, T4r4sB, Вы писали:

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


А почему ты тут думаешь именно про i32? А вдруг и его переполнит, тогда оно должно было святым духом догадаться, что надо было конвертить всё к i64? Или как?

Сложили два int32_t, получим int33_t?
Перемножаем. Первое произведение int64_t, второе int96_t, третье int128_t... Астанавитесь(c), Вите надо выйти!

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

Можно 1) влупить в лоб сразу, как в Rust, 2) маскировать проблему подольше, как в C/C++, 3) уходить от неё ценой производительности, как в Python и Erlang. Возможно, ещё как-то можно.

В Rust хорошо, что, в отличие от C/C++, тебе явно показывают проблему и дают средства её решения прямым и легкопонятным способом.

TB> Нахрен мне нужно ограничение, при котором предполагается, что промежуточный результат будет иметь те же ограничения, что и сами данные, если это вообще даже близко не так? И тогда зачем вообще ограничивать тип, когда проще все эти проверки делать в сеттере поля?


Повторюсь, в C с int или long то же самое. И вообще это ещё из Фортрана растёт, как минимум. Ничто не ново под луною.

Нахрена в нём два (минимум) уровня integral promotion — не знаю, оно таки сомнительно. Как и его ценность сейчас вообще. Но зачем его делали в далёких 70-х — очевидно.

TB>И получаем либу, с которой невозможно работать без часового курения документации.


Ну chrono это отдельная пейсТня.

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


Но тут другое. С какой именно эпохи? Юниксовой (начало 1970 года) или виндовой (1601)?
А может, с "юлианского дня" номер 1, как сделали в Delphi?

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


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

TB>Point+Point это нормальная операция, не надо её запрещать.


Надо.

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


Ну вот эти конкретные примеры, IMHO, на пользу.
Re[6]: Антипаттерн, противоположный Primitive Obsession
Здравствуйте, T4r4sB, Вы писали:

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


А почему ты тут думаешь именно про i32? А вдруг и его переполнит, тогда оно должно было святым духом догадаться, что надо было конвертить всё к i64? Или как?

Сложили два int32_t, получим int33_t?
Перемножаем. Первое произведение int64_t, второе int96_t, третье int128_t... Астанавитесь(c), Вите надо выйти!

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

Можно 1) влупить в лоб сразу, как в Rust, 2) маскировать проблему подольше, как в C/C++, 3) уходить от неё ценой производительности, как в Python и Erlang. Возможно, ещё как-то можно.

В Rust хорошо, что, в отличие от C/C++, тебе явно показывают проблему и дают средства её решения прямым и легкопонятным способом.

Да, и вдогонку — а действительно, почему у тебя они в u8? Это же тип скорее для упаковки в структуру, чем для манипулирования. Во всех современных ABI всё равно будет один регистр занят, так что u8 или i32 — одномайственно.

Я видел кучу кода, где, например, берут из переменной типа u8 (uint8_t) количество элементов, а затем итерируют по нему опять же переменной типа u8. Это, да, безграмотно.

TB> Нахрен мне нужно ограничение, при котором предполагается, что промежуточный результат будет иметь те же ограничения, что и сами данные, если это вообще даже близко не так? И тогда зачем вообще ограничивать тип, когда проще все эти проверки делать в сеттере поля?


Повторюсь, в C с int или long то же самое. И вообще это ещё из Фортрана растёт, как минимум. Ничто не ново под луною.

Нахрена в нём два (минимум) уровня integral promotion — не знаю, оно таки сомнительно. Как и его ценность сейчас вообще. Но зачем его делали в далёких 70-х — очевидно.

TB>И получаем либу, с которой невозможно работать без часового курения документации.


Ну chrono это отдельная пейсТня.

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


Но тут другое. С какой именно эпохи? Юниксовой (начало 1970 года) или виндовой (1601)?
А может, с "юлианского дня" номер 1, как сделали в Delphi?

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


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

TB>Point+Point это нормальная операция, не надо её запрещать.


Надо.

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


Ну вот эти конкретные примеры, IMHO, на пользу.