Fork me on GitHub
#beginners
<
2017-11-12
>
seancorfield00:11:35

Even for a single operation, depending on what you are doing, the transducer version can be faster.

boldaslove15600:11:41

Thanks, I take it transducer is always a better solution than threading macro. So does all of the benefits still applied to clojurescript?

boldaslove15600:11:26

And is there any github repo I can study where it abuses transducer?

Drew Verlee00:11:03

When is it appropriate to create a closure over a function? e.g

(defn foo
  [x]
  (let [bar (fn [y] y)]
   (bar x)))
The trade off seems obvious, the closure is only usable inside the function. Which is not the default i would assume most ppl would lean towards. What are some good reasons to do that though?

seancorfield01:11:08

@drewverlee The question I would ask myself is: could this new function be useful to code outside this (enclosing) function? If you think it could be (and, often, it could) then make it a defn instead.

seancorfield01:11:54

OTOH, if it closes over a number of local bindings or arguments, and you need its arity to match some particular usage within the (enclosing) function, then a closure is probably the right thing.

seancorfield01:11:06

For example, in clojure.java.jdbc, there are a number of "helper" closures defined locally, because they close over local bindings and arguments and don't make sense outside that context. But there are other small "helper" functions defined at the top-level because they only depend on their arguments and they might be reusable elsewhere.

dpsutton01:11:23

one other consideration is that you may want the function defined outside of the defn form ie, (let [f (fn [x] x)] (defn thing [y] (f y))

Drew Verlee02:11:38

@dpsutton i see how thats useful. @seancorfield That makes sense, i appreciate the jdbc example. I’m glad the advice matches my intuition. I really appreciate the feedback

athomasoriginal16:11:44

I have a function like this:

(def v [1 2 3 4 5])

(defn compare-values [v]
    (for [x v 
            y v ]
      (compare-stuff x y))
The function compare-stuff is going to perform some logic and return a vector if said logic is met. Otherwise, I return nothing. I am currently going through the process of writing tests and noticed that when I pass the above (compare-values [ 1 2 3]) I will get (nil nil nil). I see that this is because compare-stuff is going to return nil if I do not explicitly return a value, but is there a way to have (compare-values [1 2 3]) return () instead of (nil nil nil)?

adi16:11:10

if compare-stuff returns nothing when the logic is not met, then (nil nil nil) seems to be the right result... fits the shape of the input collection

athomasoriginal16:11:15

Correct. Is there a way to control the output so I can get something more in-line to what I would like to see returned which would be ()?

adi16:11:25

if you wish to discard nil values from the result of for, then maybe filter out nils?

adi16:11:42

(remove nil? 
   (for [x v 
         y v] ...))

eggsyntax16:11:56

Looks like you've got a stray paren there:

(for [x v )
            y v ]

athomasoriginal16:11:22

Sorry, messed up the cleanup there. Fixed

eggsyntax16:11:40

Depends on why you want it to be () in particular. Do you just want to filter out nil results?

eggsyntax16:11:26

What if it came back, say, (nil 2 nil) -- what would be the output you wanted?

athomasoriginal16:11:51

I would want it to be (2) - so yes, I want to filter our the nils - but leave other values

eggsyntax16:11:45

There are a few ways to do that; one is (filter identity <result>)

eggsyntax16:11:02

Oh, just saw that @adityaathalye is replying in parallel 😆

eggsyntax16:11:28

Another is just (keep identity <result>)

athomasoriginal16:11:04

Thanks @adityaathalye and @eggsyntax - big help. Thinking in functional paradigm colours is kicking my ass.

eggsyntax16:11:19

It takes some getting used to, for sure 🙂

eggsyntax16:11:28

Comes naturally after a while, I promise.

dpsutton16:11:03

check out keep

derpocious19:11:23

Hey guys, I'm having trouble returning something from loop /recur

derpocious19:11:34

(defn integersLessThan 
  "Returns a vector of integers less than
  the number passed in."
  [n]
(loop [x 0
       acc []]
  (if (= x 0)
    (println "starting with: " x acc))

  (when (> x n)
    (println "Done looping! " x acc)
    acc)

  (when (<= x n)
    (let [newNum (+ x 1)]
    (println "looping!" x)
    (println acc)  
    (recur newNum (conj acc newNum))))))

(integersLessThan 8)

derpocious19:11:10

I would think that line 12 should return the "acc" vector, but for some reason my function always returns nil. I'm really confused by why this is. Is the loop /recur one of those things that is meant only for side effects and is not supposed to ever return something?

dpsutton19:11:17

@derpocious what is the last form in your loop?

madstap19:11:47

When x is more than n, (when (> x n) acc) returns acc, and then (when (<= x n) ,,,) runs and returns nil. loop returns the value of the last form.

madstap19:11:00

To fix it put them both inside different branches inside one if