This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-14
Channels
- # beginners (31)
- # boot (9)
- # cider (10)
- # cljs-dev (9)
- # cljsrn (16)
- # clojure (222)
- # clojure-austin (4)
- # clojure-france (13)
- # clojure-italy (21)
- # clojure-nl (2)
- # clojure-russia (71)
- # clojure-spec (9)
- # clojure-uk (39)
- # clojurescript (50)
- # cursive (16)
- # datomic (69)
- # dirac (2)
- # figwheel (1)
- # graphql (19)
- # hoplon (4)
- # jobs (1)
- # klipse (3)
- # leiningen (4)
- # liberator (3)
- # luminus (9)
- # lumo (9)
- # off-topic (3)
- # om (21)
- # onyx (11)
- # parinfer (2)
- # pedestal (8)
- # planck (19)
- # re-frame (17)
- # reagent (12)
- # remote-jobs (1)
- # ring-swagger (3)
- # spacemacs (17)
- # specter (23)
- # sql (1)
- # unrepl (64)
- # untangled (19)
- # yada (5)
> (reduce inc 10 (range 5))
15
все окДаже чтоб понятней:
cljs.user=> (reduce #(do (println "NUM:" %) (inc %)) 10 (range 5))
NUM: 10
NUM: 11
NUM: 12
NUM: 13
NUM: 14
15
ааа, что-то ваша жвм кложа не динамичная совсем
(nth (iterate inc 10) 5)
iterate
function
Usage: (iterate f x)
Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects
Added in Clojure version 1.0
помнил же что есть чота похожее 🙂Хороший класс https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Volatile.java 🙂
@artemyarulin @roman01la удачи с .cljc
Кстати, итерейт наверное при первой реализации сделает 32 вызова, из которых ты только 5ый возьмешь, @artemyarulin
ааа, а я то думал почему в доке аж написано f must be free of side-effects. хотя вроде не
Нет, ну вообще, иногда бывает все укладывается хорошо в -> или ->>, а какой-нибудь один вызов нет
>(nth (iterate #(do (println "Yep") (inc %)) 10) 2)
Yep
Yep
Yep
Yep
Yep
15
есть какой-нибудь способ сделать stateful postwalk без атома https://gist.github.com/razum2um/b691ad0d760795efaeb886e6caf05122 ?
ну разве что тока через replace какой - обходя дерево выпиливать все что не нужно оставляя только то что ищешь чтоб в конце получить [1 2 3]
Может через
tree-seq
Returns a lazy sequence of the nodes in a tree, via a depth-first walk.
branch? must be a fn of one arg that returns true if passed a node
that can have children (but may not). children must be a fn of one
arg that returns a sequence of the children. Will only be called on
nodes for which branch? returns true. Root is the root node of the
tree.
он вернет все, дальше фильтр и как раз получить что ищешь без атомаможет волатайл подойдет https://stackoverflow.com/questions/31288608/what-is-clojure-volatile
@artemyarulin вот tree-seq я смотрел, но чет не осилил, не совсем то 🙂
@nicola да, я понимаю, что для функциональной аггрегации есть только reduce, но печалит, что надо самому повторять все ветвления из clojure.walk/walk
и то, что postwalk работает по нужной схеме, прям как надо, но рядом ничего не протащить
тупенький вариант
(defn reduce-walk [x acc f]
(let [acc (f acc x)]
(cond (map? x) (reduce (fn [acc [k v]] (reduce-walk v acc f)) acc x)
(coll? x) (reduce (fn [acc v] (reduce-walk v acc f)) acc x)
:else acc)))
(reduce-walk {:data 3 :children [{:children {:children []}}
{:children [{:children [] :data 1}]}
{:children [] :data 2}]}
[] (fn [acc x]
(if (:data x) (conj acc (:data x)) acc)))
Коллеги а посоветуйте про архитектуре приложений почитать что нибудь. У нас в проде появился SOAP сервер на clojure и вот он растет и растет и какой-то он не особо структурированный получается. Собственно я пришел с python django celery apps, там все как то просто с этим потому что фреймворк учил как организовать приложение и примеров полно. А тут как сложно мне приходится
фишка clojure - что ты можешь структурировать под приложение - не воевать с framework - но собрать под свои нужды - о чем ваш сервис?
@razum2um вот тут несколько вариантов разобрано и есть пример кода для обхода со стейтом https://www.ibm.com/developerworks/library/j-treevisit/
@nicola приложение SOAP сервис который транслируются входящие запросы на другой внутренний сервис и содержит какую бизнес логику на своей стороне. Есть обработка валидация обработка ошибок и так далее
собственно проблемы начинаются с места когда в момент обработки запроса на какой то стадии мы можем решить вернуть ошибку. Или например ошибку скомбинировать с данными полученными от внутреннего сервиса
@rmuslimov я бы на middle-ware все построил
что-то типа - https://github.com/niquola/unifn
у тебя одни mw будут складывать в context map - другие валидировать - третьи проксировать - полный декомплект :0
Насколько оправдано писать такой макрос:
(defmacro where=
"Add :where clause into query map if s not nil
Will not work in case you want :where [:= :key nil]"
[m s]
`(cond-> ~m
((complement nil?) ~s) (merge-where [:= (keyword '~s) ~s])))
(defn get-list [{:keys [organization-type]
:as params}]
(-> {:select :* :from :categories}
(honey/where= organization-type)
honey/query))
на самом деле у меня было два варианта:
(defn where= [m params k]
(if (contains? params k) (merge-where m [:= k (k params)])))
(defmacro where=
"Add :where clause into query map if s not nil
Will not work in case you want :where [:= :key nil]"
[m s]
`(if ~s (merge-where ~m [:= (keyword '~s) ~s])))
Вот думаю какой из них лучше. Сначала написал функцию, потом нашёл кейс, где макрос удобнее.misha: нужно было для того, чтобы ещё пару функций туда докидать, но для этого варианта хватит и ифа, верно.
А нет, обманываю. Не иф, потому что мне нужно всегда возвращать мап.
понятно, что если merge-where - не единственное преобразование, то cond-> - в самый раз
кстати, а с cljc много граблей?
Кста интересно - кложа это лиспы, макросы ура, power! Первый урок почти везде - макросы не писать, лучше просто функции, макросы ну в ооооооочень редких случаях и даже в них лучше еще раз подумайте
кложа это данные, а то что лисп - это вторично
@artemyarulin ну макросы и правда заесь, лучше только наличные© просто большинство нужных тебе макросов уже написано (->, ->>, spec, etc.), либо они нужны на уровне либы, а не аппликейшен кода
@dragoncube ни на одни грабли не наступил пока что. но и в продакшене меня пока что нет
и чо много у тебя их уже @misha ? И неужто не было проблем когда хрен макрос в рантайме заюзаешь типа (reduce and [true false true]) ;; CompilerException
или вон тут даже не один раз народ и я жаловались что спека вся на макросах и хрен чего на основее ее сделаешь враппер или либу?
я их по началу тоже много писал, а счас думаю что в 99.9999% это овер инжинеринг и в оставшиеся 0.00001 помещаются всякие core.async и прочее
.cljc - тупо всё, кроме: rum компонентов, серверных мидлварей, записи/чтения на диск, датомик-кода
аа, сори, не прально прочитал - думал у тебя там все на них 🙂
быгыгы, 1 большой макрос апп: пишешь мейн, а он тебе разворачивает сервер, реактнейтив и юай весь
ну с (reduce and ...)
знать надо, конечно, это да. но кложа и так в тонусе держит с точки зрения "знать надо", так что типа ок.
(every? boolean [true false true])
=> false
(every? boolean [true true])
=> true
(every? boolean [true 1 true])
=> true
ну типчиков то нет, все в тонусе надо да
@rmuslimov у меня пока что нет сср, так что еще не в cljc. то я перечислял, что у меня в cljc.
@artemyarulin Вот вспомни, как часто тебе нужно было разные вещи добавить в язык. Например, в джаву какую-нибудь. Вот приблизительно столько макросов тебе и надо, и они уже написаны до тебя 🙂
ну хз, мне кажется все равно macroses are overrated. Прям в любом туториале по кложе в начале списка идет этот аргумент - добавить разные вещи в язык омг, мощЪ. А на самом деле тут наверно процентов 5 кто макросы писал и из них 5% кто это делал в либах а не у себя в уютном домашнем проекте
я отлично понимаю почему and макрос, что только через них можно было core.async запилить или спеку. Но в типичных условиях - это нафег не надо.
cljc удобно и для тестов, можно обычный lein test использовать без дополнительных усилий