Fork me on GitHub
#beginners
<
2018-12-10
>
ccann04:12:33

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

ccann05:12:02

weirdly enough this seems to only be the case in the cider debugger

andy.fingerhut06:12:46

There is a #cider channel that you might want to check in, if this issue is truly specific to Cider

👍 4
CharlotteBRF07:12:54

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

👏 4
Daniel Truemper09:12:37

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?

phoenixjj09:12:22

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.

andy.fingerhut09:12:54

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.

flefik09:12:00

@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.

flefik09:12:48

(ns my-project.foo.bar) maps to the fs path my_project/foo/bar

Daniel Truemper09:12:34

@cfeckardt I have this case but initially it loads and runs. Only when (cider-refresh) is called, it cannot find the namespace

flefik09:12:07

what's the error you're seeing?

Daniel Truemper09:12:54

clojure.lang.Compiler$CompilerException: java.lang.Exception: No namespace: felicity-lemon.config, compiling:(felicity_lemon/joining_streams.clj:1:1)

flefik09:12:11

are you using lein or boot?

flefik09:12:44

maybe move into a private chat?

Lennart Buit10:12:04

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

Lennart Buit10:12:58

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

Lennart Buit10:12:49

Multispec definition: (s/multi-spec valid-payload? (fn [a _] (type a)))

Lennart Buit10:12:24

Example branch: (defmethod message/valid-payload? SomeType [_] ::some-spec)

Casey10:12:58

Is there a function like assoc-in but that lets up conj to a list in a nested data structure?

Casey10:12:45

something like (conj-in {:friends [:alice]} [:friends] :bob) ; => {:friends [:alice :bob]}

Roger12:12:37

You could do update-in (update-in {:friends [:alice]} [:friends] conj :bob) ; => {:friends [:alice :bob]}

❤️ 4
mseddon11:12:54

are there any test coverage tools for clojurescript (even better if they also support clojure out of the box)?

RodgerDodger15:12:24

So I have the code below, and I am trying to convert the output to a single sequence of strings.

RodgerDodger15:12:42

I believe the above produces a lazy-sequence of sequences of strings

RodgerDodger15:12:31

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")?

markmarkmark15:12:46

@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.

markmarkmark15:12:25

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)

RodgerDodger15:12:00

Thank you so much, sir!

markmarkmark15:12:26

no problem. for is a pretty amazingly powerful tool.

👍 4
markmarkmark15:12:42

You can look here: https://clojuredocs.org/clojure.core/for for examples of its usage

yuhan16:12:36

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}]

yuhan16:12:23

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..

Alex Miller (Clojure team)16:12:10

you could use s/multi-spec for this

Lennart Buit19:12:31

Do you perhaps have documentation to attach a generator to a multispec? I was (and still am) struggling with that

Lennart Buit19:12:46

(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 ^^)

Alex Miller (Clojure team)21:12:07

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

Lennart Buit21:12:12

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.

Lennart Buit21:12:54

Oh that retag, I will look into that!

Lennart Buit21:12:12

That was something I didn’t quite get just yet

Lennart Buit22:12:25

Anyhow, brain food for tomorrow, as it is 11PM in CET.

Alex Miller (Clojure team)22:12:27

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

Alex Miller (Clojure team)22:12:24

or actually, identity is single arg, so would need to be (fn [val tag] val)

Lennart Buit07:12:37

Right, thanks! I think I misimplemented the retag function then. Will try

Lennart Buit20:12:11

Managed to solve this, had a multimethod that was dispatching on record type, but generators that were generating mere maps

Lennart Buit20:12:48

So, when a generated val was checked again, the multi-spec would reject it

Lennart Buit20:12:45

(In this case the type is needed for Transit generation)

Alex Miller (Clojure team)20:12:57

ah, yeah. you should be able to fmap and apply the map->record constructor using s/with-gen on each defmethod I would think

Lennart Buit20:12:13

yes, I ended up with something like this:

Lennart Buit20:12:17

(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))))))

Lennart Buit20:12:14

Took me a while to figure out, but part of the adventure right. Thanks!

Alex Miller (Clojure team)16:12:32

and tie to a multimethod that switches on first

yuhan17:12:14

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))

yuhan17:12:05

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

Alex Miller (Clojure team)17:12:14

yes, although I’d use s/tuple, not s/cat

Alex Miller (Clojure team)17:12:11

(defmethod shape-mm :circle [_] (s/tuple #{:circle} ::circle)) etc

Alex Miller (Clojure team)17:12:32

the multimethod just gives you the spec to match on

yuhan17:12:29

oh alright, didn't know about the tuple spec! That should make it less verbose

Alex Miller (Clojure team)17:12:53

tuple is designed for fixed length heterogeneous indexed collections (which are ideal for variants like this)

yuhan17:12:01

thanks, that helped a bunch 🙂

yuhan17:12:59

is the retag argument on multi-spec relevant only for s/gen usage?

Saikyun19:12:34

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?

seancorfield19:12:44

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.

seancorfield19:12:55

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.

jaide19:12:16

@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.

seancorfield19:12:22

Ah, yeah, Specter ... that's probably what you're thinking of, since it is designed for navigating complex Clojure data structures!

Saikyun20:12:12

@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-ining twice 🙂

Saikyun20:12:18

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.

jaide20:12:59

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).

jaide20:12:34

Though you may be able to write a fn for retrieving the value of the deep path you want to test and memoize that function. That way the lookup is actually only performed once but of course there are some tradeoffs.