Fork me on GitHub
#beginners
<
2021-08-19
>
John Bradens03:08:43

Any opinions on using immutant vs http-kit? Are they necessarily mutually exclusive?

seancorfield03:08:27

They are both HTTP servers. Like Jetty.

seancorfield03:08:49

Immutant hasn't been updated in 3 1/2 years. http-kit is still maintained (but not actively developed I believe at this point).

seancorfield03:08:06

Jetty is the most common HTTP server that folks use with Clojure I think @bradj4333

seancorfield03:08:49

We use Jetty at work -- to power the backend of 40+ online dating sites.

seancorfield03:08:27

We used http-kit for a while but New Relic, which we use for monitoring, doesn't support it very well, so we switched (back) to Jetty.

seancorfield03:08:20

We still use the http-kit client library but once our legacy apps are off Java 8, we'll probably switch to Java's built-in HTTP client.

John Bradens03:08:37

Thanks @seancorfield that's very helpful. I think I'll want to use Jetty too, then. I didn't know that immutant isn't updated anymore. I see lots of tutorials that use it.

Rowan Barnard03:08:53

Just letting you know in case you're interested that the 3rd edition of book Web Dev with Clojure was just published: https://pragprog.com/titles/dswdcloj3/web-development-with-clojure-third-edition/ It is what I am working through now. I am only on the second chapter but it is written by the author of one of the most commonly used Clojure web dev 'frameworks'. It is not free but given the author and that it is just published, it is likely to be good info and up-to-date, which can be a problem as you notice with many existing tutorials using now out-of-date tools and libraries.

Lucy Wang09:08:58

Hello guys, for those of you uses websockets, has anyone ever used https://github.com/ptaoussanis/sente in a commercial product? The background is I'm weighing different solutions between i) native websocket ii) sente iii) http://socket.io (by https://github.com/mrniko/netty-socketio)

lsenjov12:08:37

Not in a commercial product, but certainly a few hobby projects. If you're a pure clj/cljs stack it's extremely excellent and handles a lot of the crap bits for you (eg shaky connections)

lsenjov12:08:14

And shadow uses it, so does it count for development of production applications?

noisesmith14:08:00

there's some weirdness (eg. an underlying utility lib that has weird code that's way too low level and sometimes has very strange bugs), but it works. I'd be tempted to use the websocket API directly next time to be honest, with a router on each end (I bet bidi could be used directly, it's not that http specific...)

3
Lucy Wang10:08:42

yeah I'm also thinking about to build upon the native ws api directly.

pjones16:08:45

Does anybody know of a good tutorial on clojure + mpi? My google-fu mainly points to comments from several years ago, that clojure and mpi aren't really a thing, so I am not sure what the current status of that is. Any help/direction would be much appreciated.

dpsutton16:08:31

What is mpi? I'm not familiar with that term

emccue16:08:53

I think neanderthal might be the place to start - if I interpret what MPI is correctly

delaguardo16:08:17

“message passing interface” i think

pjones16:08:05

Yes, MPI="message passing interface". I mainly work on HPC systems at the moment, which uses mpi to communicate between compute nodes. Will check out neanderthal, thanks.

emccue16:08:57

what kind of communication?

emccue16:08:24

and i would search for a java lib to do it

delaguardo16:08:40

http://mpjexpress.org/ this one is the most advanced (imho)

emccue16:08:22

whatever ends up being the right choice for java you should use for clojure

emccue16:08:42

then we can figure out what/if any conveniences it would be nice to have for clojure apps

👍 2
sheluchin16:08:55

What is the use of s/keys's :opt? The guide says: > We’ll see later where optional attributes can be useful. Also note that ALL attributes are checked via keys, not just those listed in the :req and :opt keys. But I cannot find the later part that it refers to. https://clojure.org/guides/spec#_entity_maps

lassemaatta16:08:05

one use case is generators: :opt allows them to generate maps with both required and optional attributes.

Alex Miller (Clojure team)16:08:46

This and documentation

sheluchin17:08:30

Got it, thank you.

emccue16:08:04

neanderthal is good for the kinds of work you would be doing on a cluster though

emccue16:08:28

but i don't think it tackles any cluster communication, so its orthogonal

delaguardo16:08:46

it is more about cluster of GPUs )

pjones16:08:46

still new to clojure. haven't used in a while, and I know nothing of java. But from googling, yes it seems a java lib may be the way to go. In terms of the kind of communication, on the systems I work on, the only way for a set of tasks to be distributed over a set of nodes (so between the nodes, and therefore leverage more compute), is to use the mpi protocol. The program interfaces with a scheduler like SLURM or TORQUE, and sadly LSF too. So you effectively have

srun -n 12 java ...<best process and code ever>... 
jsrun -n 12 -a 1 python ...<more awesome stuff>.... 

sheluchin17:08:44

Could anyone explain the difference between wrapped :require entries and ones that aren't wrapped in a vector? Here is an example: https://github.com/fulcrologic/fulcro/blob/174f5ad36373eba5385fb1e3e9f85b1943547c0b/src/main/com/fulcrologic/fulcro/algorithms/tx_processing.cljc#L18

dpsutton17:08:50

> A libspec is a lib name or a vector containing a lib name followed by options expressed as sequential keywords and arguments.

dpsutton17:08:06

(doc require). But the shorthand is that you need to require code so that it is compiled by clojure and available. You can optionally add an alias to the namespace so you don't need to use a fully qualified name. (:require clojure.set) and then in code (clojure.set/union ...) vs (:require [clojure.set :as set]) and in code (set/union ...)

sheluchin17:08:00

@dpsutton but in the example link I posted there are these three lines (in order):

[com.fulcrologic.fulcro.specs]
    [com.fulcrologic.fulcro.inspect.inspect-client :as inspect :refer [ido ilet]]
    com.fulcrologic.fulcro.specs
So the first one is wrapped in a vector, and the last one is not. They are otherwise identical. Neither of them refer any symbols or alias the namespace.

dpsutton17:08:01

:as inspect creates an alias for the namespace. :refer [id ilet] refers to symbols in the namespace. i'm not following what you mean

dpsutton17:08:25

just between libspec and [libspec] there is no different. the unwrapped version is preferred i believe

dpsutton17:08:46

and the duplication should be caught by a linter and removed but does not harm anything

seancorfield17:08:56

Linters will typically assume [libspec] means you're loading the namespace for its side-effects (declaring spec, protocols, multimethods) and will not flag it as unused.

noisesmith18:08:12

> Linters will typically assume [libspec] means you're loading the namespace for its side-effects that's odd, because my convention was always that [libspec] means I intend to use the ns explicitly, but don't want and alias, while libspec is loading purely for side effects this is sort of a back-formation though - seeing that both syntaxes are allowed and then deciding on a distinction that seems to suit that variation

noisesmith18:08:02

oh, I bet you mean [libspec] as opposed to [libspec :as ...]

seancorfield18:08:34

Correct. Because I always wrap all my libspecs.

seancorfield18:08:49

(but I think some linters do draw a distinction)

seancorfield18:08:50

I just checked clj-kondo and it does not seem to care so maybe I'm wrong.

seancorfield17:08:03

But that's just convention.

dpsutton17:08:59

oh i see. hadn't heard of that. nice

seancorfield17:08:48

I prefer seeing wrapped libs always -- and in alphabetical order (my OCD!). I think it looks really odd to see a mix of wrapped and unwrapped -- and in the code above, it's just a "bug" that the same ns is required twice. It's harmless but should be "fixed".

seancorfield17:08:10

(I have clj-kondo configured to flag unsorted ns requires as an error and my colleague wrote a little Clojure script that sorts ns requires so I don't complain in PR reviews 🙂 )

sheluchin17:08:16

Thanks for the input. To be clear, I was only wondering about the difference between [libspec] and libspec in the :require reference, as well as the duplication. It sounds like I should just stick to the wrapped libspec and the duplication is of no significance in this case.

sheluchin17:08:01

@seancorfield Interesting that you prefer them to be sorted. In Python there is a convention of putting the most low-level imports near the top and working your way down to imports from your own application last. I've been naively following the same convention in Clojure, but I guess it's not a thing I should be doing.

dpsutton17:08:55

sorting is purely a stylisting thing. if you have your own convention go with that

dpsutton17:08:34

different styles and "best practices" come up because people tend to flock to one or another. But there is always room for new patterns to emerge. And that pattern is not without its merits.

👍 6
noisesmith18:08:12

> Linters will typically assume [libspec] means you're loading the namespace for its side-effects that's odd, because my convention was always that [libspec] means I intend to use the ns explicitly, but don't want and alias, while libspec is loading purely for side effects this is sort of a back-formation though - seeing that both syntaxes are allowed and then deciding on a distinction that seems to suit that variation