This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-25
Channels
- # aleph (6)
- # beginners (6)
- # boot (94)
- # cider (34)
- # cljs-dev (36)
- # cljsrn (12)
- # clojure (124)
- # clojure-dev (41)
- # clojure-dusseldorf (6)
- # clojure-italy (3)
- # clojure-norway (1)
- # clojure-russia (161)
- # clojure-sg (7)
- # clojure-spec (71)
- # clojure-uk (95)
- # clojurescript (38)
- # core-async (16)
- # cursive (14)
- # data-science (1)
- # datascript (12)
- # datomic (15)
- # emacs (22)
- # funcool (2)
- # hoplon (15)
- # jobs-rus (2)
- # juxt (9)
- # liberator (7)
- # lumo (1)
- # off-topic (136)
- # onyx (24)
- # pedestal (39)
- # perun (2)
- # planck (20)
- # re-frame (23)
- # spacemacs (31)
- # unrepl (5)
- # untangled (1)
- # vim (1)
- # yada (29)
А кто-нибудь из юзеров spacemacs'а
может помочь с биндингами?
Хочу 'cider-eval-defun-at-point
забиндить на два пробела, полазил по ~/.emacs.d/layers/+lang/clojure/packages.el
но чото не могу разобраться
Может кто делал уже?
два пробела, это как? просто два пробела?
вместо SPC m e f
--> SPC SPC
а если надо 2 пробела сделать в тексте? хотя не помню последний раз когда такое нужно было… расскажи потом если найдешь, может тож что-нить забайндю
ок, хорошо
(dolist (m '(clojure-mode
clojurec-mode
clojurescript-mode
clojurex-mode
cider-repl-mode
cider-clojure-interaction-mode))
(spacemacs/set-leader-keys-for-major-mode m
"SPC" 'cider-eval-defun-at-point))
как то так, но это переопределяет биндинг самого спэйсмакса, M-x
@artemyarulin с набором текста это не коррелирует, работает только в normal-mode
кстати, для краткости можно вместо SPC m e f
набирать , e f
ну набор текста я имею ввиду если в коменте написать надо например
да, про , e f
знаю, репл стартовать тоже изи — , '
или фигвил — ' "
но SPC SPC
еще короче
не за что, подсмлтрел вот тут https://github.com/syl20bnr/spacemacs/blob/master/layers/+lang/clojure/packages.el#L98
так работает только через SPC m SPC
или , SPC
, если что
как видно из set-leader-keys-for-major-mode m
— m
— это SPC m
или ,
может через , ,
забиндить? просто удобно же, как в lighttable, не надо окошко с реплом держать открытым
да, сделал , ,
— работает, пока брат жив, посмотрим в процессе
хоть и кастомизация есть, но таки ты привязан к cider’у — в ногу выстрелить не даст
хз, хорошо это или плохо
да в жаве тоже есть все эти мейби, но как-то, что велью на нулл проверять, что мейби.райт на нулл проверять - те же яйца
мейби это монада, но есть и другие монады
если у тебя все нуллабл то ты легко можешь забыть if a != null, при монадическом Maybe|Optional тебе забыть не даст компилятор
а мне кажется монады удобной абстракцией)
public class MonadApp {
public static void main(String[] args) {
Maybe<Integer> x = new Maybe<>(5);
Monad<Integer> y = x.bind(v -> new Maybe<Integer>(v+1))
.bind(v -> new Maybe<Integer>(v*2));
System.out.println( ((Maybe<Integer>)y).getVal() );
}
}
и у жавистов еще от количества скобочек в кложе припекает? ахахаа вот прям идеальное объяснение https://www.youtube.com/watch?v=ZhuHCtR3xq8
имхо)
https://egghead.io/courses/professor-frisby-introduces-composable-functional-javascript
но он именно показывает пример кода, рефакторинг в монаду или функтор, а потом уже рассказывает что это была монада
я вот наговнокодил с самописной maybe https://github.com/savelichalex/Souptitle/blob/master/apps/desktop/src_front/souptitle_desktop/common/components/dropzone.cljs#L59
а в кложе ведь монаду рекордами никак, да? всё равно какую-то контекстную функцию писать, которой оборачивать цепочку вызова?
типа (monad-context (-> x f g h))
ну чтобы код вообще от обычного кложа кода не отличался, но ты вместо стринги в x
положил монаду стринговую, и хоп - все нуллпоинтеры потенциальные пропали
а хотелось бы вот так:
(let [x "foo"] (-> x f g h))
и
(let [x (maybe "foo")] (-> x f g h))
так и надо же делать
и представь, что у тебя в let
- 100 строк кода всякого, а монаду ты только в биндинге подсунул, и остальное не трогал вообще
просто тебе надо на каждом шаге join ф-ю еще
типа (-> x (>>= f) (>>= g))
например при вычитывании из датаскрипта оборачиваешь в 1 месте в монаду значение, и у тебя она просачивается в остальной весь проект истребляя нуллпоинтеры, вместо того, чтобы в 10 местах вспомнить, что нужно ->
на ->maybe
заменить
по идее можно макрос конечно сделать который всегда будет join делать, а в нужной монаде нужное значение применит, так как протокол реализует
переопределить ->
? 😄
чтобы дифф 100 строк кода был
- x "foo"
+ x (maybe "foo")
а не
- x "foo"
+ x (maybe "foo")
- (-> x f g)
+ (-> x (>>= f) (>>= g))
... ; еще 196 строк
@savelichalex ну у тебя же не весь код на рокетах (много, но не весь)
да я бы вообще не стал как ты делать, как то слишком неявно все становится) я бы хотел явно монады видеть)
в кложе можно extendprotocol на nil сделать тоже, но каждую ф-ю в протокол не завернешь
но компилятор не спасёт от такого:
scala> val x: Option[String] = Some(null)
x: Option[String] = Some(null)
здравствуй, NPE 🙂ну скала язык возможностей. Там кста нельзя проще сделать = val x: Option[String] = null
?
а ну вот) Хаскель няшка в этом отношении - понятия null нету вообще
@misha ^^ вот видишь, теперь все в безопасности 😄
Дак ибо Option это класс, т.е. переменная x класса Option[String], а не переменная x типа Option[String]. Т.е. val x: Int = null сделать же при всем желании нельзя
ну я на скале месяцек всего жил, почти ничего про нее не знаю
да, option помогает выразить "значение некоторого типа или null", но от кривых рук не спасает
народ, требуется архитектор (навыки backend и фронт енд) стек datomic +(clojure back) + clojurescript (front). кому интересно в личку плиз
в москве
(def fields
{::model/range
(f/map->Field
{:label "Range"
:validators [(validators/spec ::model/range model/invalid-asn-range-message)]})})
(def crud-form
(f/map->Form
{:label "ASN Pool"
:flags {:disabled? false
:show-validation-errors? false}
:fields {:display_name (f/map->Field {:blueprint-field ::common/display_name})
:ranges (f/map->Form {:blueprint-form ::model/ranges})
:status (f/map->Field {:label "Status"})
:tags (f/map->Field {:blueprint-field ::common/tags})}}))
(def forms
{::model/details-payload
crud-form
::model/create-payload
(update crud-form :fields dissoc :status)
::model/ranges
(f/map->Form
{:label "Ranges"
:required? true
:fields [(f/map->Field {:blueprint-field ::model/range})]
; TODO: check for overlapping ranges
;:validators []
:subforms {:add-range-form (f/map->Form
{:blueprint-form ::add-range-form
:flags {:show-validation-errors? false}
:on-submit :parent-fields-conj})}})
::add-range-form
(f/map->Form
{:label "Add Range"
:validators [(validators/generic model/first-less-than-last? "First should be less than Last")]
:fields {:first (f/map->Field
{:blueprint-field ::common/asn
:required? true
:label "First"})
:last (f/map->Field
{:blueprint-field ::common/asn
:required? true
:label "Last"})}})})
для либы есть биндинги в re-frame - собсно как инициализировать по этой схеме, как диспатчить одно поле
после этого можно делать биндинги на разные UI либы, типа как у нас на semantic-ui
(defn generic-input-field
[field & [{:keys [input-type coerce-fn suppress-label? style attrs] :as options}]]
(let [read-only? (if (contains? options :read-only?)
(:read-only? options)
(forms/flag field :read-only?))]
[:div {:class (field-class field options)}
(when (not suppress-label?)
[label field])
[:div
[:input (merge
attrs
{:style style
:type input-type
:value (str (:value field))
:placeholder (str (:placeholder field))
:read-only read-only?
:on-change (forms/on-submit-fn field {:coerce-fn coerce-fn})})]]
(when-not (:suppress-validation-errors? options)
[validation-errors field options])]))
Последние веяния - определять payload который должна сделать форма через clojure.spec, на каждый on-change на форме прогонять s/explain-data
, парсить выхлоп и через subscription просовывать его в форму по полям (какие valid/не valid, какие disabled и т.д.)
это в одном месте я хак втыкал, потому что у нас в одном из response’ов от бэкэнда была семантическая дыра
суть не в этом. Начальный подход был иметь мапу которая описывает все формы как композицию полей и иметь dispatch’и b sub’ы на поля и на форму.
@misha ты прав, мы говнокодеры. я просто отвечаю на вопрос “кто как с формами воюет”
на, потешь свои “говнокод-детектив” скиллы, это обертка над semantic’овским search-field’ом с автокомплитом и малтиселектом
а вообще, как бы, если поля некоторые преиспользуются, то компоновать из полей, и подписывать на форму/поля - ок решение. даже не знаю какое годное альтернативное можно сочинить.
сорри за оффтоп, наверняка кто-то бывал на рит++ ранее. Достойное мероприятие? стоит двух проведенных там дней? http://ritfest.ru/
@misha а где там 25 строк копипасты то?
@nicola а насколько у тебя формы однородные?
@dragoncube ты шутишь?
@misha а, ты про complex-select-field ?