Fork me on GitHub
#clojure
<
2019-02-27
>
gekkostate06:02:44

Hi everyone! Has anyone encountered the java.lang.module.FindException: Module java.xml.bind not found error after adding: :jvm-opts ... and the [javax.xml.bind/jaxb-api "2.4.0-b180830.0359"] dependency?

gekkostate06:02:50

Fixed it! Adding one is fine but not both.

vemv08:02:12

Anyone heard of a library that points out the slowest members in your system? (Component/Integrant) Doesn't sound hard to build, but who knows, maybe someone already has such code

vemv08:02:48

was defnitely easy with robert-hooke. If going for it, do all logging in a ns with clojure.tools.namespace.repl/disable-reload! set

Ivar Refsdal12:02:56

Are you aware of tufte? https://github.com/ptaoussanis/tufte I'm using this for profiling (a yada server using component)

vemv12:02:21

I'm not sure something like that would have served I needed an answer to "of all my [Sierra] components, which one is the slowest"? I cannot add profiling boilerplate to every single component...

vemv12:02:24

So, I have to "profile" component/start, which code I cannot modify did so with robert hook, so args and time are logged

Ivar Refsdal12:02:41

Right, that sounds like a good solution

synthomat12:02:38

G’day! I’ve got a question about database connections in a web application: where do I actually keep the connection? Putting it into a namespace is not so great for obvious reasons. Is it a common pattern to put it in a request object of a http framework?

synthomat12:02:01

Most of the demo/example applications do keep the connection in a namespace 😞

synthomat12:02:03

(specifically speaking of compojure and monger)

synthomat12:02:06

ah, or one can create the connection in a “create-routes” method passing the connection down to handlers

synthomat12:02:05

read about stuartsierra/component, but not about mount

lispyclouds12:02:35

mount is an alternative that some people prefer, both have their ways of managing state.

synthomat12:02:02

just from contemplating the sources of “mount”: it actually “does” define a variable in the respective namespace but defers the instantiation of the actual value until you call “start” on the framework and from then on it takes care of the lifecycle

synthomat12:02:53

…trying to understand the magic behind it

synthomat12:02:32

sooo technically, if I don’t need lifecycle, I would just define an atom and “assign” the connection to it from somewhere later in the code. That’s what the component framework actually does under the hood

lispyclouds12:02:17

yeah both of them make state management nicer than the manual way. Mount however tries a kinda less opinionated approach i think: https://github.com/tolitius/mount/blob/master/doc/differences-from-component.md#differences-from-component

vemv12:02:49

IIRC Mount has the drawback of failing to create isolated systems that can be run independently e.g. what if I want to parallelize my test suite? All tests would share the same stuff

mpenet12:02:08

Integrant is also quite nice.

sgerguri13:02:11

I (and my team) bounced off duct, and by extension integrant, pretty hard. I strongly suspect component would be the same story, but it's been years since I last tried it out. FWIW we migrated everything duct/integrant to mount in an hour and the productivity boost that we have seen from doing that has been incredible. I find mount more amenable to just starting a part of the system, which means I can now do REPL-driven development inside the namespace I am writing, as opposed to somewhere else, followed by shipping it out when I'm done. In short, I just find mount to be a lot closer to rolling plain Clojure without any of this stuff than the other two.

vemv13:02:53

Honestly that sounds like a classic simple vs. easy contrast. I absolutely do repl-driven dev with Component. Everyone else in the team does, and it's a diverse one (vim, emacs, cursive...) Component/Integrant make things explicit + testable, similarly the Reloaded workflow forces you to keep things pure and non-cyclic 🙂 It wasn't entirely an easy journey, here are some notes taken https://github.com/reducecombine/rehardened

mpenet13:02:38

Your mileage may vary. We use component heavily at work and are happy with it. But I like what I read about Integrant, seems better

👍 5
mpenet13:02:08

> Honestly that sounds like a classic simple vs. easy contrast. exactly

sgerguri13:02:58

I agree, but my conclusion is opposite to yours - I view mount as simple, and integrant/component as complex. It just so happens that in this case, it is "made easy" as well. Like you say, your mileage may vary.

vemv14:02:14

I try to avoid controversy, but it might be helpful to wonder "I say x is complected, but it complects what with what? Is it a complection or a composition?" Mount appears to complect namespaces with state. You cannot take a namespace without also taking its state, and vice versa. Other libraries keep those orthogonal: I can create state (e.g. new app instances) without creating namespaces, That's the magic of Rich's discourse: he pursues an objective definition of simplicity, enabling more fruitful discussions 🙂

mpenet14:02:10

One is pure, the other is not. Sure it's more work to handle when pure, but that's also more powerful (testing/repl etc). Same argument can be made for functional programming and here we are, using clojure, so you might as well embrace (relative) purity. And you're free to use whatever you want, the rest is just subjective arguments (simplicity etc).

mpenet14:02:05

On a side note, that would be cool to have first class namespaces but that's another subject

leonoel15:02:24

would you have any links to share about first class namespaces @U050SC7SV ?

mpenet15:02:29

not really, it's not a thing in clojure, racket has something like that and ocaml functors come to mind (somewhat)

leonoel15:02:31

I'll have to move these languages up from my learning list

sgerguri15:02:09

@U050SC7SV I think you are confusing purity with functional programming. With mount we still have pure functions. The point of FP is pure functions, not pure namespaces - since namespaces are just groupings of things. Whether said groupings contain state or not is, in my humble opinion, completely beside the point of writing pure, stateless functions. State needs to live somewhere. I don't think it matters whether it's spread across the place or living in a single namespace if you can easily get hold of it when you need it. Beyond that, it boils down to whether it forces me into a particular way of doing REPL-driven development. And my point was that mount allows me to do it any way I like, unlike the alternatives.

mpenet15:02:33

I am not :) But as I said it's all quite subjective arguments at this point.

mpenet15:02:43

I like to be able to pass my state around, have multiple versions of it etc, you like to shove it at the namespace level, so be it.

synthomat16:02:03

I see, my original question has no clear answer, there’s some controversy about where to keep the state 😄

sgerguri16:02:15

I think the suggestion would be to try both mount and one of component/`integrant` and find out which one fits you better.

leonoel13:02:33

https://gist.github.com/leonoel/e933ee2b3f1e627063ab1db90d5396f9 While reading the manual I've written a clojure implementation of the example, with injure Feel free to comment

synthomat12:02:00

ah “component” even has an example on web applications

synthomat12:02:08

will check that out, thanks!

abdullahibra12:02:04

which kafka client you are using guys in production ?

danm12:02:25

The Java one

danm12:02:58

With a thin wrapper we wrote around the bits of it we need to make interacting with it more 'Clojureish'

sgerguri13:02:09

@abdullahibra We use https://github.com/dvlopt/kafka.clj which is a thin wrapper around the Java one. It even supports the Kafka Streams stuff, should one desire to use it.

abdullahibra13:02:35

great thanks guys

jarppe14:02:35

Announcing ClojuTRE 2019, September 26-27th in Helsinki, Finland. Tickets are on sale, get yours now from https://clojutre.org/2019/

👍 5
mping14:02:58

Is there any library out there with some kind of let-debug that prints a debug statement after each let? 😛

mping14:02:08

(let [a (f1)
      b (f2)]
into
(let [a (f1)
      _ (println "a" a)
      b (f2)
      _ (println "b" b)]

Alex Miller (Clojure team)15:02:24

I think there are some libs out there with stuff like this, but I'm not sure which ones off the top of my head

mping15:02:02

here’s my shot:

(defmacro letd [bindings & body]
  (let [pairs (partition 2 bindings)
        dbg   (map (fn [[v value]] `(_# (println ~(str ">>" v) ~value))) pairs)
        intv  (interleave pairs dbg)
        bs    (into [] (apply concat intv))]
    (println dbg)
    `(let* ~(destructure bs) ~@body)))

mping15:02:15

my solution does not work with destructuring 😢 tks @alexmiller

mping15:02:14

I guess is one of those things, everybody quietly rolls their own 😄

valerauko15:02:08

til interleave. i was reducing

valerauko15:02:18

(defmacro let-debug
  [bind-vec & body]
  (let [parted (partition 2 bind-vec)
        new-bind (reduce
                   (fn debugger [aggr [name value]]
                     (conj aggr
                           name value
                           '_ `(println ~(str name " is ") ~value)))
                   []
                   parted)]
    `(let ~new-bind ~@body)))

jdt16:02:50

There doesn't seem to be a channel for clojure.java.jdbc, so a simple question here. I need to write some code that will be generating a ton of very postgresql specific DDL. Without meaning to slight clojure.java.jdbc/create-table-ddl, it is nowhere near prepared to deal with schema entity references, quoted identifiers for table or column ids, and the many many options for create table. Even something as simple as a column default constraint requires special quoting to use create-table-ddl, e.g. [:text-col :text :default "'the default value'"] (note inner single quotes). I'm just wondering if someone has written an abstraction like create-table-ddl that is more capable with regard to supporting the many options of CREATE TABLE. If not I suppose I'll just be concatenating up a lot of strings, no time to write this dreamed-of abstraction now.

jdt16:02:39

as a reminder of the wide variety of options.

valerauko16:02:19

are you dynamically generating tables?

valerauko16:02:09

i feel your pain

jdt16:02:17

Part of a semi-structured to structured data storage project

jdt16:02:33

tables, schemas, partitions, the whole bit

jeff.terrell16:02:49

@dave.tenny - There's also #sql, FYI.

jdt16:02:02

thanks, will cross post there

jdt16:02:27

On a side note, I was kind of suprised when I couldn't find a nice package that encapsulates queries on the the supposed-SQL-standard "information schema" supported by postgresql.

jdt16:02:51

(as in, return maps of maps that represent schemas/tables/columns etc in a hierarchical view)

seancorfield17:02:51

> There doesn't seem to be a channel for clojure.java.jdbc, so a simple question here. The #sql channel is for clojure.java.jdbc discussions, as well as general SQL questions (and also other SQL libs).

dangercoder19:02:11

I am trying to do some calls to https with http-kit/client , but all I get is " :message "HTTPS is not supported". What http-client lib do you guys use for async-http-requests? I need to use ssl with pkcs12

dangercoder19:02:56

I am on the latest version of Http-kit. I tested Clj-http before but I did not like the async-connection-manager

noisesmith20:02:00

aleph has a client iirc

noisesmith20:02:21

it has its own setup for async (manifold) which is similar to core.async in some ways

dangercoder20:02:52

i'll have a look, thanks 🙂

dangercoder20:02:09

awh yeah. Aleph looking sweet

emccue20:02:03

@mping I cant think of a destructuring form that doesnt just use symbols

emccue20:02:42

so if you wanted that macro to log everything, you would just need to scan the thing on the left for "all symbols except _" recursively

mping21:02:48

I think ur right