Fork me on GitHub
#clojure-uk
<
2018-01-18
>
seancorfield00:01:53

"9. It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures." -- http://www.cs.yale.edu/homes/perlis-alan/quotes.html

chrjs10:01:49

Aha, thanks! I was quoting that at someone the other day and I couldn’t remember where it came from, so I settled on “… said some lisper” ¯\(ツ)

jasonbell09:01:23

Morning friends

otfrom09:01:40

I use defmulti/defmethod a lot, but then I do lots of msg and data processing, so I'm a bit weird compared to others (I do very little web programming)

jonpither09:01:01

Please could you spare some RT LOVE for this Clojure UK story.. @conan and his crew!

rickmoynihan09:01:22

@yogidevbear we use them quite a bit… maybe 50 defmulti’s throughout our codebase, with a few hundred defmethods… Could be more or less but I have multiple branches of the same repos checked out

guy09:01:49

morning!

yogidevbear09:01:29

@rickmoynihan would you say that you have a general use case for them? (e.g. like the message routing stuff people have mentioned above or something completely different)

rickmoynihan10:01:31

multiple dispatch 🙂

chrjs10:01:03

Morning folk.

rickmoynihan10:01:59

@yogidevbear Some examples might be more helpful 🙂 - The query language we use has three different query types so when you handle queries it’s useful to dispatch on each type. Sometimes depending on context the type might be a java object (for interop with 3rd party libraries) or a {:type :select} map clojure side. - In the ui you may have a concept of “panel” that can render dynamically based on some kind of :type - In parts of our application we need to coerce input arguments, which might be tabular data/files etc, but might also have several source types so the dispatch key is composite i.e. [source-type destination-type]. These are also organised in a hierarchy (and we do some fancy introspection on the defmulti to also project some of this info back out as a JSON for API for another service to consume and build UI widgets from. - We use integrant, so ig/init-key multimethod etc are used to define components and start the app. - I use them for multi-specs. - Handling mine types and format types and various things related to content negotiation etc

rickmoynihan10:01:07

There are also lots of places in our code base where I think we could improve things by using them more.

yogidevbear10:01:50

Sweet, that's a pretty broad list and sounds like a super interesting project

rickmoynihan10:01:08

well technically it’s not one project 🙂

yogidevbear10:01:25

interesting work then 😉

rickmoynihan10:01:49

Yes, it is. I can’t complain too much 🙂

rickmoynihan11:01:21

haha, I’m not sure you can be a software developer and not complain a bit! 😉

rickmoynihan11:01:49

complaining is often a pre-requisite to improving things

mccraigmccraig11:01:17

oh @yogidevbear i forgot about another thing we do - lots of our api requests get transformed into a [api-method-key params] variant in the api layer, and that is dispatched against a multimethod, which returns a [response-key params] variant, which is then xformed in to an http response. it makes http-related stuff very thin and generic, makes error handling a breeze, keeps model stuff out of http land, makes model stuff very easy to test (no request spoofing) and keeps http dependencies out of the model module

rickmoynihan11:01:29

Yeah the variant pattern is pretty neat. I’ve been thinking about using it more.

mccraigmccraig12:01:06

variants work particularly well with promises and promise short-circuiting - our error handling boils down to (throw (pr/ex error-key error-args)), which encodes the [error-key error-args] variant into the promise error state, and somewhere up the promise chain (e.g. in the aforementioned http layer) something will do a pr/catch, and unpack then present or encode the error

thomas14:01:03

so I am making the mistake of mixing some java with my Clojure... and I have found Zach Tellman's virgil project to recompile my java... but as I use a port I can't seem to restart it easily... has anyone found a solution to this

thomas14:01:11

the port isn't released for some reason

mccraigmccraig14:01:46

afaics @thomas virgil is creating a new ClassLoader for each compilation https://github.com/ztellman/virgil/blob/master/src/virgil/compile.clj#L81 which would mean that your old versions are happily carrying on running, isolated under their old ClassLoader

thomas14:01:27

I can close my port... but then when I add some java code I can't reopen it again for some reason.

mccraigmccraig14:01:31

presumably something isn't getting closed down... are you using a ServerSocket ?

thomas14:01:34

I am using a ServerSocketChannel

thomas14:01:40

trying to use NIO...

mccraigmccraig15:01:28

ah - i haven't ever used that directly, although i presume netty uses it under the covers...

mccraigmccraig15:01:49

so to close it you get the ServerSocket from the ServerSocketChannel and close that ?

mccraigmccraig15:01:07

ah, no, there's an inherited close method

mccraigmccraig15:01:55

hmm. i was going to suggest you try SO_REUSEPORT, but it seems java doesn't support it

thomas15:01:17

I actually don't use Netty... I though i'd copy the http-kit ideas over... use Java to create maps and call into my clj code.

thomas15:01:27

aahh just re-read your comment... yes I think Netty uses that as well. I'll investigate it some more when I get some time for this... just a playing with a few ideas and see if they work.

mccraigmccraig16:01:40

why did you decide to write java for the ServerSocketChannel interop @thomas? (i tend to avoid it - i can only remember once where i had to do it)

thomas16:01:48

I thought I'd use the same trick as http-kit... use a layer of Java to handle the low level network intricacies and then hop into clojure to do the fun bit where you can add (more) value.

thomas16:01:12

trying to build a very simple mqtt broker (again)

mccraigmccraig17:01:04

that looks like a fun project

rickmoynihan18:01:42

mqtt is a great protocol

rickmoynihan18:01:46

really well designed