Fork me on GitHub
#beginners
<
2016-01-19
>
chadhs21:01:50

if using def to store a value in an if statement not idiomatic?

chadhs21:01:26

example

(if (> num1 num2)
  (def thing num1)
  (def thing num2))
(do stuff with thing)

chadhs21:01:38

is there a more clojure-y approach to that ^

mfikes22:01:55

@chadhs: I think it makes a lot of sense if you are conditionally setting up global stuff based on your environment. See, for example, this bit from cljs.core: https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L278-L281

chadhs22:01:25

interesting thanks. i’m conditionally setting a value to use in the rest of the body of a function and it seemed like a decent approach.

chadhs22:01:34

but i was also suspect

mfikes22:01:07

Hmm… maybe let

mfikes22:01:23

top level defs are extremely rare

martinklepsch22:01:50

> top level defs are extremely rare

chadhs22:01:55

i haven’t seem them yet in my studies which is why i was asking

ghadi22:01:09

you mean non-top-level defs

mfikes22:01:33

Sorry, right. simple_smile

martinklepsch22:01:46

I think a general rule of thumb is to only use def as a top-level form but sometimes (rarely) there are valid reasons not to do so

mfikes22:01:24

@chadhs: You probably just want to conditionally set a local and use it in the fn, right?

chadhs22:01:12

@mfikes: yes

martinklepsch22:01:17

(let [x (if (> num1 num2) num1 num2)]
  (do-stuff-with x))

chadhs22:01:53

^ that looks cleaner and like what mfikes was referring too

chadhs22:01:59

thnx @martinklepsch

martinklepsch22:01:07

This is more idiomatic. It introduces a local binding of the result of (if (> num1 num2) num1 num2) to x which is discarded after the (let ...) closes

martinklepsch22:01:26

in the case of using def the defined thing would later still be available outside of the current scope; it is added to the global namespace.

chadhs22:01:04

important distinction, good to know thanks

mfikes22:01:39

Here is another example where a non-top-level def is useful: It does a one-time check for a bug, and does an appropriate defn that works around the bug if it is detected https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L782-L793

chadhs22:01:42

@mfikes: so the takeaway is: if you need to conditionally set something to be accessible globally and have good reason to do so?

chadhs22:01:01

otherwise keep local things local using let

mfikes22:01:42

The intent there is to really do one def, but what gets def’d is conditional. You could put the if inside the def if you really wanted to, but with defn, perhaps the link above is cleaner

martinklepsch22:01:49

I think for beginning programming with Clojure the takeaway you gave is good :+1:

martinklepsch22:01:34

When you come across a situation where you think a non-top-level def would be appropriate you can always come back here and ask for people's thoughts. simple_smile

chadhs22:01:27

thanks so much guys, the clojure community has been awesome so far 😎 👍:skin-tone-3: 🚀

vanrysss22:01:51

Hi, is there a function for getting rid of the literal annotation in a map?

vanrysss22:01:19

I'm trying to get using the key and receiving a nil, even though I can see that the value I want is present

mfikes22:01:44

Post an example

vanrysss22:01:51

{:orgbid #uuid "0b914bf4-46a6-42ba-8255-3980209b3eaa"} if I do (:orgbid mymap) returns nil

mfikes22:01:49

Odd. Works for me.

cljs.user=> (:orgbid {:orgbid #uuid "0b914bf4-46a6-42ba-8255-3980209b3eaa"})
#uuid "0b914bf4-46a6-42ba-8255-3980209b3eaa”

mfikes22:01:12

Is mymap that map?

vanrysss22:01:30

sorry, I fixed it. Didn't realize that jdbc returns a vector.

vanrysss22:01:37

I thought it was just a straight map