Fork me on GitHub
#clojure-russia
<
2017-11-14
>
rustam.gilaztdinov09:11:22

Всем привет! Некоторое время назад наткнулся на канал Timothy Baldridge на ютубе с туториалами https://www.youtube.com/channel/UC6yONKYeoE2P3bsahDtsimg/videos Заинтересовался, но стоит денег 💸 Решил потратиться, купил, посмотрел, про core.logic понравилось, и про transduce Но ситуация с тем, что и эти видео платные, плюс, например, lambdaisland тоже работает по подписке — меня очень печалит. И так в кложу неофиты не приходят, так тут еще и туториалы платные, ужс какой-то. В тредике ссылка на Я.Диск, со всеми видео с канала, кому интересно, пользуйтесь!

kuzmin_m10:11:49

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

rustam.gilaztdinov10:11:11

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

dima10:11:45

В тему видео курсов, есть еще такой ресурс: https://purelyfunctional.tv/courses/understanding-re-frame/

akond11:11:20

сколько там гигов?

igrishaev13:11:25

Вот я не пойму, зачем распространять. Ты же нарушаешь соглашение. Тебя же никто не просил об этом. И деньги ты все равно не вернешь.

dottedmag13:11:34

Из ложно понимаемого альтруизма.

igrishaev13:11:42

боже, там 3.99 в месяц.

dottedmag13:11:06

Странно, когда за курсы берут деньги в месяц. Дополнительные поборы тугодумов и занятых? 🙂

igrishaev13:11:08

Нынче везде подписка, и в общем-то это правильно.

akond13:11:34

В налоговую когда приходишь к инспектору, он тебе тоже делает подписку на их газету.

akond13:11:27

Но там rent явление частое, поэтому для них это нормально.

kuzmin_m14:11:04

а есть какой-нибудь приличный способ делать что-то вроде такого?

(with-conn 
  (fn [conn]
    (foo conn))
может быть как-то так?
(with with-conn conn
  (foo conn))
Названия тут страшненькие, но не суть. Понятно, что решается простым макросом, может быть есть что-то общепринятое?

akond14:11:33

это как способ прокидывания зависимостей?

kuzmin_m14:11:52

не совсем

kuzmin_m14:11:06

изначально я хочу делать после тестов rollback и в clojure.jdbc не получается сделать декоратор над datasource по этому пробрасывается функция with-conn

igrishaev14:11:21

а, вот что тебе нужно

kuzmin_m14:11:40

ну и бывает желание сделать что-то вроде руби блоков но тут уже руби головного мозга)

igrishaev14:11:56

(defmacro with-trx-test [& body]
  "Like with-trx, but rolls back the top-level transaction."
  `(conman/with-transaction [*db*]
     (jdbc/db-set-rollback-only! *db*)
     ~@body))

igrishaev14:11:33

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

kuzmin_m14:11:50

пойду почитаю про db-set-rollback-only!

igrishaev14:11:11

только замени conman/with-transaction на jdbc/with-db-transaction

kuzmin_m14:11:04

понятно

kuzmin_m14:11:10

как откатывать - не суть

igrishaev14:11:17

(воскл. знак на конце — часть ссылки)

kuzmin_m14:11:16

делают ли что-то вроде такого?

foo do |x|
  bar x
end
foo( x => {
  bar(x)
});

kuzmin_m14:11:31

просто беда с выравниванием

kuzmin_m14:11:43

(with-conn 
  (fn [conn]
    (foo conn))

igrishaev14:11:59

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

kuzmin_m14:11:26

это все понятно, что могу может что-то принятое есть?

kuzmin_m14:11:02

что-то вроде with-open

kuzmin_m14:11:10

но он тут не подходит

igrishaev14:11:17

я не до конца пойму, что тебе нужно, но макросы вида (with-something <variable>) очень распространены

igrishaev14:11:22

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

kuzmin_m14:11:37

foo( x => {
  bar(x)
});
пример из js6, как такое-же сделать на clojure, с нормальными отступами?

kuzmin_m14:11:24

(foo (fn [x]
  (bar x))

igrishaev14:11:25

а что делает этот код вообще?

kuzmin_m14:11:34

да просто конструкция

kuzmin_m14:11:04

var assert = require('assert');
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

kuzmin_m14:11:29

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

kuzmin_m14:11:39

а в clojure так не принятно

kuzmin_m14:11:55

и пример

(foo (fn [x]
  (bar x))
выглядит инородно

igrishaev14:11:37

то есть все, что мы обсуждали — суть холивар из-за скобок?

kuzmin_m14:11:38

как передать анонимную функию последним аргументом?

kuzmin_m14:11:49

причем тут холивар?

kuzmin_m14:11:54

из-за отступов

ponimas14:11:24

эм (foo (fn [x] (bar x)) и никаких проблем с отступами

kuzmin_m14:11:52

да, а теперь там не один bar, а десяток

kuzmin_m14:11:24

(foo (fn [x]
       (bar1 x)
       (bar2 x)
       (bar3 x)
       (bar4 x)))

kuzmin_m14:11:55

(foo
 (fn [x]
   (bar1 x)
   (bar2 x)
   (bar3 x)
   (bar4 x)))

kuzmin_m14:11:26

и теперь

foo(x => {
  bar1(x)
  bar2(x)
});

kuzmin_m14:11:08

первые 2 ИМХО выглядят как-то не очень

ponimas14:11:34

(defn xx [x] ...)
(foo xx)

kuzmin_m14:11:45

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

ponimas14:11:20

не пытаться заставить кложу выглядить как js|ruby?

kuzmin_m14:11:42

согласен

kuzmin_m14:11:01

но какая есть удобная альтернатива?

ponimas14:11:49

альтернатива чему?

kuzmin_m14:11:02

(foo (fn [x]
       (bar1 x)
       (bar2 x)
       (bar3 x)
       (bar4 x)))

ponimas14:11:22

чем не нравится?

kuzmin_m14:11:36

разбивает логику

kuzmin_m14:11:57

ну условно

(let [body (fn [conn]
                    (foo1 conn)
                    (foo2 conn))]
   (transaction conn body))

dima14:11:27

(transaction conn #(do (foo1 %) (foo2 %)))

dima14:11:27

@U1LR4AN75 так лучше отформатировано ?

kuzmin_m14:11:52

оно в длину растет

kuzmin_m14:11:11

представь что их 10

dima14:11:18

(transaction conn #(do (foo1 %)
                       (foo2 %)
                       (foo3 %)
                       (foo4 %)
                       (foo5 %)
                       (foo6 %)))
а чем так не устраивает? и как бы такой код выглядил в JS например?

kuzmin_m14:11:58

отступы большие

kuzmin_m14:11:58

т.е. не принято делать вот так

(transaction conn #(do 
  (foo1 %)
  (foo2 %)
  (foo3 %)
  ...
  (foo6 %)))

kuzmin_m14:11:49

можно сделать макрос что бы было вот так

(with transaction conn
  (foo conn)
  ....
  (foo10 conn))

ponimas14:11:53

и что не так?

ponimas14:11:10

у меня такого кода куча

kuzmin_m14:11:31

понятно

kuzmin_m14:11:58

было

(transaction conn #(do (foo1 %)
                       (foo2 %)
                       (foo3 %)
                       (foo4 %)
                       (foo5 %)
                       (foo6 %)))
стало
(with transaction conn
  (foo conn)
  ....
  (foo10 conn))
принято ли так делать?

kuzmin_m15:11:12

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

kuzmin_m15:11:39

есть же куча fn->, fn+>, ~>, +> и подобные штуки, которые похожи на ->

kuzmin_m15:11:09

(transaction conn (fn [tx]
                    (let [a (foo1 tx)
                          b (foo2 tx 123 "foo")
                          c (+ a b)
                          ...]
                      (foo10 tx c))))

kuzmin_m15:11:36

тут идея в том, что тело может быть каким угодно

kuzmin_m15:11:53

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

kuzmin_m15:11:09

вопрос в том, как обычно это делают

akond15:11:40

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

kuzmin_m15:11:24

есть фунция transaction

kuzmin_m15:11:30

она принимает коннект

kuzmin_m15:11:40

и принимает коллбэк

kuzmin_m15:11:49

в коллбэк передает транзакцию

kuzmin_m15:11:02

после вызова коллбэка коммитит транзакцию

kuzmin_m15:11:07

пример условный

kuzmin_m15:11:15

может быть что угодно

kuzmin_m15:11:42

а в коллбэке может быть все что угодно

kuzmin_m15:11:02

или нет?

akond15:11:23

то есть для тебя главное закрыть транзакцию после отработки всех кишков?

kuzmin_m15:11:50

давай абстракно

kuzmin_m15:11:58

есть нечно, что принимает коллбэк

kuzmin_m15:11:09

и это нечно что-то делает до и после вызова коллбека

kuzmin_m15:11:18

в коллбэк передается какое-то занчение

akond15:11:53

что-то типа обёртки?

kuzmin_m15:11:43

(def wrapper [callback]
  (do1)
  (callback value)
  (do2))

(wrapper (fn [value]
           (do-something value)))
                                  

kuzmin_m15:11:15

wrapper может еще какие-то аргументы принимать, до коллбэка

kuzmin_m15:11:25

(wrapper 1 2 3 (fn ....))

kuzmin_m15:11:45

т.е. в js|ruby это элементарно

kuzmin_m15:11:53

в clojure выглядит страшно

kuzmin_m15:11:05

может это как-то иначе делается?

akond15:11:46

вроде не страшно. как по мне.

ilevd16:11:29

Самое короткое, наверное, будет так

(transaction (db/req1) (db/req2))
и макросом проходить по телу и вставлять после вызова db/reqN conn, если, конечно, есть возможность отличать по названию функции что ей нужен conn.

kuzmin_m16:11:49

(def wrapper [callback]
  (do1)
  (callback value)
  (do2))

(wrapper (fn [value]
           (do-something value)))
может быть так будет понятнее

kuzmin_m16:11:27

и это do-something может быть из многих вызовов, с let и прочими конструкциями

kuzmin_m16:11:41

вернее вместо do-something

akond17:11:19

да, жаль, что мы так и не дождались стрима из #attendify

Roman Liutikov17:11:51

стрима нет, на кложе проще писать, чем настроить стрим 🙂

misha19:11:39

А сегодня ивент был, да? opieop

Roman Liutikov19:11:59

угу, еще идет, до сих пор

Roman Liutikov19:11:03

должна быть запись