Fork me on GitHub
#clojure
<
2017-07-07
>
tjscollins01:07:25

Is there a known issue between com.datomic/clj-client, figwheel, and clojure-1.9.0 ? I cannot get them to compile together. Trying to start a repl gives a spec error:

Exception in thread "main" java.lang.ExceptionInInitializerError
	at clojure.main.<clinit>(main.java:20)
Caused by: clojure.lang.ExceptionInfo: Call to clojure.core/refer-clojure did not conform to spec:
In: [2 1] val: :as fails at: [:args :exclude :op :quoted-spec :spec] predicate: #{:exclude}
In: [2 1] val: :as fails at: [:args :only :op :quoted-spec :spec] predicate: #{:only}
In: [2 1] val: :as fails at: [:args :rename :op :quoted-spec :spec] predicate: #{:rename}
In: [2] val: (quote :as) fails at: [:args :exclude :op :spec] predicate: #{:exclude}
In: [2] val: (quote :as) fails at: [:args :only :op :spec] predicate: #{:only}
In: [2] val: (quote :as) fails at: [:args :rename :op :spec] predicate: #{:rename}
:clojure.spec.alpha/spec  #object[clojure.spec.alpha$regex_spec_impl$reify__1200 0x43f50bfe "clojure.spec.alpha$regex_spec_impl$reify__1200@43f50bfe"]
:clojure.spec.alpha/value  ((quote :exclude) (quote [reduce transduce into merge map take partition partition-by bounded-count]) (quote :as) (quote core))
:clojure.spec.alpha/args  ((quote :exclude) (quote [reduce transduce into merge map take partition partition-by bounded-count]) (quote :as) (quote core))
 {:clojure.spec.alpha/problems ({:path [:args :exclude :op :spec], :pred #{:exclude}, :val (quote :as), :via [], :in [2]} {:path [:args :exclude :op :quoted-spec :spec], :pred #{:exclude}, :val :as, :via [], :in [2 1]} {:path [:args :only :op :spec], :pred #{:only}, :val (quote :as), :via [], :in [2]} {:path [:args :only :op :quoted-spec :spec], :pred #{:only}, :val :as, :via [], :in [2 1]} {:path [:args :rename :op :spec], :pred #{:rename}, :val (quote :as), :via [], :in [2]} {:path [:args :rename :op :quoted-spec :spec], :pred #{:rename}, :val :as, :via [], :in [2 1]}), :clojure.spec.alpha/spec #object[clojure.spec.alpha$regex_spec_impl$reify__1200 0x43f50bfe "clojure.spec.alpha$regex_spec_impl$reify__1200@43f50bfe"], :clojure.spec.alpha/value ((quote :exclude) (quote [reduce transduce into merge map take partition partition-by bounded-count]) (quote :as) (quote core)), :clojure.spec.alpha/args ((quote :exclude) (quote [reduce transduce into merge map take partition partition-by bounded-count]) (quote :as) (quote core))}, compiling:(clojure/core/async.clj:9:1)
The stack trace lists a few references to figwheel_sidecar, otherwise it's all clojure.lang and clojure.core. If I switch to clojure 1.8.0 or remove com.datomic/clj-client, then everything compiles fine. But that combination of clj-client and clojure 1.9.0 keeps throwing this error. Any ideas what might be causing it?

noisesmith02:07:08

1.9 enforces things that are silently accepted by older versions

noisesmith02:07:15

are you using the newest figwheel?

tjscollins02:07:27

I think so, 0.5.11

tjscollins02:07:40

It's listed as the newest on clojars

noisesmith02:07:52

there's a snapshot figwheel that eliminates the issue

tjscollins02:07:22

Nope. Still get the error. It does seem to be the same error though.

tjscollins02:07:35

It really seems weird that adding datomic/clj-client introduces the error (and removing it resolves it), but the stack trace mentions figwheel.

tjscollins02:07:20

It does work with clojure-1.9.0-alpha15 though, but not alpha16 or 17

tjscollins02:07:03

I suppose for the moment that's my workaround, to use alpha15 instead.

tjscollins02:07:53

Bah, I spoke too soon. datomic/clj wasn't included. Still doesn't work with the client library at all. I guess I'll have to give up trying out spec altogether for now.

seancorfield02:07:53

@tjscollins according to that issue " you can upgrade figwheel to 0.5.10-SNAPSHOT or greater. "

tjscollins02:07:20

Yeah, I was using 0.5.11. Tried the snapshot too. They both don't work.

tjscollins02:07:34

They work if I'm not trying to use datomic

seancorfield02:07:39

And if datomic/clj-client is causing the problem, add an exclusion on org.clojure/core.async on that dependency

tjscollins02:07:53

Adding the exclusion seems to work.

seancorfield02:07:35

I'm surprised there isn't a more recent datomic/clj-client with an up-to-date core.async dependency that works cleanly on Clojure 1.9 Alpha 17.

seancorfield02:07:51

FWIW, we have Clojure 1.9 Alpha 17 in production -- spec is awesome!

tjscollins02:07:20

Yeah, it looks really neat. I'm looking forward to trying it. Thanks for the help.

henrik09:07:47

There must be a nicer way to write this (-> csv-rows (nth 7) (#(drop 10 %)))

henrik09:07:39

Is (as-> csv-rows tmp (nth tmp 7) (drop 10 tmp)) optimal? Or is there a better way?

a1309:07:16

(-> csv-rows (nth 7) (nthnext 10))
, if I got it right

sgerguri09:07:01

What exactly are you trying to do there, @henrik?

henrik09:07:49

@sgerguri Take the 7th row in a two-dimensional vector, drop the 10 first items in that row.

a1309:07:51

nthnext version is shorter šŸ™‚

henrik09:07:34

@a13 A superior editor, I know. Iā€™ll sit down and learn it when I become a real developer.

sgerguri09:07:54

@henrik Just use Cursive. šŸ˜›

a1309:07:13

ā€žAnd thus the peace was broken once more.ā€œ

henrik09:07:04

Cursive and Emacs are roughly at the same level of approachability for me. Iā€™ll pick a proper editor to learn when The Guild of Real Developers write my name into their books.

henrik09:07:30

I briefly used Atom and Proto repl. Went back to Sublime when I couldnā€™t figure out a way to automatically clean up indentations/spaces in a document in Atom.

henrik09:07:01

I.e., ctrl+i from LispIndent.

a1309:07:04

Cursive is nice, the only thing is I don't like to use multiple editors, and since Clojure isn't the only language I use, Emacs is my editor of choice šŸ™‚ Also, Emacs is written in lisp, so it's pretty simple to hack it yourself.

sgerguri09:07:11

Thatā€™s the thing, because Cursive is just a plugin for IntelliJ IDEA you install that plus whatever other plugins you need and you have a single environment for everything.

sgerguri09:07:52

After years of Vimming this plus IdeaVim just works for me, and I donā€™t have to learn a whole new operating system to write text files. šŸ˜‰

sgerguri09:07:58

Of course, tongue half in cheek. Everyone use what they are comfortable with, but unless someone is strongly entrenched in the Emacs ecosystem I think he/she would be better off just using Cursive. Plus it earns @cfleming some dough for the great effort he put in when said person then proceeds to write Clojure commercially and decides to stick with Cursive (and hence will need a commercial license)!

cfleming10:07:57

Thanks @sgerguri! I appreciate it.

arnaud_bos12:07:28

Is anyone still using Light Table? I'm unsure of it's current status. I've tried emacs a few times but didn't put as much effort into it than when I learned vim a few years ago. Light Table + vim mode works well for me...

dominicm12:07:38

@arnaud_bos afaik, LightTable is abandoned. But that might be incorrect.

dominicm12:07:59

Vim & Clojure work well together. Whole community of us in #vim-fireplace, I've written some blogs which I'm happy to share if you're interested.

gmercer12:07:47

mluisbrown committed with sbauer322 on 29 May 2016

a1312:07:15

> Light Table + vim mode works well for me... JFYI spacemacs uses evil-mode (vim emulation layer) by default

a1312:07:31

it also has a preconfigured layer for clojure

hmaurer12:07:19

I just started using proto-repl for atom and itā€™s amazing so far

gmercer12:07:01

actually there are newer commits to LightTable

arnaud_bos12:07:48

At first I though I'd just "learn emacs" and then move to spacemacs, but the more I procrastinate the more I think I'll just go straight into spacemacs soon.

hmaurer12:07:08

@arnaud_bos have you tried atom + proto-repl?

arnaud_bos12:07:34

I've used Cursive for a while, but I don't know why it just doesn't work for me. Also the instalRepl thingy is a killer feature for me.

arnaud_bos12:07:00

I must admit I haven't try atom + proto-repl, days only have 24 hrs šŸ˜‚

gmercer12:07:40

but moving from 0.8.1 is taking a while but .. http://lighttable.com/blog/

arnaud_bos12:07:50

I've read that, that's why I said I was "unsure".

gonewest81814:07:58

Does Atom+proto repl have an interactive debugger like cider?

dealy15:07:28

I'm curious about private functions and data in Clojure. As my application has grown, there are now some fairly large (to me at least) maps that hold app state. So I have functions to handle a lot of the manipulation of that state. It seems rather unnatural for me to these large state objects in the global space so I've made them private. However every time I make something private in Clojure I feel like I'm kinda going against the grain.

dealy15:07:29

any thoughts on app design and when to it makes sense to shed some of the old OOP style organization and when to keep some of those features in Clojure?

mrchance15:07:06

@dealy I personally find that having private functions and data is not something that is worth doing, see http://steve-yegge.blogspot.de/2010/07/wikileaks-to-leak-5000-open-source-java.html for a (probably mildly satirical šŸ˜‰ ) overview

mrchance15:07:49

If it's large maps that you're struggling with, it's usually more helpful to split their handling in a clean way, e.g. with something like cursors in particular or having your functions only operate on well defined subtrees in general

dealy15:07:51

well that's only part of the problem. I'm actually more interested in design philiosophy when it comes to ensuring that data is consistently maintained. Spec will help a lot with this however its isn't production ready so I'm not using it. If someone updates app state and fubars an inner struct by removing a necessary key word, or accidentlally replaces a map with a vector, this is all possible when the app-state is available to anyone. THose kinds of concerns have always guided my design choices and its kinda hard to shake those concerns, know what I mena?

dealy15:07:32

mena = mean

mrchance15:07:21

Sure, and I do agree that it's a problem, but making functions private doesn't prevent them from breaking something in your state šŸ˜‰

mrchance15:07:37

You prevent that by limited scope and good tests

Garrett Hopper15:07:33

I'm using clojure.tools.namespace.repl to reload my code and reset my system, however it seems to be caching old code. If I change a testing println, it continues to print the old string. Even in Cursive's debugger, I'll be ontop of the line to print one thing, and it will print the old thing. Any ideas?

dominicm15:07:40

@ghopper What is your setup? Do you use defonce, component, anything like that? Or is this just with plain ol' functions? Are you using boot or leiningen?

Garrett Hopper15:07:34

Nope, no defonces or anything. Actually just tried https://github.com/weavejester/reloaded.repl and the same thing happens.

Garrett Hopper15:07:20

@dominicm Just adding a println into one of my system constructors, and it seems to hold onto the old function.

dominicm15:07:20

Just ftr, records hold onto the old behaviour for stop, but the subsequent start should work.

Garrett Hopper15:07:28

Hmm, good to know. I think I've gotten it to work. Instead of passing a function into reloaded.repl/set-init!, I passed an anonymous function, and that causes it to update.

Garrett Hopper15:07:41

Kinda strange, but oh well.

dominicm15:07:41

that's odd :thinking_face:

dominicm15:07:53

Oh, maybe it isn't.

dominicm15:07:09

How did you require the function you were passing to reloaded.repl/set-init?

Garrett Hopper15:07:18

The function was originally in a (ns user) with a (disable-reload!) maybe/

Garrett Hopper15:07:29

It was in the same namespace.

Garrett Hopper15:07:57

Yeah, seems to work for the deeper more confusing methods now too. That was confusing.

dominicm15:07:54

I'm wondering if you had a missing (:require), that would cause the refresh to not fully work I think

Garrett Hopper15:07:27

No, I don't think so. I'd tried with an alias to my system namespace and fully qualified.

Garrett Hopper15:07:03

Oh well, I'm not too worried about it now. I'm sure I was doing something that's mentioned in the readme.

dominicm15:07:07

ĀÆ\(惄)/ĀÆ

Garrett Hopper15:07:12

Thanks šŸ™‚

mccraigmccraig16:07:28

@dealy we've got large state maps client-side in our re-frame app - we've been using prismatic schema to ensure that state is updated consistently during development, though since schema doesn't do efficient delta checks we don't do it in production

tbaldridge16:07:51

@dealy quite a few people use spec in production. Most of what's "not finished" in spec is around feature requests, not so much in api changes or bugs.

dealy16:07:03

@mccraigmccraig yea, I'm aware of prismatic schema also. I was kinda more interested in having a discussion about why building apps this way (everything open vs certain things being walled off and only accessible via well defined interfaces).

dealy16:07:54

I thought spec was only part of clojure 1.9, no?

tbaldridge16:07:13

One of the reasons IMO is code bloat, writing all those interfaces will result in simple changes to the data model requiring devs to add new "add-person", "add-contact", etc. interfaces.

tbaldridge16:07:31

Sure but there's a fair amount of people using 1.9 in production as well šŸ™‚

tbaldridge16:07:07

Clojure is very good about adding new features that don't interfere with previous code. So it's very rare that upgrading to a new "alpha" of clojure will break existing code.

dealy16:07:16

maybe I'm just too old school ( or just old! ) I've never used alpha/beta versions of languages in prod

dealy16:07:05

so far none of the arguments for having everythng global are convincing to me

tbaldridge16:07:14

The other problem you'll hit is that Clojure doesn't put any real meaning to the words alpha and beta. Core.async, core.match, etc. have all been in alpha for quite some time, and yet they're used in production a lot and relatively bug-free.

dpsutton16:07:15

i don't think that's unreasonable at all

tbaldridge16:07:58

But about global state, we should talk about it in this way, with a global atom for your app state you have one place to look for the state of your app. You can "go back in time" simply by replacing the state with a previous state (global undo)

dealy16:07:28

I guess I am a little more open to libs like core.async

tbaldridge16:07:30

Debugging is simply a matter of grabbing the state and then using Clojure's normal functions to poke around.

mccraigmccraig16:07:36

a global persistent state, solid consistency checking and a principled model for managing updates beats fragments of state in lots of places, variable consistency management and ad-hoc updates every time for me

tbaldridge16:07:10

Yeah, it all depends on what sort of state we're discussing

noisesmith16:07:56

also - global app state as the output of a reduce over an immutable stream of events is a model with a bunch of really nice properties, and is easy to pull of with clojure, with help of tech like datomic and/or kafka

noisesmith16:07:31

for example: ā€œbug just happened, dump the last N events into transit data so I can replay them in a unit test reproducing the bugā€

noisesmith16:07:46

that saves days of debugging in a microservices type app

noisesmith16:07:54

or evenā€¦ ā€œbug happened last week, dump the N events preceding the bugā€ etc. - so much nicer than reading log files for 3 servers in parallel

hmaurer16:07:27

@noisesmith do you have good articles/examples of this other than datomic?

noisesmith16:07:15

@hmaurer I have an open source lib thatā€™s still young, working on moving more of my production proprietary appā€™s logic into the open source libā€¦ but it really can just be done as a reduce that calls resset! on an atom, where the input sequence is a lazy infinite sequence of kafka messages (or even rabbitmq or whatever if you want to do your own persisting)

noisesmith16:07:45

the thing is that the approach is natural enough for clojure that you hardly need a framework

hmaurer16:07:20

@noisesmith what is the open source lib?

noisesmith16:07:09

itā€™s very young, but itā€™s ludic (named because the initial metaphor was a game of chess by mail) https://github.com/noisesmith/ludic

hmaurer16:07:28

awesome, thank šŸ™‚ Iā€™ll take a look

noisesmith16:07:40

also useful for dumping and replaying data even outside such a context https://github.com/noisesmith/poirot

hmaurer16:07:04

it seems to me that a lot of the headaches with event sourcing come when you try to have a distributed, async system

hmaurer16:07:32

but in a single process, as you said, it fits nicely with clojureā€™s model

noisesmith16:07:11

if you do it right (with deterministic processing) you can replicate state - the trick is that every ā€œdecisionā€ needs to be reified as an event sent to the rest of the system

noisesmith16:07:30

this is the part that ludic is going to flesh out more in the future (still closed source stuff now sadly)

hmaurer16:07:11

do you use event sourcing in production on any project? (excluding Datomic)?

noisesmith16:07:34

yes - like I mentioned, this closed source app, which is my day job and a production app

hmaurer16:07:51

oh, sorry, missed it. Do you use Kafka with that app?

noisesmith16:07:52

and I mean really every db from postgres to cassandra to mongo is using event sourcing internally

hmaurer17:07:10

right, yes. By ā€œusing event sourcingā€ I mean as a first-class citizen

hmaurer17:07:16

not an implementation detail

noisesmith17:07:18

yes, I use kafka, since it simplifies the persist / replay part (and guarantees ordering which is a huge benefit)

hmaurer17:07:19

if that makes any sense

hmaurer17:07:54

Do you use Kafka as your primary datastore (e.g. with infinite retention period)? Or do you store your data elsewhere and only have a retention period of X weeks on kafka?

noisesmith17:07:55

right, just pointing out for the postgres etc. devs event sourcing is a first class part of their architecture šŸ˜„

noisesmith17:07:24

for client data we use postgres and mongo - kafka is for system state / messaging

noisesmith17:07:50

if every server needs to agree about the state of FOO - FOO is managed by events on kafka

noisesmith17:07:51

Iā€™m also working on a scheme to migrate events off the kafka log into s3, and off of s3 back into the app (via an adaptor compatible with our kafka inputā€¦) - but thatā€™s in design stage still

hmaurer17:07:08

so you do use kafka as a datastore? or just as a transient message broker?

noisesmith17:07:55

message (I donā€™t like the implication of ā€œbrokerā€ - for example with a proper broker you canā€™t do rewind/replay and these are trivial with kafka)

noisesmith17:07:29

where some messages are explicitly stored because they are relevant to some bug or question etc.

michaellindon17:07:44

I have a multimethods question. Suppose I am dispatching on the class of two arguments so my dispatch-fn looks like (fn [x y] [(class x) (class y)]) I can create a method matching against [class-a class-b]. Suppose for a given class-c occuring in the second position I don't care what was in the first position. I want to match on something like [_ class-c]. Is this possible? Otherwise I need to write a number of methods, one for each [class-a class-c] [class-b class-c] I'm not actually working with classes.

rickmoynihan22:07:20

michaellindon: Iā€™d suggest using the dispatch function you have and just changing the dispatch value to [Object ClassC] Remember dispatch values use isa? and work across each argument in a vector form. multimethod hierarchies are underused IMHO.

michaellindon22:07:55

i agree, i think this is what i was looking for, thank you

noisesmith17:07:21

@michaellindon why not

(fn [x y]
  (let [y-class (class y)]
     (if (contains? magic-classes y-class)
      [:magic y-class]
      [:mundane (class x) y-class]))

michaellindon17:07:43

I think this could work, thanks

bbktsk19:07:20

Hello, is there some library to do http requests using kerberos auth in clojure? We have a couple of servers setup with kerberos SSO (i.e. I do kinit on my notebook and then browser connects without further manual authentication) and I need to execute http requests to these servers from my clojure code. I have found some java examples, but they seem very, very painful 8(

hcarvalhoaves19:07:55

@bbktsk if the Java examples work, I would start w/ it, and just wrap the mess / state management behind a clj fn (instead of rewriting). do you have links for the examples?

bbktsk19:07:40

@hcarvalhoaves Well, thatā€™s my plan (b). I was hoping thereā€™s already some nice clojure library to do thatā€¦

hcarvalhoaves19:07:14

these kinds of libraries (just wrappers around Java) seem to be rare. I suspect it's because either it would be 1) too thin 2) it's easy enough to roll your own

hcarvalhoaves19:07:43

proxy in particular is ā¤ļø ... it's easier to program Java in Clojure than in Java IMO

bbktsk19:07:41

Thanks, will check that out.

tkircsi20:07:49

The original example on http://clojuredocs.org works well, but it is using a map as an input parameter. https://clojuredocs.org/clojure.core/defmulti Is it possible to dispatch according to a simple string input valueā€™s value?

dpsutton20:07:09

ugh sorry. hate when it puts it in the channel and the thread

jeff.terrell20:07:20

Me too. Happens when commenting on a snippet/image/video, since I think those are considered comments instead of threaded messages. šŸ˜•

tkircsi20:07:29

Thx. Iā€™ll try to restart

tkircsi20:07:37

It works well after the REPL restart. Thank you!