This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-30
Channels
- # announcements (15)
- # beginners (143)
- # boot (2)
- # calva (48)
- # cider (93)
- # cljsrn (2)
- # clojure (127)
- # clojure-europe (3)
- # clojure-italy (8)
- # clojure-losangeles (8)
- # clojure-nl (10)
- # clojure-spec (67)
- # clojure-uk (51)
- # clojurescript (20)
- # cursive (9)
- # data-science (2)
- # datomic (10)
- # duct (13)
- # figwheel-main (1)
- # fulcro (74)
- # instaparse (10)
- # jobs (3)
- # joker (8)
- # juxt (4)
- # lumo (1)
- # malli (11)
- # nrepl (3)
- # off-topic (4)
- # pathom (5)
- # pedestal (6)
- # planck (5)
- # re-frame (18)
- # reagent (5)
- # reitit (17)
- # shadow-cljs (165)
- # sql (30)
- # vim (12)
- # xtdb (6)
in Emacs, does cider-eval-defun-at-point work the same for cljs files as clj files?
every eval is producing a variant of
1. Unhandled java.lang.IllegalAccessError
atom does not exist
i.e. when eval'ing
(ns test.core
(:require
[reagent.core :as reagent :refer [atom]]
[reagent.session :as session]
[reitit.frontend :as reitit]
[clerk.core :as clerk]
[accountant.core :as accountant]))
in a reagent project.
if I comment out the reagent.core line it has the same error for reagent.session.
however, changes to source compile and are reflected in the browser... so maybe I'm not understanding what can be evaluated in a buffer in a cljs project as compared to a clj one.
ok, off to #cider.
Mildly annoying and perhaps an off-topic question: I’m looking for a Clojure library for “effects & handlers”, à la re-frame but for the back-end. What’s currently “trendy”? I looked at https://github.com/clojureman/special, I like the simplicity of it, but not sure if it’s okay to use it in production. Would you recommend using it or maybe something else?
@ag I'm not sure I would look at that "conditions" library and think "effects & handlers" so maybe I don't understand what you're looking for with that description...
...to me it sounds like you'd want some sort of event broadcast / listener pattern?
To be honest I don’t know exactly what I want. I’m just seeing a lot of code where side-effecty things are thrown together where the code is written in sorta “linear”, imperative fashion and I don’t like it. I want something similar to how re-frame separates subscriptions and events. For example: I have three different sources of data that I need to fetch in order to make a decision, each query depends on the results of previous query and each has to handle exceptions, etc. Moreover, sometimes you need to also update (e.g. write to db) before fetching some more data and that all can get pretty nasty. Clojure by default doesn’t give you any tools to deal with that problem, only wisdom in form: “maintain certain discipline; write small functions; compose.”
Yeah... my attempts to go down that path have all ended up looking like monadic code which is not very idiomatic Clojure and not very easy to work with, to be honest.
but it is hard when you have developers in your team coming from imperative languages and writing it the most straightforward (from their perspective) way
working mainly with Re-frame for the past several months, and now switching to do more back-end code, I have to say - I miss re-frame model. And I used Om.next as well, even though it was more difficult to grok in the beginning, it is still very nice. I want something similar for the Clojure code.
On the front end, you're constrained to single-threaded behavior so these callbacks/listeners make a lot of sense. I don't know that sort of logic makes as much sense on a multi-threaded backend tho'...?
I suspect you might be headed toward either monads (there's a contrib library for that) or core.async... But I guess I'd have to see the sort of linear/imperative code you're talking about to really offer an opinion.
but it’s not just single-threaded, everything is also asynchronous. That makes it more difficult, not easy.
I need to find a good pattern for the back-end code. Where fetching data, pure transformations and side-effects (logging and exceptions) are separated.
I also have struggled with what is the answer here. In the past I’ve gone with “well push all the impure stuff into these few ns’s” but that is admittedly dissatisfying. I remember the silliness of monads in haskell though too. one thing I guess is that in a backend/server context there’s a lot less juggling with the outside world that generally has to go on than in a ui side process
> in a backend/server context there’s a lot less juggling with the outside world I beg to differ. There’s way more. At least in the project I’m working on right now.
the pattern I’m seeing very often:
get-data -> manipulate results -> feed that to another query -> side-effect (update DB, logging, exception handling) -> return something like {:result :success}
.
and this is all in a single function. Sometimes I see things like (let [data (get-data), _ (fire-missiles data)]
- i.e. side-effecting in a let block, because no one even cares about the results of that operation.
On some of our services we have adopted a re-frame-esque approach to handling the effects. The one function that did all those side effects would now return a "fx" map. That fx map would get passed to a small function that just doseq
s over the map and executes each effect via a multimethod. This approach lets us test the whole flow without actually firing any missiles.
Yeah, something like this. One would think this kind of pattern maybe widely adopted and used, it seems that’s not the case
It's been quite successful for us. Maybe it's a bit too simple and possibly use-case dependent to turn into a library?
It's essentially this:
(defmulti mutate! ::name)
(defn run-mutations!
[mutations]
(doseq [[mutation-name mutation-map] mutations]
(mutate! (assoc mutation-map ::name mutation-name))))
it is especially difficult when you have multiple “sources of truth”. In comparison - on front-end with Re-frame - you have app-db atom - it is a single “source of truth”.
if you don't care about it, then throw it in a go block in the body of the let. at least that's what i'd do
with let-flow you don't need to manually wait for everything, it does the magic for you
@ag some food for thought https://github.com/linpengcheng/PurefunctionPipelineDataflow (I think written by @lincpa)
This is really good. But sadly it does’t give me an answer I could immediately apply. This for example: > My idea of development: > Everything is RMDB. > Send SQL, > Get Results ( or side effects). > Playing table tennis between Clojure and RMDB. What does this exactly mean?
The stuff about "Everything is RMDB", I admit I have no idea. I think some nuance is lost in translation. My interpretation of what the blog posts are about in concrete (clojure) terms is:
- Use "pass the world"-style context maps, pass this around
- Structure your functions as: [optional verification step] -> followed by a threading macro of pure functions -> end the function with a side-effect
- Each function may have a single side-effect
- Favour using simple functions like reduce, map, pmap and aim to keep your call stack as shallow as possible
The way you described the general flow of your functions made me think of PurefunctionPipelineDataflow
@michael.e.loughlin I love that
it takes a bit of work to tease apart the metaphors, but it seems like there's something there. Or perhaps I've imparted my own meaning by interpreting the metaphor. I suspect that might be the point :thinking_face:
hello everyone
is there a good way to attach a message to be returned if the spec failed ?
this lib do what i want https://github.com/leonardoborges/bouncer , so my question is could i use the same with clojure.spec
no, that's not part of spec
@alexmiller what is your suggestion to do that?
for example: if i'm using spec to validate params of APIs, so i should give the user hint what makes the call fail
You could wrap the response from spec along with the message in a higher order map. Something like this:
if validation fails, you can use explain-data to get back more detailed info about why and use that to construct a user message
@U145X0BPE This isn't always a trivial thing to do, especially with complex specs & a large information model. We have been using this lib in production to convert explain-data to user friendly error messages https://github.com/Provisdom/user-explain. It's manual, tedious work but will allow you to cover anything you'd possibly want.
Attaching additional info to specs when they fail does seem valuable. Predicates often do not return enough information to allow you to figure out what went wrong.
that's awesome 🙂
thank you
but i'm curious if spec maybe in the future support that, to attach messages in case of failure ?
You can see another approach in #announcements from @U0WL6FA77. It's less general but might be easier to understand.
Hi everyone, I'm a frontent JS developer who is not only new to Clojure and CLJS but also to backend development. From the frontend I'm used to being able to fire up chrome and inspect my http requests to see, for example, if they contain the right payload or URL params are correctly encoded and things like that. Right now, I've started writing a middleware that I need to get data from an API and I was wondering if there is something like Chrome devtools for "backends" or middlewares that I can use to inspect HTTP requests. I've tried Wireshark. It's a great app but, boy, it is complex. I was looking for something more focussed on HTTP.
The only thing, that comes to mind for me is to route everything through a proxy but that seems like a lot of overhead.
generally just logging. tap> etc. you can also connect to your running server process with a repl and poke around at any state you keep
in my experience with server side dev: log/tap> all the things. and if you can store what you’re tapping in something queryable even better
yeah I’m assuming he meant “value”. if you want a literal you type it with your hands 🙂
that said, if you are literally emitting code for something else: (symbol (str “0x” “22"))
I am parsing some data, where I have hex strings, and need to compare them. Its just more cleaner to have a map of hex literals in my code, rather than hex strings. Will go with the strings for now.
You can parse into an integer and compare integers.
(Long/parseLong "22" 16)
=> 34
The last param 16
is the base.
then use .toHexString() if you want it as a hex literal string.
the literal form of integer in Clojure are java.lang.Long values
those always print as base 10
the reader is able to read other forms, 0x etc
in what context do you want to print it as 0x55?
there are ways to influence how the printer prints things if you have some context for doing so
I have a hash map {"55" :a "FF" :b} etc, where the key is a hex value. I would have liked to represent them as literals instead of strings, its just more cleaner. However to do that I will also have to convert my input hex string to hex literals.
0x22 and 34 will be the same value (a java.lang.Long) in your data
The parsed value (the integer) can be used for this. "Literal" usually means a representation of a value before it is processed by the reader, so this term is confusing us I think. :-)
you can represent them as a long, which will get printed as base 10. you can represent them as a string, which will get printed as a string, or you can represent them as a symbol, which will get printed as a bare word. aside from the printing, those three different types of value are associated with wildly different behaviour
if you really, truly, do not care that the value is a number, if it’s just an abstract “thing” that you want printed as 0x55 but you’ll never ever try to do number things with it, you’ll never try and pass it to anything (database, serialisation tool, library) that expects it to be a number, then a symbol will give you that
@alexmiller thanks for pointing out that internally both are stored as java.lang.Long
which means this works ({0x03 :a} (Integer/parseInt "03" 16))
. My assumption was that both have a diffrent representation and therefore the above will not work.
btw, you can control how a map is printed by attaching metadata to it and defining a custom printer for it
you should use Long/parseLong, not Integer/parseInt
In control, the main integral type is Long, not Integer
user=> (defmethod print-method :foo [v ^java.io.Writer w] (.write w "overridden!"))
#object[clojure.lang.MultiFn 0x32b9bd12 "clojure.lang.MultiFn@32b9bd12"]
user=> {:a :b}
{:a :b}
user=> (with-meta {:a :b} {:type :foo})
overridden!
so you could attach a type to your particular map and then define a writer for it that writes the keys using hex notation, if you really wantedthe above works but only because longs and integers both hash the same and compare equal, but you are pushing on same fragile boundaries there
I'd say the printing thing is too clever and bound to trip you up eventually
@alexmiller thanks for pointing out the Long/parseLong and @U050MP39D for the printer
How viable is compiling Clojure to native with GraalVM I've seen some httpkit examples but never seen a "complex" example. I'm thinking about about making a desktop app where I write ui stuff natively and share backend logic via Clojure, graalvm to achieve lower resource usage and performance.
@cakir-enes not too far back, the following was asked: https://clojurians.slack.com/archives/C03S1KBA2/p1572079261366000 if you think that's similar enough to your question, may be the following is some part of an answer: https://clojurians.slack.com/archives/C03S1KBA2/p1572083952373300
is it a bad idea to leave the percented names intact while transforming an anon-fn literal to a fn expr? e.g.:
$ lein run '#(inc %)' '{:fn true}'
(fn [%1] (inc %1))
what could go wrong?nothing, that's fine
we do something very similar in spec
clojure.test does not report ArityException (arising from within tests) as errors. It just prints the stacktrace. What can I do to report such exceptions as "errors" so that lein test
reports test failure in my CI/CD pipeline?
bfabry@18723-bfabry ~/C/c/mainstuff> lein test
lein test mainstuff.core-test
lein test :only mainstuff.core-test/a-test
ERROR in (a-test) (AFn.java:429)
FIXME, I fail.
expected: (filter true? [] [])
actual: clojure.lang.ArityException: Wrong number of args (3) passed to: core/filter
at clojure.lang.AFn.throwArity (AFn.java:429)
I suspect some code of yours or another library other than clojure.test is stealing the exception
Checking the contents of your $HOME/.lein/profiles.clj is a good idea. Feel free to paste it here if it isn't too long and you want advice on what might be causing issues.
clojure.test seems to do the right thing
leiningen monkey patches clojure.test reporting, not sure if that's a factor
if so, putting :monkeypatch-clojure-test false
in project.clj would test that hypothesis and fix it
@U050MP39D @U0CMVHBL2 @alexmiller @U0NCTKEV8 Thanks everyone for the hints. I'll check go through each of them to find where the problem is.
The problem was with one of the fixtures where the code was catching the exception. :face_palm:
Makes sense. Glad you were able to find the root cause.
There isn’t anything like a select-vals
function in core, is there? I didn’t see anything.
My naive, inefficient impl:
(defn- select-vals
"Given a map and a sequential of keys, returns a non-lazy sequential of the values of those keys
in the map, in the same order as the keys. If a key is not present in the map, the corresponding
entry in the result will be nil."
[m ks]
(reduce (fn [result k] (conj result (get m k)))
[]
ks))
((apply juxt ks) m)