clojure-russia

Работа и релокейт: #jobs-rus | #clojure-russia-offtop Телеграм-чат https://t.me/clojure_ru
rustam.gilaztdinov 2018-08-26T11:19:28.000100Z

@brownmoose3q привет, а будут ли новые выпуски? Клёвые видео, ты не бросай это дело 🙏

dottedmag 2018-08-26T15:54:04.000100Z

Господа, а у меня одного любой подход к спеке заканчивается "ох, никак с её помощью толком не повалидировать внешние данные"?

dottedmag 2018-08-26T15:54:20.000100Z

И есть ли, чем валидировать внешние данные и приводить их в приличный вид?

dottedmag 2018-08-26T15:55:07.000200Z

А то у меня какая-нибудь хреновина типа {"type": "add_something", "id": "<uuid>", "pos": 17, "entry": {"id": 4, ...}} приезжает, и надо её разбирать.

dottedmag 2018-08-26T15:56:12.000100Z

Спекой неудобно. Спекой хорошо {:change/type :add-something :change/id #uuid "..." :change/pos 17 :change/entry {:entry/id 4 ...}} проверять.

akond 2018-08-26T16:58:08.000100Z

неужели совсем неудобно?

dottedmag 2018-08-26T17:13:38.000100Z

Во-первых, спека не умеет мапы со строковыми ключами.

dottedmag 2018-08-26T17:13:56.000100Z

Во-вторых, во входящих данных разные типы значений под одинаковыми ключами (см. id).

akond 2018-08-26T17:14:15.000100Z

мапу можно рассматривать как последовательность

dottedmag 2018-08-26T17:14:55.000100Z

В-третьих, всё равно надо коэрсить.

dottedmag 2018-08-26T17:15:23.000100Z

В-четвёртых, что, писать две спеки: на внешний формат, и на починеный?

dottedmag 2018-08-26T17:16:52.000100Z

@akond И как, удобно последовательность спекать "в этой последовательности обязательно иметь вектор с первым элементом "type", обязательно иметь вектор с первым элементом "pos" и обязательно иметь вектор с первым элементом "entry""?

akond 2018-08-26T17:17:34.000100Z

(s/and vector? (s/cat :k (partial = "test") :v number?))

akond 2018-08-27T10:23:13.000100Z

я проверял мапу как последовательность mapentry, поэтому нам вектор

dottedmag 2018-08-26T17:18:23.000100Z

Мне нужна "антиспека": сделанная для закрытого мира, и с предположением, что всё входящее надо трансформировать.

akond 2018-08-26T17:18:54.000100Z

тогда зачем вторая спека?

dottedmag 2018-08-26T17:19:08.000100Z

Вторая для поддержки инвариантов внутри системы.

dottedmag 2018-08-26T17:20:29.000100Z

Т.е. первая "вот здесь будут ключи, их все на этом уровне превратить в ключевые слова по этому алгоритму, другие все ключи - ошибка". Вторая (s/keys :req [:change/type :change/id :change/pos])

akond 2018-08-26T17:20:57.000100Z

тогда спека не виновата если у тебя два по сути разных набора данных

dottedmag 2018-08-26T17:21:08.000100Z

Спасибо, кэп!

dottedmag 2018-08-26T17:21:27.000100Z

> И есть ли, чем валидировать внешние данные и приводить их в приличный вид?

dottedmag 2018-08-26T17:21:46.000200Z

Можно, конечно, руками, но есть подозрение, что этот ручной труд можно автомтизировать.

dottedmag 2018-08-26T17:22:04.000100Z

Но раз ничего нет, то значит руками.

akond 2018-08-26T17:22:32.000100Z

автоматизирвать в смысле показать ей пример, а она тебе готовую спеку?

dottedmag 2018-08-26T17:23:06.000100Z

В смысле, не писать баланду "проверить, что в этой мапе ключи строки, и там есть такие-то", а DSL а-ля спека, только наоборот.

dottedmag 2018-08-26T17:23:27.000100Z

Спека живёт в открытом мире, антиспека - в закрытом.

dottedmag 2018-08-26T17:23:40.000100Z

Спека считает коэрсии отклонением, антиспека – нормой.

dottedmag 2018-08-26T17:24:24.000100Z

Спека считает, что ключи уникально идентифицируют сущности, антиспека считает, что "id" во входящем документе будет 17 раз в трёх разных синтаксисах.

dottedmag 2018-08-26T17:25:04.000100Z

Наверное, этого уже достаточно, чтобы 1) сначала сделать разбор внешних данных руками; 2) посмотреть на этот разбор и сделать из него библиотеку и DSL.

dottedmag 2018-08-26T17:25:21.000100Z

Нужно раздобыть гамак.

akond 2018-08-26T17:25:29.000100Z

можно добавить в спеку условие :else и туда все будет валиться, если я правильно понял что ты хочешь

dottedmag 2018-08-26T17:26:20.000100Z

Вот тебе паззл: покрой спекой JSON-чик выше. На первом уровне ключ "id" — UUID, на втором — int64.

akond 2018-08-26T17:26:53.000100Z

а жсон разве поддерживатье 64 битовые целые?

dottedmag 2018-08-26T17:27:18.000100Z

в JSON числа произвольной длины, если что.

dottedmag 2018-08-26T17:28:09.000100Z

В любом случае, производители и потребители этого JSON – Swift и Go, так что проблемы языков без int64 их не волнуют.

akond 2018-08-26T17:28:20.000100Z

а, это в жс ограничение

akond 2018-08-26T17:28:58.000100Z

{"type" "add_something", "id" uuid?, "pos" 17, "entry" {"id" 4}} вот так?

akond 2018-08-26T17:36:59.000100Z

ключи обязательные или нет?

dottedmag 2018-08-26T17:37:51.000100Z

Все ключи обязательные.

akond 2018-08-26T17:38:40.000100Z

`(s/explain (s/cat :first (s/and vector? (s/cat :k (partial = "type") :v string?)) :second (s/and vector? (s/cat :k2 (partial = "id") :v2 uuid?)) :third (s/and vector? (s/cat :k3 (partial = "pos") :v3 number?)) :entry (s/and vector? (s/cat :k4 (partial = "entry") :v4 some?)) ) {"type" "add_something", "id" (java.util.UUID/randomUUID), "pos" 17, "entry" {"id" 4}})`

dottedmag 2018-08-26T17:40:49.000100Z

uuid? матчит строку?

dottedmag 2018-08-26T17:41:02.000100Z

Ключи могут идти в любом порядке, это же JSON.

akond 2018-08-26T17:41:02.000200Z

не, это для примера

dottedmag 2018-08-26T17:41:31.000100Z

Да, можно отсортировать, но таких мап у меня, допустим 50, и они вложенные. Всех сортировать?

dottedmag 2018-08-26T17:42:22.000100Z

И теперь результат хочется привести к виду "Спекой хорошо ... проверять", сколько это ещё будет кода?

dottedmag 2018-08-26T17:44:48.000100Z

Да, и ещё :v4 непоспекан. Тоже (s/cat)?

akond 2018-08-26T17:45:05.000100Z

если без порядка, то (s/* (s/alt. выкрутиться можно. другое дело что много текста.

dottedmag 2018-08-26T17:45:43.000100Z

Получится больше текста, чем вручную то же самое писать.

dottedmag 2018-08-26T17:45:58.000100Z

Поэтому и нужен DSL.

akond 2018-08-26T17:49:52.000100Z

на v4 своя спека должна быть

akond 2018-08-26T17:50:07.000100Z

s/* скорее всего

akond 2018-08-26T17:51:42.000100Z

ты хотел что-то в виде bison?

akond 2018-08-26T17:52:44.000100Z

типа EBNF

akond 2018-08-26T17:57:49.000100Z

вот еще забавная штука: https://github.com/stathissideris/spec-provider

dottedmag 2018-08-26T17:58:55.000100Z

@akond Я хотел бы что-то в виде спеки, но со всеми решениями наоборот 🙂

dottedmag 2018-08-26T17:59:10.000100Z

Бизон - это ж просто EBNF. Зачем EBNF на уже разобранном дереве?

akond 2018-08-26T17:59:37.000100Z

по аналогии я имею в виду

akond 2018-08-26T17:59:59.000100Z

хотя спека и так оно и есть

akond 2018-08-26T18:01:39.000100Z

и чего это тебе по воскресеньям спекой решилось заниматься?

akond 2018-08-26T18:04:08.000100Z

"решения наоборот" - абстракция, которую я плохо (вообще не) понимаю

fmnoise 2018-08-26T20:44:18.000100Z

@dottedmag даже если ты извратишься и опишешь то что тебе надо спекой, оно будет как минимум нечитаемое

fmnoise 2018-08-26T20:45:32.000100Z

schema гораздо лучше подходит для валидации внешних данных, но насчет коерсии я не уверен

fmnoise 2018-08-26T20:47:06.000100Z

ребята с Аттендифая вот довели идею схемы до refined types https://github.com/KitApps/schema-refined

fmnoise 2018-08-26T20:54:04.000100Z

а, есть у schema коерсия

fmnoise 2018-08-26T20:54:40.000100Z

вобщем, я б schema попробовал

dottedmag 2018-08-26T21:11:23.000100Z

@fmnoise Вот, очень интересно, спасибо.