Fork me on GitHub
#beginners
<
2015-12-02
>
kauko04:12:19

Is there are difference between core.async's <! and take! ? Other than the former returns a value and must be used in a go-block, and the latter gives the value to a function

kauko04:12:54

Any reason or situation I should favor one over the other?

cjmurphy05:12:58

And I guess the answer could be the same as for the same question but about >! and put!

danielcompton07:12:38

@kauko: <! returns ‘synchronously’ inside a go block, take! returns asynchronously from outside of a go block.

kauko07:12:53

take! kind of feels more intuitive to me, but that’s probably because I’m still so used to javascript’s callback way of handling async. I feel like <! is more idiomatic, and should be preferred

kauko07:12:11

am I correct in thinking this? Using too much take!results in callback hell?

danielcompton07:12:38

Kinda, they’re just for different purposes

danielcompton07:12:49

but usually it would be more idiomatic to use <!

rantingbob09:12:15

So...I'm really really really beginning in Clojure, and I've got an idiomatic question. I have a process that munges some data from a file. I have two steps in that process that both have some similar code in them. One function does (into {} (map vector key-vec val-vec)). Another step later on does a similair thing, in fact, it destructures the map back into a vector, does some maths on the value, then repours it back into a map. With some fiddling about I could do both in the same step, but it would be less clear and make the code less reusable. Part of me wants to do it, but I don't know if I should. Thoughts?

rantingbob09:12:42

Super beginner I know

danielcompton09:12:25

@rantingbob: you probably want to make it as clear as possible, then if there are performance issues optimise it later

rantingbob09:12:00

That's what I figured...premature optimization and all that, I just wanted someone to say "yep you're not going mad" thank you

roelof11:12:08

Why do I get this error message : CompilerException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn on my code : https://www.refheap.com/112259

roelof11:12:41

solved it this way but run into another problem : I have now this (reduce (fn[acc it] (conj acc (drop-last it))) [] (partition number number list) ) but when I do [ 0 1 2 3 4 5 6 7 8] 7 and 8 are cut off.

roelof11:12:01

Is here a way I can take care that 7 and 8 are added

snowell12:12:13

@roelof Use partition-all instead of partition

snowell12:12:23

That will keep the incomplete groups

snowell12:12:43

Of course you won’t want to drop-last from THAT group, so you’ll have to code around that 😉

roelof12:12:35

correct , that is the next problem.

roelof12:12:29

Last problem to convert it back to a vector I now see [ ( 1 2) ( 4 5) ] instead of [ 1 2 3 4 5]

snowell12:12:13

Well partition-all returns a lazy-seq

roelof12:12:42

thanks, then this problem iof 4 clojure is solved I think

snowell12:12:05

I have to admit, when you posted it yesterday afternoon I dropped what I was working on and solved it 😉

roelof12:12:33

@snowell: are we talking about the same exercise

roelof12:12:38

I thought I solved it by ' (apply concat (reduce (fn[acc it] (if (= (count it) 3) (conj acc (drop-last it)) (conj acc it))) [] (partition-all number number list))) '

roelof12:12:10

but it seems to fail on case 2 [:a 😛 :c :d :e :f] 2)

roelof12:12:02

I see my problem

snowell12:12:10

Haha I just saw it too

roelof12:12:58

but I wonder if it can be improved

roelof12:12:08

it s a long code now

roelof12:12:57

@snowell: programmer as a proffesion ?

roelof12:12:25

Clojure or other languages ?

roelof12:12:42

and do not call me sir, then I feel more old then I am

snowell12:12:59

As much clojure as I can sneak in, but also some inferior languages

snowell12:12:58

Oh, I’ve done Java, Groovy, C#, Javascript, Perl, PL-SQL

roelof12:12:20

oke, me much ruby and rails , node, erlang butnever feeled like home

snowell12:12:58

No ruby/rails for me, just groovy/grails simple_smile

roelof12:12:15

I did not like Rails. too much magic for me

roelof12:12:17

@snowell: next problem also a nice challenge. split a seq but IM now allowed to use split-at

roelof12:12:47

First a little bit thinking how to solve this

roelof12:12:09

give me no hints. I like to solve this myself

snowell12:12:25

(By that I mean I will give you no hints)

roelof12:12:59

I have a idea but first some shopping to do

roelof12:12:14

for me programming is a hobby

andrut13:12:31

haha, and you do shopping professionally? simple_smile

roelof13:12:04

my proffesion is take care of my daugther

andrut13:12:17

this is a serious one!

roelof13:12:29

money paid bad.

roelof13:12:39

yep, a very serious one

roelof13:12:54

but I like it very much

andrut13:12:04

rewarding simple_smile

roelof13:12:44

and that is more important then money

roelof13:12:15

money cannot buy that

roelof13:12:55

@andrut : any idea how to improve my code I posted

andrut13:12:05

can you paste it again? is it https://www.refheap.com/112259?

andrut13:12:27

long thread to read and not sure where are you now simple_smile

roelof13:12:35

oke, I repaste it

roelof13:12:23

@andrut : here you have : (apply concat (reduce (fn[acc it] (if (= (count it) number) (conj acc (drop-last it)) (conj acc it))) [] (partition-all number list)))

andrut13:12:04

ok, I’ll look at it

andrut13:12:10

the way I just came up with is a bit easier

andrut13:12:43

I’m sure it can be improved though simple_smile do you want me to post it right away?

roelof13:12:20

I already solved it

andrut13:12:03

(fn [list number)
  (mapcat #(take (dec number) %) (partition-all number list)))

roelof13:12:43

and where do the % for . IM still not used to it

roelof13:12:54

I rather use variables names

andrut13:12:24

(fn [list number)
  (mapcat (fn [partial-list] (take (dec number) partial-list)) (partition-all number list)))

roelof13:12:48

now I see what (take(dec number) does

roelof13:12:26

and there no problem with the fact that the last part have only 2 numbers instead of 3

roelof13:12:37

where I needed to use the if part

andrut13:12:51

for (f [1 2 3 4 5 6 7 8] 3): [[1 2 3] [4 5 6] [7 8]] then take 3-1=2 from each partial list [[1 2] [4 5] [7 8]] and mapcat just concats them

andrut13:12:23

I hope it’s a good enough solution 😉

roelof13:12:32

I like the idea of using take with dec

roelof13:12:45

I will try that part out

roelof13:12:01

mapcat = apply concat ??

andrut13:12:05

yes, mapcat = (apply concat (map…)

roelof13:12:59

thanks for the tips

roelof13:12:57

escpecially for the take dec part

andrut13:12:27

just thought of some recursive version for fun

andrut13:12:29

(defn f [initial-list number]
  (loop [list initial-list
         result []]
    (if (seq (rest list))
      (recur (drop number list) (concat result (take (dec number) list)))
      result)))

roelof14:12:41

@andrut if you look carefully it looks almost the same

andrut14:12:02

sure it does simple_smile just a recursive version of it

roelof14:12:40

next problem : I have this : (mapcat (fn[acc] (conj acc (take number list) (drop number list))) ) now the answer is a empty () but then I add a [] to the end. I also not see the answer

andrut14:12:07

sorry, what’s the task here?

roelof14:12:43

I think I have problems with finding out what the initial value of mapcat must be

andrut14:12:10

you almost have it

andrut14:12:36

to be honest, I didn’t use either mapcat or conj, just a list/vector simple_smile

roelof14:12:41

most of the time I almost have it

andrut14:12:45

take and drop parts are fine

andrut14:12:36

the objective is to divide it to two parts, so it’s a fixed number of parts

andrut14:12:50

you can use that and there’s no need to use mapcat here

roelof14:12:54

oke, if I do (take number list) (drop number list) I see only see the second part

roelof14:12:09

that why I thought I need anymous function

andrut14:12:06

because if you do (take number list) (drop number list), then only the second is returned

andrut14:12:10

unless you wrap it somehow

roelof14:12:03

and if I do `[(take number list) (drop number list)]' then I see [ (1 2 3) (4 5 6)]

andrut14:12:20

why is it wrong?

roelof14:12:13

because I need this [[1 2 3] [4 5 6]])

andrut14:12:37

oh, it will work

andrut14:12:55

it’s just list instead of a vector

roelof14:12:09

so no need to convert the list to a vector

andrut14:12:55

they are equal by value

squest14:12:05

@roelof: Clojure’s equality for collection works on the value of the coll regardless whether it’s a list of a vector simple_smile

roelof14:12:36

thanks, another solved. I find it still difficult when to use mapcat / reduce and when not

andrut15:12:36

I use my favourite editor, write a test, then the function, write a test and use repl extensively; maybe that’ll help simple_smile ok, bed time

roelof15:12:35

sleep well

roelof15:12:49

IM puzzeling how to solve this one: (= [1 2 [3 4 5] [1 2 3 4 5]] (let [[a b & c :as d] ] [a b c d]))

roelof15:12:10

b looks [ 3 4 5] to me and c = [ 1 2 3 4 5 ] but I have doubt about what a is

roberto15:12:55

tip: just focus on what d should be

roelof15:12:08

@roberto: if I understand the manuals d is the old value of c

roelof15:12:37

this is a very complicated exercise

roberto15:12:25

try the let portion in a repl if you are unclear how destructuring works.

roelof15:12:56

and then make values for my own

roberto15:12:19

and go to the section on Destructuring

roelof15:12:47

oke, I think the last example is what im looking for

roelof15:12:56

oke, If I understand it right this & c :as d means that the rest of the parameters c are now stored in d

roberto15:12:58

(let [[a & b :as c] [:a :b :c]] 
    (prn a)
    (prn b)
    (prn c)
)

roberto15:12:15

would print

roberto15:12:27

:a
:b :c
:a :b :c

roberto15:12:47

:as names the entire object you are destructuring

roelof15:12:39

oke, I see now

roberto15:12:48

btw, try it out in the repl

roberto15:12:51

don’t take my word for it

roelof15:12:11

I Always try things out in repl

roelof15:12:39

I think i mixed up the parameters and the outcome

roelof15:12:38

Im thinking what schould be in the _ and I think Im almost there

roelof15:12:06

found it. Now I see it a easy one

roelof15:12:45

now time for a break. Clojure has already costs me the whole afternoon

donaldball17:12:36

apply is probably going to be a feature of your solution

roelof17:12:16

I was first thinking of using some? but if I look at the manual I think im wrong

donaldball17:12:41

Unless you’re code golfing, you actually probably want to use a fn literal with varags: (fn [& args] …)

snowell17:12:53

You could mess around with not-any? and every?

roelof17:12:03

nope, I try to learn clojure

roelof17:12:25

and so not code-golfing for me

roelof17:12:02

@snowell: thanks, I will look at the cheat-sheet what both functions do

snowell17:12:19

I always find http://clojuredocs.org to be a very helpful resource

snowell17:12:34

As they put related/similar functions at the bottom of their doc page on a function

snowell17:12:28

That just confuses me 😉

roelof17:12:54

@snowell: not-any looks very interessting

roelof17:12:07

that will be my first candidate for testing

snowell17:12:23

There is also not-every? that could prove useful

roelof17:12:21

I wil test both on repl

roelof17:12:48

and then I could see which one does the job and why the other does not the job

roberto17:12:40

look into the boolean operations

roberto17:12:32

google for clojure boolean operators and you will get some hints.

roberto17:12:01

this is really easy once you familiarize yourself with boolean operators

roelof18:12:42

@roberto I know the boolean "and" and "or"

roelof18:12:57

But my feeling says that is the wrong way

roberto18:12:06

did you try it on the repl?

roelof18:12:22

not yet, Im have had dinner.

roelof18:12:22

hmm, this is not working : (not-every? false false)

roelof18:12:49

I see then this error message : Don't know how to create ISeq from: java.lang.Boolean

roelof18:12:26

maybe look how I can make it work with a unknown parameters

roelof18:12:45

the test functions have between 1 and 3 parameters

roberto18:12:25

why do you think boolean operators are wrong?

roelof18:12:50

it feels wrong

noonian18:12:23

not-every? expects a function as the first argument and a collection as the second argument

noonian18:12:48

user=> (doc not-every?)
-------------------------
clojure.core/not-every?
([pred coll])
  Returns false if (pred x) is logical true for every x in
  coll, else true.
nil

roelof18:12:19

oke, also not handy

roelof18:12:39

because I do not have a function

roelof18:12:09

I only have 1 , 2 or 3 parameters

noonian18:12:15

You may have to write your own anonymous function for some of the 4clojure problems, and then you could potentially call not-every? in the implementation of that function

roelof18:12:27

So I think roberto has right I need to use "and" and "or"

roelof18:12:34

@noonian: I have written a lot of anymous functions for map , reduce and mapcat

noonian18:12:38

have you written a function that takes any number of arguments before?

noonian18:12:53

I think that is the piece you are missing then

roelof18:12:12

I have found out that you can use a & before it

noonian18:12:20

so if you have a function (fn [& bools] …) then bools will be bound to a collection of the arguments to your function

roelof18:12:24

or write a multimethod function

roelof18:12:44

I wonder if I multimethod is not better then

roelof18:12:04

as the answers at the bottom of that topic

noonian18:12:27

Ah, that is actually called arity overloading. Multimethods are a form of polymorphism in Clojure and are not related.

roelof18:12:06

oke, sorry for the wrong name

roelof18:12:28

but that way I almost solved it for 2 arguments

noonian18:12:30

That would make sense if you had specific behavior for a fixed set of arities, but the 4clojure problem states that your function should take a “variable number of booleans” so I think you just need one arity that takes n booleans.

roelof18:12:23

bummer, I almost had it with that way

noonian18:12:41

well, some of your logic will probably still work

noonian18:12:35

instead of having the booleans in specific arguments, a and b, adjust your function to operate on a vector a booleans bools. (def bools [false true false])

roelof19:12:06

I will think about what you mean. First bring my daugher to bed

roelof19:12:17

but the last statement confuses me

noonian19:12:53

Sorry about that, for the 4clojure problem you wouldn’t def anything, but if you were trying this out in a repl you might define a variable holding some booleans to try out functions on them.

roelof19:12:02

I have a function called test-boolean [&booleans]

noonian19:12:44

cool, so if you call (test-boolean true false true) inside your function booleans will be [true false true].

roelof19:12:52

So the booleans are a vector then like [ true false] or [ true] or [ false, true. false]

roelof19:12:57

So far so good ?

noonian19:12:35

Yes, although there should be a space between the & and booleans. I’m not sure if that matters or not to clojure.

noonian19:12:04

but stylisticly

roelof19:12:05

oke, then I have to figure out how I can test things

roelof19:12:36

but as I said first my daughter to bed

noonian19:12:38

so now the functions you were trying before might come in handy, things like not-every?

noonian19:12:45

family first!

roelof19:12:50

oke, that way

roelof19:12:59

Always family first

noonian19:12:16

and there are other boolean functions that might be useful like true? and false?

roelof19:12:43

I now got the idea what you meant Time to expirement in Replof Cursive

roelof19:12:18

hmm. I have this (not-every? false? booleans) but that one fails on (true) and (true true true)

roelof19:12:51

and if I change false? to true? it fails on others. So more research to do

clojuregeek19:12:16

I"m trying to combine my clojurescript app and my compojure app into one:

(defroutes app-routes
  (GET "/" [] (-> (resource-response "index.html" {:root "public"})
                  (content-type "text/html; charset=utf-8")))
  (GET "/api/change-log" [] (json-response (get-change-log)))
  (GET "/api/task-log" [] (json-response (get-task-log)))
  (route/resources "/")
  (route/not-found "Not Found"))

(def app app-routes)
As described here: http://zaiste.net/2014/02/web_applications_in_clojure_all_the_way_with_compojure_and_om/ .. when I go to / it attempts to download the html, even after I removed all middleware from wrapping the routes. I see comments on the post with others with the same problem...and their solution doesn't seem to work now..

roelof19:12:55

@noonian: can I pm you with the solution I found

noonian19:12:29

@roelof: sorry, wasn’t paying attention. You are very close!

noonian19:12:49

did you solve it?

roelof19:12:20

but I m not sure if it good to post it here

roelof19:12:35

maybe it spoils the fun for other people

noonian19:12:16

I think this room sees enough churn that people aren’t likely to find your answers when they are solving the problem themselves

noonian19:12:33

but feel free to pm me your solution

clojuregeek19:12:50

BTW figured out out... http://stackoverflow.com/a/14014702 ... Jetty or Tomcat caused conflict with the other solutions i found.

rantingbob20:12:24

Why would I use transducers over ->> or, given I'm only a beginner, should I just ignore transducers for now? For context, I have a pipeline thats munging a bunch of data. I'm currently using ->> to push data through a bunch of functions. I'd need to learn to write transducers (which I will do at some point anyway) but I'm unsure what benefit it would bring other than intellectual curiosity

noonian20:12:00

I’d ignore transducers for now.

rantingbob20:12:27

Why would you use a transducer over ->>? I think I should maybe come back and watch Rich Hickeys talk again once I'm a bit more experienced

noonian20:12:41

well, a transducer will have better performance than a bunch of maps and filter in sequence because a transducer doesn’t create the intermediate collections

rantingbob20:12:05

I knew that >_< and now I feel stupid

noonian20:12:49

and transducers are not tied to collection types, so you can write a transducer once and then use the same transducer on a collection or with a core.async channel

eraserhd21:12:33

I haven’t ever really needed them. That’s interesting. Hrmm