Fork me on GitHub
#clojure-russia
<
2017-02-01
>
dottedmag07:02:24

Тривиальный проект 1k LOC? Это обычно уже не тривиальный, а огромный. Или там питона 1k LOC? 🙂

rmuslimov07:02:51

начали только на cljs писать уже 791 total

niquola08:02:53

vase оч похоже на то что мы делаем, только мы за основу взяли json-schema, postgresql/jsonb and route-map 🙂

mike_ananev08:02:03

залез я посмотреть этот vase, а за ним pedestal и как-то разочаровался от pedestala: документация сырая, местами вообще отстутствует. Контейнер сервлетов jetty вешает repl при старте, даже Тим Балдридж на демо нарвался на это и не смог исправить.

kronos_vano08:02:59

tl;dr: чувак перепутал серваки

kishanov08:02:57

их там в этом когнитекте рич покусал и теперь все делают simple. хоть бы один написал нормальные туториалы и сделал нормальные обертки-интерфейсы чтобы было easy

kishanov08:02:53

каждый раз выезжает красивый блогпост вида “мы все сделали офигенно, вот вам либа”, идешь на гитхаб - а там боль и страдания

mike_ananev08:02:21

@kishanov а откуда инфа, что покусал? или это оборот такой 🙂

kishanov08:02:28

оборот, наверное. сколько не смотрел презентаций когнитековцев, они одно и тоже далдонят, как зомбаки

kishanov08:02:13

вон тот же Стю неделю назад написал блогпост про схемы в датомике - вольный пересказ толка “speculation"

mike_ananev08:02:45

что поделаешь - просвещенный авторитаризм видимо царит у них

kishanov08:02:54

“культ ричности"

mike_ananev08:02:54

что в отдельных случаях не так уж плохо

maxim09:02:20

За последнее время Pedestal прибавил в документации, раньше там вообще скудно было.

maxim09:02:35

Пока luminus и duct, мне кажется, хороши для быстрого старта

kgofhedgehogs10:02:50

Всем привет. Тут можно задавать глупые вопросы и просить о ревью кода? Сообщества по Clojure для новичков я не нашел

kronos_vano10:02:08

так и будешь во всех чатиках разрешение спрашивать?)

kgofhedgehogs10:02:37

Бывают разные, вдруг тут все злые. Надо быть осторожным

mike_ananev10:02:45

@kgofhedgehogs а что ник значит?

kgofhedgehogs10:02:18

@mike1452, килограмм ёжиков

kgofhedgehogs10:02:00

Вот ф-я парсящая строку разделенную \newline и delimiter'ами в хэшмеп с 2Д индексами. Мне кажется, что у меня слишком большой уровень вложенности. Есть способ переписать ф-ю умнее? Я имею ввиду не -> ->>‘ и as->`, а, например, способ избавиться от flatten, например. Еще интересно соответствует имя ф-и clojure стилю

(defrecord Point [x y])
(def delimiter #" ")

(defn str->cells
  "Converts string with cells separated with 
  delimiter and new lines to Points hash map"
  [^String s]
  {:pre [(re-matches #"^((?:^|\s)(?:.|\s)(?=\s|$))+$" s)]}
  (apply
    hash-map
    (flatten
      (map-indexed
        (fn [y line]
          (map-indexed
            (fn [x value] [(Point. x y) value])
            (str/split line delimiter)))
        (str/split-lines s)))))

;; Пример работы:
(str->cells "1 2\n3")  ;; -> {#Point{:x 1, :y 0} "2", #Point{:x 0, :y 0} #Point{:x 0, :y 1} "3"}
Этот же код на пастбин http://pastebin.com/xLmLAk5Y

mike_ananev10:02:40

@kgofhedgehogs пример исходной строки есть?

mike_ananev10:02:02

а вижу, но он как-то не похож на то что парсится

kgofhedgehogs10:02:49

@mike1452: типа так.

Y\X 0 1
0   1 2
1   3

mike_ananev10:02:19

из примера не понятно как связаны аргументы "1 2\n3" и выходной результат. может быть для входных данных "1 2\n3" должна быть выходная структура {#Point{:x 1, :y 2} "3"} ?

nwalkr10:02:09

так написано же - мап с индексом-2д-позицией элемента в файле

kgofhedgehogs10:02:31

@mike1452: позиция символа. Delimiter это сдвиг по X, \n сдвиг по Y

kgofhedgehogs10:02:59

Грубо говоря в Y помещается кол-во \n до текущего символа, а в Х кол-во delimiter'ов с последнего \n

nwalkr10:02:02

я бы переписал это в обычную рекурсию, а то и в reduce по подготовленному потоку токенов.

kgofhedgehogs10:02:32

@nwalkr: а пример можно?

nwalkr10:02:33

пока нет. скажем так, к чему бы я стремился - одна сущность, которая делает из строки seq токенов, вторая делает seq<Token> -> seq<Pos, Data>. ну и дальше это уже обрабатывать как угодно.

nwalkr10:02:21

я наверное переобобщаю, но меня недавно покусали csv-файлы по 200мб.

kgofhedgehogs10:02:20

Я второй день изучаю кложур, совсем ничего не понял. Можно ключевых слов чтобы погуглить?

nwalkr10:02:44

clojure sequences

nwalkr10:02:31

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

kgofhedgehogs10:02:24

Ну а название моей ф-и в clojure стиле?

nwalkr10:02:32

мне кажется, вполне

kgofhedgehogs11:02:53

@nwalkr: а пример ждать или забить? :)

nwalkr11:02:08

ну я сейчас попробую накидать

edbond12:02:01

Подскажите как можно короче записать? (first (filter #(= (:id %) id) (:snippets db)))

glebkaf12:02:01

Я такое выражение обернул в find-first функцию и использую где нужно, получается на две скобочки короче 🙂

mike_ananev12:02:17

@kgofhedgehogs у меня вот так получилось

mike_ananev12:02:12

результат вывода (str->cells++ "1 2 3 4\n5\n6 7") идентичен результату твоей функции

kgofhedgehogs12:02:02

@mike1452: спасибо. Чем for и loop лучше map-indexed? С map-indexed не надо инкрементить, использовать nth и заморачиваться с рекурсией

mike_ananev12:02:30

@kgofhedgehogs в общем я стараюсь чтобы код функции не занимал больше 5-7 строк и выполнял строго атомарное действие

mike_ananev12:02:33

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

kgofhedgehogs12:02:50

@mike1452: согласен, поэтому понятен вынос действия аналогичного моей второй неименованной ф-и в отдельную ф-ю

mike_ananev12:02:37

именно. анализировать простые функции легче

kgofhedgehogs12:02:27

Но луп и фор вместо map-indexed мне не понятен :)

nwalkr12:02:38

у меня получилось заметно сложнее, зато ленивое

kgofhedgehogs12:02:02

У меня не ленивое? Что его заставляет вычислиться?

mike_ananev12:02:25

@kgofhedgehogs я просто привык к loop-recur

mike_ananev12:02:45

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

mike_ananev12:02:57

результат я могу так же эммитить чанками

kgofhedgehogs12:02:13

Мне кажется это что-то императивное, а не функциональное. Я не прав?

kgofhedgehogs12:02:00

@nwalkr, а где твой вариант?

nwalkr12:02:54

со всеми характерными чертами

nwalkr12:02:50

но мне не очень нравятся вот эти merge

kgofhedgehogs12:02:32

@nwalkr: если придраться, то на выходе не хешмап

nwalkr12:02:55

(into {} (str->cells …))

nwalkr12:02:35

ну и поправить [x y token] на [[x y] token]

kgofhedgehogs12:02:00

@nwalkr О как. Спасибо А почему именно into? Разве (hash-map (str->cells)) не будет работать?

kgofhedgehogs12:02:21

Вернее, я вижу, что он работать не будет...

kgofhedgehogs12:02:40

Ай. Забей. пошел читать про into

nwalkr12:02:24

основные идеи я почерпнул из http://blog.malcolmsparks.com/?p=17

nwalkr12:02:55

очень познавательно

pacman12:02:30

Всем доброго времени суток. В общем хочется спросить тех кто юзает emacs+cider - временами дико тормозит на больших фалах с расширением .clj - это както лечится?

seryh13:02:44

У меня тормозил из за linum-mode

kgofhedgehogs13:02:17

Как это в один хешмап склеить?

(list 
  (list {:a 1} {:b 2})
  (list {:c 3}))

nwalkr13:02:13

(apply merge (apply flatten [t])) но мне как-то не нравится

kgofhedgehogs13:02:02

Чет просто flatten сработал

kgofhedgehogs13:02:24

(->> (list 
       (list {:a 1} {:b 2})
       (list {:c 3}))
     (flatten))  ;; ({:a 1} {:b 2} {:c 3})

kgofhedgehogs13:02:42

А. У меня получился не один хешмап, сорри

kgofhedgehogs13:02:44

(->> (list 
       (list {:a 1} {:b 2})
       (list {:c 3}))
     (flatten)
     (apply merge))
@nwalkr: Вот так сработало. Короче чем у тебя на один apply

kgofhedgehogs13:02:34

Извиинте за флуд. Совместил код @mike1452 со своими map-indexed, получилось читаемее:

(defn line->cells
  "Converts string with cells to sequence of maps of Points"
  [^Long y ^String line]
  (map-indexed
    (fn [x value] {(Point. x y) (hex->num value)})
    (str/split line delimiter)))

(defn str->cells
  "Converts string with cells separated with
  delimiter and new lines to Points hash map"
  [^String s]
  (->> s
       (str/split-lines)
       (map-indexed line->cells)
       (flatten)
       (apply merge)))
Коллекция не ленивая получается, правильно понимаю?

nwalkr13:02:25

но оно тебе надо?

nwalkr13:02:49

вообще, то, что я написал называется преждевременной оптимизацией, и за это бьют

kgofhedgehogs13:02:25

Неа, просто интересуюсь У меня флеттен делает ее не ленивой? Или что?

nwalkr13:02:01

flatten вроде нет

kgofhedgehogs13:02:08

А что тогда?

nwalkr13:02:42

а вот apply merge у меня вызвает глубочайшие сомнения

nwalkr13:02:48

ну и да

kgofhedgehogs13:02:08

Что за сомнения?

nwalkr13:02:39

str/split-lines/`str/split` разве возвращают seq?

nwalkr13:02:59

merge берет список мапов и возвращает мап. к ленивым seq он точно не имеет никакого отношения.

nwalkr13:02:22

split-lines тоже возвращает vec, что тоже не про то

kgofhedgehogs13:02:33

Ну т.е. ни намека на ленивость в моем коде нет? 🙂

nwalkr13:02:58

ну, все, что в середине между split-lines и apply должно быть lazy seq

mike_ananev13:02:09

@kgofhedgehogs Как впечатления от языка на 2й день изучения?

mike_ananev13:02:29

и с какого языка переход?

kgofhedgehogs13:02:08

@mike1452: никогда раньше не программировал на функциональном языке. Пока что очень рад. Кажется, это мой новый любимый яп. Все выглядит очень изящно. До этого программировал на C#, Python и js.

nwalkr13:02:43

а чем тебе c# не функциональный? Х)

mike_ananev13:02:47

@kgofhedgehogs у языка есть одна проблема. после него на других языка писать просто неудобно становиться.

kgofhedgehogs13:02:11

@nwalkr , ну я там активно использовал linq, но захотел узнать что такое именно фп, а не смесь всего подряд

artemyarulin13:02:50

шарп много чо фп могет, но все равно ооп/классики фе

nwalkr13:02:20

можно еще f# потрогать, он прикольный

kgofhedgehogs13:02:05

@mike1452 вот подозреваю, что потом от c# буду много корчиться. Но это просто дело привычки

kgofhedgehogs13:02:43

Очень понравилась концепция отсутствия переменных в привычном до этого смысле

artemyarulin13:02:21

репл драйвен девелпмент еще не прощупал? Я после этого на другие языки смотреть не могу(

mike_ananev13:02:23

repl driven разработка просто киллер фича (одна из)

kgofhedgehogs13:02:28

В питоне много ванлайнеров с лямбдами и мапами много ваял раньше. Даже до рекурсивных анонимных лямбд упарывался

kgofhedgehogs13:02:56

Я правильно понимаю, что вы говорите об интерактивности прямо в редакторе? Типа пишешь код и тестируешь его прямо там же

kgofhedgehogs13:02:21

Ну вот пока очень нравится, но не использую на полную. Не привык

mike_ananev13:02:59

@kgofhedgehogs нужно настроить ide и все хоткеи для работы с кодом: отправка его в репл

kgofhedgehogs13:02:15

Я использую lighttable. Тут как-то скудно по функционалу

kgofhedgehogs13:02:26

Мб я просто не нашел нужной кнопки, которая прокачает всё

nwalkr13:02:14

в lighttable очень крутые инстареплы

kgofhedgehogs13:02:33

Ну я могу выделять код и экзекутать его. Это классно. Но тут вроде больше ничего нет

nwalkr13:02:35

но они сейчас плагин

nwalkr13:02:47

а что ты хотел еще?

nwalkr13:02:06

если хочешь прям ide - бери cursive

artemyarulin13:02:29

емакс бери (let’s the holy war begin! troll )

kgofhedgehogs13:02:51

Не не. Я не дорос до емакса

kgofhedgehogs13:02:30

> а что ты хотел еще? @nwalkr можно в лайт тейбл сделать отдельный репл, чтобы документацию не вызывать не записывая команду в мой рабочий исходник, например? И split, чтобы несколько файлов сразу смотреть. И к башу доступ, чтобы lein команды использовать

artemyarulin13:02:52

а зачем тебе лейн?

hippo13:02:53

@kgofhedgehogs тебе определенно нужен emacs

nwalkr13:02:01

или курсив

nwalkr13:02:09

так проще будет

artemyarulin13:02:36

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

nwalkr13:02:02

lighttable очень прикольный, но тоже конструктор

artemyarulin13:02:15

его ж вроде как бы забросили не?

nwalkr13:02:18

причем, отвратно документированный

nwalkr13:02:28

да не, кто-то вроде пишет

kgofhedgehogs13:02:41

>@artemyarulin а зачем тебе лейн? ну тесты запустить, например

artemyarulin13:02:49

изначальный автор ушел пилить мега тему http://witheve.com

artemyarulin13:02:14

должен быть хоткей, репл же. В емаксе например C-c C-t n

nwalkr13:02:20

можно считать, лайттейбл все

hippo13:02:57

да бери курсив и не заморачивайся

kgofhedgehogs13:02:03

Ща посмотрю

hippo13:02:04

там и тесты и репл

kgofhedgehogs13:02:17

А скобки там разноцветные?

nwalkr13:02:32

и лицензия опенсорс там такая же как в community идее

hippo13:02:33

насколько я помню, нет)

nwalkr13:02:43

есть там разноцветные скобки

nwalkr13:02:46

если настроить

kgofhedgehogs13:02:57

Сложно? Или просто плагин поставить?

artemyarulin13:02:25

тут народ кста атом счас прокачивает, вроде все ок там и из коробки

misha13:02:30

и паринфер сразу включай

hippo13:02:46

@artemyarulin и репл есть и eval-last-expr?

artemyarulin13:02:41

@hippo да вроде как есть, я сам не юзал

kgofhedgehogs13:02:01

cursive это плагин для intellij?

kgofhedgehogs13:02:11

оке. ща поставлю

hippo13:02:47

@artemyarulin слишком хорошо, чтоб быть правдой

artemyarulin13:02:09

ну дак хипстерский редактор, графики из данных все дела)

nwalkr13:02:26

я не верю как-то в атом

artemyarulin13:02:46

а ты в чем пишешь кложуру?

misha13:02:58

в уме kappa

nwalkr13:02:00

мелочевку в lighttable, что посерьезнее в курсиве. я еще не склонился куда-то окончательно.

nwalkr13:02:33

курсив подкупает тем, что в библиотечном коде копаться легко.

hippo13:02:51

и дебаггер вроде норм в курсиве

nwalkr13:02:06

вот был бы курсив с идеей еще чуточку полегче, цены бы им не было

kgofhedgehogs14:02:17

оффтоп: intellij так на pycharm похожа. Нельзя его функционал в intellij встроить?

alexander_mihailov14:02:56

Так накати плагин для питона?

nwalkr14:02:15

не, плагин для питона так себе

nwalkr14:02:33

а вот вкатить cursive в pycharm можно попробовать

misha14:02:50

подожди месяцок, и тебе больше не понадобится pycharm

kgofhedgehogs14:02:20

Я им и не пользуюсь. Просто думаю о возможных вариантах сокращения кол-ва редакторов и иде

alexander_mihailov14:02:40

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

alexander_mihailov14:02:15

Emacs хорош когда не нужно писать на джаве. У меня так и не получилось распинать интеграцию с eclipse'ом.

kgofhedgehogs14:02:16

Так. Я установил cursive. Проект все еще ляйном создавать?

alexander_mihailov14:02:42

Хотя можешь и через идеевский диалог создания проекта.

kgofhedgehogs14:02:54

Я там курсив не вижу

kgofhedgehogs14:02:49

Ага. Надо было просто перезапустить intellij

kgofhedgehogs14:02:02

Так. Все работает. Курсив установил. Вопрос продублирую. Можно ли скобки цветными сделать и как вызватьь instarepl?

alexander_mihailov14:02:29

Language & Frameworks > Clojure > Rainbow parentheses

kgofhedgehogs14:02:02

И еще. Я на репл жму, а он пустой какой-то

alexander_mihailov14:02:22

run configuration для repl заведи и запускай его.

kgofhedgehogs14:02:34

> instarepl? Чтобы как в лайттейбл выделять строку и исполнять ее в репл. Или нет тут такого?

kgofhedgehogs14:02:21

Репл завелся

kgofhedgehogs14:02:23

Так. Понял. Тут шорткат, чтобы текущее выражение в этот репл отправить

misha14:02:37

сначала создаешь настройки, чтобы по клику дебаг/ран запускалось, что ты там настроил (репл) потом запускаешь потом биндишь себе: отправить текущую форму в репл, загрузить весь неймспейс в репл, и тд

kgofhedgehogs14:02:44

Спасибо. Делаю

misha14:02:13

что такое паринфер знаешь?

misha14:02:37

должен быть по-дефолту включен: выделяешь строки и уровень вложености им меняешь tab/shift-tab

misha14:02:04

песня

kgofhedgehogs14:02:08

Нет, не знаю, но по дефолту не работает

misha14:02:59

preferences > editor > general > smart keys

misha14:02:48

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

kgofhedgehogs14:02:50

Еще мне не дают ставить закрывающиеся скобки самому

kgofhedgehogs14:02:13

Parinfer включен

misha14:02:16

привыкнешь™

kgofhedgehogs14:02:02

А как закрыть-то??

kgofhedgehogs14:02:09

Как бы не табался. не закрывается

misha14:02:32

значит что-то еще не настроено, там с этим был гемор

kgofhedgehogs14:02:38

Через ctrl+c + ctrl+v закрыл

kgofhedgehogs14:02:05

Так. С Мишей в личке всё разрулили. Всё закрывается

misha14:02:45

надо было в выпадайке выбрать паринфер индент мод

kgofhedgehogs15:02:52

зачем иногда перед скобками ставят кавычку? Причем разные: ` или '

kgofhedgehogs15:02:39

Вот, например, есть некоторая плоскость. На ней есть некоторые значения имеющие x и y координаты. Большая часть плоскости не содержит значений. Т.е. по некоторым x и y nil. Какую бы структуры для хранения значений вы бы выбрали, чтобы быстро получать данные, добавлять и изменять? И чтобы не сильно сложно было. Размер плоскости по x и y до 1к ячеек

kgofhedgehogs15:02:21

Я вот выбрал hash-map, в кач-ве ключей которого экземпляры (defrecord Point [x y])

kgofhedgehogs15:02:48

И пытаюсь выбрать что лучше для ключей : экземпляры (defrecord Point [x y]) или просто хеш-мапы {:x "x", :y "y"}

kgofhedgehogs15:02:04

И я предпочитаю чтобы в коде было читаемость > производительность

kgofhedgehogs15:02:16

(я делаю conway's game of life)

misha15:02:53

{[x y] v}?

misha15:02:54

(assoc-in [{5 :foo} {100 :bar}] [1 50] :baz)
-> [{5 :foo} {100 :bar, 50 :baz}]

kgofhedgehogs15:02:17

> {[x y] v} Вот так как-то

nwalkr15:02:31

блин, я никак не могу добиться вызова RejectedExecutionHandler от ThreadPoolExecutor

nwalkr15:02:50

я что-то вообще не понимаю

misha15:02:53

индекс в векторе = х ключ в мапе = y

misha16:02:20

может будет быстрее, чем собирать [x y] ключи

misha16:02:00

функции всё теже: assoc-in, и get-in

kgofhedgehogs16:02:27

Есть тут что-то типа питоновского timeit?

misha16:02:55

(time
  (dotimes [n 10000]
    (assoc-in [{5 :foo} {100 :bar}] [1 50] :baz)))

=> "Elapsed time: 32.835000 msecs"

kgofhedgehogs16:02:42

Отлично. А время разве не надо поделить на 10000?

misha16:02:00

это я тебе для примера

misha16:02:01

если будешь замерять всякие map - не забывай о ленивости, и заворачивай в doall

misha16:02:50

(time
  (map inc (range 1000000)))

"Elapsed time: 0.305000 msecs"

(time
  (doall
    (map inc (range 1000000))))

"Elapsed time: 1308.710000 msecs"

kgofhedgehogs16:02:13

>индекс в векторе = х >ключ в мапе = y Ну т.е. буду иметь вектор с тысячью хешмапами, большинство из которых будет пустыми. Так?

misha16:02:30

поначалу - да

misha16:02:19

посмотри сюда еще, правда тут на дефстрактах отмерших, зато от самого rich солнцеликого https://gist.github.com/spacemanaki/1093917

misha16:02:19

можно еще {x {y v}}, чтобы пустышки не хранить

kgofhedgehogs16:02:00

Что значит "отмершие" дефстракты?

kgofhedgehogs16:02:13

Что вместо них?

kgofhedgehogs16:02:13

Вижу. Спасибо

kgofhedgehogs16:02:58

Что лучше (partial reduce +) или #(reduce + %)?

misha16:02:18

в каком контексте?

kgofhedgehogs16:02:27

Вот так вообще хотел сделать, но это слишком #(reduce + (/ % (count colors)))

misha16:02:53

я обычно ->/`->>` использую вместо компоуза в таких местах (хз чем это хуже/лучше)

kgofhedgehogs16:02:18

А как мне ->> вставить вместо композа??

misha16:02:59

(map #(-> (reduce + %) (/ (count colors)) double math/round))

misha16:02:37

(macroexpand '(-> (reduce + %) (/ (count :colors)) Math/round))
(Math/round (/ (reduce + %) (count :colors)))

misha16:02:01

есть еще всякие as-> и cond->

kgofhedgehogs16:02:16

as-> знаю, про cond-> ща прочитаю

misha16:02:35

as-> хорошо, когда нить длинная, а аргумент, то первый, то последний, то посередине где-то

misha16:02:28

мне - да, всё сверху вниз как минимум

kgofhedgehogs16:02:36

Отлично

misha16:02:30

а что такое (apply map vector)?

kgofhedgehogs16:02:06

Это аналог питонвого zip(*iterable) Он типа попарно склеит элементы (apply map vector [[1 2 3] [a b c] [Q W E]]) ;; -> [[1 a Q] [2 b W] [3 c E]]

kgofhedgehogs16:02:38

в функции я перевожу переданные цвета вот так 0xRrGgBb -> [0xRr 0xGg 0xBb]" затем объединяю каналы всех цветов, произвожу операции в результате которых получается один цвет, его я перевожу обратно вот так [0xRr 0xGg 0xBb] -> 0xRrGgBb

kgofhedgehogs16:02:44

И всё это выглядит элегантно. Мне нравится clojure

dottedmag17:02:43

@yogthos Вот интересно, у тебя другие результаты наблюдений за JVM, чем у этого чувака? https://www.opensourcery.co.za/2017/01/05/the-jvm-is-not-that-heavy/

dottedmag17:02:18

А, я вижу, ты там уже накомментил 🙂

dottedmag17:02:40

Я всё забываю, что бывают ситуации, когда 256 мег на процесс - это слишком много.

prepor17:02:41

@yogthos > you're running on something like Amazon Lambda, then it does become a problem. почему? оно же кеширует прозрачно инстансы

dottedmag17:02:55

@prepor Если нагрузка маленькая, то инстансы ведь прибиваются?

prepor17:02:33

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

prepor17:02:52

окей, если "маленькая нагрузка", ок

dottedmag17:02:56

У @yogthos основная претензия к потреблению памяти маленькими ненагруженными сервисами на clojure, как я понял.

dottedmag17:02:40

@prepor Самопингать - вызвали lambda-функцию, а lambda-функция вызывает сама себя, чтобы не умереть 😃

rmuslimov17:02:42

и как часто надо самопингать чтобы не умереть?

dottedmag17:02:00

На каждом запросе вызывать самого себя.

rmuslimov17:02:43

как часто был вопрос

dottedmag17:02:48

"Рекурсия, сущ. См. рекурсия"

rmuslimov17:02:52

то есть с каким таймаутом

rmuslimov17:02:17

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

dottedmag17:02:23

Ну так перед окончанием запроса сделать асинхронный запрос самого себя.

rmuslimov17:02:56

> However, if you haven’t changed the code and not too much time has gone by, Lambda may reuse the previous container. This offers some performance advantages to both parties: Lambda gets to skip the nodejs language initialization, and you get to skip initialization in your code. Files that you wrote to /tmp last time around will still be there if the sandbox gets reused.

rmuslimov17:02:25

not too much time - это сколько интересно

artemyarulin17:02:49

implementation detail на скок я помню

yogthos18:02:21

@dottedmag I think the JVM is great for most cases, but I did find situations where Node was a better fit

yogthos18:02:43

Mainly simple services that are mostly IO oriented

yogthos18:02:47

The article mainly complains about workflow/dev process, but if you use Clojure with Node, it's the same tooling as the JVM

dragoncube18:02:06

все от scale зависит, если таких сервисов с пяток и нагрузка маленькая, то overhead от JavaScript будет не заметен, а вот во время девелопмента быстро рестартующая нода конечно будет сильно выигрывать

dragoncube18:02:59

а вот если нагрузка такая что надо запустить 1k инстансов на ноде и скажем с 20-100 на JVM тут уже другая экономика

nwalkr18:02:49

меня в этой ситуации печалит то, что нормальные multicore рантаймы вообще можно пересчитать по пальцам, и определенная монструозность jvm в сравнении с beam и рантаймом go очень печалит.

nwalkr18:02:21

go и erlang в плане потребления памяти и свойств gc из коробки выглядят все же гораздо приятнее. но на первом просто писать не хочется, а второй - все-таки гетто. поэтому jvm все же безальтернативна.

rkosenko18:02:56

@nwalkr Common LISP? 😉

nwalkr18:02:40

к своему стыду, про него я вообще ничего не знаю.

andmed18:02:07

жава тяжелая?... кхм. в pom.xml кложи версии 1.9 -- 3 (три) депенденси. ТРИ. этож чистый jre кмк прекрасная реализация. на проверенной платформе

andmed18:02:44

в жаве 100500 способов сделать одну и ту же вещь

andmed18:02:00

и все-со строгой типизацией trollface

andmed18:02:47

но к кложе это не относится

dottedmag18:02:56

Интересно, вот это нинасколько не ускорит ведь запуск Clojure? http://openjdk.java.net/jeps/295

rkosenko18:02:56

@andmed так, наверно, о том же и речь - для простого сервиса нужно JRE, который нынче весит почти 100МБ. А там какой-нибудь Go генерит бинарник, который даже от libc не зависит и весит при этом считанные мегабайты.

dottedmag18:02:57

А нода наговнякает на гиг спокойно.

artemyarulin18:02:09

а зачем оно нужно быстрый запуск? Для девелопмента у меня реплы месяцами живут, на проде не так важно если оно 2 или 10 секунд запускается ибо не часто же происходит и опять же если больше чем 1 инстантс то пофег, не?

dottedmag18:02:42

@artemyarulin Чем быстрее перезапуск, тем проще рестарт в продакшне.

dottedmag18:02:49

И происходит часто, если деплоить постоянно 🙂

dottedmag19:02:44

@artemyarulin Если рестарт быстрее, чем типичный таймаут на фронтэндовом прокси, то можно рестартить без проблем. Если рестарт медленнее, то нужно начинать что-то придумывать.

artemyarulin19:02:52

Дак это если один инстанс

dottedmag19:02:53

Таймаут на фронтэнде в 15 секунд - это плохо.

artemyarulin19:02:04

если инстанс один то даунтайм в любом случае неизбежен и аптайм 100 не достижим в принципе. А если больше 2 то уже пофег если 5 или 15 сек

dottedmag19:02:10

Так нет. Вот есть у тебя nginx. У него таймаут в 2 секунды и heartbeat раз в секунду. Если рестарт бэкенда быстрее секунды, то никакие запросы не получат 502.

dottedmag19:02:25

nginx можно ребутить раз в год 🙂

dottedmag19:02:53

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

artemyarulin19:02:13

чота не уверен, а ну да вот если тока затюнить

rmuslimov19:02:16

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

rkosenko19:02:23

если один из этих инстансов может выдерживать двойную нагрузку дольше времени рестарта

dottedmag19:02:47

Не всё равно, потому что 1) если твой один инстанс может выдержать нагрузку двух, то зачем два? 2) если таймаут запроса меньше типичного времени рестарта (типа, приехал запрос на фронтнэд, он его определил в один из бэкендов, и тот за время меньше таймаута смог рестартовать и обработать), то рестарт становится прозрачным для operations, и можно не придумывать спецпроцедуру для этого.

rmuslimov19:02:49

или заведи третий, загрузка >50 плохо

artemyarulin19:02:20

>1) если твой один инстанс может выдержать нагрузку двух, то зачем два? да ну это не серьездно

dottedmag19:02:27

только как hot standby

rmuslimov19:02:38

> 1) если твой один инстанс может выдержать нагрузку двух, то зачем два? High availability

rmuslimov19:02:48

а если дата сервер потух на минутку

dottedmag19:02:11

если есть возможность держать hot standby, то рестарт становится тривиальным: переключи на standby, рестартуй, переключи обратно, рестартуй standby.

rmuslimov19:02:14

ну если сервис более менен серьезный нужно уже пару серверов пусть и пустых

dottedmag19:02:43

Гугель советует N+1 всегда, впрочем. Чтобы потухание одного сервера не вело к проблемам.

dottedmag19:02:18

И N+2, чтобы потухание при апгрейдах не вело.

artemyarulin19:02:30

ну я думаю мы просто о разном грим да - если нагрузка небольшая, 1 сервак, то да, долгий рестарт может быть не комфортным. Если что-то серьезное пошло где N>2 то уже пофег

rmuslimov19:02:02

да, и второй поинт от @dottedmag тоже (выводи из оборота сервак перед ребутом)

dottedmag19:02:36

Ну да, вообще про малонагруженные сервисы начинали говорить.

dottedmag19:02:49

А там больше двух серверов только если сервить с какой-нибудь raspberry pi %)

dragoncube19:02:19

jeps/295: The JDK 9 version only supports Linux/x64

dragoncube19:02:08

видать на ARM завезут не скоро

dottedmag19:02:29

Remove the ability to request, at JRE launch time, a version of the JRE that is not the JRE being launched. thisisfine

dottedmag19:02:01

@artemyarulin В особо малонагруженных сервисах можно успеть рестартнуть между двумя запросами 😃

antonshwab19:02:00

:spock-hand::skin-tone-3: Нужна помощь. Кто нибудь пробовал cider-connect с хоста к кложуровскому реплу, который запущен в виртуальной машине?

rmuslimov19:02:07

я делал когда то давно давно, все было без проблем вроде

rmuslimov19:02:39

а что не так?

antonshwab20:02:09

Вверху мой Вагрантфайл. Поднимаю бокс, захожу в него, включаю lein и после прописываю по требованию cider-connect хост: 127.0.0.1 и порт: 1234. И ничего не происходит.

mihailt20:02:58

хмм вот только что прочитал попробовал http://www.braveclojure.com/basic-emacs/ вроде все не плохо, но как это реально все запомнить?

mike_ananev20:02:29

чет под вечер туплю. как вывести исходники функции как данные (форму), чтобы по сети строчку перегнать?

mike_ananev20:02:59

(source ) работает только для clojure.core, а мне надо мои

kishanov21:02:13

https://clojuredocs.org/clojure.repl/source - работает для всего, что определено в namespace’ах

kishanov21:02:01

там только трюк что ему нужно название функции передавать. Если ты его в переменную сохраняешь - работать не будет, будет писать source not found

mike_ananev21:02:03

@kishanov в общем понятно...

kgofhedgehogs22:02:16

Как аналогичное написать на кложур? Код на питоне:

c = defaultdict(list)
    for cell in world:
        for n in neighborhood(cell):
            c[n].append(world[cell])
neighborhood возвращает некоторую коллекцию defaultdict(list) возвращает хешмеп со спикском как дефолтным значением для любого ключа append это вставка в конец списка world это некоторый хешмеп cell это некотрый ключ из этого хещмепа n могут повторяться Ну а пока я это расписывал, я разобрался 🙂

misha22:02:06

покажи

kgofhedgehogs22:02:47

А я не написал, просто разобрался 🙂 Ща напишу. Минуту

kgofhedgehogs22:02:45

NullPointerException clojure.lang.Numbers.ops (Numbers.java:1013)

kgofhedgehogs22:02:53

Что-то не работает =|

kgofhedgehogs22:02:15

Я пожалуй, сделаю это завтра

kgofhedgehogs22:02:26

А если у тебя есть вариант, то скиь его сюда плиз 🙂

misha22:02:21

(defn tick [w]
  (->> w
    (mapcat (fn [[k v]]
              (map #(hash-map % [v]) (neighborhood k))))
    (apply merge-with concat)))

misha22:02:30

можно через транзиент заморочиться еще

kgofhedgehogs22:02:09

Напиши название функции, чтобы я погуглил

misha22:02:43

ну типа тик, как в "тик так"

misha22:02:58

пусть f будет )

kgofhedgehogs22:02:27

Всё я до завтра

rmuslimov23:02:59

@kgofhedgehogs

from funcy import first, group_by, walk_values

walk_values(
    lambda m: [v[1] for v in m],
    group_by(
        first,
        ((n, v) for cell, v in world.items() for n in neighborhood[cell])
    )))
Вот от этой питоновской версии легко прийти к кложуровской

rmuslimov23:02:14

сначала развернули, потом в два шага собрали

misha23:02:43

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

rmuslimov23:02:28

да так и есть

kishanov23:02:15

я тоже такие закорючки на питоне делал с нашими питонобойцами, которые пришли из с++. они меня выгнали из своего императивного кружка в итоге

kishanov23:02:13

хотя если с таким кодом в продакшен влезть - личная job security будет защищена

misha23:02:01

ну лист компрехеншены в питоне оч понятные

rmuslimov23:02:16

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