Search
Write a publication
Pull to refresh
103
36
Михаил @m03r

User

Send message

~==~ выглядит ровно как сравнение в SQL с учётом nullable, на этот счёт недавно была полемическая статья.

Я совершенно согласен, что в целом для Maybe обыкновенный == выглядит удобнее почти во всех случаях.

Кстати, в IEEE 754 прочитал (раздел 5.11):

Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself.

Соответственно, для каждой операции сравнения разный набор этих вариантов превращается в true или false, там ниже таблицы истинности.

Как это работает — понятно, а что это с точки зрения типов и как это думать — перестал понимать совсем.

Maybe Float всем лучше! Обнаружил тут крейт Noisy Float, не такой уж непопулярный, который как раз-таки с безопасным float

UPD: безопасный он довольно условно: просто паникует при любом ненормальном числе. Видимо, это поведение более востребовано, чем аккуратный Option вокруг почти всего

Хороший вопрос! Для меня сравнение тут возможно трёх видов (Number во всех трёх случаях включает не NaN, Option<Number> — включает):

  1. Option<Number> -> Option<Number> -> Option<Bool>, когда сравниваются только числа, а не-числа приводят к принципиально другому результату. Это как в SQL с nullable-типами: NULL = NULL даёт NULL

  2. Option<Number> -> Option<Number> -> Bool по типу SQL-ного IS NOT DISTINCT FROM (оно же <=> в MySQL). Это Ваш вариант

  3. Option<Number> -> Option<Number> -> Bool , в виде модификации первого варианта, когда Some(true) приравнивается к true, а всё остальное — к false. Это вариант из IEEE 754. Кстати, преобразование Some<Bool> в Bool здесь по аналогии с работой WHERE в SQL: отбираются только строки со значением условия TRUE, а FALSE и NULL — нет, происходит эдакое впихивание трёх значенийOption<Bool> в два значения Bool.

Я думаю о том, что блок с условием NaN == NaN не выполнится, по аналогии с тем, как в SQL не отберутся строки с NULL = NULL.

Кстати, читал тут документацию, и почему-то NaN ** 0 в Javascript даёт единицу. Вероятно, потому что нулевая степень чего угодно, даже жаренной с грибами картошки, даёт всё равно единицу.

Был бы явный Option, было бы логично: (Some(5) == Some(5)) == Some(true), при этом (Some(5) == None) == None) и (None == None) = None).

Но Option тут половинчатый, и такое решение выглядит довольно логично. В конце концов, NaN представляет разные ситуации не-чисел, например, parseInt("blah") и "".charCodeAt(1). Было бы странно говорить, что они равны в контексте сравнения чисел.

Много и по делу, спасибо! Если бы хабрамаркетологи следовали хотя бы части упомянутых рекомендаций...

Одно только резануло: милый крабик Rust он, конечно, симпатичный, но гораздо больший эмоциональный отклик у меня вызывает красота концепций, положенных в основу языка. И без крабика я точно так же бы его любил.

А вот не менее милый суслик Go меня скорее раздражает, потому что мне не нравится дизайн языка (и, получается, поэтому даже хороший маркетинг для меня не работает, как это и описано в статье).

UPD: комментарий не предназначен для разжигания. Я просто хочу отметить, что для создания эмоциональной связи с продуктом иногда достаточно и просто кусков кода

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

Интерактивное демо просто восхитительное! — сразу всё становится понятно. И ещё вспомнилось видео про спирали из простых чисел, не оно ли послужило источником вдохновения?

"Морфологию волшебной сказки" Проппа почему-то не вспомнили

То-то в местной Пятёрочке почти два месяца висело объявление, что карты лояльности временно не работают.

А это, оказывается, внеплановая миграция.

Интересно, что же так нестабильно работало?

другой программист не знает, какие из всех возможных поведений вы использовали намеренно, а про какие не подумали

Кажется, этот аргумент применим вообще к любому мало-мальски нетривиальному коду.

У нас же разговор про запрос, а не про схему данных.

Задачу я сформулировал следующим образом (и как бы мне теоретически мог сформулировать её коллега-маркетолог): "Интересно, кто что себе покупает на ДР", и условие в запросе в точности соответствует постановке.

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

Что касается моделирования задачи, то условие «у некоторых пользователей есть дата рождения» полностью соответствует nullable-колонке в таблице с пользователями, разве нет?

Насчёт правильного условия в JOIN — согласен, сравнение дат лучше во WHERE.

Тем не менее, для меня очевидно и ожидаемо, что WHERE user.bdate = DATE(order.ctime) отбросит нулевые значения.

Да хоть во WHERE, не нужны дополнительные проверки на NULL, потому что то же равенство даст тот же NULL и строки не будут выбраны

А как по-вашему 1 > NULL — это истина или ложь? А 1 < NULL?

Если я хочу сравнить с числом средний чек пользователя, а у него покупок нет, то AVG(amount) будет NULL, даже если вообще вся база у меня спроектирована без нулевых колонок.

Как ещё предложите обрабатывать такие случаи?

Допустим, табличка с пользователями, у некоторых есть дата рождения, и табличка с заказами, в которых есть дата оплаты, но только в том случае, если он оплачен.

Интересно, кто что себе покупает на ДР.

Типа: ON user.id = order.user_id AND user.bdate = DATE(order.paid_at).

В реальности я бы скорее смотрел заказы за неделю до дня рождения, т. е. BETWEEN bd - INTERVAL 7 DAY AND bd, и всё бы тоже прекрасно работало.

Вам ни разу не приходилось делать JOIN по nullable-колонкам? Если ко всем NULLам из одной таблицы приджойнятся все NULLы из другой, будет хорошо и правильно?

Почему Вы упорно пытаетесь свести NOT DISTINCT к равенству/идентичности? Это просто отдельный концепт.

Если уж говорить об аналогиях NULL среди типов данных языков программирования, то для меня это всегда казалось чем-то близким монаде MayBe или типу Option .

А поскольку NULL может случиться где угодно, в Option получаются неявно завёрнуты вообще все значения.

И distinct/равенство, отлично вписываются в эту концепцию: distinct сравнивает сами Option'ы (и возвращает bool), а равенство — их содержимое (и возвращает тоже Option). А вот в JS ничего подобного нет.

В одном из ответов на stackoverflow приведены интересные цитаты из спецификации SQL. Если кратко: NULL друг другу не равны (not equal), но при этом они неразличимы (not distinct). Таким образом, GROUP BY не попирает догму, а просто использует иную концепцию.

Собственно, SQL2003 определяет оператор IS DISTINCT FROM, а в MySQL есть <=>

Если NULL будет равен сам себе, то внешние соединения по нулевым полям дадут совершенно неинтуитивный результат. Отсутствующее отчество у Джона Смита — это не то же, что отсутствующее отчество у Джимми Вонга

Вот только 0,001 секунд без fwirte достигается из-за того, что умный компилятор вырезает вообще все вычисления, потому что их результат никак не используется.

Information

Rating
374-th
Registered
Activity