Fork me on GitHub
#beginners
<
2015-11-20
>
roelof07:11:43

why does this (println (set (map (partial matching-part "left_") ["right_", "left_", "center-", "right2-", "left2-"]))) give a null pointer exception ?

roelof07:11:44

meikemertsch: ping

rauh07:11:16

@roelof: What is matching-part?

meikemertsch07:11:38

Good morning :)

roelof07:11:50

@rauh: missing part is another function

roelof07:11:15

matching part I mean

roelof07:11:11

meikemertsch: I wonder why (println (set (map (partial matching-part "left_") ["right_", "left_", "center-", "right2-", "left2-"]))) give a null pointer exception

meikemertsch07:11:35

Be careful with "_" and "-"

roelof07:11:47

aha, I needed to replace part with something else

roelof07:11:28

I want to do some experiments to look if I can solve the exercise myself

meikemertsch07:11:32

Part is one of the elements in your hobbit list

meikemertsch07:11:53

These are maps with name and size.

meikemertsch07:11:24

You put just a string there, so on evaluation there is no key "name"

meikemertsch07:11:53

Partial matching-part part

roelof07:11:01

oke, so I can better make some experiments on the whole file

meikemertsch07:11:08

Not Partial matching-part "left-2"

meikemertsch07:11:24

Yeah, seems reasonable. Or you do

meikemertsch07:11:09

Partial matching-part {:name "left-eye" :size 1}

meikemertsch07:11:24

That could work

roelof07:11:48

oke, I have a idea how I can make it work with the range function

roelof07:11:04

I wanted to test it out

meikemertsch07:11:47

I'm currently shopping. Am home with proper keyboard in about 45 mins

roelof07:11:47

Then I do some shopping

roelof07:11:59

I think we see each other this afternoon

meikemertsch07:11:16

Feel free to ping me again please :)

meikemertsch07:11:40

I am not as fast in typing with my phone ;)

roelof07:11:57

np, I experiment with how to get something like this test1 test2

roelof07:11:10

when Im stuck i will ask you

roelof08:11:43

what is wrong here : (println (map (partial (str "test" )) [1 2] ) ) I see this error message Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn,

roelof08:11:03

I figured out that the [ 1 2] makes the error message

meikemertsch08:11:50

Let’s take it in a private room?

roelof08:11:16

oke , you are Lucky I was looking just before the shopping

meikemertsch08:11:28

I’m back home and at your service

jethroksy08:11:26

@roelof partial accepts a function, and so does map so you should be doing (map (partial str "test") [1 2])

jethroksy08:11:07

@roelof idiomatic clojure encourages you to be more explicit about your mappings though; the same can be achieved with this: (map (fn [n] str "test" n) [1 2]) Or better: (map #(str "test" %) [1 2])

meikemertsch08:11:32

Hi @jethroksy can you tell me more about it being more idiomatic than partial?

meikemertsch08:11:45

I’m still learning and would like to know more about that

jethroksy09:11:20

@meikemertsch when we use functions like map and reduce we tend to already know what we're trying to process. That is, we know the arity of element fed into the map and reduce. In this case it's of arity 1 (the numbers 1 and 2). Partial on the other hand doesn't do an arity check. By explicitly telling map with (fn [n] ...) That you're dealing with only an integer eliminates the possibility of a whole host of arity-related bugs. If this sounds terribly hard to understand, its because I suck at explaining :P but what I'm essentially trying to say is the more declarative you are about stuff that tend not to change, the better?

meikemertsch09:11:05

nice, thanks..

meikemertsch09:11:30

I have a follow up question then. In which cases would it be idiomatic to use partial then?

jethroksy09:11:52

I'd use it when trying to create higher-order functions from the lower level ones

jethroksy09:11:38

So suppose I wanna multiply things by a 100 a lot, I'd do: (def multiply-by-100 (partial * 100))

jethroksy09:11:17

Then I could call it on any integer (multiply-by-100 5) should return 500

meikemertsch09:11:54

Yeah, that one is clear. But why would you not use

(def multiply-by-100 #(* 100 %))

jethroksy09:11:53

Notice * takes multiple arities

jethroksy09:11:00

Your version would only allow 1

jethroksy09:11:21

So my version would allow (def multiply-by-100 5 2) and return 1000

meikemertsch09:11:23

I’m kinda searching for a heuristic when to use partial/named functions/anonymous functions

meikemertsch09:11:47

(def multiply-by-100 #(apply * 100 &%))

jethroksy09:11:56

But that's not really answering your question because the shorthand notation has a version that allows multiple arities

jethroksy09:11:17

I guess anonymous functions and partial functions can both be used to achieve equivalent outcomes, but readability is better often in one more than the other?

jethroksy09:11:03

Let's take for example the generation of a list of random numbers:

meikemertsch09:11:05

I kinda favour partial…. but I’d like to know idiomatic ways, too 😉

jethroksy09:11:37

(repeatedly 10 #(rand-int 10)) appears clearer to me than

jethroksy09:11:54

(repeatedly 10 (partial rand-int 10))

jethroksy09:11:58

Although both work

meikemertsch09:11:31

thanks, will look into it

jethroksy09:11:21

His conclusion is that it's a matter of personal preference, and I think it is, but functions give finer control

meikemertsch09:11:17

simple_smile Thanks for your patience

jethroksy09:11:26

I think I learnt something new here as well 😄

ian09:11:23

to hopefully add something of value for someone, partial is a function that literally just returns an anonymous function - it is a specific use of anonymous functions. I haven't looked at either of the blog posts linked, so I might be repeating this, but partial doesn't do anything an anonymous function can't, and I believe the same holds true in the opposite direction.

ian09:11:24

I'd say, of course, it's personal preference, but partial does have the advantage of an immediately clear use of an anonymous function in some situations (the common example being detailed above by @jethroksy of "I'm performing this same calculation a lot of times and want to abstract it out to a more meaningful value").