Fork me on GitHub
#beginners
<
2016-09-15
>
practicalli-johnny12:09:11

Thanks @tap for suggesting apply function, that works well. I'd tried map and partial, but not apply. Seems more obvious now.

singen12:09:50

I’m having terrible trouble using and a partial function. Is it so that I cannot pass a function from bar in require bar :as foo as argument?

val_waeselynck12:09:44

@singen no sure what you're asking

val_waeselynck12:09:54

can you show us some code ?

singen12:09:02

Yeah, it’s pretty hard to figure out from that

singen12:09:35

What happened was that I defined the same function twice

singen12:09:08

And I was trying to pass foo/function as argument

singen12:09:59

Which resulted in a arityexception that made it look like my function argument was wrong

gowder18:09:11

Would someone mind taking a second to tell me what stupid obvious mistake I'm making here? Trying, just for my own edification, to implement my own (non-lazy) version of filter into a vector, but for some reason it only returns the result of the filter function applied to the last element of the collection. It also seems to not be taking seriously my request to stick it into a vector... I have to be making some silly semantic mistake, but for the life of me I can't see what it is.

(defn flt [func coll] 
  (let [reducer
   (fn [v elem] (if (func elem) (conj v elem)))] 
  (reduce reducer [] coll)))

(flt even? [1 2 3 4])
; => (4)
(flt even? [1 2 3 4 5 6])
; => (6)
(flt even? [1 2 3 4 5 6 7])
; => nil

akiva18:09:59

First, Clojure on its own will switch collection types around which it feels is best for performance.

akiva18:09:07

I ran into this headfirst when I began.

akiva18:09:50

Also, reduce needs to be passed back to it the accumulator else it’s going to just keep taking [] as what it’s conjing to.

akiva18:09:10

If you absolutely must have a vector as the result, you need to tell it so once the reduce is done. Usually into works well here.

gowder18:09:58

Hmm thanks @akiva --- I must confess I'm super confused by this. Something simple like (reduce conj [] '(1 2 3)) works as expected, without into or passing reduce back into anything...

akiva18:09:31

It’s probably a closure issue, no pun intended. I’m guessing that when it’s calling the anonymous function outside of the reduce, it’s resetting itself to factory defaults, so to speak.

akiva18:09:57

In other words, each call to reducer is producing a brand new version of the function.

gowder19:09:18

Hmm. Interesting. Will have to experiment with defining reducer outside the let block or something. Thanks!

akiva19:09:59

You bet. This might be one of those issues where letfn is more apropros than let.

akiva19:09:50

I almost always define functions external to the calling function. I’ve never in my life put a fn in a let.

curlyfry19:09:38

@gowder @akiva: I think the problem is just that the anonymous fn is missing an else form

akiva19:09:54

Ooo, yes.

akiva19:09:00

I didn’t even think about that!

curlyfry19:09:10

The rest works fine 🙂

gowder19:09:36

ooh. bugger. I always, always forget that conditionals return nil if no else form is supplied, as opposed to just not returning at all.

akiva19:09:52

Yep, yep. If it had been a snake...

gowder19:09:55

this is what happens to your brain when you learn programming in imperative languages with an explicit return

gowder19:09:16

thank you @curlyfry ! it's always the simple stuff

curlyfry19:09:23

No problem! Just try to remember that you always have to return the "result so far" in the reducing function, even if that particular step didn't really change anything

akiva19:09:35

This is where I wish Clojure was a bit more F#-like in that F# won’t even compile a conditional without an else. I think Haskell is the same.

akiva19:09:04

Clojure’s forgiving.

akiva19:09:17

It’s also a good time to bring up eastwood and kibit.

curlyfry19:09:18

Also (while I know this was mostly an exercise) there is filterv

curlyfry19:09:35

if you ever want to filter into a vector again

akiva19:09:57

And mapv if you just want to map into a vector.

akiva19:09:33

Although I’m almost certain that @alexmiller typed that it’s more efficient to use into since it’s internally a transducer. But if performance isn’t an issue...

gowder19:09:33

:unicorn_face: