Fork me on GitHub
#beginners
<
2020-06-05
>
jason.li07:06:14

Does someone know how to refer a spec def from another namespace?

qythium08:06:38

You need to ensure the other namespace is loaded by requiring it, after that its specs can be accessed as usual using qualified keywords

joshkh10:06:10

what am i doing wrong where by the case doesn't match on the class in the second example?

(= clojure.lang.PersistentVector (type []))
=> true

(case (type [])
  clojure.lang.PersistentVector "vector"
  "unknown")
=> "unknown"

delaguardo10:06:24

in case test-constants are not evaluated and clojure.lang.PersistentVector is a symbol in case context

delaguardo10:06:11

it is better to use cond or condp when you want dispatch by type

(condp instance? [1 2 3]
  clojure.lang.PersistentVector "[]"
  clojure.lang.PersistentHashMap "{}") 
something like this

joshkh10:06:52

that's interesting, thank you very much for explaining

delaguardo11:06:17

also case is a macro so you always can use macroexpand to see it’s true form 🙂

noisesmith16:06:52

(case (symbol (str (type []))) ...)
should work as well

delaguardo17:06:58

Cool trick, didn't think about it)

timofey.sitnikov11:06:36

Good morning, I am looking at https://github.com/stuartsierra/component/blob/master/src/com/stuartsierra/component.cljc, and I cannot figure out this line: (map->SystemMap (apply array-map keyvals)) , how is it that the map->SystemMap is a function? I thought that -> was a threading operator. If I do this:

Clojure 1.10.0
user=> (type map->SystemMap)             ; does not exist in this ns
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: map->SystemMap in this context
user=> (defrecord SystemMap [a b])
user.SystemMap
user=> (type map->SystemMap)              ; now it exists, how?
user$eval138$map__GT_SystemMap__158
user=> (type map->)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: map-> in this context
user=> (macroexpand map->SystemMap)
#object[user$eval138$map__GT_SystemMap__158 0x4e25147a "[email protected]"]
Where can I read about the map->?

juan.ignacio84811:06:13

https://clojure.org/reference/datatypes > when a defrecord Bar is defined a corresponding function `map->Bar` is defined that takes a map and initializes a new record instance with its contents (versions 1.3 and later only)

ddouglass11:06:29

https://clojuredocs.org/clojure.core/defrecord > Given (defrecord TypeName ...), two factory functions will be defined: ->TypeName, taking positional parameters for the fields, and map->TypeName, taking a map of keywords to field values.

timofey.sitnikov11:06:46

OK, thank you @juan.ignacio848 and @ddouglass, it simply constructs an object of the type of defined defrecord , like so:

user=> (defrecord SystemMap [a b])
user.SystemMap
user=> (def mm (map->SystemMap {:a 10 :b 20}))
#'user/mm
user=> (println mm)
#user.SystemMap{:a 10, :b 20}
Would it be correct to say that map->SystemMap is a macro? Or is it an actual function. Becasue macroexapnd outputs: #object[user$eval137$map__GT_SystemMap__157 0x35d3ab60 "[email protected]"] So does that mean its a macro?

timofey.sitnikov11:06:46

OK, thank you @juan.ignacio848 and @ddouglass, it simply constructs an object of the type of defined defrecord , like so:

user=> (defrecord SystemMap [a b])
user.SystemMap
user=> (def mm (map->SystemMap {:a 10 :b 20}))
#'user/mm
user=> (println mm)
#user.SystemMap{:a 10, :b 20}
Would it be correct to say that map->SystemMap is a macro? Or is it an actual function. Becasue macroexapnd outputs: #object[user$eval137$map__GT_SystemMap__157 0x35d3ab60 "[email protected]"] So does that mean its a macro?

juan.ignacio84811:06:59

That I don't know 🙂 > I thought that `->` was a threading operator. Yes, -> that's one of the threading macros. But try this on your repl: (defn foo->bar [x] x) -  and `>` , among others, are characters that are valid in function names

timofey.sitnikov11:06:09

That is what I have been suspecting but was not sure. For that reason, I was making an assumption that it is simply a macro.

roguas12:06:35

is there a way to capture current let bindings and automatically cast them into a map?

somedude31417:06:24

I am currently getting {:lang "fr"} with the following destructuring: [{{:keys [params]} :request}] how can I destructure it further to only get fr?

smith.adriane17:06:35

this might work:

[{{{lang :lang} :params} :request}]
typically, I don’t use destructuring if the nesting is more than 1 level. I find the following more readable: (-> request :params :lang)

smith.adriane17:06:18

or even (get-in request [:params :lang])

somedude31417:06:39

Thank you so much, the first one worked

somedude31417:06:33

Just confused how come :keys is not needed 😐

smith.adriane17:06:11

[{{{:keys [lang]} :params} :request}] would also work

smith.adriane17:06:25

it’s just an alternative way to write it

somedude31417:06:21

Got it, thanks

smith.adriane17:06:22

I only use destructuring minimally , so https://clojure.org/guides/destructuring#_associative_destructuring might be a better resource

phil63418:06:12

and learned a bit about Luminus's innards in the process

kaxaw7583620:06:20

If I have :foo {:extra-deps <some-jar> :main-opts ["some command"]} in aliases, clojure -R:foo -M:foo should work correct?

alexmiller20:06:03

should, or just -A:foo

alexmiller20:06:17

oh, you have a jar file

alexmiller20:06:48

should then be :foo {:extra-deps {:local/root "path/to/file.jar"} :main-opts ["some" "command"]}

kaxaw7583620:06:09

thanks for confirming, now to check why isn't working

alexmiller20:06:07

what's the error and what's your command in main-opts?

kaxaw7583621:06:14

sorry yeah, bad command line args

somedude31421:06:39

Hey guys, what I missing here: I am using bidi router and I have this handler:

(defn index-handler [request] (res/response request))
And this middleware but x-bob is not appended to the output of the above:
(defn wrap-lang [handler]
  (fn [request]
    (let [response (handler request)]
      (assoc-in response [:headers "x-bob"] "Robert"))))
Any idea why?

noisesmith21:06:58

@somedude314 all I can think is you aren't using the handler that your middleware created

user>
(defn wrap-lang [handler]
  (fn [request]
    (let [response (handler request)]
      (assoc-in response [:headers "x-bob"] "Robert"))))
#'user/wrap-lang
(defn handler [request]
  {:code 200 :headers {} :body "OK"})
#'user/handler
(ins)user=> (def h (wrap-lang handler))
#'user/h
(ins)user=> (handler {})
{:code 200, :headers {}, :body "OK"}
(ins)user=> (h {})
{:code 200, :headers {"x-bob" "Robert"}, :body "OK"}

somedude31421:06:35

Sorry totally confused here. How can I not be using it when I have it listed like this:

(def app
  (-> handler
      wrap-strip-trailing-slash
      wrap-session
      wrap-flash
      wrap-lang))

(def reloadable-app
  (wrap-reload #'app))

(defn -main [& _args]
  (run-server (if dev? reloadable-app app) {:port 8080}))

somedude31421:06:52

wrap-strip-trailing-slash is working fine for me

noisesmith22:06:40

it could be that some other middleware is clobbering :headers - but that wouldn't be the case if you are using the ring versions of those handlers

noisesmith22:06:55

I can't explain your bug, but I can say your code works as it should :D

somedude31422:06:46

Thanks 🙂 I will see if I can figure it out

somedude31400:06:21

@ I had to change my middleware to:

(defn wrap-lang [handler]
  (fn [request]
    (handler (assoc-in request [:headers "x-bob"] "Robert"))))

noisesmith00:06:49

oh you meant to change the headers coming in, rather than the response? weird

somedude31400:06:52

Lol. Sorry. Sort of. I only modified :headers as a test, not thinking it mattered. What I am really trying to do is injecting the current language which sometimes come from the URL prefix and sometimes from the logged in user in the context variables to pass it to my templates.

robertaguilerajr23:06:05

Hello all, working my way through some clojure exercises and I'm a little confused on what I'm getting back. I'm given a string ACGTGGTCTTAA and I need to replace each letter with a specific value. After I split it, and replace the values I get the following vector below. I need to join it back together but I'm confused on a couple of things. 1. Why is the vector itself surrounded in "" 2. What are the \ characters behind and in front of each letter mean?

;; => "[\"U\" \"G\" \"C\" \"A\" \"C\" \"C\" \"A\" \"G\" \"A\" \"A\" \"U\" \"U\"]"
I'll place my code in a thread if that helps.

robertaguilerajr23:06:05

Hello all, working my way through some clojure exercises and I'm a little confused on what I'm getting back. I'm given a string ACGTGGTCTTAA and I need to replace each letter with a specific value. After I split it, and replace the values I get the following vector below. I need to join it back together but I'm confused on a couple of things. 1. Why is the vector itself surrounded in "" 2. What are the \ characters behind and in front of each letter mean?

;; => "[\"U\" \"G\" \"C\" \"A\" \"C\" \"C\" \"A\" \"G\" \"A\" \"A\" \"U\" \"U\"]"
I'll place my code in a thread if that helps.

robertaguilerajr23:06:36

(defn to-rna
  [dna]
  (let [dna-split (str/split dna #"")
        rna-split (str/replace dna-split #"C|G|A|T" {"C" "G" "G" "C" "A" "U" "T" "A"})]
    rna-split))

seancorfield23:06:23

@ That can't be your actual code -- your let has no body so it will return nil.

seancorfield23:06:15

I suspect you're just calling str on rna-split which produces a string that looks like it has a vector inside it.

robertaguilerajr23:06:42

@ sorry updated it.

hiredman23:06:05

you are calling str/replace on something that is not a string

seancorfield23:06:07

Ah, I see where it's going wrong... dna-split is a sequence of strings, not a string, so when you call str/replace on it, it's getting converted to a string

seancorfield23:06:05

I don't think you need that first step at all -- just call str/replace on the dna string you are passed in.

robertaguilerajr23:06:10

Ah, I didn't have to split it in the first place.

seancorfield23:06:14

user=> (defn to-rna
         [dna]
         (str/replace dna  #"C|G|A|T" {"C" "G" "G" "C" "A" "U" "T" "A"}))
#'user/to-rna
user=> (to-rna "ACGTGGTCTTAA")
"UGCACCAGAAUU"
user=> 

robertaguilerajr23:06:44

Sorry one more question, is that the best way to go about replacing those values? I find it a little hard to read.

robertaguilerajr23:06:05

At least the map at the end {"C" "G" ...}

seancorfield23:06:30

would you find it easier to read if you separated each pair with a comma?

seancorfield23:06:53

{"C" "G",  "G" "C",  "A" "U",  "T" "A"}

robertaguilerajr23:06:25

Yup that helps. Forgot that Clojure ignores commas. Thanks @

seancorfield23:06:58

I never think of using a map or function in the third arg of str/replace so that's quite elegant...

robertaguilerajr23:06:47

The commas definitely do help.