Fork me on GitHub
#clojure-russia
<
2015-12-03
>
wwall07:12:46

Народ. всем привет. С макросом можете помочь?

wwall07:12:05

есть такой код - http://pastebin.com/HVvHpNYZ

wwall07:12:35

работает. но он не макрос. там шенериться текст, который я потом в файл переношу

wwall07:12:46

хотелось бы просто макросом сделать.

artemyarulin07:12:28

и в чем именно проблема?

niquola07:12:30

Лучше данными сделай

niquola07:12:13

Вынеси весь конфиг в структуру данных - например в hash-map ;)

wwall07:12:44

проблема - в написании макроса.

wwall07:12:01

требуется макрос который бы по генерировал три парсера

wwall07:12:20

один для русского языка, один для англиского и общий - соединяя их через или

wwall07:12:48

nicola - как вынести в конфиг?

dima07:12:18

а в чем именно проблема с макросом?

(defmacro generate-lex
[lex-name en ru]
 (let [ru-name (clojure.string/join  [lex-name "-ru"])
   ...
  `(defparser ~ru-name [] (let->> ...)
  ...
  )))

niquola07:12:17

До работы доеду - покажу

niquola07:12:58

Данные потом можно в файлик или в базу закинуть ;)

wwall07:12:34

проблема - преобразовать строку символов, например "var" в парсер вида (let->> [v1 (choice (char \v) (char \V)) v2 (choice (char \a) (char \A)) v3 (choice (char \r) (char \r)) ] (always {:value (clojure.string/join [v1 v2 v3])})

wwall07:12:41

Не понимаю (не знаю) как сдлеать следующее - по строке сгенерировать список, этот список правильно поставить в парсер, объявить 3 парсера в одном макросе

wwall07:12:53

буду благодарен любой помощи

dima07:12:08

то что я вижу в снипете это попытка сгенерировать строку с кодом. Строку затем можно превратить в код при помощи (eval (read-string “(my clojure code”))), но по-моему лучше все таки написать макрос, который будет генерировать нужный код..

dima07:12:46

Где код макроса в снипете? я его там не нахожу

wwall07:12:06

нет так кода макроса

wwall07:12:15

там есть генерация строки

wwall07:12:34

надо переделать на макрос

wwall07:12:53

ща попробую

turtle07:12:30

ognivo: явашный тредпул очень качественный. Если нужно тонкое управление, проще над ним удобную обёртку просто сделать.

prepor07:12:06

core.async, внезапно, использует явашный тредпул

prepor07:12:33

и уже является "удобной оберткой" над ним

turtle07:12:33

prepor: core.async не смотрел, но осуждаю. А вообще, у него же другие задачи.

prepor07:12:34

его задача — организация (конкурирующих) процессов. это ровно то о чем тут идет речь

turtle07:12:27

Полистал апи, не увидел управления тредпулами, настройками и т.д.

turtle07:12:38

Так что осуждаю. simple_smile

turtle07:12:03

Я ещё выше сказал, конкурирующие процессы последовательно уложить - это агент справится, даже думать не надо.

turtle08:12:38

Всё ж зависит от того, что человеку надо, я его до конца не понял.

turtle08:12:11

wwall: тебе зачем макрос? Чтобы был или какие цели преследуешь?

wwall08:12:33

что бы код проще выглядел.

wwall08:12:44

так то можно и текстом оставить

wwall08:12:54

но хочетяс понять как пишется макрос

wwall08:12:58

пока есть время и задача

turtle08:12:19

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

turtle08:12:31

А вообще, я бы советовал избегать макросов до последнего.

turtle08:12:00

Хотя в твоём случае как раз можно в компайл-тайм вынести.

artemyarulin08:12:09

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

wwall08:12:25

в данном случае для фана simple_smile

wwall08:12:06

код то уже есть - но бесит 150 строк однообразного кода

wwall08:12:28

(defparser lxmProcedure-ru [] (let->> [start (lineno) var-1 (choice (char \п) (char \П)) var-2 (choice (char \р) (char \Р)) var-3 (choice (char \о) (char \О)) var-4 (choice (char \ц) (char \Ц)) var-5 (choice (char \е) (char \Е)) var-6 (choice (char \д) (char \Д)) var-7 (choice (char \у) (char \У)) var-8 (choice (char \р) (char \Р)) var-9 (choice (char \а) (char \А)) ] (always {:lang :ru :value (clojure.string/join [ var-1 var-2 var-3 var-4 var-5 var-6 var-7 var-8 var-9]) :pos start}))) (defparser lxmProcedure-en [] (let->> [start (lineno) var-1 (choice (char \p) (char \P)) var-2 (choice (char \r) (char \R)) var-3 (choice (char \o) (char \O)) var-4 (choice (char \c) (char \C)) var-5 (choice (char \e) (char \E)) var-6 (choice (char \d) (char \D)) var-7 (choice (char \u) (char \U)) var-8 (choice (char \r) (char \R)) var-9 (choice (char \e) (char \E)) ] (always {:lang :en :value (clojure.string/join [ var-1 var-2 var-3 var-4 var-5 var-6 var-7 var-8 var-9]) :pos start}))) (defparser lxmProcedure [] (let->> [start (lineno) v (choice (lxmProcedure-ru) (lxmProcedure-en))] (always {:type :lxmProcedure :value v :pos start})))

wwall08:12:15

и не читаемо и смысла никакого... Проще бы выглядело (generate-lex "lxmProcedure" "procedure" "процедура")

ponimas08:12:51

Народ, а кто honeysql юзает? с его помощью возможно сделать постгресовский копи?

turtle08:12:18

Чот код не понял, как-то он плохо выглядит. simple_smile

turtle08:12:22

Не форматированно.

wwall08:12:27

итак, есть такое - (defmacro generate-lex [lex-name en ru] (let [ru-name (clojure.string/join [lex-name "-ru"]) ru-parser (map (fn [x y] [(clojure.string/join ["var" ~y "#"]) (choice (char ~(clojure.string/lower-case x)) (char ~(clojure.string/upper-case x)))]) ru (take (count ru) (int-seq)))] `(defparser ~ru-name [] (let->> [~ru-parser] (always {:result :test}) )))) при раскрытии loxy.core> (macroexpand-1 '(generate-lex lxmOR "or" "или")) (the.parsatron/defparser "lxmOR-ru" [] (the.parsatron/let->> [(["var1#" (the.parsatron/choice (clojure.core/char "и") (clojure.core/char "И"))] ["var2#" (the.parsatron/choice (clojure.core/char "л") (clojure.core/char "Л"))] ["var3#" (the.parsatron/choice (clojure.core/char "и") (clojure.core/char "И"))])] (the.parsatron/always {:result :test})) как поубирать строки у var и сделать из (char "и") char (\и)

artemyarulin08:12:37

а если для фана то конечно гогого. Пользуюсь случаем - мне стало все понятно после прочтения вот этой книженции http://www.amazon.com/Mastering-Clojure-Macros-Cleaner-Smarter/dp/1941222226

wwall08:12:18

вот так в отформтированном фиде выглядит - (defparser lxmProcedure-ru [] (let->> [start (lineno) var-1 (choice (char \п) (char \П)) var-2 (choice (char \р) (char \Р)) var-3 (choice (char \о) (char \О)) var-4 (choice (char \ц) (char \Ц)) var-5 (choice (char \е) (char \Е)) var-6 (choice (char \д) (char \Д)) var-7 (choice (char \у) (char \У)) var-8 (choice (char \р) (char \Р)) var-9 (choice (char \а) (char \А)) ] (always {:lang :ru :value (clojure.string/join [ var-1 var-2 var-3 var-4 var-5 var-6 var-7 var-8 var-9]) :pos start}))) (defparser lxmProcedure-en [] (let->> [start (lineno) var-1 (choice (char \p) (char \P)) var-2 (choice (char \r) (char \R)) var-3 (choice (char \o) (char \O)) var-4 (choice (char \c) (char \C)) var-5 (choice (char \e) (char \E)) var-6 (choice (char \d) (char \D)) var-7 (choice (char \u) (char \U)) var-8 (choice (char \r) (char \R)) var-9 (choice (char \e) (char \E))] (always {:lang :en :value (clojure.string/join [ var-1 var-2 var-3 var-4 var-5 var-6 var-7 var-8 var-9]) :pos start}))) (defparser lxmProcedure [] (let->> [start (lineno) v (choice (lxmProcedure-ru) (lxmProcedure-en))] (always {:type :lxmProcedure :value v :pos start})))

wwall08:12:54

artemyarulin - посмотрю - спасибо

turtle08:12:13

Поубирать - строку в кейворд преобразовать, вроде.

turtle08:12:33

А не, в символ - (symbol ...)

turtle08:12:54

А вар лучше не так делай, а через gensym

turtle08:12:39

В твоём случае получится (symbol (clojure.string/join ["var" `~y "#"]))

turtle08:12:48

Но опять же - делай через gensym переменные.

wwall08:12:10

у меня уже так в макросе - (defmacro generate-lex [lex-name en ru] (let [ru-name (make-sym (clojure.string/join [lex-name "-ru"])) ru-parser (map (fn [x y] [(clojure.string/join ["var" ~y "#"]) (choice (char ~(clojure.string/lower-case x)) (char ~(clojure.string/upper-case x)))]) ru (take (count ru) (int-seq)))] `(defparser ~ru-name [] (let->> [~ru-parser] (always {:result :test}) ))))

turtle08:12:47

И что у тебя получается?

wwall08:12:18

loxy.core> (macroexpand-1 '(generate-lex lxmOR "or" "или")) (the.parsatron/defparser lxmOR-ru [] (the.parsatron/let->> [(["var1#" (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))] ["var2#" (the.parsatron/choice (clojure.core/char \л) (clojure.core/char \Л))] ["var3#" (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))])] (the.parsatron/always {:result :test})))

niquola08:12:46

@ponimas не думаю, но его можно расширить через мультиметода - https://github.com/niquola/clj-pg/blob/master/src/clj_pg/honey.clj

turtle08:12:35

wwall: забыл, что тебя в результате смущает?

wwall08:12:33

смотри - сейчас макрос такой - (defmacro generate-lex [lex-name en ru] (let [ru-name (make-sym (clojure.string/join [lex-name "-ru"])) ru-parser (into [] (map (fn [x y] [(make-sym (clojure.string/join ["var" `~y "#"])) `(choice (char ~((into [] (clojure.string/lower-case x)) 0)) (char ~((into [] (clojure.string/upper-case x)) 0)))]) ru (take (count ru) (int-seq))))] `(defparser ~ru-name [] (let->> ~ru-parser (always {:result :test}) )))) и вывод - loxy.core> (macroexpand-1 '(generate-lex lxmOR "or" "или")) (the.parsatron/defparser lxmOR-ru [] (the.parsatron/let->> [[var1# (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))] [var2# (the.parsatron/choice (clojure.core/char \л) (clojure.core/char \Л))] [var3# (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))]] (the.parsatron/always {:result :test}))) как видно для (let->> вывод неверный. Есть let->> [[var1# ( а надо let->> [var1# (

turtle08:12:16

1. ~@ru-parser, 2. для имени вара нужно использовать gensym, 3. Если строка, то её надо в символ преобразовать.

turtle08:12:24

А если gensym, то сразу символ будет.

prepor08:12:36

gensym совсем не для этого

wwall08:12:46

то есть как-то [ [x y] [z t]] отобразить в [x y z t]

prepor08:12:52

gensym что бы избежать пересечений имен

turtle08:12:18

Ты намекаешь что внутри его собственной функции не будет пересечения имён?

prepor08:12:39

syntax quote (` ) имеет сахар для gensym в виде foo#

prepor08:12:58

я говорю зачем gensym в макросах нужен )

turtle08:12:04

А, точняк. Это же clojure. simple_smile

turtle08:12:26

Затем, чтобы не пересекаться в именах?

turtle08:12:34

Бывает часто нужен.

turtle08:12:42

Собственно, вне макроса мне он ни разу не понадобился.

wwall08:12:02

gensym прикрутил. хуже не стало

wwall08:12:13

вопрос собвственно теперь только в отображении коллекции

turtle08:12:18

wwall: кстати, а зачем ты "#" добавляешь?

wwall08:12:26

e;t yt lj,fdkz. ^)

turtle08:12:29

~@ru-parser - пробовал так?

prepor08:12:50

ну типа пишешь ты макрос типа (defmacro [& body] `(let [foo# (computation)] (prn foo#) ~@body)))

prepor08:12:58

foo# это сахар для gensym

turtle08:12:16

Да, я вспомнил, что # - это сахар.

prepor08:12:20

и оно тебе обеспечивает, что у тебя имена биндингов не пересекутся с тем, что внутри body

turtle08:12:30

У тебя компутейшн не вычислится в компайл-тайме.

ponimas08:12:42

@nicola: спасибо!

prepor08:12:48

у меня? да, но я к этому и не стремился )

wwall08:12:02

вопрос - как [ [x y ] [z t ] ] отобразить в [x y z t]

turtle08:12:06

Это я так, к слову. Пример слегонца неудачный.

turtle08:12:15

wwall: ~@ru-parser - пробовал так?

prepor08:12:26

удачный. макросы не для того что бы в "компайл тайме" что то вычислять

prepor08:12:47

а для того что бы вводить новые конструкции языка

turtle08:12:49

В целом, учитывая, что они работают в компайл тайм - вполне.

prepor08:12:52

в общем эту конкретную задач ПЛОХО решать через макросы

turtle08:12:05

Новые конструкции языка в ФП в новых функциях отлично решаются.

turtle08:12:13

А ридер макро в кложуре, вроде, отстойный какой-то.

prepor08:12:15

(def foo (computation)) тоже вычислится в "компайл тайме"

prepor08:12:32

просто чуть-чуть в другом, но с точки зрения решения задачи все равно

turtle08:12:44

Другой компайл тайм. Задумался.

prepor08:12:55

это, это лисп, у него их два

turtle08:12:57

Даже не так - чуть-чуть другой компайл тайм.

prepor08:12:04

> А ридер макро в кложуре, вроде, отстойный какой-то. нет "ридера макро". есть просто ридер

turtle08:12:17

И ридер отстойный тоже.

turtle08:12:39

Но это и не нужно, так что в этом плане у меня к кложуре претензий нет.

turtle08:12:49

Претензии к коммон лиспу за перегруженность есть. simple_smile

prepor08:12:10

и так. есть generate-lex. он делает две вещи: формирует собственно неких лексер и добавляет несколько def-ов. первая часть решается без макросов и лишь вторая — это дело макроса

wwall08:12:34

но у меня уже через intern сделано

turtle08:12:47

wwall: и что получилось?

wwall08:12:49

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

wwall08:12:17

на сейчас стоит проблема с формированием биндингов у let->>

turtle08:12:21

prepor: вторую часть можно вполне и без макросов решить.

wwall08:12:27

а в остальном - все работает

turtle08:12:29

Деф всё равно в глобал биндинг биндит.

turtle08:12:34

Вот, масло масляное. simple_smile

turtle08:12:48

wwall: ну после ~@ru-parser что получилось на выводе?

wwall08:12:02

(macroexpand-1 '(generate-lex lxmOR "or" "или")) (the.parsatron/defparser lxmOR-ru [] (the.parsatron/let->> [[var12250 (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))] [var12251 (the.parsatron/choice (clojure.core/char \л) (clojure.core/char \Л))] [var12252 (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))]] (the.parsatron/always {:result :test})))

turtle08:12:20

А сам макрос покажи текущий.

wwall08:12:35

(defmacro generate-lex [lex-name en ru] (let [ru-name (make-sym (clojure.string/join [lex-name "-ru"])) ru-parser (into [] (map (fn [x y] [ (gensym "var") `(choice (char ~((into [] (clojure.string/lower-case x)) 0)) (char ~((into [] (clojure.string/upper-case x)) 0)))]) ru (take (count ru) (int-seq))))] `(defparser ~ru-name [] (let->> ~ru-parser (always {:result :test}) ))))

turtle08:12:08

Ну так тут у тебя ru-parser. А я хотел посмотреть с @ru-parser.

wwall08:12:48

(the.parsatron/defparser \l \x \m \O \R \- \r \u [] (the.parsatron/let->> [[var12175 (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))] [var12176 (the.parsatron/choice (clojure.core/char \л) (clojure.core/char \Л))] [var12177 (the.parsatron/choice (clojure.core/char \и) (clojure.core/char \И))]] (the.parsatron/always {:result :test}))) - тут имя как последовательность char

wwall08:12:07

я эту фишку чуть позже лучше в ru воткну

prepor08:12:43

turtle: > вторую часть можно вполне и без макросов решить. как?

turtle08:12:56

Обычном циклом в лоад тайме.

wwall08:12:11

там тоже генерация парсера

wwall08:12:28

тут вся работа - в компиле тайм

prepor08:12:31

в смысле? если я хочу var новый заиметь, что мне в цикл пихать?

turtle08:12:04

Если один новый вар, то ничего пихать не надо.

prepor08:12:24

у парня делается (defparser " ru-name

prepor08:12:36

на сколько я понимаю это создание новый варов

prepor08:12:19

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

turtle08:12:42

wwall: можно сделать нахально ~(into [] (concat ru-parser))

turtle08:12:52

Но вроде через @ должно работать.

turtle09:12:07

wwall: какие успехи?

wwall09:12:14

да отвлекли. ща продолжу simple_smile

wwall09:12:02

подскажите как [ [1 2] [3 4] ] преобразовать в [1 2 3 4]? не получается

artemyarulin09:12:38

вопрос - никто не делала optimistic UI вообще и в om-next в частности? На самом деле Ом не причем, просто не пойму как вообще обрабатывать ошибки например: - Пользователь создал новую сущность, я в UI ее показал как будто создана, отправил на сервер сообщение для создания - Пользователь поменял эту сущность. Я это благополучно сделал в UI, отправил на сервер Первое сообщение вернулось с ошибкой и чо теперь делать? Ну т.е. я счас на коленке придумаю конечно какой workaround именно для этого кейса, но может есть какие стратегии/паттерны для общего случая?

a.espolov09:12:17

судя по всему их нет

a.espolov09:12:25

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

delaguardo09:12:21

"отправил на сервер сообщение для создания" а что в этом случае отправляется на сервер? я правильно понимаю что данные о состоянии элемента?

delaguardo09:12:54

и в ответ должно прийти новое состояние элемента?

a.espolov09:12:42

че за хрень с datomic free он мне русские символы не фига ни в utf-8 возвращает

a.espolov09:12:47

так и должно быть?

a.espolov09:12:02

@delaguardo: вся сущность целиком, либо как минимум то что должно сохранить в базе

a.espolov09:12:28

а в ответ должно прийти добавлена она или нет

a.espolov09:12:48

но это самый простой случай

a.espolov09:12:14

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

wwall09:12:38

вопрос - макрос дожен порождать три формы. как их сделать в одном макросе?

wwall09:12:13

есть такое (defmacro deftoken [lex-name en ru] (let [ ru-name (make-sym (clojure.string/join [lex-name "-ru"])) en-name (make-sym (clojure.string/join [lex-name "-en"])) ru-parser-data (into [] (map (fn [x y] [ (gensym "ru-var") `(choice (char ~((into [] (clojure.string/lower-case x)) 0)) (char ~((into [] (clojure.string/upper-case x)) 0)))]) ru (take (count ru) (int-seq)))) ru-parser-binding (into [] (apply concat ru-parser-data)) ru-list-binding (into [] (map (fn [[x y]] x)) ru-parser-data ) en-parser-data (into [] (map (fn [x y] [ (gensym "en-var") `(choice (char ~((into [] (clojure.string/lower-case x)) 0)) (char ~((into [] (clojure.string/upper-case x)) 0)))]) en (take (count en) (int-seq)))) en-parser-binding (into [] (apply concat en-parser-data)) en-list-binding (into [] (map (fn [[x y]] x)) en-parser-data )] @(`(defparser ~ru-name [] (let->> ~ru-parser-binding (always {:lang :ru :value (clojure.string/join ~ru-list-binding) }))) `(defparser ~en-name [] (let->> ~en-parser-binding (always {:lang :en :value (clojure.string/join ~ru-list-binding) }))) `(defparser ~lex-name [] (let->> [start (lineno) v# (choice (ru-name) (en-name))] (always {:pos :start :value v#}))))))

wwall09:12:47

не работает 😞

prepor09:12:02

`(do (defparser ru-name []...) (defparser en-name []...))

artemyarulin09:12:18

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

wwall09:12:17

ДААААААААААААААААААААААААААААААААААААА

wwall09:12:22

Мужики - спасибо вам

niquola10:12:00

@artemyarulin вывести экран для merge ;)

niquola10:12:46

Либо попробовать смерджить автоматически

niquola10:12:54

Как git

niquola10:12:00

общего решения нет, в частом случае порой можно

artemyarulin10:12:33

ну до мержа точно доводить не хочу, хотя на гит смотрел да:) Пока вывел несколько правил когда optimistic update запрещен: - сущность тока создана в pending state, редактировать ее нельзя - удаление через is-deleted чтобы можно было вернуть назад легко - если сущность в pending state - связанные с ней менять тоже нельзя т.е. идея конфликт исключить вообще

artemyarulin10:12:41

точнее не так - конфликт будет, но не будет проблем когда одну транзакцию надо отменить, а на основе нее уже 100 других

niquola10:12:39

нудк это писимистик

niquola11:12:42

если простыми словами: один пользователь отредактировал - другой удалил - кто из них прав? система не знает, знает только кто первый ( и то не всегда). По честному надо их обоих сконнектить - чтоб они к консенсусу пришли. Т.е. открывается групповой чатик и merge инструмент и они сами решают simple_smile

artemyarulin11:12:13

ну у меня не совсем прям real-time collaboration. Чисто client-server, но клиент может сидеть с нескольких машин/девайсов. У меня емайл клиент по сути - пометил сообщения как прочитанное, другое удалил, третье написал, на четвертое ответил, в принципе для этого стандартного кейса все будет выглядеть как optimistic. А вот когда написал сообщение, положил в черновики и решил сразу ее отредактировать то - низя да, ибо еще не пришел confirm from server. Ну тут я уже углубляюсь в логику своего приложения, т.е. да ответ тут верный дали - depends on app simple_smile

razum2um13:12:41

@artemyarulin: исключить конфликты наверняка можно только CRDT, но тема любопытная

razum2um13:12:30

@nicola: > открывается групповой чатик и merge инструмент и они сами решают вот я пока склоняюсь к Колиной позиции, хотя наш фронтенд жутко против, но я не на этом проекте с синхронизацией и оффлайном...

artemyarulin13:12:09

@razum2um: во спасибо, почитаю. Тема и впрям интересная, странно что быстрый гуглешь ничего не дал - вроде optimistic updates тема счас популярная

prepor14:12:58

CRDT часто ничего не решает. ну т.е. вот если вы удалили разные элементы списка какого-нибудь — ок, но это и без crdt можно решить часто. А тема типа "я удалил, он отредактировал" не особо решается. Совместное редактирование текста, на сколько мне известно, тоже лучше решать не через CRDT.

prepor14:12:10

Эта тема вообще как-то так связывает тему распределенных баз данных и построение GUI (казалось бы!), что не думаю, что ее хоть кто-то научился элегантно решать в более-менее общем случае

artemyarulin14:12:22

просто Нолен в презентации говорил что ом-некст, траляля, история, optimistic updates, сломалось - откатил и я что-то прям ожидал ОМГ все из коробки simple_smile

razum2um14:12:27

@prepor: ну так @artemyarulin правильно заметил, “удалил” не должно быть, есть “отредактировал +deleted=1”

razum2um14:12:27

но, да нигде не видно, чего-то общего

razum2um14:12:16

и выступление Нолена кстати радует, чувствуется, что он туда смотрит и хочет гордиться передовым построением ui

prepor14:12:37

razum2um: в целом да. но при наличии единого транзактора crtd как то не особо в касу. ты и так можешь сообщить клиенту последнее валидное состояние и только оно будет валидным, не важно что там думает клиент

razum2um14:12:51

один транзактор не масштабируется, да и “забить на клиента и принудительно его сбрасывать” тоже не айс 😕

prepor14:12:48

не масштабируется, но се ля ви. к тому же распределенный эффективный транзактор тоже не фантастика

artemyarulin14:12:48

кстати пока гуглил нашел как метеор эту проблему “решил” - локальная транзакция апплаиться на локальный сторедж во фронте. Уходит запрос на сервак, приходит ответ от него - откатывается локальная транзакция и апплаиться уже данные с сервака ибо “сервак всегда прав”(с) Совсем не ах, зато из коробки

prepor14:12:15

и так, наверно, жить все же удобнее и понятнее чем в eventually consisten мире crtd-структур. но я хз

prepor14:12:22

artemyarulin: и это при том что у них понятия "транзакции" ж толком нет, так?

artemyarulin14:12:56

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

artemyarulin14:12:49

ну т.е. я просто про подход - пока гуглил просто наткнулся на “фсе фреймворки гавно и тока один метеор цветет ибо optimistic update везде и ничего не надо делать"

razum2um14:12:00

@artemyarulin: кстати, наши заюзали вот это https://github.com/gritzko/swarm

artemyarulin14:12:30

спасибо, посмотрю чо там внутрях