Fork me on GitHub
#clojure-russia
<
2017-05-31
>
mike_ananev03:05:21

@yogthos Поиграл с lumo. Взял простые примеры для Node.js с https://www.tutorialspoint.com/nodejs/nodejs_first_application.htm Поиграл с чтением локальных файлов и созданием примитивного web-сервера. Просто повторил приведенные примеры в синтаксисе ClojureScript. Все работает. Действительно, надо попробовать пописать скрипты на этом lumo вместо bash'a. Выглядит перспективно.

yogthos03:05:47

это к стати тоже интересно https://github.com/eginez/calvin

akond07:05:52

@achikin опять на промисах и колбеках писать?

y.khmelevskii07:05:35

уже вовсю используются async/await

akond08:05:37

async тоже не сахарный. нельзя внутри синхронной функции использовать await. получается всегда нужно заранее писать на async/await.

akond08:05:54

это в js

mike_ananev08:05:14

@nicola вчера упоминали про aot в системных сервисах на clojure. что имелось в виду под AOT? Наличие :gen-class в каждом файле и :aot :all в секции uberjar или что-то еще? я просто всегда пишу :aot :all и :gen-class на автомате. Для меня AOT именно это. Может быть есть что-то еще?

achikin09:05:35

Да, вот хотел предложить темы для следующих выпусков если еще не было. :aot, :gen-class и прочие настройки для jvm.

achikin09:05:17

Например когда надо делать :aot а когда это вредно.

achikin09:05:45

Нет, сам clojurescrpit там хорошо работает, но если ты хочешь стороннюю библиотеку, например clj-http - придется приложить усилия и “простенький скрипт” уже не получится.

niquola09:05:05

@achernik - именно это и имелось ввиду

achikin10:05:37

Ну а почему тогда в стандартном темплейте lein есть :skip-aot?

andre11:05:53

как-то хенгаут ушел в специфику формочек, и для тех кто хочет познакомится с ре-фрейм не очень познавательно будет. для большинства проектов хватает того что предлагает ре-фрейм, и это круто, его хватает. не надо ничего придумывать доделывать, ну можно если захочется всякие удобняшки, но в целом его плюсы такие, один раз ознакомился и понял и все. дальше оно все очень хорошо просто работает, буквально за минуты вы можете делать правки в чужом проекте, особенно если использовать re-frisk, т.к. структура проекта любого размера сразу вам хорошо понятна и вы быстро можете найти интересующий вас код, вы не увидите там ничего нового, в чем вам придется разбираться, весь стейт (мозг) в одном месте, ивенты (кровеносные сосуды) видны как распространяют дату по приложению. Так же упомянули что работает быстро, да, работает действительно быстро, есть дедупликация подписок, т.е. если вы работает с реагентом у вас все реакции всегда будут пересчитываться. в ре-фрейме сабскрибшены которые не активны ( т.е. нет замаунтеных вьюх которые подписаны на эти сабскрибшены) не будут пересчитываться, плюс дедупликация, одинаковые компутации не выполняются, только одна. Ивенты тоже решают две важных задачи, производительность. т.к. реализована finite-state-machine на goog.async.nextTick, и вся ваша логика разбита на маленькие чистые функции которые выполняются в каждом тике, плюс разбивая вашу логику на маленькие чистые функции очень легко находить ошибки в коде, с ре-фрейм я вообще забыл что такое дебажить код, две вещи которые могут произойти в рантайме это хиккап не валидный. и ошибка в ивенте, вот ошибку хорошо бы в re-frisk отловить, но пока re-frame не предлагает никакой реализации для этого, я разговаривал с Майком, в планах есть, т.е. если произойдет ошибка в ивенте этот ивент подсветится красным. RN приложение писать на re-frame просто сказка. Т.е. для большинства проектов ре-фрейм предлагает паттерн которого вам хватит, вам не придется чего -то придумать дописывать расширять итд. Ну разве что Make Views Great Again https://github.com/Day8/re-frame/issues/299

achikin11:05:28

Мне наоборот понравилось что подняли важные темы и поговорили про то, чего нет в re-frame и про то как организовывать большие проекты. С re-frame “из коробки” любой сам в состоянии разобраться.

achikin11:05:52

Ошибки на самом деле иногда это боль. Невалидный hiccup сложновато искать.

andrewtropin12:05:54

Хотел спросить, кто чем работает с sql'ом? А если точнее, то хотелось бы услышать плюсы и минусы korma и hugsql.

rmuslimov13:05:10

korma старая библиотека не обновлялась давно, по зависимостям могут быть конфликты. Я бы не стал ее больше брать только изза этого

kronos_vano13:05:43

Ловили недавно баг, не срабатывал жавоский булеан в кложе. Оказывается (= (Boolean. false) true). Конечно не стоит юзать Boolean. но если это делает внешняя java библиотека то выбор у тебя не большой

povloid13:05:59

@rmuslimov - korma нормальная либа. Пока не подводила. Да и развивать там особо уже нечего

povloid13:05:15

но для репортов лучше юзать yesql

rmuslimov13:05:21

@kronos_vano в “joy of clojure” этому факту целая страница посвящена

kronos_vano13:05:40

И что там рекомендуется?

rmuslimov13:05:01

по-моему смысл был остерегаться

kronos_vano13:05:48

Остерегаться чего? java библиотек которые это делают? К сожалению в нашем случае не получится 😞

andrewtropin09:06:30

nicola: Как вы делаете например pagination? Добавляете в каждый запрос limit и offset? Возникает проблема излишнего копипаста. Возможно есть какие-то приятные фичи у honeysql, которых нет у hugsql, чтобы делать подобные штуки удобнее?

niquola11:06:53

: limit & :offset ;)

niquola11:06:16

А в чем проблема?

andrewtropin13:06:00

Получается, что мне в одном месте нужно провалидировать значения этих параметров в кложе, потом добавить в .sql файл limit & offset, потом добавить в респонс Link header. Получается три места куда нужно что-то написать, чтобы появилась пагинация, это ещё не считая параметров эндпоинтов у компожуры. кажется, если бы sql генерировался из какой-нибудь структурки данных, все эти три места можно было сократить до одного вызова функции. Хотя код сейчас структурирован так, что всё равно хэдеры отдельно в респонс добавлять придётся. И в итоге и правда не так много профита получится, но тем не менее, два места (валидация и sql) сократится до одного.

andrewtropin13:06:09

небольшой оффтоп: а какой стэк вы на бэке используете? веб-сервер, component/mount, какую либу для роутинга и т.д.

niquola16:06:55

Ты видимо спутал с yesql - https://github.com/jkk/honeysql

niquola16:06:08

honeysql и есть структурка данных

andrewtropin10:06:37

facepalm I'm blind 😃 Да, спутал. Тогда всё встало на свои места.

andrewtropin10:06:04

Спасибо за инфу про стэк.

andrewtropin10:06:49

Ещё вопрос, а вы что-то типа swagger используете? или как документируете свои апишки?

dottedmag16:05:50

@kronos_vano Ловить на стыке и конвертить 😞

kronos_vano16:05:40

dottedmag: Так и делаем. Но поймать это было непросто

artemyarulin17:05:36

>(= (Boolean. false) true) а можно объяснить для тупых почему так?

dragoncube18:05:24

а в чем вопрос то?

dragoncube18:05:33

user=> (= (Boolean. false) true)
false

fmnoise18:05:28

видимо разные версии кложи/жвм

artemyarulin18:05:24

т.е. в какой-то версии это тру, прально я понимаю?

dragoncube19:05:27

очень странно там последние изменения были 7 лет назад

dragoncube19:05:40

из разных потоков не сравнивали случайно? 🙂

artemyarulin19:05:29

ага, подозрительно чота

dragoncube19:05:11

полез в исходники посмотреть, а там такооое 🙀

dottedmag19:05:26

@artemyarulin Потому что любой джава-объект в булевом контексте тру

dragoncube19:05:57

куски кода закоменнченые, всякие print’ы и ноль комментов

dottedmag19:05:16

@dragoncube Так проблема-то в том, что (= (Boolean. false) false) тоже false.

dottedmag19:05:48

@dragoncube Комментарии тут особенно не нужны, компилятор вполне себе понятный, если вчитаться.

dragoncube19:05:17

user=> (= (Boolean. false) false)
true

dottedmag19:05:40

гм, было ж по-другому?

dragoncube19:05:53

@dottedmag ну может не нужны, но код выглядит КРАЙНЕ не аккуратно

dragoncube19:05:26

user=> (= (Boolean. false) false)
true
user=> (= (Boolean. false) true)
false
user=> (= (Boolean. true) true)
true
user=> (= (Boolean. true) false)
false

dottedmag19:05:00

@dragoncube А, не в сравнении! В булевом контексте.

dottedmag19:05:07

Попробуй (if (Boolean. false) true)

dragoncube19:05:32

ну так это другое дело

dottedmag19:05:33

И, соответственно, (if (boolean (Boolean. false)) true)

dragoncube19:05:56

это то понятно почему

dragoncube19:05:51

в этом контексте (Boolean. false) эквивалентно (Integer. 1)

dragoncube19:05:25

ну или (Integer. 42)

artemyarulin19:05:46

аааа, а то нагнали паники понимаешь))

dragoncube19:05:55

потому что (Boolean. false) это инстанс нового объекта который совсем не тот на который ссылается кожуриный компилятор когда упоминается false

artemyarulin19:05:39

а в жаве самой кста new Boolean(true) != true ?

dragoncube19:05:08

public class Main {

  public static void main(String [] args) {
    
    System.out.println(System.identityHashCode(new Boolean(false)));
    System.out.println(System.identityHashCode(false));
    System.out.println(System.identityHashCode(Boolean.FALSE));
    System.out.println(new Boolean(false) == Boolean.FALSE);
    
  }
}

dragoncube19:05:15

java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
   
1252169911
2101973421
2101973421
false

dragoncube19:05:22

с true такая же история

artemyarulin19:05:09

а если в if контексте if (new Boolean(false)) то оно как себя ведет? Или компилятор потребует к bool привести?

artemyarulin19:05:59

ага, а хотя пофег, я думаю редко кто оборачивает true|false в Boolean

dragoncube19:05:10

ну бывает

dragoncube19:05:35

потому как в коллекциях примитивные типы нельзя хранить

dragoncube19:05:54

в твое примере сначала будет unboxing который приведет к примитиву false

dragoncube19:05:58

и уже два примитива будут сравниваться

misha21:05:51

(true? (Boolean. false))
=> false
(true? (Boolean. true))
=> false
(true? (Boolean/TRUE))
=> true
(true? (Boolean/FALSE))
=> false
(true? (boolean (Boolean. true)))
=> true

dragoncube22:05:25

это кстати показательный полный interop с Java 🙂 все точно также

andrewtropin09:06:30
replied to a thread:honeysql

nicola: Как вы делаете например pagination? Добавляете в каждый запрос limit и offset? Возникает проблема излишнего копипаста. Возможно есть какие-то приятные фичи у honeysql, которых нет у hugsql, чтобы делать подобные штуки удобнее?