Fork me on GitHub
#clojure-russia
<
2016-02-05
>
rm04:02:23

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

rm05:02:03

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

artemyarulin07:02:59

@rm @misha @abtv @turtle всем спасибо за комментарии, классно когда есть такая площадка где можно обсудить такие темы simple_smile Думаю пока сделаю PoC на простых графах + алгоритм Дейкстры (ну или какой еще) на достижимость. Когда насобираю данных и пойму лучше стандартные ошибки - то попробую уже перевести на core.logic. Еще кстати вопрос - кто-нить делал с ним что-нить?

prepor08:02:40

Дядя, у тебя же конечный, не цикличный граф? Тебе просто топологически отсортировать нужно и все.

rmuslimov08:02:58

ребята, у меня видимо детский вопрос - а отчего может быть что lein repl работает успешно, а lein uberjar летит в тан-тарары со следующим трейсом: Caused by: java.lang.ClassNotFoundException: com.stuartsierra.component.Lifecycle at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ….

rmuslimov08:02:52

причем и кода почти никакого нет, просто темплейт с ring-jetty-component + jarohen/phoenix

andfadeev08:02:24

:aot :gen-class везде где нужно?

rmuslimov08:02:17

:gen-class в главном неймспейсе, и :profiles {:uberjar {:aot :all} в project.clj

andfadeev08:02:17

попробуй в неймспес с компонентами добавить gen-class (https://gist.github.com/jalehman/10494205), я правда с компонентом не работаю, так что не точно

artemyarulin08:02:23

@prepor: Ушел гуглить, спасибо 😳

rmuslimov08:02:48

@andfadeev: я в какой-то момент успел везде засунуть component, как-то не помогает

rmuslimov08:02:59

ну и сейчас тоже не получилось

rmuslimov08:02:23

выложил весь проект из нескольких строк https://gist.github.com/rmuslimov/b8fff1f70e2fbb5f8bbf

andfadeev08:02:44

я зачем :exclusions [com.stuartsierra/dependency] ?

prepor08:02:08

+1. и почему :dev {:source-paths ["dev"]} ?

rmuslimov08:02:55

:exclusions написал оттого что lein deps :tree так посоветовал

rmuslimov08:02:38

а про :dev, да как то осталось - неужели это может на что то влиять

rmuslimov08:02:41

сам dev пустой

rmuslimov08:02:54

убрал обе надписи, эффект тот же

rmuslimov08:02:54

кажется я понял, если вынести phoenix/config

rmuslimov08:02:22

и убрать plugins в dev

rmuslimov08:02:27

то начинается собираться

rmuslimov08:02:44

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

artemyarulin09:02:34

ага, открыл уже эту же статью на вики

artemyarulin09:02:50

спасибо

artemyarulin09:02:52

я уже тут спрашивал, но может ты @prepor знаешь: на графах же мне не выразить что a -> b c -> d b + d -> z т.е. только когда оба b и d достигнуты, а не один из них? или может другая какая абстракция есть для этого кроме графов?

prepor09:02:17

в смысле тебе нужно иметь некий коллбэк на исполнение z если "выполнены" b и d?

artemyarulin09:02:48

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

prepor09:02:50

ну пусть у каждой ноды будет {:required-activations #{:b :d}, :activations (atom #{}) :dependants #{:x}}

prepor09:02:56

каждая нода при выполнении добавляет активации в dependants. если :activations становится суперсетом :required-activations, то оно тоже активируется. required-activations и dependants вычисляются как раз в момент сортировки.

prepor09:02:12

на самом деле это не стейт машина, а примитивный случай forward chaining

prepor09:02:38

(в противовес core.logic и пролог, которые имплементация backward chaining)

artemyarulin09:02:34

ага, во, спасибо за новый термины -ушел гуглить их

prepor09:02:10

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

artemyarulin09:02:25

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

artemyarulin09:02:27

спасибо)

prepor09:02:12

вообще, на кложе есть реализация rule engine https://github.com/rbrush/clara-rules

prepor09:02:51

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

artemyarulin09:02:06

оспади, скок новых слов:)

artemyarulin09:02:22

ок, почитаю все равно, спасибо

artemyarulin09:02:53

вообще часто вижу темин экспертные системы - это прям AI? Стоит почитать про это?

artemyarulin09:02:06

в повседневной жизни можно че применить оттуда?

rm09:02:44

спроси @nicola, вроде он пишет. Но это не аи (потому что аи не существует), а в зависимости от хитровыдуманности может быть от пачки ифов до обученной нейросети

artemyarulin09:02:38

ну почти ai ладно simple_smile

serce09:02:10

Привет!

serce09:02:27

Для планирования времени встреч я помню сервис какой использовали?

serce09:02:41

Я забыл какой, можете скинуть кто помнит?

prepor09:02:43

> вообще часто вижу темин экспертные системы - это прям AI? Это AI в тех терминах под которым его понимали в 80-х, 90-х )

prepor09:02:16

Светлоликого нашего Хики в списке есть несколько книг по тематике http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH

abtv10:02:21

@artemyarulin: когда много правил, они часто противоречивы (ибо достаточно просты, чтобы выразить что-то сложное). Лет 5 назад я не смог реализовать парсер фактов для русского языка чисто на правилах, приходилось искать и другие способы. Я использовал стеммер Яндекса для морфологического анализа, а сверху этого построил правила для синтаксического анализа и извлечения фактов. Очень часто там срабатывало несколько правил и была неоднозначность. Я дописал еще несколько правил-эвристик (т.е. у меня была иерархия правил), но до нормального извлечения фактов было очень далеко. Проект был исследовательский.

abtv10:02:49

морфоанализатор -> синтаксический анализатор -> извлекатель фактов (этапы 2 и 3 содержали разный набор правил)

abtv10:02:56

1 этап не мой

artemyarulin10:02:04

масштабно

nicola10:02:16

@artemyarulin задача оч похожа на типичную для logical programming (core.logic)

artemyarulin10:02:43

@nicola: дада, мы пришли к этому вчера, подсказали добрые люди

artemyarulin10:02:59

@abtv: А правила противоречивы - логически просто? или ошибки в коде?

artemyarulin10:02:14

т.е. не решить их в итоге никак?

abtv10:02:15

моя проблема была в том, что 1 этап может зависеть от 3 этапа, т.е. например, часть речи можно определить только на этапе семантического анализа

abtv10:02:52

правила противоречивы, потому что их составил человек и они не в 100% случаев верны

rm10:02:58

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

abtv10:02:10

или там есть еще куча условий

nicola10:02:12

Если пространство решений велико - есть солверы - у нас про них Дима Грошев на fprog. рассказывал

artemyarulin10:02:32

@nicola: солверы это чо?

artemyarulin10:02:37

термин такой?

abtv10:02:55

я это извлечение фактов писал один, слишком сложно для одного человека. в т.ч. я писал и правила. хорошо, хоть mystem был simple_smile с контекстом все очень сложно, по-идее там многопроходный алгоритм должен быть

abtv10:02:43

я описывал факт как <subject, verb-class, objects>, где subject - это набора правил для подлежащего, verb-class - набор правил для сказуемого (есть несколько типов сказуемого) и objects - объект, на который направлено действие (тоже набор правил). Они распадались на свои правила. Думаю, что анализ естественного языка - слишком сложная область просто. Для чего-то другого это можно сделать с гораздо меньшими усилиями.

artemyarulin10:02:20

оспади куда я полез simple_smile

rm10:02:11

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

artemyarulin10:02:39

да скорее всего дадут набор атомов и скажут что делов на 5 минут simple_smile

artemyarulin10:02:14

всем спасибо, ушел гуглить:)

artemyarulin10:02:45

а вот если я хочу поиграться с либой в репле, мне обязательно нужно новый project.clj создавать, добавлять депенденси туда, репл пере-запускать? Ничо нету попроще?

prepor10:02:30

> задача оч похожа на типичную для logical programming (core.logic) это обратная core.logic задача

prepor10:02:04

> А правила противоречивы - логически просто? или ошибки в коде? в рул енжинах каждое срабатывание может привести к срабатыниваю нескольких "продакшенов". что с этим делать решается каждая система по-своему, в зависимости от решаемой задачи

artemyarulin10:02:33

обратная всмысле она не решается с помощью core.logic?

prepor10:02:54

core.logic это про "у меня есть z и d, что могло привести к этому?"

prepor10:02:38

впрочем я нихрена не эксперт в лоджик программинг

prepor10:02:08

вот пусть @larhat скажет, он у нас академик

larhat10:02:33

ты больше с этим ковырялся же %)

larhat11:02:29

вот про всё это backtracking vs forward chainnig

artemyarulin11:02:26

ну вот скажите тогда хоть - тяжело начать с этим core.logic? я в своем время загорелся, месяц смотрел видео всякие, казалось бы понял - но как начал делать хелло ворлд у меня мозг взорвался и я начал заниматься другим

larhat11:02:31

ну надо reasoned schemer читать какой-нибуд, его не портанули на коре логик ещё?

be912:02:58

посоветуйте, что для SQL взять. а то библиотек развелось…

be912:02:44

задача — небольшой CRUD. хорошо бы и миграции

be913:02:49

со статьей одна беда: «I should note that I’ve never used any of these, just java.jdbc, so this is all first impressions.»

be913:02:25

а так пока думаю взять korma+ragtime

andfadeev13:02:10

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

be913:02:33

почему?

be913:02:41

кстати, как православно протаскивать db-conn в ring хандлеры? корма какой-то свой пул соединений разводит, а в honeysql и прочих как?

prepor13:02:04

> есть вот такая статья https://adambard.com/blog/clojure-sql-libs-compared/ долб писал какой-то. даже тупо фактические ошибки есть "Suricatta is a combination jdbc helper (providing some nice refinements over jdbc’s api) and Korma-esque query DSL. Here’s what the latter looks like:"

be913:02:42

«первое впечатление» …

prepor13:02:14

> кстати, как православно протаскивать db-conn в ring хандлеры? корма какой-то свой пул соединений разводит, а в honeysql и прочих как? никак, он sql формирует, что б его в базу скармливать есть например jdbc. глобальное состояние иметь с пулом почти всегда плохо

prepor13:02:02

> «первое впечатление» … там jdbc вообще нет

prepor13:02:15

о чем в первой строчке документации пишут

be913:02:05

да это понятно, что honeysql только строки формирует.

be913:02:30

вопрос сводится к тому, как jdbc-соединение протаскивать

andfadeev13:02:45

ну suricatta можно по разному юзать You can build queries with suricatta and execute them with clojure.jdbc. You can use suricatta for executing queries with string-based sql. You can combine the suricatta library with clojure.jdbc. And obviously, you can forget jdbc and use suricatta for both purposes, building and/or executing queries.

prepor13:02:50

> вопрос сводится к тому, как jdbc-соединение протаскивать mount, component, буквально вчера обсуждали

be913:02:07

чем это будет отличаться от глобального состояния?

be913:02:02

кроме большей управляемости

prepor13:02:23

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

prepor13:02:27

> чем это будет отличаться от глобального состояния? много чем. эксплицитным определением зависимостей, автоматического и правильного порядка старта / стопа, понятным механизмом DI, например

prepor14:02:17

кстати, @niwinz > using core.async channels as response but since the version 0.4.0 it is removed because core.async is not a proper abstraction for represent a promise. почему? в последнем core.async даже прям отдельный promise-chan появился

niwinz14:02:18

core.async channels does not have the notion of error and futures work much better in that place

prepor14:02:23

niwinz: я использую простое соглашение: если в канал пришел Throwable, то это ошибка, думаю в библиотеках это тоже можно использовать. Но в целом проблема есть, конечно. Зато core.async очень хорош для api к курсорам.

niwinz14:02:23

indeed, is just to much opinionated in my opinion, so I prefer leave this from the official api and allow to the user build as it needs in the application...

prepor14:02:00

ок, спасибо!

niwinz14:02:33

@prepor: do you remember our chat about http2? I have read about it, and my suspicion about its (no) beneffits in local (low-latency) networks are mostly true.

prepor14:02:48

Я тоже ) Я почитал спеку хттп2 и оно ОЧЕНЬ сложное и все что там усложнено не имеет отношения к low latency сетям

niwinz14:02:13

I really want do my own benchmarks, but is prettly clear (this is not the first article).

niwinz14:02:52

So the best usage of http2 is have a nginx/haproxy/whatever for serve content over http2 but communicate with http1 in local network nginx<->backend

prepor14:02:56

У nginx в мейлисте есть обсуждение поддержки http2 для proxy_pass.

niwinz14:02:31

Hmm as fas as I know it does not support http2 in proxy pass

prepor14:02:11

да, и там обсуждают почему и как )

prepor14:02:01

не могу найти. но в целом пишут что профита особого не будет, а работы много

niwinz14:02:51

This is the talk about that, but I don't know where are the slides. xD

prepor14:02:22

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

niwinz14:02:27

interesting

kronos_vano14:02:32

протобуфы гоняешь?

prepor14:02:02

и вся логика сбора статистики и трейсинга сосредоточена в балансере. тут бонус в том, что zmq-протокол (zmtp) очень тупой и его легко релизовать. особенно это релевантно для языков где нет нормального хттп-сервера и его сложно реализовать, например ocaml

prepor14:02:13

в окамле, как и в руби, питоне, сейчас есть gil, значит для того что бы загрузить все ядра нужно поднимать несколько процессов. обычно это решается мастер-процессом с listen и форканьем accept-процессов. но это тоже не самая простая модель в реализации. а с zmq-балансером я могу просто стартануть n-инстансов и каждый из них подключится к балансеру сам.

prepor14:02:19

kronos_vano: ага

prepor14:02:06

nicola: документация норм!

rm14:02:24

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

niwinz15:02:05

@prepor: my concern about zmq is how it plays with async io? I mean, in an example: I have catacumba as async http frontend but I want to build my backend services and communicate them with zmq. It there a simple way to use zmq in "async" way from async http frontend?

kronos_vano15:02:01

Кину с умным видом ссылку и промолчу: https://github.com/lynaghk/zmq-async

niwinz15:02:11

jeje, thanks! I know about that but is not the exactly that I'm looking

niwinz15:02:54

Hmm I think that I found myself the response 😄

kronos_vano15:02:11

Please, share

niwinz15:02:15

I have very little knowledge about zmq, and was knew only the basic socket types.

niwinz15:02:32

REQ/REP is the analogous to the rpc calls

niwinz15:02:49

But there are a DIALER socket type that is analogous to REQ but is async

niwinz15:02:26

I can send multiple REQ-like requests and later receive them as them are ready

niwinz15:02:01

in contrast to the REQ/REP that is strictly sync (you can't send multiple REQ and later receive the REP...)

prepor15:02:38

@niwinz: zmq можно разделить на две части: - Библиотеку libzmq, которая реализует довольно много своих асбтракций, поднимает io-треды, в которых читает/пишет во внешний мир, принимает соединения, реконнектится и т.д., реализует zmq-сокеты разных типов, у каждого из которых есть свой буфер. Т.е. допустим send в zmq-сокет необязательно блокирующая операция, если в буфере есть место, то данные просто туда добавятся, а реальная отправка произойдет асинхронно в тред-пуле. Тоже самое с recv, только в обратную сторону. Самое стремное, что zmq-сокеты не тредсейфны. Но есть так называемые inproc сокеты, которые работают инмемори в рамках zmq-контекста. Т.е. libzmq-путь сделать то, что тебе нужно, это поднять zmq-proxy-queue (http://api.zeromq.org/4-0:zmq-proxy), который с одной стороны будет торчать наружу, а с другой в inproc-сокет. И реализовать ивентлуп, который бы читал / писал из этого инпрок сокета ответы / запросы. Я бы не назвал это "простым способом" - Вторая часть это простейший бинарный протокол zmtp (http://rfc.zeromq.org/spec:15), который можно использовать напрямую и есть имплементации для, например, jvm (https://github.com/spotify/netty-zmtp). Тут ты уже сам полностью волен сделать нужную тебе логику со знакомыми интерфейсами. И это будет полностью совместимо с libzmq, которая может работать с другой стороны (в бекенде)

prepor15:02:33

> I can send multiple REQ-like requests and later receive them as them are ready да, но ты должен обработать это в неком ивентлупе и отроутить куда надо

prepor15:02:30

+ повторюсь, zmq-сокеты не тредсейфны, т.е. в dealer-сокет нельзя писать параллельно из разных тредов, например

prepor15:02:39

нужно через что-то синхронизировать

niwinz15:02:07

I know about thread safety

prepor15:02:07

libzmq для jvm реализовано в двух вариантах: jzmq (jni вокруг сишной libzmq) и jeromq(native java). у них одинаковый интерфейс и они swappable

niwinz15:02:27

that are your recommendation?

prepor15:02:51

Для инфраструктурных вещей (бекенд http балансера) я бы, наверно, взял netty-zmtp и сделал все поверх него. Это даст больше контроля и позволит все сделать так как надо с полностью асинхронным io. При этом бекенды можно будет писать с libzmq на любом языке в несколько строк и достаточно эффективно.

niwinz15:02:58

Very interesting! Thanks for sharing!

prepor15:02:36

@niwinz: В клиенте для руби я использую просто req-сокет. Для кложи написал обертку реализующую примерно то, о чем я писал с интерфейсом в core.async (https://github.com/prepor/clojure-lucky-client/blob/master/src/lucky_client/reactor.clj), как я и говорил, у меня не получилось "легко". Ну и это очень похоже на то, что делает zmq-async. С этим я могу писать сервер как:

(let [[backend-stopper requests] (backend/create *reactor* [""])]
  (async/go-loop []
              (when-let [[answer method body] (async/<! requests)]
                (async/>! answer body)
                (recur))))
И клиент как:
(let [client (client/create *reactor* [""])]
  (async/<! (client/request client "ping" "Hey, whatzuuup?")))

prepor15:02:01

Мы долгое время жили со стандартным libzmq-proxy-queue в качестве балансера, вот сейчас написал / пишу свое, там так https://github.com/prepor/lucky/blob/master/src/lucky/backend.go#L151 (имлементация протокола весьма простая https://github.com/prepor/go-zmtp/blob/master/zmtp.go).

prepor15:02:05

Бэкенд при этом будет выглядеть на питоне например так:

import zmq

ctx = zmq.Context()
s = ctx.socket(zmq.REP)
s.connect("")

while True:
    req = s.recv_multipart()
    s.send("reply!")

prepor15:02:53

Если еще поднять перед этим zmq-proxy-queue и поднять такие rep-сокеты в тред-пуле, то получится вполне себе такой эффективный многотредовый сервачок с буферизацией и backpressure

niwinz15:02:46

Very very nice!

niwinz15:02:02

Thanks again for sharing that!