This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-24
Channels
- # beginners (10)
- # boot (14)
- # cider (80)
- # clara (1)
- # cljs-dev (19)
- # cljsrn (7)
- # clojure (284)
- # clojure-france (4)
- # clojure-italy (57)
- # clojure-poland (8)
- # clojure-russia (10)
- # clojure-spec (65)
- # clojure-uk (155)
- # clojurescript (156)
- # code-reviews (6)
- # copenhagen-clojurians (16)
- # cursive (10)
- # datomic (10)
- # emacs (13)
- # euroclojure (1)
- # graphql (4)
- # jobs (2)
- # lein-figwheel (3)
- # luminus (4)
- # off-topic (2)
- # onyx (42)
- # parinfer (23)
- # pedestal (1)
- # protorepl (8)
- # re-frame (34)
- # reagent (17)
- # ring-swagger (5)
- # timbre (24)
- # vim (72)
- # yada (1)
Hey, what is the go-to Ring logger? https://github.com/nberger/ring-logger ?
noob question: ((fn [a b] [a b]) 1 2) eval to [1 2], (#(vector %1 %2) 1 2) eval to [1 2] too, why (#([%1 %2]) 1 2) got clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector
just like #(+ %1 %2) expands to (fn [x y] (+ x y)) #([%1 %2]) expands to (fn [x y] ([x y])) - #() keeps the outer parens
->
is a macro also known as thread-first and it's being abused here to be able to use a vector literal where it would otherwise not work
yes - do is better than -> here (in this context do and -> are the same)
so the [%1 %2] was evaled in place and used as the initial value of ->, but there is no further functions, so it got returned
with more forms,-> would be writing each form into the one after it
@leira exactly
thanks @noisesmith!
Is there any sane way of handling repeated date conversions between java.sql.date and java.util.Date or should I give up and use timestamps instead (if that would be better)? Every sql update query rotates the date back a full day because of the time zone getting chopped off and re-added.
@tjscollins The only sane solution is to have all your servers set to UTC and your database set to UTC, and work entirely in UTC date/times -- and only convert to/from local date/times on the fringe.
I was afraid it would be something like that.
Our data center is East Coast and we have everything set to UTC across the board.
Thanks
What database are you using?
Postgres. Wanted to use datomic, but my organization's purchasing rules wouldn't allow it without too many headaches.
I don't know about Postgres but with MySQL you have to explicitly set the DB to UTC separately from the O/S. Just FYI.
Thanks, I'm digging into the docs now to figure it out.
Is there a clojure library for parsing javadocs into clojure data (so I can build my own search system) ?
greetings, [finite state machines] can anyone describe the difference between "composite state" and "(sub) machine"? UML spec says those are basically the same thing, however, there are 2 names, which is suspicious:
A submachine State implies a macro-like insertion of the specification of the corresponding submachine StateMachine. It is, therefore, semantically equivalent to a composite State. The Regions of the submachine StateMachine are the Regions of the composite State.
I'm trying to "live at the REPL" more. One common debugging issue is how to quickly evaluate forms within functions or let bindings, where the symbols are not defined. ProtoREPL has a whole feature around this, and it looks like Cider does too.... (We use Cursive as we've come from a Java shop and deal with lots of Java code still.) Is this something people use a lot? Is there a repl independent approach to this?
@apbleonard You should be able to do this in Cursive - if thereās something missing (or if you have a link to some doc about ProtoREPLās approach to this) Iād be very interested to see it.
You can select any form and that will be sent, or thereās the āSend form before caretā action. Cursive doesnāt do anything clever with missing symbols though, is that what youāre referring to?
Sorry I meant to quote this discussion https://github.com/clojure-emacs/cider/issues/1809
@apbleonard So thatās sort of what I had in mind. If you send a form for evaluation, I can check if any of its bindings are not defined in that form. I had envisioned a popup dialog when you evaluate the form which would allow you to enter a value for each one. Does that sound like what you had in mind?
That sounds nice š
I think this is related to tracing though. In protorepl (sorry to mention the competition!) you stick a (save) form in your code and it can remember values flowing through code as a test runs say, and then you can def these values so you can evaluate forms and debug as you go.
No problem at all, ProtoREPL is awesome, itās by far my second favourite Clojure environment š
Ok, I see - I think that should be possible. One issue with that is that IntelliJās ability to paint things over the editor isnāt as slick as Atomās yet.
Hi, how to do optimistic locking in java.jdbc
, write a sql that update by id and version field?
@cfleming I think tools like this would really help the team debug efficiently. Experienced Java developers used to debuggers balk at the debugging approaches we resort to - still generally sprinkling printlns in the code. We know evaluating forms in the REPL is the way, but it feels like it's hard work to be efficient. Not sure if Sayid's approach to tracing, where every function call's arguments is saved is too "omniscient" or could be drawn upon? https://github.com/jasongilman/proto-repl-sayid
Sure, I think Sayid is great too - there are lots of different ways to skin the cat.
Yes - perhaps I should stop being so purist and get better at using it!
Itās essential to my work, definitely. Fortunately we donāt have to choose, we can have both!
hey, I have a function f
that calls g
, and g
calls f
, how to order defn's
so the compiler knows about all definitions?
@featalion that's it, thanks
Hello. I'm trying to set up a project for both client and server development, using compojure and http-kit. Since I already had a project going, I decided to modify my own project.clj
to match the the one I would get using lein new compojure ..
, but I'm getting some errors from ring regarding jetty. Here is my project.clj
: https://gist.github.com/dea054c015658d4ed3295b40b12c8fd5
Here are the errors: https://gist.github.com/f3f62cb6633979ebbfb849a8b6b20861
I also just noticed that lein deps :tree
seems to output a good deal of warnings regarding my dependencies. I'm honestly not sure what the best way to fix that would be, so I'll post that as well: https://gist.github.com/87f04f1805c2cc20e1dee2a9defe0462
Hmm. This seems to have something to do with datomic. I added exclusions like this: [com.datomic/clj-client "0.8.606" :exclusions [org.eclipse.jetty/jetty-http]]
and eventually got it to run. Now the lein ring
server starts but attempting to connect to it just results in a connection reset
Why does (if-let [x y] ...)
expands to
(let*
[temp__4655__auto__ y]
(if temp__4655__auto__ (clojure.core/let [x temp__4655__auto__] ...) nil))
and not to
(let [x y]
(if x ...))
?so that x
doesn't have to be re-evaluated multiple times
Different question: Is this an ok way to access both the first arg and all args? (fn [& [head :as all]])
user=> (macroexpand-1 '(if-let [x (do (prn :foo) true)] [x x] (prn :no)))
(clojure.core/let [temp__6751__auto__ (do (prn :foo) true)] (if temp__6751__auto__ (clojure.core/let [x temp__6751__auto__] [x x]) (prn :no)))
i.e. in cases where x
is used in the body of the if-let
@pesterhazy it still wouldnāt get evaluated multiple times with
(let [x (do (prn :foo) true)] (if x [x x]))
isn't that pretty much what the actual implementation does?
I am getting a StackOverflow error when trying to use log4j with Leiningen, could someone please take a look at the stacktrace? https://gist.github.com/hmaurer/40c1bc6d08550222f65e06a6366f0eb9
fixed it by removing a few dependenciesā¦ still strange though, I would like to understand why simply adding dependencies to project.clj could cause a stackoverflow error when launching the repl
Hi everyone, I've been doing some experiments on visualizing clojure.spec fails and ended up wrapping them in a library
maybe it's useful to someone else
Given that I have figwheel set up to use a ring handler via :ring-handler
, and that handler is also set to auto reload via ring.middlware.reload/reload
, is there some way I can make it reload everything? Basically restart the whole deal. I'm working with a library called sente
which is for websocket communications, and it doesn't look like the code that initializes everything related to that is being re-run, so it's kind of painful to iterate.
what I do is put all the code that has a lifecycle into https://github.com/stuartsierra/component so I have a way to restart the entire thing
@jpmonettas Hmm, alright. I'll see if I can whip something up that works. Thanks š
don't know if you are currently using something like components or mount
but I've done that with sente
you create something like a web-server component, and in the start/stop of that component you start/stop http-kit server, sente channels etc
Nah, not using anything like that. I'm pretty new to all of this, so still trying to figure out best practices and what people are doing etc.
Okay, I see. Is it possible to get that to play well with figwheel using :ring-handler
?
I mean, if you move all the stuff that deals with state into components, and then create a system(a bunch of components) you end up with a restart fn you can use wherever you want
I never fired it from that reload middleware but can't see any issues with that
I see. I guess I just don't quite grok how all these things work together. But I'm sure I can come up with something from what you've told me. Thanks!
does anyone have a pro-tip/link to an example of using core.async with ring? or some other http server? like how does one wait for input on a channel and flush said result to a response?
aleph actually has an async request handler infrastructure - and it uses manifold that is designed to integrate easily with core.async
if you use eg. jetty your async code will run but there will still be a blocking thread per request until you respond
the real question I guess is why you are using async, then you can use that answer to guide how you integrate that with a ring server
for the go-loop as you show it, you end up with a single block of code that can only deal with one request at a time - thereās valid reasons to do this sometimes but itās a pretty severe bottleneck
awesome - I will look into aleph. I was thinking of using core.async as a general abstraction on input/output
when I say āone request at a time in the blockā I mean globally, only one of your requests can be in that block - so if you have five concurrent clients, it takes 5x as long to complete
which usually isnāt the kind of behavior you want in a web server at all
with manifold, you can set up a function that gets called with an input channel and an output channel, and it is instantiated as many times as you get requests, which is a more reasonable pattern of behavior
aleph + manifold seems to be the ticket. many thanks for pointing me in that direction š
Is there a way to quickly run tests when a file changes? Manually running lein test
takes about 10s to boot for me, and using https://github.com/weavejester/lein-auto take the same time
I assume the delay is coming from the jvm boot time, but I donāt know how to avoid it
@hmaurer fyi lein test just uses clojure.test, and you can require that and run (clojure.test/run-all-tests)
in your repl (after requiring your test namespaces of course)
@hmaurer I'd recommend running tests from a persistent repl, and using something like clojure.tools.namespace to ensure code is reloaded and up to date
fwiw, I always have something like this in user.clj
(defn run-unit-tests []
(repl/refresh)
(test/run-all-tests #"^project-ns.*$"))
@U050MP39D I am trying to avoid Cursive for now to get a first-hand experience on clojure, and not have too much hidden behind IDE magic
that's fair, and to do what cursive does without cursive it's basically just (do (repl/refresh) (test/run-test ...))
@U050MP39D yep, right now I have a function āreloadā which calls clojure.tools.namespace.repl/refresh, as well as restarts my system
you could hook up the run-all-tests to run as part of your system refresh if you have such defined
@noisesmith ah, good point. Thanks!
are there any āgood practiceā I should be aware of regarding testing clojure? (either tools/libs or approaches). Or should I just get started with clojure.test?
Also, is it advisable to place pre/post conditions on every ācoreā functions of an app? Including spec checks on arguments.
one thing to keep in mind is that testing functional code is easier than what you are probably used to
good functional design in general separates the mutable / side effecting source and sink of your data from the immutable guts
if you do that right, you can unit test the immutable guts easily, and separately verify that the mutable input and output logic works
where the input and output would likely be integration tests, or even better they can be verified by the tests on the separate code implementing the i/o
@hmaurer what that looks like in the big picture is a bunch of immutable code that does no io or side effects, and a top level ādriverā that connects that to data - which can easily be subbed out by a lambda or direct function argument in your test
@noisesmith Ok, Iāll try to follow that idea. I have done some FP before so itās not completely unfamiliar. The app I am currently working on is very much CRUD, so I donāt think there will be that much distinction to make betwen i/o code and pure functions (almost everything does i/o)
I donāt like midje at all
yeah - but there are some nice additions to it, like difftest
expectations is decent too
Alright, thanks! Also, whatās your stand on using pre/post conditions on functions. Is that something that should be done?
I'd stick with spec for that sort of thing, it's pretty much pre/post v 2.0
I found problems where they were being missed at dev time and caught things at run time, and they throw AssertionError which our try/catch blocks werenāt catching which led to annoying hard to debug failures
(especially inside futures and go blocks)
on the subject of testing though, what I like in a testing lib is utter simplicity. A testing framework really only needs to be about 100 lines of Clojure code. Clojure.test is about 500 but that's mostly cruft that could be stripped out (by breaking backwards compatibility).
yeah, I find if something is hard to test with clojure.test thatās a sign my code is too āfancyā for its own good and the easier to test code is better
Also, if you find code that re-defs vars for testing/mocking that's a bit of a code-smell, imo. It's not always avoidable, but the cases when you need with-redefs
or the like should be really rare.
@tbaldridge good point, when I read about with-redefs it did seem to be like a ābetter avoid if possibleā construct
@hmaurer what editor are you using?
regarding the short test lib I just wanted to make sure. Some other languages tend to have rather large ātesting frameworksā, and while clojure.test seemed enough it felt a bit like cheating
@tbaldridge Atom at the moment
Some like Cursive (and I think Cider as well) have keybindings for running tests via a IDE command
fair enough, so yeah, you can send across run-all-tests or write some sort of editor macro that dumps that into a repl for you
Something like that could be coded with emacs+inferior lisp with about 10 lines of code, so I assume Atom would be close to the same.
I also bind CTRL+` to "send the sexpr under the cursor to the repl". That's also a big time saver.
simplicity is great but it kind of sucks that midje had better tooling baked in 2 years ago than exists for clojure.test at all today
what sort of tooling?
As mentioned things like auto-runners are a bit pointless in Clojure because there shouldn't be a reason to restart the repl
it's more of a design difference than a lack of tooling.
interesting, I never had it running that way, but honestly I'd be a bit nervous of something auto-running my code whenever I change it.
midje: at repl (midje.repl/autotest) clojure.test: ? need some leiningen plugin thing which is bound to break with other lein plugins
Woudln't want to accidentally type (sh/sh "rm -rf foo")
then accidentally delete 3 characters from that string ^^
... I mean. test autorunners have been around since junit and I've literally never heard of someone managing that (not saying it's not possible, but sheesh)
So to make it a bit more concrete, my workflow is this:
* Edit some code
* Send it to the repl with either "send form" or "reload current namespace in repl"
* Test the code I just sent by hand, normally with a few bits of code I keep in a (comments ...)
block
* Once it appears to work, I switch to the test namespace and re-run all the tests, or maybe just the tests I care about (keybindings for that)
But with a REPL you end up doing a lot lest test-driven development. It's not "write test", "write code". It's more like "write spec", "write code", "play in repl", "fix code", "write a test if it needs to exist".
that is also my workflow, but having worked with good autorunners before I can say from experience a good autorunner is still an improvement to that workflow
But how much time does that save? Like 3 sec every 10 min?
honestly if it worked well it would probably add up to more though. my test suite takes longer than a 3s difference between the full suite and the "tests affected" set for most things
That's kindof my point though, when I'm trying to fix a specific bug, I run all the tests, then pick one failing one, and make that work. Whenever I make a code change I rerun only that single test.
which is what an autorunner does for you. I'm not sure I understand the objection to having the computer do it instead of doing it yourself
Because the computer won't do it right
And if there's one thing that utterly kills my productivity, it's making a change and then seeing that a test didn't pass due to stale code.
when I used these things back in ruby days, the vast majority of the time it did. when it didn't there was nothing stopping me manually intervening
Stuff like Java imports of deftypes, global state, multimethod dispatch functions, etc. All those things break most autorunners (even Midje in some cases)
not the repl though
the repl only does what I tell it to, so whenever I change a form I reload it. or the entire namespace.
that's not going to help you with any state referring to the old protocol. this is a well documented annoyance. whatever, fine, it all works perfectly for you. I'm just saying I've done the clojure workflow both with a good autotester and without and it was better with one
some people like it, especially if they are used to that kind of dsl for testing
I like midje. but it wasn't widely embraced and the lead developer is done with clojure. I would not start a new project with it
Elixir
Iāve been using Midje lately but have found some bad issues. One being dependency errors get swallowed and are a pain to fix.
For better or worse, Midje is a DSL, your tests aren't written in Clojure they're written in a Midje testing language. And yes, that can be the source of a lot of confusing errors.
There are more people maintaining Midje after Marick (we are big users of it where I work at).
While I can't speak for the future, in the short term it should be up-to-date.
@U69US8BKQ clojure.test. And I wish it was simpler š
All a testing lib really needs is deftest (that generates a tagged function), some sort of smart assert, and a run-all-tests
@U69US8BKQ I'll put in Expectations which is more BDD in style than clojure.test
's assertion-based format -- and now supports all the clojure.test
tooling.
There's an #expectations channel if you have any questions.
lazy question: @seancorfield is there any notion of "business time" in clj-time?
in my past ruby life I used this: https://github.com/bokmann/business_time
Using that with https://github.com/dm3/clojure.java-time ought to get you what you need, fairly cleanly.
FYI, at World Singles, we're slowly migrating away from clj-time to clojure.java-time (or just using Java Time directly).
See this https://github.com/clj-time/clj-time/issues/196#issuecomment-294067755 -- and read the whole thread for background. It is a discussion around moving clj-time
to JSR-310 and the pros and cons... and why, ultimately, I came out against the switch of implementation and why I would encourage folks to use clojure.java-time
instead of clj-time
if they want to switch from Joda Time to Java Time.
I have a Clojure design problem which Iād love some feedback on. I have a SeriesStore
record and corresponding SeriesStore
protocol. There are different stores for different accounts etc, so I need some way to create these stores. Iām considering two options:
1. Have a regular fn that is a closure around all dependencies of the store, and then pass that fn around
2. Create another record which contains all the dependencies, e.g SeriesStoreFactory
, and then pass an instance of that record around.
i.e regular fn closure vs. record, which is preferable and why?
Records almost always win @schmee for the simple reason that functions are opaque. Once you close over something with a function there's no way to introspect the closure to see what you closed over.
Sometimes you need that for debugging, other times just to do keys
or to otherwise get the state out inside some function.
hello everyone while using clojure.test
its possible to share data between tests?
something like
(def data (atom :none))
(deftest t1 ... (reset! data 10))
(deftest t2 ... (do-stuff 10))
If I wish to set up some data that should be accessible to all tests (either set up once before all tests or set up and tear down before and after each test), how can I do it with clojure.test? with-fixtures doesnāt appear to let me pass data down to the test. I could use a global atom but that seems nasty
@tbaldridge sounds reasonable. but sometimes you want it opaque though? my main concern with records is that I want to keep it as functional as possible, and I worry that my code will start to look like OO if there are too many records all over the place. whatās your experience on striking the right balance between records and fns?
Right, you got to separate out "is a protocol" from "looks like OOP"
OOP = information hiding, local mutation, and inheritence
records and protocols don't do any of that.
true, true. and I actually have polymorphism in this case, so Iāll go with records. thanks for the input!
@owen Iāve tried the whole gamut of state management libs in clojure, Iām currently experimenting with https://github.com/vspinu/commix which I think is fantastic so far!
Better than most node libraries! #burn
> Commix was built as a response to a range of limitations in Integrant which in turn was designed to overcome limitations in Component.
I tried using Integrant but I immediately found myself working around it instead of with it, then I stumbled over commix here: https://github.com/weavejester/integrant/issues/21
I recognized some of the problems I encountered in the ādifferences from Integrantā section
Does anyone have a recommendation for me on how to share some stuff between tests? e.g. a database connection
well if is something static i think you can just
(def db-spec (..))
(deftest test
(jdbc/query db-spec ..))
i really would like to know how i can share data that is produced by one test in another testim trying to do some sort of all-or-nothing integration api integration test imagine that i do a request to create an user, and it returns me an id afterwards in another test id like to user this id to create a bank account for this user (or something like that)
@plins ah, I was planning on doing the same thing. It seems to me this should be done within one test block? I donāt think there are much guarantees as to in which order tests will run
im trying to avoid a giant let with tons of implicit tests, but i seems that i got no other option
@plins I am a newb, but what do you think would be the issue? You can nest testing
calls to create context
unless there's a serious desire to split the tests across multiple files I would go the huge let block over the dynamic vars
@U050MP39D huge let blocks canāt be shared across tests though
well they can't be shared across deftests I guess, but they can be shared across assertions
@U050MP39D would you mind showing me a quick example?
I guess I'm generally a bit ambivalent about the difference between "tests" and "assertions". I don't really care about the granularity
I don't know about common, but I would prefer it over fixtures populating dynamic vars
and from what I just inferred from the source of testing
, it returns its last expression
(defn- create-user-account []
(testing "Create a user account"
(let [user-account (app/create-user-account)]
(is (= ....))
user-account)))
(defn- create-bank-account [user-account]
(testing "Create bank account"))
(deftest scenario-1
(let [user-account (create-user-account)
bank-account (create-bank-account user-account)]))
I havenāt tried it though, and completely new to clojure.test, so donāt take my word on it
@plins I just tried to use testing
inside a defn-
function called from a deftest
and it worked, but the doc says `May be nested,
but must occur inside a test function (deftest).`, so I am not sure how to take it
maybe it means it will work so long as itās called within the callstack of a deftest
function
@hmaurer I just did a macroexpand
of (testing "foo" body)
and it looks like it relies on dynamic calls for context so I think you're OK -- but it's definitely a bit unorthodox.
(macroexpand '(clojure.test/testing "foo" (something)))
=> (let*
[]
(clojure.core/push-thread-bindings
(clojure.core/hash-map
(var clojure.test/*testing-contexts*)
(clojure.core/conj clojure.test/*testing-contexts* "foo")))
(try (something) (finally (clojure.core/pop-thread-bindings))))
@seancorfield so deftest sets a dynamic var which is available anywhere within the callstack during its execution?
do you have a better suggestion to do what I was trying to do? (split a test in this way)
I haven't seen it done that way before -- so it looks unfamiliar -- but if clojure.test
manages all of its testing context dynamically, I guess it's fine. I guess I would have a specific test for each creation function that asserted whatever behavior I expected (and cleaned up after itself), and then in the main test I'd just call the creation functions without worrying about testing
or is
...
In other words, I'd only have "one" test for those common things, rather than repeating the tests every time they are called.
if you don't have :gen-class in a ns form, compile is a nop, and if you don't have gen-class I doubt you really want to aot compile
I noticed that most ns don't necessarily get aot'd, when I stripped out clj files jar started to fail
does anyone know of a library for doing set-like operations (`intersect`, union
) on possibly infinite sets?
I didn't find anything in my quick searching, but rolling my own shouldn't be too hard
oh, just because that is a more logic based representation of a set vs. a datastructure