Fork me on GitHub
#clojure
<
2017-09-06
>
dbushenko07:09:18

anyone knows what is with immutant? Jim Crossley committed to it last on 20th of July, and its like 1.5 month noone is working on immutant.

bendlas09:09:19

@dbushenko not familiar with immutant in particular, but in clojure-land, a project not being worked on, often means that it's done, or at least no open bugs.

bendlas10:09:44

deciding whether to use immutant is also easy: do you need or want to integrate with a JEE or JBoss environment? => use immutant Otherwise, you might be better off piecing together various agnostic libraries: pedestal, ring, liberator, ... and run them on whatever server you like

grounded_sage10:09:36

I've got an idea that I would like to discuss with someone that will help people to learn new things and get more contributions to open source.

grounded_sage10:09:36

Who would be the best person to talk to?

Tom H.12:09:31

Why must it be some*one*? šŸ™‚

manutter5112:09:49

If itā€™s Clojure-specific, Iā€™d post it here and ask people to use ā€œStart A Threadā€ to reply. If itā€™s not Clojure-specific Iā€™d take it to the #off-topic channel

jcrossley312:09:51

@dbushenko what @bendlas said šŸ™‚ we'll fix bugs as they're reported, of course.

qqq13:09:28

when defining assert-tag, is it better to do (assert-tag object keyword) or (asset-tag keyword object) ?

danm14:09:57

Are you expecting your function to mostly be used in a thread-first or thread-last pattern?

danm14:09:44

Is it working on single entities, or sequences of entities? I seem to recall the former are generally thread first (asset-tag object keyword), but if you would expect object to be a vector that could be mapped over or similar that's normally thread last (asset-tag keyword object) when called

bja15:09:38

I don't use the rest of immutant, but immutant.web is a nice way to run ring apps

stephenmhopper17:09:33

What do people typically use for running background jobs inside of a Clojure web application? In a past life, I was doing lots of web development with Scala and Play and using Akka for background jobs. With Clojure and Ring, whatā€™s a good choice for firing off the occasional background job?

noisesmith17:09:07

ScheduledThreadPoolExecutor comes with the vm, but there are handy wrappers like At-At if you need it

noisesmith17:09:31

thereā€™s also Pulsar if you need to get fancy (eg. distributed state among many servers)

rcustodio18:09:18

Hello everybody

rcustodio18:09:59

I'm new at clojure and functional programming, I hope to learn a lot to get the better of it

ghadi18:09:37

welcome @rcustodio ! may I suggest joining the #beginners room? there are a lot of useful people in there

rcustodio18:09:04

Thanks @ghadi!! I will go there

rcustodio18:09:09

To ask questions

ghadi18:09:51

Good luck on the journey. Clojure is a fun time

stephenmhopper18:09:21

@joelkuiper @noisesmith Thanks for the suggestions, Iā€™ll start with those!

yonatanel19:09:21

What's the go-to lib to process data (e.g. http post request) through a pipeline of validations, enrichment, error handling without deep branching and scattering try-catch, updating db and emitting events? The pipeline being the main thing. It doesn't need to be distributed, just expressed well.

yonatanel19:09:01

Maybe something like pedestal interceptors?

sundarj19:09:16

funcool/cats?

yonatanel19:09:26

@sundarj Doesn't seem like what I'm looking for. I want to define steps and if something fails I wanna know the step and context. Stuff like that.

hmaurer20:09:19

Jokes aside, are you sure monads are the thing to recommend @sundarj ? It seems to me that unless you are interested in the FP aspects, they wonā€™t be a very pragmatic way for someone to ā€œpipeline processing stepsā€

hmaurer20:09:28

well, no more pragmatic than -> and functions

sundarj20:09:30

i'm sure Haskellers would have something to say to you about that šŸ˜›

sundarj20:09:05

what he's asking for is a way to abstract away transforming data and errors into the same operations - that is exactly what category theory does

hmaurer20:09:16

true, true

hmaurer20:09:38

but there isnā€™t much of a practical benefit in this specific case over throwing exceptions

sundarj20:09:29

i would say not having to sprinkle try catch everywhere is a practical benefit

sundarj20:09:05

we already have nil punning in clojure to abstract away most null checks, this is more of the same

hmaurer20:09:43

@sundarj out of curiosity, do you use monads on a regular basis in your Clojure code?

sundarj20:09:31

@U5ZAJ15P0 i'll pm you so as to not clog up this thread šŸ™‚

lemontea15:09:38

aspiring (not much good) Haskell-er here: I thought the heavy category-theoretic stuff like Monad is too rigid - a pros if you're after type safety and predictability but a cons in dynamic world. But sounds like you want explicit control over the pipeline so this might be legit

hcarvalhoaves20:09:29

@yonatanel one approach is following interpreter pattern. if you have functions return instructions that will be evaluated later, any function in the middle of the pipeline can override what the final list of instructions should be

hcarvalhoaves20:09:59

you can also model as a stack machine

hcarvalhoaves20:09:13

if you want side-effects, the pedestal interceptor model or any eager pipeline is a bad approach IMO - if you delay side-effects to the end you can have better commit/rollback, pruning unneeded side-effects, etc

hcarvalhoaves21:09:16

I'm not aware of any library for this but in general, not hard to do. you can, e.g. exploit delay to decouple the functions that emit the instructions from the one that evaluates them

tbaldridge21:09:52

Agreed, this sort of stuff can easily be modeled via a set of "step" functions that are transformations from a state to a new state. If your state is immutable, rollback is free. Bonus points if (like interceptors) the steps are defined via data. Then everything is introspect-able, and you can even compose steps programmatically via other functions.

tbaldridge21:09:05

All that stuff becomes much harder once you hide it all behind opaque functions.

tbaldridge21:09:40

(as monads do)

hcarvalhoaves21:09:41

just one note: rollback isn't necessarily free (what you're doing might not be commutative), but at least you can control rollback w/ something better than try/catch

tbaldridge21:09:17

yeah, although something like the state monad doesn't help with that either

hcarvalhoaves21:09:29

e.g. your function can return [(forward-fn) (rollback-fn)]

tbaldridge21:09:37

Unless you use something like an IO monad, and doing that is just madness

tbaldridge21:09:00

@hcarvalhoaves or perhaps a record + a protocol with an optional IRollback

tbaldridge21:09:29

One of the reasons Interceptors use protocols is that once you need more than just (.invoke ...) functions become hard to use

Garrett Hopper21:09:04

Has anyone had issue with boot-reload trying to reload a file before boot-cljs has had time to write it to resources and be read to be served by your http server? (Aleph in my case; serving using ring.middleware.resource/wrap-resource)