Fork me on GitHub
#beginners
<
2019-04-06
>
seancorfield01:04:47

@nathantech2005 Sounds more like a version mismatch. Recent versions use the new, standalone nrepl, not the contrib version. And that's possibly down the version of the plugin in Spacemacs...

seancorfield01:04:24

I haven't used Emacs for years but you could try asking in #spacemacs (or #emacs if you can't get an answer there).

seancorfield01:04:52

Yeah, if that's in your profiles.clj and you try to jack in with a different version of CIDER you will get the error you saw.

seancorfield01:04:41

I very much doubt Spacemacs changed your profiles.clj -- but as a general point, I recommend having as few things in that file as possible. It's the #1 cause of problems with Leiningen for beginners 😞

yuhan02:04:14

Do specs have to be re-evaluated every time one of their nested specs gets redefined?

yuhan02:04:11

eg.

(s/def ::foo (s/coll-of ::bar))
(s/def ::bar int?)

(s/conform ::foo [1.0]) ;; => :clojure.spec.alpha/invalid

yuhan02:04:51

After changing

(s/def ::bar float?)
(s/conform ::foo ...) will continue using the old definition of ::bar and report now-valid things as invalid

yuhan02:04:46

This tripped me up a few times before, and now I generally put all specs in a single do block during development to make sure they get refreshed, just confused why it behaves this way for certain specs and not others (eg. s/keys doesn't have this issue)

dangercoder14:04:56

Is this "Idiomatic" Clojure code for handling polymorpism? Both "mock" and "prod" implements the Api protocol but I will want to run the mock version depending on some config later on.

schmidt7315:04:30

@UBN9SNVB4 Yes this is definitely idiomatic. This style is more suited to component than mount though. Take a look here: https://github.com/stuartsierra/component it might be better suited to your use case. IMO, it is much easier to mock resources/functionality in component than in mount.

dangercoder15:04:10

ive read a little bit about component before, will have a look thanks! 🙂

mfikes15:04:00

I think the pattern of using a "regular" function that can then somehow decide to create a real or mock implementation is certainly common. I've no direct experience with Mount, so can't speak to that particular manner of implementing that pattern.

👍 4
bringe15:04:58

I'm still pretty new to spec, and this is the second time I've come across this problem, and I feel like there's a simple solution I'm just missing. In this example, in the ::input spec I need :metrics to be a collection of maps with :name and :value in them. But in the ::output spec I need the same key, :metrics, to be a collection of maps with the same keys but also :type as an additional key.

bringe15:04:09

But I can't call it ::metrics-with-type because then it's looking for the key :metrics-with-type. I need it to be called the same thing but represent something else in the ::output

bringe15:04:30

Not sure what options I have here.

mfikes15:04:45

@brandon.ringe That sounds like a use case that spec2 might be better at. (I'm guessing you would define a metrics schema and then for the input you would use a select that says you need just name and value, but for the output you would use a different select that says you need name, value and type.) See Rich's recent talk on it and some documentation on it here https://github.com/clojure/spec-alpha2/wiki/Schema-and-select

bringe15:04:37

@mfikes Interesting. Thanks a lot.

mfikes15:04:11

@brandon.ringe FWIW, spec2 may not yet be suitable for real stuff, and is probably mostly in a state where it can be tried out. (I think it is still being developed.)

bringe15:04:21

Yeah, I'm thinking for now I'll just figure some way around. Possibly renaming the input key, or not using the input spec and just using the output spec with the full set of keys on metrics.

bringe15:04:04

Or rather, removing ::metrics with the input as required, leaving on ::output as the full

mfikes15:04:38

Yeah, another workaround would be to make the type an optional key instead of required, and just "hope" that whoever generates output includes that key. If the key does happen to be included, it will be checked for conformance in appropriate places.

bringe15:04:17

Ah yeah. I was thinking about that.

seancorfield16:04:12

@brandon.ringe :input/metrics and :output/metrics would be two different specs for the same unqualified key :metrics in two different contexts.

bringe16:04:47

@seancorfield thanks! I'll try this out

Mno18:04:09

Has anyone used d3 with clojurescript that can help me solve this interop? I’m trying to use stratify as per this example:

var root = d3.stratify()
    .id(function(d) { return d.name; })
    .parentId(function(d) { return d.parent; })
    (table);

lilactown18:04:19

#((get-in (js->clj %1) [:parent :uuid])) doesn’t quite look right. I think you have too many parens

lilactown18:04:34

are you receiving an error of some sort?

Mno18:04:08

TypeError: module$node_modules$d3_hierarchy$dist$d3_hierarchy.stratify.id is not a function

Mno18:04:30

Maybe i should just define that function seperately and pass it in?

lilactown18:04:55

try wrapping stratify in parens first

lilactown18:04:03

-> (d3/stratify)

lilactown18:04:23

you are not calling it as a function

Mno18:04:25

it returns #object[stratify] which is a javascript object?

lilactown18:04:37

I’m not sure what you mean

lilactown18:04:53

in your Js code, you call stratify d3.stratify()

lilactown18:04:04

you need to do the same in your CLJS. (d3/stratify)

lilactown18:04:28

right now you’re accessing it like a variable in the d3 namespace. like d3.stratify.id(...) in JS

Mno18:04:45

ahhh that makes sense.

Mno18:04:08

I’ll see what i can do with this thing it returned.

Mno18:04:34

Thanks!

👍 4
Lennart Buit19:04:34

can you give an example?

Lennart Buit19:04:27

but you are basically abstracting(?) over function invocation here

Lennart Buit19:04:00

yeah but you gotta tell clojure somewhere which function you intended to call

Lennart Buit19:04:40

(don’t def inside of a defn, theres let for that)

Lennart Buit19:04:07

(and letfn for defining nested functions)

Lennart Buit19:04:38

ehm, well, the same binding refers to the same value if thats what you are asking

Lennart Buit19:04:16

(let [a (some-terrible-computation)]
  (println a a)
Evals (some-terrible-computation) once

Lennart Buit19:04:30

but okay, you have your nice function, what would you like to abstract of it and why

lilactown19:04:07

you can use binding. but I think explicitly taking a fn as an arg (or even just have two functions) is better

4
Lennart Buit19:04:15

well in this particular case, your golden-mean is a constant (or actually two)

Lennart Buit19:04:29

(was reading up on wiki :P)

lilactown19:04:26

in general though what you’re looking for is binding. but there are lots of caveats

lilactown19:04:47

it doesn’t work nicely with laziness

Lennart Buit19:04:58

well hard to understand

Lennart Buit19:04:13

because the place where you set the binding is not the place where you are using the value of that binding

Lennart Buit19:04:39

so, it takes one of those magical 7 value slots in our short term memory

lilactown19:04:53

readable code is easier to maintain 🙂

4
lilactown19:04:20

IMO binding use should never be part of a user-level API

lilactown19:04:45

it should be opaque to the user, part of a larger abstraction

Lennart Buit19:04:50

Thanks for filling in @U4YGF4NGM! I like to add that making something stupidly simple is often worth it

👍 4
Lennart Buit19:04:33

two defs, since its a constant 😉

Lennart Buit20:04:58

yeah the golden ratio

Lennart Buit20:04:05

natures magic constant

Lennart Buit20:04:38

try some of the project euler problems in Clojure!

Lennart Buit19:04:51

It sounds like a … thing that is not really desirable 😛

lilactown19:04:07
replied to a thread:can you give an example?

you can use binding. but I think explicitly taking a fn as an arg (or even just have two functions) is better

4
sotrhraven22:04:51

For someone with little resources. Is there a link or tutorial to help a beginner?

sotrhraven22:04:36

Something that has a guide kind of feel to the learning process.

jaihindhreddy22:04:02

@sotrhraven absolutely! Clojure for the Brave and True is an excellent resource. https://www.braveclojure.com/clojure-for-the-brave-and-true/

jaihindhreddy22:04:20

Free to read online.

sotrhraven22:04:33

@jaihindhreddy will check that one out

jaihindhreddy22:04:49

Also check out http://4clojure.com Has a bunch of problems that start from the very basic getting progressively harder and more elaborate, and is the most interactive way to learn Clojure IMO

sotrhraven23:04:11

adding it to the list