This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-20
Channels
- # beginners (17)
- # boot (19)
- # chestnut (1)
- # cider (25)
- # clara (1)
- # cljs-dev (15)
- # cljsrn (10)
- # clojars (9)
- # clojure (182)
- # clojure-brasil (27)
- # clojure-dusseldorf (2)
- # clojure-gamedev (5)
- # clojure-germany (1)
- # clojure-greece (2)
- # clojure-italy (18)
- # clojure-poland (5)
- # clojure-romania (3)
- # clojure-russia (29)
- # clojure-serbia (6)
- # clojure-spec (9)
- # clojure-uk (77)
- # clojure-ukraine (1)
- # clojurescript (61)
- # cursive (5)
- # datomic (20)
- # defnpodcast (1)
- # emacs (10)
- # fulcro (2)
- # graphql (2)
- # hoplon (11)
- # lumo (4)
- # off-topic (50)
- # om (3)
- # onyx (26)
- # other-languages (39)
- # parinfer (2)
- # pedestal (5)
- # re-frame (32)
- # reagent (48)
- # rum (7)
- # shadow-cljs (10)
- # spacemacs (29)
- # sql (10)
- # unrepl (58)
- # vim (3)
hi everyone, basic question about threading. Why doesnt this work
(-> 10
inc
dec
(fn [x] (* x x)))
I expected output of 100as for the why... this will reveal š
(macroexpand-1 '(-> 10
inc
dec
(fn [x] (* x x))))
oh i see it now
thanks š
@ondrej.cermak have you considered a database trigger that writes to a separate logging table on inserts and updates to specific tables?
@zwhitten Yes I did, but i haven't figured out how to get the current user logged in š
@ondrej.cermak Did I see you're using postgres? If so, CURRENT_USER
should give you what you want.
That would be SQL user, not application user. I would need to find a way to append id of current id to every SQL query for the trigger to work š
I'd create a wrapper to the database query functions that takes the logged in user as an argument. Use that data to log anywhere/way you want.
Thanks. @bronsa @lady3janepl
@grzm that actually sounds good. Are you familiar with sqlKorma ? Im wondering what would be the less possible way to wrap native sqlkorma functions for this to work. There could for example be problem with threading macros
I haven't used Korma before. At a very brief glance, it's too magic for me. I pretty much just use clojure.java.jdbc and write my sql directly.
Oh, alright .. Well, i came to clojure from OOP languages with frameworks like SpringMVC .. so at least a querybuilder is kinda a must for me š
this may be a good time for a simple macro. defquery
that takes a user and then just passes everything through to a defn that includes whatever logging form you normally do.
Hello, are there any clojure libraries that play nicely with bitcoin, or any bitcoin exchanges powered by clojure?
district0x got some work on ethereum https://medium.com/@matus.lestan/how-to-create-decentralised-apps-with-clojurescript-re-frame-and-ethereum-81de24d72ff5
@ondrej.cermak Clojure requires a different mindset to OOP -- but you might want to look at HoneySQL as a composable way to build queries from expressions (which is compatible with clojure.java.jdbc
).
is there a way to tell clojure.core/memoize to only keep WEAK references to its arguments ? I need this to be WEAK in both clj and cljs
@U3JURM9B6 no but I guess it wouldn't be too hard to roll your own version of memoize using weak maps. Be careful of browser support though.
@U3JURM9B6 core.cache has these sorts of things https://github.com/clojure/core.cache - itās very flexible but not as easy to use as memoize
the key thing for me that made core.cache āclickā is that nothing in core.cache knows or cares how your mutable storage is implemented - it has a bunch of functions that accept an immutable hash map, and return an immutable hash-map, and itās your job to figure out what to do with that hash-map in your app
compare to memoize, which implicitly uses an atom holding an immutable hash-map that you never touch directly
oh, sadly core.cache isnāt cljs compatible- I wonder what else is out there
@turkkam I have been using it for a project for the past couple months and it mostly just works. Most quirks are due to the way the developer server is set up and the REPL. Let me know if you have specific questions and happy to help.
Have you been using standard or flexible environment ? I was looking at setting up project for standard environment. It seems like you have to do a fair bit of hackery if you want to use leiningen for building the project. š
Standard environment. Yeah, it takes a little bit, but it's a lot easier now that there are no restrictions on what classes to use. Let me know if you have specific questions and if there's interest, I might publish it as a lein plugin.
Here's a preview of the latest setup I'm working with. Main draw back at the moment is no nrepl support, but using a socket repl. Definitely a couple of other rough edges, but thought I'll share. For anyone else interested, feel free to reach out. https://gist.github.com/alpeware/f18bef80cb521347d22b85f1ad07ada7
does clojure have any libraries pertaining to data analysis/data science?
Howdy. What would you guys recommend for putting together a simple ReSTful API for passing JSON from Mongo to a web client?
@turkkam I have been using it for a project for the past couple months and it mostly just works. Most quirks are due to the way the developer server is set up and the REPL. Let me know if you have specific questions and happy to help.
hey guys, does somebody know the owner of
? I just tried it today and it says that the domain name has expired š
Just putting it here hoping it that the owner sees it.
maybe a clone on
The repo is here
https://github.com/Raynes/tryclojure
unfortunately the owner passed away last year (see https://cemerick.com/2016/12/07/rip-anthony-grimes/), not sure if anybody else has access to the domain
oh, didnt know that. Well there are now some other websites out there with Clojure repl so it shouldnt be a problem.
Guys, is there a beautiful way to implement this in clojure?
(defn handle-job-entity
[result {:keys [new_agent new_job job_request] :as entity}]
(when new_agent
(handle-new-agent entity))
(when new_job
(handle-new-job entity))
(when job_request
(handle-job-request entity)))
Every time I receive an entity that has this three keys but only one is true at a time@tvalerio I had this in mind:
(defmulti a (fn [result command]
(->> command (filter second) ffirst)))
(defmethod a :new_agent ...)
hope it helps!@tvalerio if all functions use the same argument, why dont you just pass the function as argument? (handle-job-entity new-whatever entity)
and inside it, you just do (new-whatever entity)
But in that case, how can I know what function to pass? I think Iād have to check that three values
@tvalerio the code that calls handle-job-entity
must know which function to call, otherwise it would not be possible to pass it as an argument as you show above. I assumed that you were in control of that code.
Yes, I am.
The function that calls handle-job-entity
is handle-job-entities
(defn handle-job-entities
[job-entities]
(reduce handle-job-entity {} job-entities))
So in this function will I have to check some how that same values Iām receiving in handle-job-entity
and pass the correct function right?
@tvalerio it depends. Multimethods are much more flexible but if you are just starting I would recommend you to stay with the basics. That way you can avoid overloading yourself with new stuff.
I see. Good idea š¬ But in that case where I pass the function depending on the value of that three keys, wouldān I end up with the same problem before?
Iāve tried to do like this:
(declare handle-new-agent handle-new-job handle-job-request)
(def entity-functions {:new_agent handle-new-agent, :new_job handle-new-job, :job_request handle-new-job})
(defn handle-new-agent
[result entity]
(prn "handle-new-agent: " entity))
(defn handle-new-job
[result entity]
(prn "handle-new-job: " entity))
(defn handle-job-request
[result entity]
(prn "handle-job-request: " entity))
(defn handle-job-entities
[job-entities]
(reduce (fn [result entity] ((entity-functions (first (keys entity))) result entity)) {} job-entities))
But it gives me an Attempting to call unbound fn: #'job-queue.job-queue-core/handle-new-agent
sorry, I forgot that before the def
I have:
(declare handle-new-agent handle-new-job handle-job-request)
might it be that it's inconsistently evaluated into the repl? try loading it from scratch
here's the fix:
(def entity-functions {:new_agent #'handle-new-agent, :new_job #'handle-new-job, :job_request #'handle-new-job})
declare
returns special clojure.lang.Var$Unbound
objects, you aren't supposed to handle them directly as the (def entity-functions ...
code does
a simpler lesson would be: define things in a way that the compiler can resolve at every moment
coming from other languages you might be tempted to define higher-abstraction-level functions first, it would be nice if Clojure favored that style but it doesn't
(condp #(get %2 %1) entity
:new_job
(handle-new-job entity)
:new_agent
(handle-new-agent entity))
could anybody remind me the easiest way to get start/end of the year for the datetime instance? I checked clj-time
sources but without result (or did I skipped those functions?). thanks.
@igrishaev did you try clj-time
?
are there any functions to jump at the beginning/ending of some period: week, month, year etc?
@igrishaev "get next Monday": https://gist.github.com/rauhs/3ec9f05f2501bfb40acec35eca3fa73e#file-java-8-time-clj-L32-L36
Beginning/end of year should super easy, no? Just get the current year and create a new date with Jan 1 & Dec 31st?
@rauh thank you, the code looks interesting. Yes, dealing with the year issue would be easy. I just expected some general functions to exist.
select date_trunc('week', current_timestamp);
date_trunc
------------------------
2017-11-20 00:00:00+03
(1 row)
@igrishaev Read the doc string of TemporalAdjuster, it has TemporalAdjusters/firstDayOfYear
, and month (and last respectively)
Hi, y'all! Is there a way to stub clj-time to return a certain time instead of now, when I call (t/now)
? I want to write tests and I am looking for something like timecop (a Ruby gem)
We tend to write our stuff so that most time-based functions take in a definition of 'now' as an argument. Makes testing easier, and then we generally only generate 'now' in one place in the live code and use it where needed
Hey guys, I'm trying to manipulate a record in Java. It seems assoc returns an Associative type. Is there a way to get back the same record type or do I have to just cast it everytime?
example:
// c is a record of type "Context" created in Clojure with (defrecord Context [foo bar])
// this returns Associative rather than Context
c.assoc("some_key", "some_val")
//ideally I could just do this
c = c.assoc("some_key", "some_val")
@igel you could try using mocking library for that: https://github.com/igrishaev/mockery
(with-mock _ {:target :clj-time.core/now
:return (date-time 2017 12 31)}
... code goes here))
There was a recent library I saw that implemented some sort of computation DAG, very much like AWS Step Functions. I lost the link, does it ring a bell for anyone?
that was it, thanks @lovuikeng
@rnagpal if you look at the classpath in the running repl, all your source directories need to be on the class path (and the namespace needs to form a path starting at a classpath entry matching the namespace name)
(System/getProperty "java.class.path")
a āsource pathā is a leaky leiningen abstraction, all clojure itself cares about is the classpath
@noisesmith I do see the directory in class path
then the path to your file does not match the namespace, or it failed to load for some other reason and you misunderstood the error
Exception in thread "main" java.io.FileNotFoundException: Could not locate ****/system__init.class or ****/system.clj on classpath., compiling:(server.clj:1:1)
well, the part where the problem is would be in the somewhere - double check that -
is translated to _
and that the file path from the classpath root matches the full namespace
and you have a //system.clj on the classpath during uberjar creation?
lein with-profile uberjar cp
yeah @noisesmith its not there
dev profile is for things you only use in dev
itās specifically for things you want during dev but not while making an artifact
donāt do that! if you need the source files in your uberjar, put them in the normal source paths, donāt put them in dev
if you add the dev profile to your uberjar command, you also pull in things that are only needed during dev (especially a risk with tools like cider that add to your dev profile)
it would also mean your test files would end up in the jar - not usually what people want
Thanks @noisesmith I was stuck on it for some time. Didnt know how to check class path.
it says āuse the uberjar configuration, and run the cp commandā
ālein cpā would run lein with the default profile and show the classpath
you can also use lein with-profile +foo ...
to merge rather than replace profiles
uberjar is a profile, yes - you can see a lot more example and info in the output of lein help sample
Thanks @noisesmith.
depends on the features you need, but we (CircleCI) use https://github.com/circleci/bond
I have had good success in the past with making protocols that represent external side-effects (e.g. a mail server) and then reifying dummy impls.
very simple and light
@ghadi but how can i test a function that depends on another one that calls external systems or has side effect
^^ thatās an awesome way to think about it
ideally the external functionality has a thin wrapper that you can easily cover with integration tests, and you can pass in an alternate stub implementation for testing things that use it
(I think this expands on what ghadi was saying)
sometimes itās even worth making a protocol, in order to have two implementations (the stub and the one that uses some external / stateful / side effecting resource)
If you're using Ring or similar, you can make a middleware that inserts the appropriate implementation into the request context, that way you don't have to grab it from a global var
@noisesmith @ghadi I got the point but I really don't know why we should avoid mocks? aren't they easier than stubing protocols?
they lead to unneeded complexity, you end up wrangling an implicit global state in order to verify something that shouldnāt care about it
with-redefs for example causes a multitude of problems, including preventing parallel testing
if you really want the easier / global / implicit thing, at least implement it in terms of something that uses an explicit argument to the function - you can easily build implicit / global / stateful out of explicit immutable arguments, but it is much harder to go the other way
valid point but this will add too many types and records which i try to avoid most of the time
you can do it without a protocol or record - I only mention using a protocol (which in my practice means using a reify in the test, and either a record or reify in the implementation) - because that can simplify the swapping of implementations
if you prefer functions, use functions, it does work
are there any known gotchas involving partial application around a stest/instrument
ed function ?
I get this error
Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method, or the namespace has not been AOT-compiled.
you can run an uberjar without AOT if you can specify the java command line: java -cp my-uber.jar clojure.main -m my.ns
if you need the jar to be startable or loaded by some other java process, you probably need aot though
Thanks @noisesmith. I was missing (:gen-class)
I have a wrap-auth
fn in compojure-api, and an endpoint where I'd like it to be conditionally applied
contingent on a query parameter
is that possible?
ex, either they're authenticated, or a query param has a valid signature (in which case, non-authd is fine)
yes, you can make a middleware that either returns the handler unchanged, or applies a middleware, based on some property of the request-map
something like (defn conditional-middleware [pred? middleware handler] (fn [request] (if (pred? request) ((middleware handler) request) (handler request))))
if you donāt like ((
you can use let to bind the wrapped handler
oh nice, I think that'll work thank you!
the devilish thing with ring is itās very flexible and things like this are easy to apply, but it can be very hard to debug when you have enough wrappers like this - my theory is that pedestal interceptors are an improvement as they are data you can investigate on the fly but havenāt used them in anger
I'm in the same camp, anytime I can convert "effects" to data, it tends to be a win
Ring is also rather anti-async, you can bolt-in async stuff, but it doesn't work super well.
relatedly, I have a :path-param
that I'm trying to pull off the request
in my wrap
per
but the best I can find on there is :path-info
which has my route un-parsed
is there place I can get a parsed :path-param
, eg for myroute/:x
, (get-in request [:path-params??? :x)