This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-02-04
Channels
- # aatree (5)
- # admin-announcements (37)
- # alda (1)
- # announcements (4)
- # architecture (1)
- # aws (3)
- # beginners (82)
- # boot (230)
- # braid-chat (14)
- # cider (48)
- # cljs-dev (8)
- # cljsrn (31)
- # clojars (47)
- # clojure (72)
- # clojure-austin (2)
- # clojure-russia (396)
- # clojurescript (72)
- # community-development (3)
- # component (6)
- # core-async (6)
- # cursive (26)
- # datomic (42)
- # emacs (6)
- # events (35)
- # hoplon (57)
- # immutant (3)
- # jobs (2)
- # jobs-discuss (10)
- # ldnclj (16)
- # luminus (2)
- # off-topic (50)
- # om (181)
- # parinfer (285)
- # proton (68)
- # re-frame (19)
- # reagent (2)
- # ring-swagger (23)
- # yada (36)
@artemyarulin: а зачем тебе это?
@artemyarulin: то же самое хотел спросить. в чём цимес? почему не выкинуть всё и не сделать на каком-нибудь boot?
@asolovyov @be9: Так и знал что надо будет подготовить речь почему и зачем, не успел
Если коротко:
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 это моя функция которую я могу переиспользовать опять же во всех проектах), задеплоит его в наш докер репои все это написано нами - я сейчас свой проект пишу для мобайл, там у меня для каждого om-next компонента (тоже только один файл) создается browser,android,ios версия, прогоняются тесты для всех из них, делаются скриншоты, обновляются доки
я, правда "хочу просто build build whatever", заменяю на "если есть что запускать, оно должно запускаться make'ом"
make тема, у нас половина на них
но он не умеет зависимости, в ручную я этого не хочу
ну вот, ты на 50% уже понял почему я хочу buck
я не понимаю почему, но кложурскриптовый read-string пытается #e0e8ef
в {"background-color":"#e0e8ef"}
прочитать как reader tag
reade-string вроде принимает еще параметры чтоб можно было указать какие кастомные парсеры он должен понимать
дада, я имею ввиду может дать ему пустой лист иль че еще
Uncaught Error: Could not find tag parser for e0e8ef in ("inst" "uuid" "queue" "js" "datascript/Datom" "datascript/DB" "route-map.core.Match")
на удивление нормальная статься про JS на хабре - https://habrahabr.ru/post/275729/#twenty-two продвигает функциональщину
Всем привет. Я новичок в clojurescript, подхожу к нему переодически и по немного стараюсь писать. В очередном подходе при решении задачи возник вопрос. Допустим у меня есть форма логина. На ней есть поле логин/пароль и три радиобатона, которые определяют маску ввода для поля логин. При написании компонента пользую Rum и ReactJS. У меня есть общий state в котором зафиксирован выбранный радиобаттон, это некоторая информация о типе пользователя. Соответвенно при выборе нового radiobutton я обновляю state -> перерисовка компонента. В результате поля логина/пароля на форме отчищаются, что логично с точки зрения ReactJS. Мне идея хранения логина/пароля в общем state и его обновление по on-change кажется сомнительной. Пока сделал некоторый дополнительный state рядом с компонентом. Но может есть у кого другие идеи?
@artofshine: Ни знаю ничо про Rum, но у react комонентов есть еще локал стейт
как раз для этого
ну и на самом деле не вижу ничо плохого все класть в стейт, прям 100% инфы о UI
народ, поясните за рекорды. Делаю defrecord, потом иду в репл. Из того неймспейса, где рекорд определен, его видно. А из другого нет
для конкретно этой задачи лучше локал стэйт. для чего то больше лучше в общий
; 2. first require the namespace and then import ; the record as a regular class. clojuredocs поясняет
@artemyarulin @savelichalex локальный state существует до момент пока react не решит, что пора перерисовать компонент. То есть если у меня radiobutton перерисовывается после изменения глобального state, то в результате перевыбор radiobutton преведет к перерисовки компонента и как следствие потери local-state
@artofshine: уверен?
чота ты наверно не то делаешь, локал стейт живет между рендерами
мы имеем ввиду this.state, а не просто “локальный стейт"
Да, я понял о чем речь. К примеру, я создаю в локальном state компонента некоторую переменную. После этого меняю значения props у компонента и случается re-render. Переменная в локальном state сохранит свое значение?
у меня еще вопрос. Я открываю сокет и через 30 секунд хочу, чтобы он закрылся. По идее, достаточно в соседнем треде написать примерно (sleep 30) (.close socket). Как открыть новый тред и передать туда сокет? Ну и надо еще тредсейф, чтобы в этот момент ничего не писалось туда
ога, ога. Мы тут вчера затеили жуткий оффтоп и постим фотки из окна, присоеденяйтесь
да покажь, интересно же - многие в других странах вообще, интересно все равно
это столица? я забыл уже где ты там)
симпатичный домик
который пониже
а точно, пазиков наверно в Москве, Питере уже нету
ага, пазиков много, а еще газелей)) их сейчас микроавтобусы (типа фордов вроде) вытесняют
а у меня из окна виден мой же балкон. А через балкон ничего не видно, потому что стекла запотели
колодцы, питер, ностальжи
bluurn: привет!
звучит как инопланетяне)
@nicola: уел всех да
ох блин... конвертнул все приложение в .cljc, и теперь при любом изменении клиентского tools.namespace говорит, что раз я его реквайрю во вьюхе, то у меня веб-сервер зависит от него и рестартует всю мою систему
asolovyov: в tools.namespace типа есть хуки которыми ему можно говорить в какие директории смотреть.
Второй митап функциональных программистов в Москве. Поговорим про Erlang, Clojure, Scala и все, что с ними связано.
а таймпад бесплатный?
просто говори. Выйдешь и начинай вещать! Уверяю, никто не заметит что ты не готовился)
@prepor: расскажи про ocaml
@kronos_vano: тут тоже мне нечего поведать миру пока )
3 марта 😞
> fxposter: никакого context в ринге нет > https://github.com/mmcgrana/ring/blob/master/SPEC @prepor: в спеке может и нет, а в коде есть https://ring-clojure.github.io/ring/ring.util.request.html#var-set-context
да, и еще вопрос - кто-нибудь сталкивался с задачей получения “текущего порта, на который пришел запрос” в ринге при условии, что вы юзаете несколько коннекторов?
; 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)))))
приходится писать такое (напоминает о старом добром руби), но мне это не нравится> ну добавить разный мидлварь прокидывающий код при старте каждого коннектора и все а я не нашел куда. и вообще сомневаюсь что это возможно без манкипатчинга.
fxposter: а в чем проблема? Если эта информация есть в реквесте, то что тебе помешает добавить нужный миддлварь, который ее достанет?
если вы посмотрите спеку - то внутри map-а есть только одно поле, относящееся к порту
в противном случае - у тебя просто в 2 раза больше тредов (и памяти тоже немного больше) и нельзя “забрать треды с внутреннего апи и отдать внешнему"
(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))
я не смотрел на всякие httpkit-ы и прочее, но jetty-адаптер рассчитан на использование вида “юзайте так или умрите"
если нужно что-то подправить и не удовлетворяют те что есть абсолютно нормально взять и написать 50 строк у себя, даже если 45 из них будут повторять эти хелперы
кложа простая как пять копеек, что бы добавить ::local-port и ::component в каждый свой хандлер нужно совсем немного усилий и ничего не поломается
а как же “code reuse” как же “возможность упустить что-то очень важное, что уже учтено в библиотеках"
https://github.com/ring-clojure/ring/blob/5eb93b63f1676cac26121a92c50a39e14e38edac/ring-jetty-adapter/src/ring/adapter/jetty.clj тут 30 строк полезного кода )
которые можно заюзать, если они вам походят — если нет, ну и хрен с ними. код реюзом точно также не надо злоупотреблять )
просто ты берешь кложурку, потому что тебе нужно процессить данные и юзать zookeeper и думаешь что “щас вот все быстренько скомпоную”, а в итоге оказывается что собственно полезного кода - половина. остальное - это вот подобные “скопированные” зависимости, которые теперь нужно поддерживать тебе
я вот сейчас попробовал юзать https://github.com/stuartsierra/component
да нет особых проблем ) кложа - хостед язык. если хочется запускать джетти, то запускать джетти нужно запуская джетти, никто не пытается городить гигантские абстракции для этого
кстати, а существуют вообще какие-то высокоуровневые примеры того, как приложения строить на кложуре. т.е. что-то типа rails, но не в плане кода, а в плане гайдлайнов - что-куда совать
ибо рельсы несмотря на то, что их все ругают все же дают очень стройный базовый каркас
ну сравнивать производство однотипных сайтов и чуть более уникальных продуктов не стоит, наверное
> ибо рельсы несмотря на то, что их все ругают все же дают очень стройный базовый каркас никаких особых гайдов нет, но я бы и не начинал небольшое приложение с "продуманной структуры директорий". херачить в один файлик что б работало и норм. когда придет понимание какие барьеры абстракции и модули тут есть, тогда можно и разбивать
> когда придет понимание какие барьеры абстракции и модули тут есть, тогда можно и разбивать это хорошо для тебя. но не для того, кто возможно прийдет разбираться с этим после тебя
> шаринг структуры все равно будет присутствовать маунт не отрицает шаринг структур, он как раз про это
> "типа рельс" в кложе не принято, принято из либок собирать больше это я уже слышал, но это не значит что нельзя сделать “набор советов”, которым можно не следовать, если не хочется
> это хорошо для тебя. но не для того, кто возможно прийдет разбираться с этим после тебя это не значит говнокодить. я просто говорю что не стоит пытаться повторить иерархии рельсы или спринга для приложения в 500 строк
> посмотрю, спасибо ну я то как раз сказал, что мне кажется он принципиально неправильным )
@prepor: но ты же не будешь отрицать, что то что у рельсов “стандартная” структура все же помогает вливаться в проект?
мне в итоге пришлось сгенерировать 2 шаблона - один из компожуры, второй из конпонента, а потом их руками “мержить"
стану ) нихрена она не помогает, тем более структуры никакой и нет. типичный рельсо проект это пиздец в моделях свзанных коллбэками глубиной в десятки вызовов
но если ты сделал запрос - то ты все же понимаешь, куда смотреть, чтобы понять, как и куда он пойдет
т.е. вся "структура", которую предлагает рельса это "код хуярить в models, а вот роуты у вас будут в config/routes.rb". спасибо, помогли
потому что в противном случае - “я вот делаю запрос сюда”, а куда он доходит и через какие дебри вообще непонятно
я не знаю, насколько это важно, когда ты уже понимаешь что в проекте происходит - реально никогда не задумывался об этом
я помню, как я учил рельсу с этими конвенциями, угу. Две недели ни хрена не одупляешь и перепечатываешь код из гайда, потом внезапно щелкает и начинаешь с бешеной скоростью лепить круды. А через три месяца думаешь, что ж я наделал и как это теперь рефакторить
но вообще, это странно. Обычно у тебя где-нибудь, да пиздец. Или контроллеры, или модели, или хренова гора сервис-объектов
фиг знает, у меня пока неплохо получается этого избегать. Недавно заменил рельсоприложение кложурным, все рады
Скоро можно будет clojure в postgres! Альваро пишет правильную pg/java без jdbc и напрямую через внутренний api postgresql ;)
> Скоро можно будет clojure в postgres! Альваро пишет правильную pg/java без jdbc и напрямую через внутренний api postgresql ;) чем это хорошо? будет асинхронный интерфейс? оно вроде уже есть
dottedmag: ну defcomponent это просто обертка вокруг компонента (возможно, не лучшим образом задизайненая), позволяющая систему определять кодом, а не данными. Никакой магии сверху там нет, все так же нужно эксплицитно по коду передавать компоненты, с которыми работает каждая конкретная функция
@prepor: пока не ломается и это "перегрузка" варов optional, если маунт использовать в cljc-mode
, то вары отдыхают: https://github.com/tolitius/mount/blob/master/src/mount/core.cljc#L74
даров
> 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
> 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-* запустить опять, то все компоненты будут смотреть в один и тот же стейт, разве нет?
зачем это все: http://www.dotkam.com/2016/01/31/yurt-mounts-local-real-estate/ не, смотри, мы просто используем вары для blueprint'a (i.e. чертежа), а реальная "система" is detached
я defcomponent тоже с идеей "у нас уже есть неймспейсы топологически сортированные, зачем код подсовывать другими механизмами" делал
смотри почему мне нравится эксплицитность, может быть есть какие-то идеи на этот счет: - очень часто я использую следующий "трюк": любая функция работающая с постгрей принимает db в какой-то форме. на вызывающей стороне я могу подсунуть функции или прям компонент db или объект транзакции (with-db-transaction и т.д.) И это будет замечательно работать и на всей кодобазе - тоже касается и других компонентов, например клиентов в сервисы. при принятии запроса я формирую контекст запроса, содержащий айдишник запроса и подмешиваю этот контекст в клиенты. Клиент при отправке запроса видит этот контекст и подмешивает его в запрос. Так реализуется трейсинг, контекст автоматически пробрасывается по всей цепочке вызовов, включая любую асинхронщину
А проблему с портом в итоге решили?
Мне идея разделять права доступа к API через порт кажется немного странной. Если учитывать, что сервер может находится за 2-3 натами.
ты точно так же можешь передавать и подмешивать с 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, и только иногда полезно его указывать руками
> точно так можешь большенство функций оставить stateless, и передавать туда компоненты так же точно как они передаются в "component" но это же противоречит "фишке" маунта нет? мне тогда руками надо создавать "систему" и потом разделять ее на наборы компонентов для передачи функциям?
я согласен что эксплицитность определения зависимостей решается тулингом, если я просто могу вызвать у маунта "от чего зависит этот неймспейс", то это уже ок
ну т.е. вот у меня код делал (widget/find-vesion widget ...) и всегда требовал передачи этого widget парамертром в функцию. подобных вызовов сотни по коду. сейчас у меня появилась фича сделать контекст для трейсинга и все остается как было. если бы у меня был маунт я ведь не удержался бы от того что бы не сделать "хелпер" с (widget/find-vesion ...)? )
полтора года мне не нужно было ничего в эти клиенты подмешивать, с чего вдруг пришлось бы? )
"фишка" есть, и она в том что "догма bad, pragmatism гуд" то есть можно и нужно использовать так как того требует дезайн, желание, задача. руками кстати ничего создавать не надо, у тебя может быть какой нить namespace у которого через просто несколько :require
с будет доступ ко всем компонентам, и оттуда ты можешь "чэйнать" их в app. но опять же это выбор
"не удержался бы": да, я понимаю к чему ты, но ведь единственное лекарство от "не удержался бы" это опыт )
на самом деле Юрта для Джеймса Риверса (a.k.a. compojure
), который сказал что прям щаз будет использовать маунт если я ему покажу как использовать компоненты локально. но пару людей уже че т с ней делают.. Юрта молода, так что посмотрим
Кто нить пользует SQS ?
смотрите, я хочу сделать 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
Есть ли у макросов фаза когда уже все макрос раскрылись?я тупой
хотя неа. Не уверен в общем, жду комментариев
точно так же как ты не можешь использовать еще не объявленную функцию. или иметь циклические зависимости неймспейсов
хм, да тут prepor наверно прав - что я наверно не туда капаю
да неа, счас сек, я тут спросил как мне сделать решение, а в итоге надо было описать задачу саму, сек
После прочтения 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 будет забыт. Т.е. при таком коде конечно ничо не сделать, но вот думаю как это переписать на макросы чтоб это стало возможнопо сути граф и надо доказать что ничего не забыто и не будет дедлоков. Просто в итоге на основе этой пдф будет очень много if с кучей бранчей, очень легко забыть что-нить, вот думаю как упростить себе жизнь
хм, о, надо почитать да
эм, может плохо описал - вот пример на питончике из этой пдф https://github.com/PlatformLab/mappy/blob/master/job.py#L24-L65
в примере видно что куча if/else - я хочу чтоб хотяб чутка проверок было что я ничего совсем банального не забыл
один? типа функция, которая принимает машину, и валидируемую функцию, и, собственно, валидирует ее?
я наверно слишком много инфы дал, давай попроще: У меня есть стейт машина, есть 3 правила a -> b b -> c c -> :finish я хочу валидировать что все переходы обработаны и что стейт машина не будет в состоянии дедлока (т.е. не будет такого правила которая она не знает как обработать)
т.е. если убрать b->c я хочу получить ошибку что хз как обработать цепочку a->b дальше
>валидировать на полноту во, правильное слово
мне куда копать? чего в гугле вводить хоть?
построить граф и посмотреть что для всех точек есть путь до :finish?
Тему не читал, https://github.com/cdorrat/reduce-fsm это не подойдёт?
думал о нем, оно вроде как раз для этого
хм, стейт машина она всеж деревянная как я понимаю. А я хочу правила чутка посложнее типа a & b -> c a & !b -> z или такое тоже поддерживается?
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.
да, я понимаю что это задача как раз для логического программирования, но может что полегче есть
@misha: А ты пробовал core.logic сам?
да блин, я думал за вечер набросать просто чтоб работало, а тут как-то побольше задача будет
есть же алгоритм Дейкстры для обхода графа (типа наименьшего пути). Можно его приспособить для нахождения связей. Там нет рокет саенса, просто если был в вершине, ее надо помечать. Если граф не связан, то после обхода останутся непомеченные вершины
(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}
хм, я вот думал про графы. А в графах можно выразить что а -> b b -> c b+c -> z т.е. что z доступен только когда оба b+c достигнуты
тьфу, сорри
a->b c->d b+d -> z
[] -> a [] -> c
ну т.е. есть какое-то начальное значение 0 из которого уже выходят другие значения
или вот тоже пример в голову пришел a->b только когда НЕ с. Это же графами уже не выразить?
или есть чото специальное для такого?
тру да
дак я как раз от ифов и хочу уйти
да, вариант тоже кстати. Но это решать проблему брутфорсом, как-то не спортивно
дада, на раз валидация
тогда генераторами тестировать. и твоя проблема плавно перетекает в "как нагенерить генератор для стейтмашины"
ок, согласен на решение второй проблемы 😄
да он занятой дядька, чо дергать по пустякам - пускай ом-некст допилит
надо переспать с проблемой, авось на утро чо придет в голову. Хотя core.logic да, походу как раз под эту задачу