This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-10
Channels
- # 100-days-of-code (2)
- # adventofcode (188)
- # aleph (3)
- # announcements (2)
- # beginners (76)
- # boot (3)
- # braveandtrue (49)
- # cider (82)
- # clara (15)
- # clojure (101)
- # clojure-europe (4)
- # clojure-india (3)
- # clojure-italy (26)
- # clojure-kc (1)
- # clojure-nl (4)
- # clojure-norway (1)
- # clojure-russia (5)
- # clojure-uk (33)
- # clojurescript (32)
- # crypto (20)
- # cursive (34)
- # datomic (45)
- # emacs (3)
- # events (1)
- # figwheel (1)
- # figwheel-main (10)
- # fulcro (30)
- # graphql (14)
- # hoplon (12)
- # hyperfiddle (21)
- # jobs (11)
- # kaocha (7)
- # klipse (8)
- # leiningen (10)
- # luminus (3)
- # nrepl (18)
- # off-topic (232)
- # onyx (8)
- # pathom (6)
- # re-frame (30)
- # reagent (3)
- # reitit (6)
- # remote-jobs (3)
- # ring-swagger (4)
- # shadow-cljs (21)
- # spacemacs (5)
- # sql (18)
- # tools-deps (23)
- # yada (2)
I’m trying to call https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#remove-int-
the int primitive version of java’s remove
on arraylist and it always instead calls the Object
version, does anyone have any pointers? I tried type hinting. (.remove ^ArrayList xs (int i))
returns true/false
There is a #cider channel that you might want to check in, if this issue is truly specific to Cider
For anyone interested in learning Clara rules, here's my toy project engine shown at ClojureX https://github.com/charlottebrf/flat-chores-engine. Feel free to make a PR with any extra rules! I hope it's especially useful because I did it TDD, so there are examples of how you test Clara sessions - something I found hard to find easily when I started
I have a problem with CIDER and reloading namespaces. I can run the application once but as soon as I reload CIDER complains that it cannot find a certain namespace. I've been reading "Reloading Woes" (https://lambdaisland.com/blog/09-02-2018-reloading-woes) and trying to find out the problem but to no help. Does anyone have a hint at the source of the problem?
Hi All, I am working on putting some sample data processing work using Clojure and Incanter. Work in progress. When you guys find some time please have a look. Trying to port some hands on work done in Python using Clojure. Will be using datasets available in public domain. Feedback and suggestions are welcome. Please have a look here: https://github.com/phoenix2082/punter . Thanks.
Someone here may read your question later and know more than I do, but wanted to let you know there is also a #cider channel where people knowledgeable about Cider might be able to help.
@andy.fingerhut thanks! Will check there
@truemped that error can occur when your (ns forms do not match the path in your resource-paths. Normally the repl will warn on boot in this case.
@cfeckardt I have this case but initially it loads and runs. Only when (cider-refresh)
is called, it cannot find the namespace
clojure.lang.Compiler$CompilerException: java.lang.Exception: No namespace: felicity-lemon.config, compiling:(felicity_lemon/joining_streams.clj:1:1)
leiningen
Hmm, spec Q: I have a multi-spec
that is dispatching on type (it is validating records against their spec), but the automatically generated generator can’t seem to provide generated values
Can I in some way say that it has to use a generator for a spec that have been specified in one of the branches of the multi method
Multispec definition: (s/multi-spec valid-payload? (fn [a _] (type a)))
Example branch: (defmethod message/valid-payload? SomeType [_] ::some-spec)
Is there a function like assoc-in
but that lets up conj to a list in a nested data structure?
something like (conj-in {:friends [:alice]} [:friends] :bob) ; => {:friends [:alice :bob]}
You could do update-in
(update-in {:friends [:alice]} [:friends] conj :bob) ; => {:friends [:alice :bob]}
are there any test coverage tools for clojurescript (even better if they also support clojure out of the box)?
So I have the code below, and I am trying to convert the output to a single sequence of strings.
I believe the above produces a lazy-sequence of sequences of strings
Does anyone have any recommendations as to how to get (("22" "42" "12") ("24" "44" "14") ("21" "41" "11")) to ("22" "42" 12" "24" "44" "14" "21" "41" "11")?
@rodger.scott for can take multiple bindings in the []. You can move the h (mappings :1)
into the binding directly after the z (mappings :1)
and you should get the result you want.
for can also do lets in the binding itself. so you can do (for [z (mappings :1) h (mappings :1) :let [j (str z h)]] j)
@markmarkmark Wow! That was it!
Thank you so much, sir!
You can look here: https://clojuredocs.org/clojure.core/for for examples of its usage
Is there an idiomatic way to spec 'variant' types?
eg. a ::shape
spec that will match vectors of the form
[:circle {:radius 10.0}]
[:rectangle {:width 5.0 :height 2.0}]
but reject
[:rectangle {:radius 1.0}]
This is what I came up with:
(s/def ::radius number?)
(s/def ::width number?)
(s/def ::height number?)
(s/def ::circle (s/keys :req-un [::radius]))
(s/def ::rectangle (s/keys :req-un [::width ::height]))
(s/def ::shape
(s/or :circle (s/cat :shape-type #{:circle} :shape-specs ::circle)
:rectangle (s/cat :shape-type #{:rectangle} :shape-specs ::rectangle)))
but that last def seems quite clunky and redundant..you could use s/multi-spec for this
Do you perhaps have documentation to attach a generator to a multispec? I was (and still am) struggling with that
(Not trying to be rude! It was just the Q I asked before that was ignored, and since you seem to suggest multi-spec I was hoping you would have a nice resource, haha ^^)
sorry, been offline most of the day. multispec should have a generator by default (need a good retag for that per the docstring). You can use s/with-gen though to attach a generator to any spec
No worries, you are helping me after all!
Yeah I found that, but I didn’t figure yet how to apply that with a multi-spec
, because there are as many ways to generate a “valid” payload as there are branches of my multimethod.
Oh that retag, I will look into that!
That was something I didn’t quite get just yet
Anyhow, brain food for tomorrow, as it is 11PM in CET.
the way gen works on multispecs is to pick a multimethod value, run the generator for the produced spec, then put that through the retag function. depending how you write your multispec, a retag function of identity
may be sufficient
or actually, identity is single arg, so would need to be (fn [val tag] val)
Right, thanks! I think I misimplemented the retag function then. Will try
Managed to solve this, had a multimethod that was dispatching on record type, but generators that were generating mere maps
So, when a generated val was checked again, the multi-spec would reject it
(In this case the type is needed for Transit generation)
ah, yeah. you should be able to fmap and apply the map->record constructor using s/with-gen on each defmethod I would think
yes, I ended up with something like this:
(s/def ::some-payload
(let [spec (s/keys :req-un [[::some-key
::some-other-key]])]
(s/with-gen spec
(fn [] (gen/fmap (fn [v] (map->SomePayload v)) (s/gen spec))))))
Took me a while to figure out, but part of the adventure right. Thanks!
and tie to a multimethod that switches on first
Something like this?
(defmulti shape-mm first)
(defmethod shape-mm :circle [_] (s/cat :shape-type #{:circle} :shape-specs ::circle))
(defmethod shape-mm :rectangle [_] (s/cat :shape-type #{:rectangle} :shape-specs ::rectangle))
(s/def ::shape (s/multi-spec shape-mm identity))
Is there a way to only match on the second element of the vector after dispatching? Finding it hard to wrap my head around how the multimethod dispatch works
yes, although I’d use s/tuple, not s/cat
(defmethod shape-mm :circle [_] (s/tuple #{:circle} ::circle))
etc
the multimethod just gives you the spec to match on
tuple is designed for fixed length heterogeneous indexed collections (which are ideal for variants like this)
I've heard somewhere that you can use spec to extract parts of a map, e.g. I have map, in my spec I make sure that a certain key exists, then I can use that value instead of having to use get-in
to grab it again. is that so? and if so, are there any articles/examples about it?
Spec lets you "conform" an input value to a spec and the result may be different to the input, but I would say most specs produce the same shape as the input. If anything, conformance tends to add structure, not take it away.
If you have a spec for the keys in a map, when you conform a map to that spec, you're still going to get a map back, and you'll still have to use get
/`get-in` to pull data out of it, in my experience.
@saikyun In addition to what Sean mentioned you may be thinking of https://github.com/nathanmarz/specter which offers extended means to extract nested data.
Ah, yeah, Specter ... that's probably what you're thinking of, since it is designed for navigating complex Clojure data structures!
@seancorfield @jayzawrotny thanks for the information. 🙂 I'm working with a nested map (a "database"), and certain functions need the whole thing in order to have a generic signature. and sometimes I want to check for the existence of certain rows, and it feels unnecessary to go through the trouble of get-in
ing twice 🙂
specter does seem interesting, but it seems I'd still need to do things twice (once in the spec and once in the function). maybe spec isn't the answer in this case.
Perhaps. Spec is used to test if the input is the correct shape where as Specter is used to manipulate complex shapes. It likely isn’t the best idea to couple those two tasks together as you may want to loosen or tighten Spec in specific runtime contexts. However, Specter does claim to offer more performant offerings for get-in: > In addition, Specter has performance rivaling hand-optimized code (see this benchmark). Clojure’s only comparable built-in operations are get-in and update-in, and the Specter equivalents are 30% and 85% faster respectively (while being just as concise).