Fork me on GitHub
#clojure-russia
<
2018-08-26
>
rustam.gilaztdinov11:08:28

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

dottedmag15:08:04

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

dottedmag15:08:20

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

dottedmag15:08:07

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

dottedmag15:08:12

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

akond16:08:08

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

dottedmag17:08:38

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

dottedmag17:08:56

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

akond17:08:15

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

dottedmag17:08:55

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

dottedmag17:08:23

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

dottedmag17:08:52

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

akond17:08:34

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

misha04:08:24

(s/and map? (s/cat ...)) может имел ввиду?

akond10:08:13

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

dottedmag17:08:23

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

akond17:08:54

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

dottedmag17:08:08

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

dottedmag17:08:29

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

akond17:08:57

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

dottedmag17:08:08

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

dottedmag17:08:27

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

dottedmag17:08:46

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

dottedmag17:08:04

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

akond17:08:32

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

dottedmag17:08:06

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

dottedmag17:08:27

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

dottedmag17:08:40

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

dottedmag17:08:24

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

dottedmag17:08:04

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

dottedmag17:08:21

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

akond17:08:29

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

dottedmag17:08:20

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

akond17:08:53

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

dottedmag17:08:18

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

dottedmag17:08:09

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

akond17:08:20

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

akond17:08:58

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

akond17:08:59

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

dottedmag17:08:51

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

akond17:08:40

`(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}})`

dottedmag17:08:49

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

dottedmag17:08:02

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

akond17:08:02

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

dottedmag17:08:31

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

dottedmag17:08:22

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

dottedmag17:08:48

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

akond17:08:05

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

dottedmag17:08:43

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

dottedmag17:08:58

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

akond17:08:52

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

akond17:08:07

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

akond17:08:42

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

akond17:08:44

типа EBNF

akond17:08:49

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

dottedmag17:08:55

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

dottedmag17:08:10

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

akond17:08:37

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

akond17:08:59

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

akond18:08:39

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

akond18:08:08

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

fmnoise20:08:18

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

fmnoise20:08:32

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

fmnoise20:08:06

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

fmnoise20:08:04

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

fmnoise20:08:40

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

dottedmag21:08:23

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