Fork me on GitHub
#beginners
<
2015-11-25
>
seancorfield00:11:04

Hi @nando ! No, that whole approach — which is common in procedural code — just doesn’t fly in FP.

seancorfield00:11:45

About the closest you get is loop / recur where you have an "accumulator" variable that you rebind in the recur...

seancorfield00:11:27

(loop [n 5 acc 0] (if (zero? n) acc (recur (dec n) (+ acc (* n n)))))

seancorfield00:11:23

which produces 55

seancorfield00:11:46

but even there the more idiomatic approach is to use map / reduce: (reduce + (map (fn [n] (* n n)) (range 1 6)))

seancorfield00:11:55

or: (reduce + (map #(* % %) (range 1 6))) if you prefer the shorthand version of (fn …)

kauko08:11:59

@nando: one thing that helped “twist my brain” was to draw on paper. Draw the data you have and the result you want, and then start sketching the steps. Granted, this can be difficult in the beginning when you don’t know the tools you have at your disposal

kauko08:11:07

but still, it can help

kauko08:11:41

Heh, now I realised this conversation happened 8 hours ago 😐

nando10:11:41

@seancorfield: Thanks very much for the clarification. I’m going to try #30 again with reduce after rereading some material on it last night.

nando10:11:01

@kauko: That’s a good suggestion! I've used pen and paper when I have a difficult algorithm to work through procedurally, and I hadn’t yet thought to try that with Clojure.

adlermedrado11:11:09

Hello all. Does anyone here using Atom for Clojure development?

roelof11:11:31

im not, Im using Light table

adlermedrado11:11:36

Cool, I’m asking it because I’m using Atom for working with other languages and it would be great to use the same tool for all my needs…

roelof12:11:10

I have a question for myself. Why is this one false : (= {:line 13, :column 28, :end-line 13, :end-column 34, :division "West"} (meta '^{:division "West"} Giants))

roelof12:11:54

@adlermedrado: if I google it looks like you can use Atom for clojure

roelof12:11:58

but I cannot help you which module you can use the best

roelof12:11:45

@adlermedrado: but maybe I will keep track of Atom. Im not complete satisfied with Light table

nando12:11:51

@adlermedrado: I’ve found several packages for Atom for developing with Clojure

adlermedrado12:11:13

Thank you. I’ll try it.

nando12:11:00

I just found them yesterday and haven’t had a chance to try them out.

cjmurphy12:11:39

Yes Parinfer has been talked about quite a bit in the Slacks as well.

cjmurphy12:11:58

But you want a repl, so you would want that one for sure as well

roelof12:11:36

Can I also evalute forms on the fly like Lighttable ??

nando12:11:00

@roelof: From the docs for proto-repl, yes, but it seems to eval in a separate window

nando12:11:05

I have yet to try it.

roelof12:11:16

I use it now but get grazy about a error message when I type something

roelof12:11:42

I have asked the light table guys but no answer in some days

roelof12:11:15

so maybe Atom can be one of the alternatives

roelof12:11:22

@nando: Did you have time to try it

roelof12:11:05

I doubt now between cursive and atom

nando13:11:45

I haven’t had time to try the Clojure plugins on Atom - working at the moment in my day job

roelof13:11:45

oke, no problem

nando13:11:51

… but I just took a moment to open a clj file in Atom and started the REPL and executed a block.

nando13:11:46

Seems to work fine, although the REPL is in a separate window side by side with the code, rather than inline as is the case in Light Table

roelof13:11:18

that is no problem

roelof13:11:35

Im happy if I can see the outcome

roelof13:11:27

nando : IM trying to solve the koans found here : https://github.com/functional-koans/clojure-koans/blob/master/src/koans/23_meta.clj and with Cursive and Light table no success

roelof13:11:06

Nando : how can I send something to the repl of a external file. I have opened the koans file and want to evalute a function

meikemertsch14:11:33

@roelof: what's meta and what is Giants and why is it uppercase?

roelof14:11:30

meikemertsch: I have no clue. Its a koan from the clojure koans

roelof14:11:41

Chapter 23 the last one

roelof14:11:42

@meikemertsch: when Im done with that , I solved all koans simple_smile and I will start with 4clojure

nando14:11:48

I think “Giants” is an American sports team

nando14:11:17

But I don’t remember which sport ...

roelof14:11:19

Can be, if the maker of the koans is a American

samflores14:11:06

@roelof I think your local version of the koan is missing a '

roelof14:11:10

then there is also a error in the github repo

roelof14:11:22

where do you think a ' is missing

samflores14:11:14

(meta '^{:division "West"} Giants)

samflores14:11:35

just before the meta macro ^

samflores14:11:01

the only reason Clojure would complain about not being able to resolve Giants is if it's trying to evaluate it

roelof14:11:02

oke, if I look at the Original it looks like this : (= (meta '^{:division "West"} Giants))

roelof14:11:52

and mine looks like this : (= {:division "West"} (meta '^{:division "West"} Giants))

samflores14:11:52

right. I omitted the = part

roelof14:11:11

so the ' is there

samflores14:11:18

it looks fine to me :thinking_face:

roelof14:11:38

I have also asked on the cursive mailing list

samflores14:11:38

and evaluates just fine in my repl

samflores14:11:23

have you tried just pasting that exact line in a terminal repl (`lein repl`)?

roelof14:11:42

Does cursive has a terminal repl

roelof14:11:00

or schould i open a prompt and load the file

samflores14:11:33

I've never used cursive. I'm just suggesting you to start a new repl session and evaluate that single line to make sure nothing is messing with your env

roelof14:11:04

I can load the file with (load 23..... .clj) in repl ?

samflores14:11:23

you don't need to load the file

roelof14:11:22

oke, then I see true as answer

nando14:11:15

@roelof: To open a REPL in Atom, first install the packages I’ve listed before. Then from the Packages menu, go to proto-repl > Start REPL

nando14:11:17

cmd+alt+b is the shortcut to evaluate a form in Atom.

nando14:11:49

You can type it in directly in the REPL, or open a file and eval a form to the REPL

roelof14:11:20

aha, I see a error message on proto-repl

roelof14:11:21

;; You can disable this help text in the settings. ;; Loading REPL... Error starting repl: Error: spawn lein ENOENT You may need to configure the lein path in proto-repl settings REPL Closed

nando14:11:16

Well, you may need to do what it says ...

roelof14:11:26

where can I find and alter those settings then

nando14:11:46

Under proto-repl settings

roelof15:11:43

Found it and did add the directory : C:\Users\rwobb\.lein\bin but still no luck

wasser15:11:11

@roelof not sure if you've solved it, but your first post looks like you were using LightTable. It was adding extra metadata to the "Giants" entity (the :line, :column, etc. stuff). Running in a "bare" REPL, like 'lein repl' shows the answer as the koan expects. I like LT, but sometimes it's a bit too helpful.

roelof15:11:03

I did use Light table but LT seems to say the koan is wrong where it is right

samflores15:11:58

LightTable seems to add some metadata when it evaluates the forms

samflores15:11:32

that's why I asked you to try a plain REPL

samflores15:11:45

I don't know why Cursive is failing tho

roelof15:11:04

I know, when I only have this (= {:division "West"} (meta '^{:division "West"} Giants)) LT says wrong where a bare repl says im right

roelof15:11:18

or do we misunderstood each other. I like to see that LT is saying that the koan is right

wasser15:11:20

@roelof that's absolutely correct. The two repls give different answers because LT is adding more metadata on its own. It looks like it adds line numbering metadata probably for live-repl usage so it can show the results in the right places.

roelof15:11:50

I saw that already

wasser15:11:10

I'm not sure what Cursive is up to, either.

roelof15:11:32

Im also not.

roelof15:11:05

I saw when I change it to this : (= {:division "West"} (meta '^{:division "West"} 'Giants)) can work with it

roelof15:11:46

Im making a issue for LT on this matter

roelof15:11:48

thanks all

roelof15:11:54

I call it a day

roelof17:11:44

Im trying to solve a challenge from 4 clojure , Where I have to duplicate every item in a list

roelof17:11:45

So I did https://www.refheap.com/112064 but now I see ( ( 1 1) ( 2 2) ( 3 3) instead of ( 1 1 2 2 3 3)

roelof17:11:26

Is there a way I can make from ( () ()) to () again. I have looked at the cheat-sheet but it do not seem to be a function for it

nando17:11:25

I think the issue with using map is that it will always return the same number of elements in the seq

roelof17:11:49

oke, then I think I try reduce

roelof18:11:38

How can I make this work :

roelof18:11:13

I think I have again a parentheses problem

nando18:11:21

Is this #33 you are trying to solve?

nando18:11:00

If so, it seems to take 2 args, the sequence and the multiple

roelof18:11:29

no, #32 duplicate a sequence

roelof18:11:28

#nando #33 is the next I have to solve

roelof18:11:15

@nando: no, it want to solve #32 , # 33 is the next one I have to solve

roelof18:11:57

The problem is I think how I take the element that reduce has , make a argument for repeat

nando18:11:05

Here’s the reduce example from living clojure :

nando18:11:18

(reduce (fn [r x] (if (nil? x) r (conj r x))) [] [:mouse nil :duck nil nil :lory])

roelof18:11:12

thanks, I thought I need some sort of anymous function

seancorfield18:11:25

@roelof: take a look at mapcat and compare it to map — that should help you with duplicating the list items.

seancorfield18:11:38

Mornin’ @nando ! Great to see you here my friend!

roelof18:11:57

I see that my solution makes the reverse of the solution

nando18:11:37

Good morning Sean

roelof18:11:22

seancorfield: chips, now no output : https://www.refheap.com/112069

seancorfield18:11:42

You’re passing two lists to mapcat — one is empty so mapcat stops processing.

seancorfield18:11:13

Both map and mapcat can accept multiple lists and apply functions to elements of each of those lists.

seancorfield18:11:32

Your anonymous function is still designed for reduce, not map (or mapcat).

seancorfield18:11:12

In your original solution — that produced ((1 1) (2 2) (3 3)) you were very close, and that was where I was suggesting mapcat instead of map.

roelof18:11:07

@seancorfield: you mean the one where I use partial ?

seancorfield18:11:07

Oh, I didn’t even look at the code — I just assumed from your answer you had used map… I see now you didn’t (and your code was rather more complicated).

seancorfield18:11:27

Ah, wait, you do have map in there… what’s the merge for?

roelof18:11:14

a try to look if I could make one list of ir

roelof18:11:05

this one works : (mapcat (partial replicate 2 ) list)) simple_smile simple_smile

roelof18:11:28

but I wonder if there is a "better" solution

seancorfield18:11:49

OK, so let’s go back to first principles: given a list of items, you want to duplicate each one. So that sounds like a map problem and there are lots of ways to "duplicate" an item. I’d probably use vector: (map #(vector % %) my-list) or (map (fn [x] [x x]) my-list)

seancorfield18:11:21

As you found, that produces a sequence of pairs so you want those concatenated which is what mapcat does, compared to map.

seancorfield18:11:51

I hadn’t thought of using replicate — that’s a good approach too!

roelof18:11:58

oke, that is the first one that pops into my mind when I read duplicate

roelof18:11:02

Then the next one is also easy. I have to replicate a number of times. So I can make a variable of the number

roelof18:11:18

with vector that is not easy I think

roelof18:11:32

@seancorfield: so my solution is good

seancorfield18:11:37

One of the hardest things I found when learning Clojure was becoming familiar with enough of the functions in core to reach for the correct one when I’m "close" to a solution.

seancorfield18:11:30

I’d often reach a complicated solution, show it to more experienced Clojurians, and they’d say "Take a look at… (some new-to-me function)" and it was a revelation: always making my solutions simpler!

seancorfield19:11:21

Sounds like you’re having fun with 4clojure? simple_smile

roelof19:11:39

yeeeaahh lots of fun

roelof19:11:52

@seancorfield: I looked how other people have solved it

roelof19:11:22

reduce #(conj %1 %2 %2) [] %1 is the empty [] and %2 the item from the list ??

roelof19:11:42

and the most difficult to understand was this solution : #(interleave % %)

roelof19:11:02

@seancorfield: can you say if Im on the right track with the reduce function ?

seancorfield19:11:07

Sorry, had to step away to talk to an electrician...

seancorfield19:11:36

That works because conj takes a collection and any number of additional items to add to it — and conj on a vector adds the elements at the end (`conj` on a list adds them at the beginning)

seancorfield19:11:55

eight.core=> (conj [1 2] 3 4)
[1 2 3 4]
eight.core=> (conj '(1 2) 3 4)
(4 3 1 2)

seancorfield19:11:53

So the function reduce takes is called with the initial value [] and the first element of the list, then with the result of that call and the second element of the list and so on.

seancorfield19:11:31

So you get (conj [] 1 1) which produces [1 1] and then (conj [1 1] 2 2) produces [1 1 2 2]

seancorfield19:11:33

In a functional language, when working with pure functions (no side effects), you can think of "evaluation" as pure substitution rules which sometimes helps when writing out the solution’s evaluation by hand.

roelof19:11:25

oke, so Im right that %1 is on the first run [] and % 2 is 1

roelof19:11:47

the second run %1 will be [1 1] and %2 is 2

roelof19:11:53

am I right

seancorfield20:11:58

Yes, that’s correct. Sorry, I was away working simple_smile

roelof20:11:16

thanks and have a nice day/evening

seancorfield20:11:08

You too! Remember most Americans will be away from their computers for a few days: tomorrow is Thanksgiving and most Americans take Thursday and Friday off.

seancorfield20:11:27

I’m off tomorrow (it’s my wife’s birthday) but I’ll be around Friday (working).

roelof20:11:07

oke, thanks for telling me this , Im a European so for me no holidays