Fork me on GitHub
#clojure-russia
<
2015-11-12
>
oxgrouby05:11:32

вот скажите, чем мотивировались называя функци ex-info и ex-data?

oxgrouby05:11:38

пипец как семантично )

kharus05:11:35

А как надо было?

oxgrouby05:11:23

ну первая мысль ex-with-info и ex-extract-info например, тоже не оч, но хотя бы понятно что оно делает )

Kira Sotnikov05:11:14

Кхм, пацаны, а как канонично хэндлить ошибки?

Kira Sotnikov05:11:28

Ну например в джаве и питоне есть ыксепшоны

malch05:11:00

@lowl4tency: Так же, как в java

Kira Sotnikov05:11:08

Я вот дергаю апишечку, через https://github.com/owainlewis/twilio а как мне захэндлить если оно пошло не так

malch05:11:27

Оберни в try - catch

Kira Sotnikov05:11:47

оу, пойду ка почитаю, не знал что есть try catch simple_smile

malch05:11:59

Можешь еще https://github.com/scgilardi/slingshot добавить

Kira Sotnikov05:11:10

У меня агрессивный путь погружения в кложу.

oxgrouby05:11:44

ещё был какая-то либа для erlang-стайл обработки ошибок, понравилась, но особо нигде не заюзал, ща найду

Kira Sotnikov05:11:04

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

Kira Sotnikov05:11:16

О, либа майкла

Kira Sotnikov05:11:25

Это же крутой чувак из onyx-team

malch05:11:29

@oxgrouby: я на нее поглядел, но даже сам автор ей не особо пользуется

malch05:11:50

И я не вполне уверен, что она “хорошая” в смысле идеологии

oxgrouby05:11:20

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

malch05:11:30

В Erlang у тебя модель приложения другая

malch05:11:58

Ты пишешь actor-ов, а над ними ставишь супервизоров, которые обрабатывают ошибки

oxgrouby05:11:16

ну это ясно )

malch05:11:34

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

malch05:11:51

А в java, (ну и, видимо, clojure) это не совсем так

Kira Sotnikov06:11:20

думаю мне пока хватит обычного try catch

malch06:11:31

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

oxgrouby06:11:04

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

malch06:11:21

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

malch06:11:28

это как?

oxgrouby06:11:56

ну возвращать Option, Result -- как в хачкеллях

malch06:11:07

А зачем?

oxgrouby06:11:21

чтобы не забывать их обрабатывать

malch06:11:35

nil в clojure убирает (почти полностью) необходимость Option

oxgrouby06:11:37

тупо если не проверил - не скомпилится )

oxgrouby06:11:50

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

malch06:11:04

Хм, тогда лучше сразу другим языком пользуйся 😉

oxgrouby06:11:39

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

malch06:11:59

Scala, Haskell?

malch06:11:08

Если хочешь статических типов

malch06:11:59

@oxgrouby: я и сам прекрасно понимаю плюсы той же Scala, но я свой выбор сделал

oxgrouby06:11:03

хаскелль - ломают совместимость и не притащиш в команду

oxgrouby06:11:38

скала... да ну чот как, шило на мыло да ещё и нелисп)

oxgrouby06:11:53

там те же эксепшоны частенько встречаются

malch06:11:45

Мне лично хватает https://github.com/Prismatic/schema

malch06:11:07

Ну и руки не дошли https://github.com/clojure/core.typed попробовать

oxgrouby06:11:32

я вот ща как раз с кортайпедом играюсь)

malch06:11:45

И как оно?

oxgrouby06:11:14

ломающе мозг, но когда привыкаешь -- классно )

oxgrouby06:11:48

а как тут в слаке листинги постить?

Kira Sotnikov06:11:03

постишь код, снизу справа есть ссылочка create snippet

Kira Sotnikov06:11:39

Жмешь, появляется pop-up

oxgrouby06:11:53

он типа сам определяет что текст - код и только тогда она появляется? :-O

malch06:11:04

@lowl4tency: мне кажется, что он у тебя синтаксис не распознал

oxgrouby06:11:17

а, ясно

Kira Sotnikov06:11:42

Думаю когда больше одной тсроки

Kira Sotnikov06:11:52

кхм, а я кложуру не нашел в списке

Kira Sotnikov06:11:09

Плохо искал )

malch06:11:18

можно и просто в тексте

(println “Hello, world!”)

malch06:11:51

@lowl4tency: пару стилевых советов дать? 😄

oxgrouby06:11:59

🚜 ух ты как тут много смайликов )

Kira Sotnikov06:11:10

malch: да, конечно

Kira Sotnikov06:11:24

malch: я вчера первый раз писал что-то на кложе дальше репла

malch06:11:45

x лучше на той же строке оставить

Kira Sotnikov06:11:23

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

malch06:11:44

и я бы написал (vals (:phones config))

Kira Sotnikov06:11:41

malch: а разницы с (-> config :phones) нету?

malch06:11:43

ну или уже

(-> config
:phones
vals)

Kira Sotnikov06:11:04

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

Kira Sotnikov06:11:17

-> ->> map-> и тд

malch06:11:41

Разницы нет, просто зачем добавлять макрос для одной операции 😄

Kira Sotnikov06:11:14

эм, нафига оно тогда нужно )

Kira Sotnikov06:11:25

Ок, перепилю на твой вариант

malch06:11:27

Когда больше

Kira Sotnikov06:11:59

О, спасибо

oxgrouby06:11:39

каждый раз открываю что-то новое когда читаю этот стайлгайд )

Kira Sotnikov06:11:13

я даже не знал что он существует )

malch06:11:36

@lowl4tency: Ну а так твой код должен работать 😉

Kira Sotnikov06:11:51

malch: спасибо за ревью и советы

Kira Sotnikov06:11:07

Осталось понять почему оно не работает на лямбде

malch06:11:14

Да без проблем, обращайся 😄

Kira Sotnikov06:11:27

Такое ощущение что лямбда тупо игнорит мой хттп реквест

Kira Sotnikov06:11:45

надо еще запилить review-rus канал simple_smile

artemyarulin06:11:25

Я бы не сказал что try/catch это канонично в ФП. В кложуре они есть по причине интеропа в жаву

artemyarulin06:11:59

ну и конечно асинхронный код try/catch не покроешь

oxgrouby06:11:09

...а разве фп описывает хоть какие-то каноны по обработке ошибок? ортогональные вещи по идее

Kira Sotnikov06:11:54

а что канонично в фп?

Kira Sotnikov06:11:04

как понять что пошло не так без ыксепшонов?

artemyarulin06:11:32

в статичных языках дело конечно решеное - Result<Error,Value>, Maybe, Optional, etc.

malch06:11:47

@artemyarulin: atom тоже не канонично в фп. Clojure никогда и не пытался быть чисто функциональным языком

malch06:11:01

Не забивай @lowl4tency голову

artemyarulin06:11:20

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

Kira Sotnikov06:11:34

Просто академический интерес )

artemyarulin06:11:42

ну почему-же не забивать голову - это вполне себе важная проблема

malch06:11:02

Важная, согласен 😊

oxgrouby06:11:11

...но не проблема фп

artemyarulin06:11:20

просто стандартная clojure.core не кидает эксепшенов - прикиньте если бы кидала все время? бррр

malch06:11:32

Но я считаю, что в Clojure стоит именно try catch пользоваться

malch06:11:43

так же, как и в clojurescript

artemyarulin06:11:10

ну это давний холивар exception|return err object на сколько я помню :)))

malch06:11:24

Хотя и уверен, что это не лучший вариант “вообще"

malch06:11:49

Like Java, Clojure provides a couple of forms for throwing and catching runtime exceptions: throw and catch, respectively. Although throw and catch map almost directly down to Java and JavaScript, they’re considered the standard way of dealing with error handling. In other words, even in the absence of interoperability, most Clojure code uses throw and catch to perform error handling.

malch06:11:08

Это из “Joy of Clojure”, сейчас перечитываю

oxgrouby06:11:48

всем if err != nil {

Kira Sotnikov06:11:52

о, спасибо

Kira Sotnikov06:11:17

(if ( != err nil)

malch06:11:58

(if err …)
😃

oxgrouby06:11:33

> (if ( != err nil) (edited) not=

malch06:11:36

этим nil и хорош

artemyarulin06:11:43

(when-not тогда уж

artemyarulin06:11:02

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

Kira Sotnikov06:11:06

artemyarulin: ну вот я вызываю хттп апи реквест, как понять без трай кетч что не случилось чего-то плохого

Kira Sotnikov06:11:08

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

delaguardo06:11:45

для этого есть статус в реквесте же

oxgrouby06:11:49

у меня как правило в этом случае админы жалуются что в продакшне всё падает =\

artemyarulin06:11:00

да тыща вариантов на самом деле. Если не тошнит от коллбеков то можно передать on-success, on-error Есил core.async (а мы же говорит об асинхронной операции?) то можно либо 2 канала вернуть с ошибками и рузультатами, или один и внутрь класть либо значение либо объект ошибки

artemyarulin06:11:20

HTTP status не будет если сети то нету

artemyarulin06:11:48

на самом деле в этом случае как раз try|catch работать не будет вообще ибо асинк

artemyarulin06:11:11

ну если конечно не юзать спец хелперы как когда-то Нолен описал

artemyarulin06:11:31

если кому интересно

artemyarulin06:11:34

ну или по хардкору подключить cats либу с монадами и заюзать оттуда магию. У меня мозгов не хватило понять:)

oxgrouby06:11:44

cats клёвый, но вся беда такая же как у core.typed -- в сторонних либах их нету, поэтому полной уверености что все ситауции обработал тоже нет

artemyarulin06:11:46

ну этого не будет никогда ибо динамик тайпс. Если хочется гарантий - то rust|scala|Java lol simple_smile

oxgrouby06:11:33

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

artemyarulin06:11:20

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

oxgrouby06:11:16

и nio вроде как ещё недопилили

artemyarulin06:11:16

java.nio или ты о rust/mio?

oxgrouby06:11:23

о расте

artemyarulin06:11:42

эт да, рановато в общем пока

alexey.badenkov07:11:09

А где можно ссылочки посмотреть с последнего хенгаута?

Kira Sotnikov07:11:08

кхм, а еще глупый вопрос, у меня есть функция, (defn blabla [] (do snth)) а как сделать чтобы она что-то вернула или получить результат выполнения?

oxgrouby07:11:31

она возвращает результат последней операции, как раби

oxgrouby07:11:43

т.е. snth вернёт

Kira Sotnikov07:11:31

(println blabla) напечатает этот результат?

oxgrouby07:11:42

нет, (println (blabla))

Kira Sotnikov07:11:59

блин скобочки мне взрывают мозг, сраные смайлики ))

oxgrouby07:11:08

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

Kira Sotnikov07:11:01

не скобочки норм, лучше чем отступы

Kira Sotnikov07:11:10

но вот мозг взрывается с непривычки

oxgrouby07:11:28

потом без них не сможешь

Kira Sotnikov07:11:31

{:message (str (get-in event ["Records" 0 "Sns" "Message"]))})

Kira Sotnikov07:11:45

а вот это можно переписать через ключи?

Kira Sotnikov07:11:08

типа как (:a mymap)

Kira Sotnikov07:11:32

(:Records 0 :Sns :Message event)

Kira Sotnikov07:11:43

event это распаршенный джейсон

oxgrouby07:11:59

(-> event (get-in ["Records" 0 "Sns" "Message"]) str :message)

Kira Sotnikov07:11:55

теже яйца )

oxgrouby07:11:09

тогда я не оч понимаю что ты хочешь и зачем

Kira Sotnikov07:11:10

ну вот у меня было (vals (-> config :phones)

Kira Sotnikov07:11:26

а можно было просто (vals (:phones config)

Kira Sotnikov07:11:35

смотрится приятнее

oxgrouby07:11:24

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

oxgrouby07:11:13

другое дело - нахер строки в ключах - clojure.walk/keywordize-keys

Kira Sotnikov07:11:44

о прикольно

Kira Sotnikov07:11:49

Джесон же

oxgrouby07:11:15

он уже перестал быть джейсоном, теперь это самые обычные кложурные структуры

oxgrouby07:11:33

это не питоны-жавы где для каждого протокола свои класы тяпают-ляпают

oxgrouby07:11:53

а вообще у json парсера кложурного должна быть опция кейвордирования

niquola07:11:05

(-> config :phones vals)

oxgrouby07:11:06

или там :key-fn keyword, или как там делалось

oxgrouby07:11:32

и, кстати, ты можешь дёрнуть как функцию ассоциативную структуру - хешмап и вектор например, типа ([1 2] 0) == 1, ({:q "w"} :q} == "w"

oxgrouby07:11:17

подытожывая, у тебя должно быть типа (->> event :records 0 :sns :message str (hash-map :message)) simple_smile

oxgrouby07:11:19

или даже лучше не ->>, а some->>, чтобы не словить нулпоинтерэксепшн внезапно, неловко было бы

oxgrouby07:11:25

что-то я заболтался...

malch07:11:32

@oxgrouby: выглядит менее понятно, чем get-in

oxgrouby07:11:52

дело привычки

malch07:11:04

не в привычке дело 😃

oxgrouby07:11:23

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

malch07:11:53

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

malch07:11:03

твой вариант придется внимательно читать

oxgrouby07:11:13

ну может быть

Kira Sotnikov08:11:13

Эээ, два раза вызвал одно и тоже, а выхлоп в репле разный

oxgrouby08:11:45

а что делает send-message?

oxgrouby08:11:03

и эцсамое

oxgrouby08:11:14

вангую что ты юзаешь for не совсем по назначению

oxgrouby08:11:31

он не такой как в других языках =0

Kira Sotnikov08:11:41

я же питоноеб

oxgrouby08:11:48

он ленивый

Kira Sotnikov08:11:07

прям как я ._.

Kira Sotnikov08:11:34

oxgrouby: а что использовать чтобы функцию натравить на массив

Kira Sotnikov08:11:39

про мап знаю

Kira Sotnikov08:11:50

но я не знаю как натравить мап на функцию у которой два аргумента

oxgrouby08:11:53

doseq для сайдэфектов, map для преобразования

oxgrouby08:11:54

например

Kira Sotnikov08:11:05

сайдэфект это вызов функции?

Kira Sotnikov08:11:15

точнее наоборот, вызов функции это сайд эфект?

oxgrouby08:11:15

> но я не знаю как натравить мап на функцию у которой два аргумента // врапер сделать например\

oxgrouby08:11:33

сайд эфект это когда что-то делает вне текущего контекста, println например

oxgrouby08:11:46

а если ты просто делаешь (inc %) -- это не сайдэфекет

oxgrouby08:11:03

т.е. когда что-то меняется за скобочками

Kira Sotnikov08:11:21

ну вот например, (map (blabla arg1 arg2)) я хочу чтобы функция выполнилась для каждого элемента массива arg2 но arg1 должен быть в каждом вызове один и тот же

Kira Sotnikov08:11:37

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

oxgrouby08:11:11

(map #(fun arg1 %) [1 2 3])

oxgrouby08:11:23

ну теперь точно на обед

ponimas08:11:58

(map (partial fun arg1) [1 2 3]) имхо красивее

niquola09:11:38

@lowl4tency: replace for with doseq

Kira Sotnikov09:11:53

nicola: уже зареплейсил

Kira Sotnikov09:11:04

спасибо

oxgrouby09:11:38

ребят, а напомните плиз где находилась форма с эмейлом для инвайта сюда?

oxgrouby09:11:48

спасибо

teivar10:11:37

Всем привет, подскажите корректно ли не использовать проверку 0 при вычислении average-length

teivar10:11:00

получается при count 0 она же и не вызовется никогда

kirillov11:11:45

Смотрите как интересно))) http://www.lispcast.com/solid-principles-in-clojure Не было еще такого?

oxgrouby11:11:02

на реддите было

oxgrouby11:11:06

хорошая статья

konukhov11:11:40

да, вчера в призматике прочитал – классная

oxgrouby13:11:20

тем временем clojure-1.8.0-RC1

oxgrouby13:11:45

а я проспал :-S

ponimas14:11:39

>1.8.0-RC1 кто попробовал? как там стартап тайм?

oxgrouby14:11:57

лично меня больше радует http://dev.clojure.org/jira/browse/CLJ-1562 и расширение clojure.string )

malch14:11:02

@ponimas: Я пробую. Не измерял, на глаз примерно то же самое. Проблем не нашел

niquola15:11:14

Ктонить возился с

connectionInitSql
?

thickprogrammer22:11:40

(defn func [x] (+ x 10)) (def y func) (def z #'func) (y 5) (z 5) подскажите, я правильно понимаю - после переопределения func , например, (defn func [x] (+ x 15)) y продолжает ссылаться на старую функцию func , а z всегда при вызове будет резолвить текущее значение символа?

dottedmag23:11:01

@thickprogrammer: По эффектам - да, по смыслу - нет.

dottedmag23:11:00

(def y func) складывает в переменную y функцию func. (def z #'func) складывает в переменную z переменную func.

dottedmag23:11:35

boot.user=> (defn func [x] (+ x 10))
#'boot.user/func
boot.user=> (type func)
boot.user$func
boot.user=> (def y func)
#'boot.user/y
boot.user=> (type y)
boot.user$func
boot.user=> (def z #'func)
#'boot.user/z
boot.user=> (type z)
clojure.lang.Var
boot.user=>

dottedmag23:11:27

Почему это работает? clojure.lang.Var резолвится в значение переменной, когда его трогают (через @ или на первом месте в исполняемой форме).

dottedmag23:11:55

(@z 1) тоже работает :)

thickprogrammer23:11:16

не совсем понял. что означает - "складывает в переменную y функцию func " - ссылку на функцию ? если так , то я не понимаю - почему "по смыслу нет". т.к. в "у" у нас ссылка на старую функцию, а в "z" ссылка на "func" , при резолве которого, получаем ссылку на новую функцию.