Fork me on GitHub
#beginners
<
2016-12-13
>
roelofw07:12:03

Maybe a stupid beginners question. What is the clojure way to make a comment in a code which explains the challenges I have made. I like to store the solved 4clojure challenges in a file

roelofw07:12:36

I could do :

; comment  (defn ..... ) 
or
(defn ...  "comment"  ) 

seancorfield07:12:57

(defn func-name
  "This is the docstring"
  [the arguments]
  (the function body))
Like that?

roelofw07:12:27

that is one of the options , @seancorfield

roelofw07:12:45

So that one is more the clojure way ?

seancorfield07:12:53

Since the docstring can span multiple lines you can write an essay there 🙂

seancorfield07:12:11

There are several ways to provide actual comments in code tho'

;; this is a full line comment
(some code) ; this is an end of line comment
(comment 'and (this is any) :code you "want" as a comment)

seancorfield07:12:47

(I think that last one will work -- I mostly use it to provide code examples in a comment so the contents are always valid Clojure code in my files)

roelofw07:12:09

oke, I use now this :

(defn notthing-but-the-truth
  "This is a clojure form. Enter a value which will make the form evaluate to true.
  Don't over think it! If you are confused, see the getting started page. Hint: true is equal to true."
  (= true true)
  )  

seancorfield07:12:26

You're missing the argument vector.

roelofw07:12:01

I only have to think about when there are more "tests" with the same solution

roelofw07:12:13

maybe use them as real tests

roelofw07:12:00

@seancorfield is this good clojure :

defn list-conj-1
  "When operating on a list, the conj function will return a new list with one or more items \"added\" to the front."
  []
  (do (= '(1 2 3 4) (conj '(2 3 4) 1))
      (= '(1 2 3 4) (conj '(3 4) 2 1))
      )) 

agile_geek08:12:11

The issue with ☝️ is that the first check on equality of the list with the result of conj is discarded by the second.

agile_geek08:12:49

In other words, you don't know the result of the first test of equality and you only return the result of the last one

agile_geek08:12:35

If you want both to be true is there a logical operator you can use that checks both things are true?

roelofw13:12:41

@agile_geek so I can better use and because both have to be true

roelofw13:12:50

Changed it

roelofw13:12:18

now I also store my solutions to 4clojure on github 🙂

pradeepcheers14:12:27

This is a sample from Clojure for the brave and true book,

pradeepcheers14:12:36

(defn my-reduce
  ([f initial coll]
   (loop [result initial remaining coll]
     (if(empty? remaining)
      result
      (recur (f result (first remaining)) (rest remaining)))))
  ([f [head & tail]]
    (my-reduce f head tail)))

pradeepcheers14:12:05

can someone explain the behaviour of recur here please?

pradeepcheers14:12:11

(recur (f result (first remaining)) (rest remaining)))))

pradeepcheers14:12:24

is it calling the loop or function?

pradeepcheers14:12:30

Also what is the point of using

f
here?
f
is just being passed around.

donaldball14:12:24

recur essentially invokes the next highest target with the given arguments. In this case, it will be the loop form, with (f result (first remaining)) in the result binding and (rest remaining) in the remaining binding.

donaldball14:12:01

f is called with result (first remaining) in this evaluation

pradeepcheers14:12:21

Thanks @donaldball

donaldball14:12:38

Pretty sure valid recur targets are just loop and fns fwiw

gregnwosu15:12:36

can i overload a function based on different keys in a map?

gregnwosu15:12:47

e.g. 
(defn myfun 
   [param1 {:keys [key1 key2 key3]}] 
     (....body 1) 
   [param1 {:keys [key1 key2]}] 
     (…body2) 

dominicm15:12:08

I don't think so

gregnwosu15:12:42

ah thanks .....

dpsutton15:12:30

you could use core.match inside of it though

kyle_schmidt15:12:52

(some nil? [key1 key2 key3])
To check if keys exist

dominicm15:12:19

(defn myfun
  [param1 {:keys [key1 key2 key3] :as param2}]
  (if (contains? param2 :key2)
    (body1)
    (body2)))

dominicm15:12:46

@kyle_schmidt Problem with checking for nil? is that there's a difference between: {:a 10 :is-foo? nil} and {:a 10}

kyle_schmidt15:12:57

@dominicm Is there a problem doing this:

(let [{:keys [a is-foo?]} {:a 10 :is-foo? nil}]
        (some nil? [a is-foo?]))

dominicm15:12:02

Only if the absense of is-foo? might have a different meaning to nil.

gregnwosu15:12:54

yes ive come across core match seems like the way to go

kyle_schmidt15:12:02

Because this gives the same result:

(let [{:keys [a is-foo?]} {:a 10}]
        (some nil? [a is-foo?]))

dominicm15:12:30

@kyle_schmidt Yep, sometimes the fact that those input maps are different is important.

dominicm15:12:40

Lack of a key != key-value is nil

dominicm15:12:08

@kyle_schmidt Also, I think you want every? not some there.

kyle_schmidt15:12:28

@dominicm do you usually check the values that you parse from a map? Is it idiomatic to do so or do you operate assuming the keys are there? Or does it depend?

rauh16:12:24

@gregnwosu I probably wouldn't throw core.match at this problem. Options: 1. defmulti with (comp set keys) as dispatcher function. 2. Destruct and use a sentinel at :or: {:keys [a] :or {a ::sentinel}}

gregnwosu16:12:20

@rauh thanks, can you provide me with a brief snippet so I can grok it

rauh16:12:14

(fn [{:keys [a] :or {a ::sentinel}}]
   (if (= a ::sentinal)
     (a-was-not-provided)
     (a-was-provided)))

dominicm16:12:29

@rauh isn't contains? just the same as using sentinel?

rauh16:12:22

Yeah, it's a matter of taste.

dominicm16:12:30

@kyle_schmidt Most of the time, if I can possibly be given nil, I handle it using when for example. But mostly, it depends as you say.

dominicm16:12:48

@rauh I would, personally, consider contains? more idiomatic. Why do you prefer sentinel?

rauh16:12:03

Well I'd probably use some name that indicates what this options does, so kind of more self-documenting code

dominicm16:12:28

@rauh Not sure I understand. Could you expand on that?

gregnwosu16:12:30

i prefer match , its seems clearer i hate having if statements in code

roelofw16:12:10

How can I rewrite this solution to a 4clojure challenge better :

(defn double-down
  "Write a function which doubles a number"
  []
  (and (= ((fn [x] ( * x 2)) 2) 4)
       (= ((fn [x] ( * x 2)) 3) 6)
       (= ((fn [x] ( * x 2)) 11) 22)
       (= ((fn [x] ( * x 2)) 7) 14)))  

roelofw16:12:23

it looks very clumpsy to me

dominicm16:12:58

Which challenge? Looks kinda odd to me?

roelofw16:12:58

I try to store my solutions so I can look it back

roelofw16:12:11

but this does not seem to be a good solution

roelofw16:12:57

or can I better make the function and use that one for all the fn cases seperate

roelofw16:12:49

so something like this :

(defn dounble-down 
  [x] 
  (* 2 x ))


(fn[x] (double-down x ) 4)    

roelofw16:12:37

I mean (fn[x] (double-down 2) 4)

dominicm16:12:56

Just to be clear, your solution is (fn [x] ( * x 2)) right?

roelofw16:12:37

and that have to be "inserted" into the 4 cases so there all be true

dominicm16:12:49

Alternatives I can think of: #(* % 2) and (partial * 2)

dominicm16:12:57

But I think your answer is very good.

roelofw16:12:26

maybe a idea to make the functions and let the cases be test-cases to the function

dominicm16:12:43

Or do you mean for testing the cases during development?

roelofw16:12:10

this challenges I have solved but there are a lot more

dpsutton16:12:32

just bind it in a let

dominicm16:12:03

Oh, is this about the whole function instead of just the solution to 4clojure?

roelofw16:12:12

@dpsutton : how to do mean that. I cannot see the whole picture

roelofw16:12:42

@dominicm ultimate , its storing my solutions to 4clojure challenges

dominicm16:12:34

(let [foo (fn [x] (* x 2))]
    (and (= (foo 2) 4)
            (= (foo 3) 6)))

roelofw16:12:40

@dpsutton that is a nice solution. I have to type in the solution one time

wilcov16:12:54

@roelofw you probably want to store it some other place than 4clojure itself but if you are you logged into 4clojure you can click the solutions button and the answer you've provided is displayed as the first result

val_waeselynck21:12:59

@dhruv1 are you using a particular React wrapper? (Reagent, Om, Rum, ...)

dhruv121:12:19

i will move onto using warppers once I understand how to get started without the wrappers

val_waeselynck21:12:55

@dhruv1 well, you can use JS interop directly

dhruv121:12:26

so i would have to do something like js/React.createClass app-bar ...

val_waeselynck21:12:50

i.e (js/React.createClass #js {:render (fn [] (this-as this ...))})

dhruv122:12:14

thank you!

val_waeselynck22:12:40

My advice: use interop as long as necessary to get it, then have a look at sablono: https://github.com/r0man/sablono