Fork me on GitHub
#clojure-russia
<
2016-02-04
>
asolovyov06:02:44

@artemyarulin: а зачем тебе это?

be906:02:04

@artemyarulin: то же самое хотел спросить. в чём цимес? почему не выкинуть всё и не сделать на каком-нибудь boot?

artemyarulin07:02:41

@asolovyov @be9: Так и знал что надо будет подготовить речь почему и зачем, не успел simple_smile Если коротко: 1) У меня много разных проектов, в том числе и мобильных - buck build | test ios-project android-project уже из коробки (это главная боль да) 2) Я его хочу на работу протащить - у нас языков с десяток, систем сборок еще больше - я не хочу думать, я хочу просто buck build hate-hate-but-go-project 3) Я хочу явные зависимости между разными языками - Clojure проект зависит от Java проекта, iOS проект зависит от JS проекта 4) Я хочу монорепо, одна билд система на весь репо, одна система сборки независимо от языка 5) Я хочу поменять один модуль, а потом не парясь запустить тесты для него и для всех модулей которыe от него зависят: git status -s | awk '{print $2'} | xargs -I {} buck query "owner('{}')” | buck audit dependencies | xargs buck test 6) Ну и самое главное я не хочу 3 проекта, 4 либы - я хочу 200 мелких независимых модулей (каждый с тестами и с со всеми зависимостями, чтоб можно было убержар собрать если надо даже) который я буду по жуткому реюзать во всех проектах Пример: Чтобы мне сейчас запустить новый микросервис мне нужно создать BUCK файл и файл с функцией обработчика сервиса:

clj_module(name = ‘ms22',
           src = ‘ms22.clj',
           main = ‘unity.service.ms22',
           modules = ['//lib/io/net/ws:pipe’]
docker_release(‘:ms22’)
далее бак за меня уже подтащит все зависимости, подтащит с десяток разных модулей которые поднимут aleph, добавят всякие нужные нам health-check, сбилдит убержар, создаст докер контейнер с этим жарником (docker_release это моя функция которую я могу переиспользовать опять же во всех проектах), задеплоит его в наш докер репо

artemyarulin07:02:57

и все это написано нами - я сейчас свой проект пишу для мобайл, там у меня для каждого om-next компонента (тоже только один файл) создается browser,android,ios версия, прогоняются тесты для всех из них, делаются скриншоты, обновляются доки

asolovyov07:02:58

оки-доки, в твоем примере есть смысл, убедил simple_smile

asolovyov07:02:28

я, правда "хочу просто build build whatever", заменяю на "если есть что запускать, оно должно запускаться make'ом"

asolovyov07:02:43

и тогда Makefile служит еще одновременно докой "а что тут интересного есть"

artemyarulin07:02:45

make тема, у нас половина на них

artemyarulin07:02:57

но он не умеет зависимости, в ручную я этого не хочу

asolovyov07:02:01

я даже не имею в виду, что собирать им надо, я часто его использую как запускалку

asolovyov07:02:11

для лейна, для бута, для джанги, для фласка, для всего

asolovyov07:02:26

когда ты клонируешь новый проект, makefile всегда точка входа и это норм спасает

artemyarulin07:02:29

ну вот, ты на 50% уже понял почему я хочу buck simple_smile

asolovyov07:02:32

а то между языками переключаться ужас

asolovyov07:02:41

та не, я полностью понял

asolovyov07:02:59

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

asolovyov07:02:25

я не понимаю почему, но кложурскриптовый read-string пытается #e0e8ef в {"background-color":"#e0e8ef"} прочитать как reader tag

asolovyov07:02:32

Could not find tag parser for e0e8ef

asolovyov07:02:39

и я реально охреневаю

asolovyov07:02:42

а почему - непонятно

asolovyov07:02:46

это ж строка, блин

artemyarulin07:02:28

reade-string вроде принимает еще параметры чтоб можно было указать какие кастомные парсеры он должен понимать

asolovyov07:02:48

но это не кастомный парсер

asolovyov07:02:51

это строка с цветом :)))

artemyarulin07:02:13

дада, я имею ввиду может дать ему пустой лист иль че еще

asolovyov07:02:36

та не, у меня там есть чо парсить

asolovyov07:02:39

он ваще вот так ругается:

asolovyov07:02:45

Uncaught Error: Could not find tag parser for e0e8ef in ("inst" "uuid" "queue" "js" "datascript/Datom" "datascript/DB" "route-map.core.Match")

asolovyov07:02:06

я не могу понять, что его внутрь строки заставляет глянуть...

asolovyov07:02:43

я тупица

asolovyov07:02:54

я ему данные подсунул как жсон, а читаю как edn

turtle07:02:05

Самокритично. simple_smile

artemyarulin08:02:56

на удивление нормальная статься про JS на хабре - https://habrahabr.ru/post/275729/#twenty-two продвигает функциональщину

artofshine09:02:32

Всем привет. Я новичок в clojurescript, подхожу к нему переодически и по немного стараюсь писать. В очередном подходе при решении задачи возник вопрос. Допустим у меня есть форма логина. На ней есть поле логин/пароль и три радиобатона, которые определяют маску ввода для поля логин. При написании компонента пользую Rum и ReactJS. У меня есть общий state в котором зафиксирован выбранный радиобаттон, это некоторая информация о типе пользователя. Соответвенно при выборе нового radiobutton я обновляю state -> перерисовка компонента. В результате поля логина/пароля на форме отчищаются, что логично с точки зрения ReactJS. Мне идея хранения логина/пароля в общем state и его обновление по on-change кажется сомнительной. Пока сделал некоторый дополнительный state рядом с компонентом. Но может есть у кого другие идеи?

artemyarulin09:02:45

@artofshine: Ни знаю ничо про Rum, но у react комонентов есть еще локал стейт

artemyarulin09:02:49

как раз для этого

artemyarulin09:02:19

ну и на самом деле не вижу ничо плохого все класть в стейт, прям 100% инфы о UI

rm09:02:05

народ, поясните за рекорды. Делаю defrecord, потом иду в репл. Из того неймспейса, где рекорд определен, его видно. А из другого нет

savelichalex09:02:06

для конкретно этой задачи лучше локал стэйт. для чего то больше лучше в общий

rm09:02:19

; 2. first require the namespace and then import ; the record as a regular class. clojuredocs поясняет

artofshine09:02:37

@artemyarulin @savelichalex локальный state существует до момент пока react не решит, что пора перерисовать компонент. То есть если у меня radiobutton перерисовывается после изменения глобального state, то в результате перевыбор radiobutton преведет к перерисовки компонента и как следствие потери local-state

artemyarulin09:02:35

чота ты наверно не то делаешь, локал стейт живет между рендерами

artemyarulin09:02:56

мы имеем ввиду this.state, а не просто “локальный стейт"

artofshine09:02:07

Да, я понял о чем речь. К примеру, я создаю в локальном state компонента некоторую переменную. После этого меняю значения props у компонента и случается re-render. Переменная в локальном state сохранит свое значение?

rm09:02:06

у меня еще вопрос. Я открываю сокет и через 30 секунд хочу, чтобы он закрылся. По идее, достаточно в соседнем треде написать примерно (sleep 30) (.close socket). Как открыть новый тред и передать туда сокет? Ну и надо еще тредсейф, чтобы в этот момент ничего не писалось туда

abtv09:02:55

Двухэтажные домики?

abtv09:02:13

За городом?

artemyarulin09:02:47

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

abtv09:02:29

У меня слишком скучный вид из окна - на проспект))

artemyarulin09:02:01

да покажь, интересно же - многие в других странах вообще, интересно все равно simple_smile

abtv09:02:34

когда окна чистые вид получше)

artemyarulin09:02:59

это столица? я забыл уже где ты там)

abtv09:02:20

Курск

kronos_vano09:02:30

симпатичный домик

kronos_vano09:02:33

который пониже

artemyarulin09:02:46

а точно, пазиков наверно в Москве, Питере уже нету simple_smile

abtv09:02:35

ага, пазиков много, а еще газелей)) их сейчас микроавтобусы (типа фордов вроде) вытесняют

rm09:02:38

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

artemyarulin10:02:18

колодцы, питер, ностальжи simple_smile

bluurn10:02:49

Привет, кложуряне!

Kira Sotnikov10:02:24

bluurn: привет!

savelichalex10:02:58

звучит как инопланетяне)

vltar10:02:25

Всем привет

vltar10:02:43

Посмотрел в окна, одна сплошная радость simple_smile

rm10:02:29

безысходненько

rm10:02:11

ща я добью таску и побью вас всех в безысходности

cookie10:02:54

Ого, у вас такие конференции проводятся. круто.

artemyarulin10:02:42

@nicola: уел всех да simple_smile

asolovyov11:02:33

ох блин... конвертнул все приложение в .cljc, и теперь при любом изменении клиентского tools.namespace говорит, что раз я его реквайрю во вьюхе, то у меня веб-сервер зависит от него и рестартует всю мою систему

asolovyov11:02:46

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

prepor11:02:59

asolovyov: в tools.namespace типа есть хуки которыми ему можно говорить в какие директории смотреть.

prepor11:02:17

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

asolovyov11:02:57

ну как-то поможет наверное

asolovyov11:02:24

ну в общем да, ща попробую

asolovyov11:02:27

а то ужас

asolovyov11:02:37

жаль, правда, оно ж тогда обновляться не будет 😄

asolovyov11:02:09

так и сделал, если файл внутри фронтэнда - просто не делаю релоад ))

kirillov11:02:00

Второй митап функциональных программистов в Москве. Поговорим про Erlang, Clojure, Scala и все, что с ними связано.

kirillov11:02:47

Будем очень рады, если вы придете и конечно же ждем предложений выступить 😉

kirillov11:02:15

По всем вопросам пишите Лене (ее email на странице)

Kira Sotnikov11:02:18

а таймпад бесплатный?

kirillov12:02:09

там есть бесплатные фичи, которых вполне хватает)

kirillov12:02:19

@prepor: айда выступать?

kirillov12:02:45

помню мы тебя подначивали на RailsClub )))

kirillov12:02:48

и ты обещал подумать)

prepor12:02:57

@kirillov: я подумал-подумал и мне таки нечего сказать, за что стыдно не было бы )

kirillov12:02:39

тебе надо самомнение повышать!

cookie12:02:53

а видео доклад будет? Ну скажет прямая трансляция или что-то подобное.

kirillov12:02:58

просто говори. Выйдешь и начинай вещать! Уверяю, никто не заметит что ты не готовился)

kirillov12:02:26

думаю, Рамблер сделает и трансляцию и запись. Как это с Ruby митапом было

kronos_vano12:02:32

@prepor: расскажи про ocaml

kirillov12:02:34

мы их обязательно попросим)

kirillov12:02:00

давайте все вместе уговорим @prepor выступить? 😉

prepor12:02:16

не вгоняй меня в краску, а? )

prepor12:02:36

@kronos_vano: тут тоже мне нечего поведать миру пока )

Kira Sotnikov12:02:54

3 марта 😞

fxposter14:02:59

> fxposter: никакого context в ринге нет > https://github.com/mmcgrana/ring/blob/master/SPEC @prepor: в спеке может и нет, а в коде есть https://ring-clojure.github.io/ring/ring.util.request.html#var-set-context

prepor14:02:42

fxposter: ну так надо говорить какой код вы используете, как нам угадать-то? )

fxposter14:02:02

там после моего вопроса эта самая ссылка сразу почти проскочила simple_smile

fxposter14:02:01

да, и еще вопрос - кто-нибудь сталкивался с задачей получения “текущего порта, на который пришел запрос” в ринге при условии, что вы юзаете несколько коннекторов? simple_smile

fxposter14:02:16

это какой-то ад

fxposter14:02:51

; HACK to add ability to dispatch based on local port
(in-ns 'ring.util.servlet)
(let [old-fn build-request-map]
  (defn build-request-map [^HttpServletRequest request]
    (let [old-result (old-fn request)]
      (assoc old-result :local-port (.getLocalPort request)))))
приходится писать такое (напоминает о старом добром руби), но мне это не нравится

prepor15:02:41

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

fxposter15:02:48

и я на 99% процентов уверен, что direct linking мне это все поломает

prepor15:02:39

что такое direct linking?

fxposter15:02:00

> ну добавить разный мидлварь прокидывающий код при старте каждого коннектора и все а я не нашел куда. и вообще сомневаюсь что это возможно без манкипатчинга.

rm15:02:18

fxposter: а в чем проблема? Если эта информация есть в реквесте, то что тебе помешает добавить нужный миддлварь, который ее достанет?

fxposter15:02:27

ее НЕТ

fxposter15:02:33

в реквесте этого нет вообще

prepor15:02:34

ну как нет то

prepor15:02:38

как стартуется аппа?

prepor15:02:41

как старутется сервер?

prepor15:02:46

когда порт передается?

fxposter15:02:12

если вы посмотрите спеку - то внутри map-а есть только одно поле, относящееся к порту

fxposter15:02:16

это :server-port

fxposter15:02:33

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

prepor15:02:36

ну вот в run-jetty передается хандлер

fxposter15:02:49

а в хендлер передается map-а

fxposter15:02:54

в которой ничего нет

prepor15:02:57

оберните хандлер в мидлваре передающий порт

fxposter15:02:11

вопрос не в этом

fxposter15:02:20

у меня есть 2 типа API

fxposter15:02:24

внутреннее и внешнее

fxposter15:02:30

они доступны на разных портах

prepor15:02:37

(run-jetty (fn [r] (my-app (assoc r ::local-port 700)) {:port 7000})

fxposter15:02:51

и хотелось бы не стартовать 2 раза jetty

fxposter15:02:02

а обойтись одним сервером и 2 коннекторами

fxposter15:02:07

а потом диспатчить по порту

fxposter15:02:20

потому как не хочется скейлить эти апи отдельно

prepor15:02:24

что такое "коннектор тогда"?

fxposter15:02:50

org.eclipse.jetty.server ServerConnector

prepor15:02:09

сервлетчина какая-то )

fxposter15:02:12

их очень проблематично создавать руками simple_smile

prepor15:02:18

чем это отличается от "пусть два раза джетти"?

fxposter15:02:25

именно, и на этом базируется ring.jetty.adapter

fxposter15:02:50

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

fxposter15:02:29

в противном случае - у тебя просто в 2 раза больше тредов (и памяти тоже немного больше) и нельзя “забрать треды с внутреннего апи и отдать внешнему"

prepor15:02:35

точно один тредпул?

fxposter15:02:57

(defn- ^Server create-server [options]
  (let [server (Server. (create-threadpool options))]
    (.addConnector server (http-connector server options))
    (when (or (options :ssl?) (options :ssl-port))
      (.addConnector server (ssl-connector server options)))
    server))

fxposter15:02:52

вообще мне этот ring и дефолтные адаптеры какими-то уж очень ограниченными кажутся

fxposter15:02:31

чтобы добавить свой коннектор (не ssl) - нужно тоже постараться simple_smile

fxposter15:02:44

я не смотрел на всякие httpkit-ы и прочее, но jetty-адаптер рассчитан на использование вида “юзайте так или умрите"

prepor15:02:57

ну там кода-то

fxposter15:02:09

да, можно перенести себе, но как-то не ок simple_smile

prepor15:02:14

очень ок

prepor15:02:18

ваще норм

prepor15:02:24

это хелперы

fxposter15:02:56

ситуация усложняется еще тем, что я решил юзать component

prepor15:02:59

если нужно что-то подправить и не удовлетворяют те что есть абсолютно нормально взять и написать 50 строк у себя, даже если 45 из них будут повторять эти хелперы

fxposter15:02:04

и нашел ring.component.jetty

prepor15:02:19

не нужно ничего находить

fxposter15:02:23

который жестко зависит от jetty.adapter simple_smile

prepor15:02:29

компонент впихивается в одной строчкой

fxposter15:02:34

и в итоге если мне копировать - то копировать все simple_smile

prepor15:02:48

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

prepor15:02:58

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

prepor15:02:10

все это займет 50 строк кода и полчаса времени

prepor15:02:22

меньше чем копаться в особенностях всех этих зависимостей

prepor15:02:05

кложа простая как пять копеек, что бы добавить ::local-port и ::component в каждый свой хандлер нужно совсем немного усилий и ничего не поломается

prepor15:02:13

юз ит )

fxposter15:02:52

а как же “code reuse” simple_smile как же “возможность упустить что-то очень важное, что уже учтено в библиотеках"

prepor15:02:13

fxposter: это — не билиотеки, это просто набор хелперов

prepor15:02:15

оберток

prepor15:02:54

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

fxposter15:02:54

просто ты берешь кложурку, потому что тебе нужно процессить данные и юзать zookeeper и думаешь что “щас вот все быстренько скомпоную”, а в итоге оказывается что собственно полезного кода - половина. остальное - это вот подобные “скопированные” зависимости, которые теперь нужно поддерживать тебе simple_smile

fxposter15:02:18

я вот сейчас попробовал юзать https://github.com/stuartsierra/component

fxposter15:02:27

еще добавил себе проблем simple_smile

prepor15:02:56

да нет особых проблем ) кложа - хостед язык. если хочется запускать джетти, то запускать джетти нужно запуская джетти, никто не пытается городить гигантские абстракции для этого

prepor15:02:59

в этом как раз поинт

fxposter15:02:06

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

larhat15:02:12

mount на вид получше компонента

larhat15:02:29

(а если компонент, то у @prepor'а есть в гитхабе хелперы)

prepor15:02:35

mount из репла, конечно, поприятнее, но я таки считаю принципиально неправильным

fxposter15:02:36

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

larhat15:02:39

сам компонент конечно многословный достаточно

larhat15:02:14

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

fxposter15:02:56

шаринг структуры все равно будет присутствовать simple_smile

prepor15:02:01

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

prepor15:02:05

как-то так )

larhat15:02:17

"типа рельс" в кложе не принято, принято из либок собирать больше

larhat15:02:25

про один файлик норм совет

fxposter15:02:37

> когда придет понимание какие барьеры абстракции и модули тут есть, тогда можно и разбивать это хорошо для тебя. но не для того, кто возможно прийдет разбираться с этим после тебя simple_smile

prepor15:02:57

> шаринг структуры все равно будет присутствовать simple_smile маунт не отрицает шаринг структур, он как раз про это

fxposter15:02:18

> "типа рельс" в кложе не принято, принято из либок собирать больше это я уже слышал, но это не значит что нельзя сделать “набор советов”, которым можно не следовать, если не хочется simple_smile

fxposter15:02:53

маунт я пока не видел )

fxposter15:02:00

посмотрю, спасибо

prepor15:02:00

> это хорошо для тебя. но не для того, кто возможно прийдет разбираться с этим после тебя simple_smile это не значит говнокодить. я просто говорю что не стоит пытаться повторить иерархии рельсы или спринга для приложения в 500 строк

larhat15:02:17

например

larhat15:02:21

lein new ...

prepor15:02:29

> посмотрю, спасибо ну я то как раз сказал, что мне кажется он принципиально неправильным )

larhat15:02:29

если "как рельсы" скафолдинга охота

fxposter15:02:30

оно маленькое simple_smile

fxposter15:02:58

@prepor: но ты же не будешь отрицать, что то что у рельсов “стандартная” структура все же помогает вливаться в проект?

larhat15:02:16

предментная область обычное больше значения имеет

larhat15:02:23

а язык/фреймворк по сравнению с этим — ерунда

fxposter15:02:44

мне в итоге пришлось сгенерировать 2 шаблона - один из компожуры, второй из конпонента, а потом их руками “мержить"

prepor15:02:46

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

fxposter15:02:21

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

fxposter15:02:26

routes -> controller -> model

prepor15:02:28

т.е. вся "структура", которую предлагает рельса это "код хуярить в models, а вот роуты у вас будут в config/routes.rb". спасибо, помогли

fxposter15:02:51

ну ИМХО - это все же полезно simple_smile

fxposter15:02:20

потому что в противном случае - “я вот делаю запрос сюда”, а куда он доходит и через какие дебри вообще непонятно

fxposter15:02:05

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

larhat15:02:11

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

larhat15:02:24

ссылку на simple made easy надо вверх

fxposter15:02:31

про simple made easy можно не вспоминать

larhat15:02:50

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

fxposter15:02:11

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

fxposter15:02:22

по крайней мере до какой-то степени

rm15:02:59

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

fxposter15:02:04

но почему-то все хотят велосипеды simple_smile

fxposter15:02:34

@rm: если не думать - везде будет плохо

fxposter15:02:42

и неважно на кложуре ты пишешь или нет

fxposter15:02:03

у меня таких проблем с рельсами не было simple_smile

rm15:02:10

ишь ты

rm15:02:24

но вообще, это странно. Обычно у тебя где-нибудь, да пиздец. Или контроллеры, или модели, или хренова гора сервис-объектов

fxposter15:02:04

да, но подобное скорее всего будет и в compojure-honeysql-что-нибудь-еще simple_smile

larhat15:02:26

ну раз будет, то можт рельсы тогда?

larhat15:02:35

там можно жруби взять, если жвм нужен

fxposter15:02:55

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

rm15:02:05

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

turtle15:02:32

Потом кложурное на что-нибудь заменишь. simple_smile

rm15:02:57

да, потому что so hot right now

fxposter15:02:59

jruby как-то у нас совсем не прижился simple_smile

rm15:02:08

я же из-за этого стал переписывать

fxposter15:02:13

точнее он даже и не пытался приживаться

niquola15:02:03

Скоро можно будет clojure в postgres! Альваро пишет правильную pg/java без jdbc и напрямую через внутренний api postgresql ;)

prepor15:02:03

> Скоро можно будет clojure в postgres! Альваро пишет правильную pg/java без jdbc и напрямую через внутренний api postgresql ;) чем это хорошо? будет асинхронный интерфейс? оно вроде уже есть

larhat15:02:52

@yogthos: лучше чем что?

yogthos15:02:01

compojure-template

larhat15:02:18

а, чем?

larhat15:02:23

если рельсы хочется?

larhat15:02:25

ну наверное

yogthos15:02:54

it’s up to date, and batteries included

dottedmag15:02:17

@prepor: А расскажи, чем mount отличается от defcomponent?

prepor15:02:09

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

prepor15:02:26

mount же перегружает вары

prepor15:02:52

я кстати не знаю как mount будет работать в 1.8 с дайрект линкингом и будет ли

dottedmag15:02:56

А, понятно.

prepor15:02:34

вот тут должно сломаться

niquola15:02:49

@prepor будет и асинхронный

tolitius15:02:10

@prepor: пока не ломается simple_smile и это "перегрузка" варов optional, если маунт использовать в cljc-mode, то вары отдыхают: https://github.com/tolitius/mount/blob/master/src/mount/core.cljc#L74

prepor16:02:55

А объяснишь как это работает?

prepor16:02:03

Т.е. вот в варе у меня будет DerefableState ?

prepor16:02:24

И вместо db/state мне нужно будет использовать @db/state?

prepor16:02:10

tolitius: ба, так это ж автор, привет )

prepor16:02:01

> пока не ломается не ломается при компиляции с directlinking и перебиндингов варов?

tolitius16:02:38

даров simple_smile > db/state мне нужно будет использовать @db/state ага, cljc-mode (i.e. DerefableState) я сначала сделал для ClojureScript support, так как в ClojureScript, unless Bootstrap, Clojure namespace APIs в нефаворе, так как :advanced все мешает и кидает в глобальную кучу. В этом моде и Clojure и ClojureScript API / usage are consistent. И в принципе мне нравится @ что то за чем подразумевается state. https://github.com/tolitius/mount/blob/master/doc/clojurescript.md#managing-state-in-clojurescript > не ломается при компиляции с directlinking и перебиндингов варов? это новьЙо я еще не пробовал, и by default, "дирекнут" только кложуровский core., и концептуально (если и будут проблеммы), DerefableState approach should still work, хотя конечно, я согласен, надо подумать. Но эт нормальная эволюция либов с языком. А ну и если че есть Юрта: https://github.com/tolitius/yurt simple_smile

prepor16:02:22

с DerefableState да, должно работать

prepor16:02:05

> tolitius/yurt нейминг ок )

tolitius16:02:45

сложно клипарт подобрать тока, Юрт векторных не так много )

prepor16:02:20

> Usually a test Yurt would be started with a different configuration so, for example, dev and test HTTP server components can run simultaneously on different ports. вот это не вдуплил не заглядывая в код. ведь state он один, и если через start-* запустить опять, то все компоненты будут смотреть в один и тот же стейт, разве нет?

tolitius16:02:59

зачем это все: http://www.dotkam.com/2016/01/31/yurt-mounts-local-real-estate/ не, смотри, мы просто используем вары для blueprint'a (i.e. чертежа), а реальная "система" is detached

tolitius16:02:09

то есть она реально локальна

prepor16:02:30

хех, забавно, окей, посмотрю, спасибо

tolitius16:02:51

вары ресетаются в NotStartedState, и могут опять быть "грязно использованы"

prepor16:02:13

ну я кажется понял в чем прикол

prepor16:02:27

вар просто как ссылка на стейт используется

prepor16:02:37

стейт можно копирнуть при старте системы

prepor16:02:02

ок, посмотрю / почитаю сначала )

tolitius16:02:07

ага, просто чтоб dependencies и прочее у компилятора позаимствовать

tolitius16:02:38

да, система стартуется и сразу детачается

prepor16:02:47

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

tolitius16:02:58

запоминая все :stop функции в себе

tolitius16:02:39

да согласен, мне кажется очень рабочая и простая идея

prepor16:02:48

смотри почему мне нравится эксплицитность, может быть есть какие-то идеи на этот счет: - очень часто я использую следующий "трюк": любая функция работающая с постгрей принимает db в какой-то форме. на вызывающей стороне я могу подсунуть функции или прям компонент db или объект транзакции (with-db-transaction и т.д.) И это будет замечательно работать и на всей кодобазе - тоже касается и других компонентов, например клиентов в сервисы. при принятии запроса я формирую контекст запроса, содержащий айдишник запроса и подмешиваю этот контекст в клиенты. Клиент при отправке запроса видит этот контекст и подмешивает его в запрос. Так реализуется трейсинг, контекст автоматически пробрасывается по всей цепочке вызовов, включая любую асинхронщину

prepor16:02:16

при этом введение этого "контекста" не меняет ни единой строчки кода

prepor16:02:28

думаю, маунт фундаментально с этим не согласовывается, да?

tolitius16:02:03

ща погоди, дай переварить )

tolitius16:02:06

мне кажется мы говорит о разных "эксплицитностях"

artofshine16:02:57

А проблему с портом в итоге решили?

artofshine16:02:16

Мне идея разделять права доступа к API через порт кажется немного странной. Если учитывать, что сервер может находится за 2-3 натами.

tolitius16:02:52

ты точно так же можешь передавать и подмешивать с mount'ом. все будет зависеть от дезайна, в частности "где" начало системы и "откуда" передаются компоненты. ведь ты точно так можешь большенство функций оставить stateless, и передавать туда компоненты так же точно как они передаются в "component" "эксплиситность" определения dependencies (без которой "component" не может), эт немного другая "эксплистность", и есть несколько мыслей на этот счет: https://github.com/tolitius/mount/issues/48 и https://github.com/tolitius/mount/issues/12#issuecomment-167150505 то есть мне кажется полезно to visualize the dependency graph, и только иногда полезно его указывать руками

prepor16:02:17

> точно так можешь большенство функций оставить stateless, и передавать туда компоненты так же точно как они передаются в "component" но это же противоречит "фишке" маунта нет? мне тогда руками надо создавать "систему" и потом разделять ее на наборы компонентов для передачи функциям?

prepor16:02:11

я согласен что эксплицитность определения зависимостей решается тулингом, если я просто могу вызвать у маунта "от чего зависит этот неймспейс", то это уже ок

prepor16:02:05

ну т.е. вот у меня код делал (widget/find-vesion widget ...) и всегда требовал передачи этого widget парамертром в функцию. подобных вызовов сотни по коду. сейчас у меня появилась фича сделать контекст для трейсинга и все остается как было. если бы у меня был маунт я ведь не удержался бы от того что бы не сделать "хелпер" с (widget/find-vesion ...)? )

prepor16:02:35

полтора года мне не нужно было ничего в эти клиенты подмешивать, с чего вдруг пришлось бы? )

tolitius16:02:04

"фишка" есть, и она в том что "догма bad, pragmatism гуд" simple_smile то есть можно и нужно использовать так как того требует дезайн, желание, задача. руками кстати ничего создавать не надо, у тебя может быть какой нить namespace у которого через просто несколько :requireс будет доступ ко всем компонентам, и оттуда ты можешь "чэйнать" их в app. но опять же это выбор

prepor16:02:26

да я понимаю. то как юрта использует маунт уменьшило у него минусов )

tolitius16:02:41

"не удержался бы": да, я понимаю к чему ты, но ведь единственное лекарство от "не удержался бы" это опыт )

prepor16:02:43

окей, спасибо за ответы!

tolitius16:02:25

на самом деле Юрта для Джеймса Риверса (a.k.a. compojure), который сказал что прям щаз будет использовать маунт если я ему покажу как использовать компоненты локально. но пару людей уже че т с ней делают.. Юрта молода, так что посмотрим

tolitius16:02:56

да, конечно. если есть идеи, критика always welcome simple_smile

kronos_vano17:02:11

Кто нить пользует SQS ?

larhat17:02:27

не из кложи

artemyarulin18:02:53

смотрите, я хочу сделать 2 макроса:

(provides :a)
(wants :a)
все ок, но я хочу чтобы макрос кидал ошибку когда wants вызывается для не существующего provides:
(provides :a_typo)
(wants :a) ;; Exception, :a wasn't provided
Внимание вопрос: Как это сделать если я хочу иметь возможность использовать макрос в любом порядке?
(wants :a)
(wants :b)
(provides :a)
(provides :b)
;; ok
(wants :c) ;; Exception
Есть ли у макросов фаза когда уже все макрос раскрылись?

artemyarulin18:02:38

хотя неа. Не уверен в общем, жду комментариев

prepor19:02:42

никак

prepor19:02:53

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

prepor19:02:41

точно так же как ты не можешь использовать еще не объявленную функцию. или иметь циклические зависимости неймспейсов

prepor19:02:59

и это почти всегда хорошо. скорее всего у тебя проблемы с дизайном

misha19:02:24

ну макроэкспанд ≠ вызов функции жеж

misha19:02:48

так что я думаю должно быть возможным такое нахачить

artemyarulin19:02:07

хм, да тут prepor наверно прав - что я наверно не туда капаю

misha19:02:04

а кто аргумент макры? всё, что угодно? примитивы всякие, да?

artemyarulin19:02:43

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

misha19:02:45

может обыграть атомы с валидаторами и листенерами?

misha19:02:20

попахивает статик тайпингом kappa

artemyarulin19:02:45

После прочтения http://web.stanford.edu/~ouster/cgi-bin/papers/rules-atc15 очень захотелось реализовать и попробовать вот такое на кложуре (это без макросов):

(def state (atom {:a 0}))

(while-not (:end @state))
   (when (:c @state) (swap! state assoc :end)
   (when (and (:a @state) (:b @state)) (do (work2) (swap! state assoc :c 3))
   (when (:a @state) (do (work1) (swap! state assoc :b 2))
По сути конечный автомат, тока на месте стейта мапа. Каждый шаг автомата зависит от N ключей и может создать другие M ключей. Хочется на этапе компиляции получить ошибку если существует такая последовательность шагов автомата которая не приведет к результату. В данном примере если первый when будет забыт. Т.е. при таком коде конечно ничо не сделать, но вот думаю как это переписать на макросы чтоб это стало возможно

artemyarulin19:02:29

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

misha19:02:14

анализировать сорс. это ж лисп ; )

misha19:02:19

и дочитать little prover, там про доказательства валидиности кода как раз

artemyarulin19:02:02

хм, о, надо почитать да

misha19:02:31

что из этого "апи", а что "имплементация"?

artemyarulin19:02:11

эм, может плохо описал - вот пример на питончике из этой пдф https://github.com/PlatformLab/mappy/blob/master/job.py#L24-L65

misha19:02:13

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

artemyarulin19:02:01

в примере видно что куча if/else - я хочу чтоб хотяб чутка проверок было что я ничего совсем банального не забыл

misha19:02:56

это вот applyRules как часто писать надо?

misha19:02:47

один? типа функция, которая принимает машину, и валидируемую функцию, и, собственно, валидирует ее?

misha19:02:05

или это описание стейта?

misha19:02:23

или в питоне это описание стейта + валидация вкучу?

artemyarulin19:02:21

я наверно слишком много инфы дал, давай попроще: У меня есть стейт машина, есть 3 правила a -> b b -> c c -> :finish я хочу валидировать что все переходы обработаны и что стейт машина не будет в состоянии дедлока (т.е. не будет такого правила которая она не знает как обработать)

artemyarulin19:02:04

т.е. если убрать b->c я хочу получить ошибку что хз как обработать цепочку a->b дальше

misha19:02:18

а, тебе саму стейт машину валидировать на полноту

artemyarulin19:02:58

>валидировать на полноту во, правильное слово

artemyarulin19:02:31

мне куда копать? чего в гугле вводить хоть?

artemyarulin19:02:03

построить граф и посмотреть что для всех точек есть путь до :finish?

misha19:02:09

что-то такое знакомое. типа logic programming и тд

turtle19:02:18

Тему не читал, https://github.com/cdorrat/reduce-fsm это не подойдёт?

misha19:02:21

совсем недавно видел готовое 1в1

artemyarulin19:02:28

думал о нем, оно вроде как раз для этого

misha19:02:36

тоже эту 2 мины назад открыл

turtle19:02:46

Я пользовал её.

turtle19:02:58

У неё есть глюк при комплияции в aot, в остальном норм.

turtle19:02:10

А вообще, aot зло.

artemyarulin19:02:09

хм, стейт машина она всеж деревянная как я понимаю. А я хочу правила чутка посложнее типа a & b -> c a & !b -> z или такое тоже поддерживается?

misha19:02:00

The miniKanren folks are working on two new constraints presento and absento. One interesting thing that has come up in the discussions about their semantics is whether miniKanren (and of course core.logic) should produce answers if there is no possibility of satisifying the constraints.

artemyarulin19:02:01

да, я понимаю что это задача как раз для логического программирования, но может что полегче есть

artemyarulin19:02:15

@misha: А ты пробовал core.logic сам?

misha19:02:24

нет еще

misha19:02:31

на даталоге напиши )

misha19:02:00

и в датаскрипт положи, и запросами валидируй

artemyarulin19:02:19

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

misha19:02:25

задача, вообще, интересная

misha19:02:36

а где тебе стейт машина нужна вообще?

misha19:02:16

а то одно дело валидировать словарик, и немного другое - 700 строк сорскода.

rm19:02:22

есть же алгоритм Дейкстры для обхода графа (типа наименьшего пути). Можно его приспособить для нахождения связей. Там нет рокет саенса, просто если был в вершине, ее надо помечать. Если граф не связан, то после обхода останутся непомеченные вершины

misha20:02:23

(def demo-graph {:red    {:green 10, :blue   5, :orange 8},
                 :green  {:red 10,   :blue   3},
                 :blue   {:green 3,  :red    5, :purple 7},
                 :purple {:blue 7,   :orange 2},
                 :orange {:purple 2, :red    2}})

(prn (dijkstra demo-graph :red))
=>> {:red 0, :green 8, :blue 5, :purple 10, :orange 8}

misha20:02:47

собственно

rm20:02:52

пока я писал буквами, Миша накодил

rm20:02:54

офигеть

misha20:02:58

нагуглил

rm20:02:04

аа :)

misha20:02:10

кодреюз!

artemyarulin20:02:28

хм, я вот думал про графы. А в графах можно выразить что а -> b b -> c b+c -> z т.е. что z доступен только когда оба b+c достигнуты

misha20:02:35

а как может быть просто "с"? если а - старт

artemyarulin20:02:59

тьфу, сорри

artemyarulin20:02:21

a->b c->d b+d -> z

misha20:02:09

а как получить а и с? simple_smile

artemyarulin20:02:10

[] -> a [] -> c

artemyarulin20:02:29

ну т.е. есть какое-то начальное значение 0 из которого уже выходят другие значения

artemyarulin20:02:06

или вот тоже пример в голову пришел a->b только когда НЕ с. Это же графами уже не выразить?

artemyarulin20:02:14

или есть чото специальное для такого?

misha20:02:48

такое можно на кор-асинке намонстрить каналами

misha20:02:28

но чем дальше, тем core.logic больше подходит

misha20:02:09

либо на ифах kappa

artemyarulin20:02:21

дак я как раз от ифов и хочу уйти simple_smile

misha20:02:15

cond + test.check

misha20:02:45

ставишь :else и тестируешь на недостижимость

artemyarulin20:02:04

да, вариант тоже кстати. Но это решать проблему брутфорсом, как-то не спортивно

misha20:02:09

или prismatic.schema, что там с генераторами

misha20:02:37

ну тебе же отвалидировать код раз? или это динамические стейт машины?

artemyarulin20:02:51

дада, на раз валидация

misha20:02:41

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

artemyarulin20:02:01

ок, согласен на решение второй проблемы 😄

misha20:02:16

или у Нолена спроси, может он минут за 5 тебе всё решит )

artemyarulin20:02:40

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

artemyarulin20:02:24

надо переспать с проблемой, авось на утро чо придет в голову. Хотя core.logic да, походу как раз под эту задачу