Fork me on GitHub
#beginners
<
2016-11-23
>
mathpunk00:11:28

After reading, it looks like it's a matter of setting a :ring-handler option. I'm going to proceed under the assumption that I have no idea how to do something so complicated that it's not a "simple" ring server anymore...

roelofw07:11:57

Why here a class exception :

(fn [s] (reduce (fn[acc n] (if (not= n (last acc)) (conj n acc))) [(first s)] s )) 

rauh07:11:11

@roelofw Do you want to just know the mistake, or learn how to find it?

roelofw07:11:12

Last one. Learn how to find it. @rauh

roelofw07:11:26

Otherwise I have to ask every time again

rauh07:11:48

Do you have access to the full stacktrace?

rauh07:11:28

(pst) on the repl

roelofw07:11:35

I saw this error message on the 4clojure editor but I can copy it on a repl

rauh07:11:52

You may want to invest into getting an editor setup, Cursive is super simple and can print the last stacktrace very nicely

roelofw07:11:41

I have cursive

rauh07:11:17

It has the command "Print last exception", which you should def. bind to something if it's not already

roelofw07:11:12

Wierd, the code

(fn [s] (reduce (fn[acc n] (if (not= n (last acc)) (conj n acc))) [(first s)] s ))
=> #object[user$eval1273$fn__1274 0x16b6478 "[email protected]"]  

roelofw07:11:18

works fine in repl

rauh07:11:53

It's just a function definition, nothing gets evaluated

rauh07:11:20

Run it with example data, you can wrap it in 2 more () and then pass it some vector

roelofw07:11:19

oke, now I see the same error message

rauh07:11:00

print the stacktrace with Cursive

roelofw07:11:10

and with pst I see this error message :

ClassCastException java.lang.Long cannot be cast to clojure.lang.IPersistentCollection
	clojure.core/conj--4345 (core.clj:82)
	clojure.core/conj--4345 (core.clj:82)
	user/eval1525/fn--1526/fn--1527 (form-init7761432892955560103.clj:1)
	clojure.lang.PersistentVector.reduce (PersistentVector.java:341)
	clojure.core/reduce (core.clj:6544)
	clojure.core/reduce (core.clj:6527)
	user/eval1525/fn--1526 (form-init7761432892955560103.clj:1)
	user/eval1525 (form-init7761432892955560103.clj:1)
	user/eval1525 (form-init7761432892955560103.clj:1)
	clojure.lang.Compiler.eval (Compiler.java:6927)
	clojure.lang.Compiler.eval (Compiler.java:6890)
	clojure.core/eval (core.clj:3105)
=> nil

roelofw07:11:26

so it looks that my conj is not good

rauh07:11:32

Yup ๐Ÿ™‚

roelofw07:11:37

back to the manual why ?

rauh07:11:57

So it expects a collection, but it was given a Long for one of it's arguments

rauh07:11:15

just take a good look at the conj, and look up its documentation

roelofw07:11:55

I did , I mixed up acc and n

roelofw07:11:11

now I can work on making the function work

roelofw07:11:09

I have to compress ( 1 2 2 3 3 2 2) to ( 1 2 3 2)

roelofw07:11:33

I thought when I did [ (first acc) ] I see a vector but it looks not. conj places the new entries on the front and not in the end

roelofw07:11:26

anyone a tip why this is not working as expected

rauh07:11:27

Try the Cursive debugger

roelofw07:11:08

Can I look step for step in a reduce function ?

roelofw07:11:12

When I do debug I see no output at all

seancorfield08:11:49

@roelofw If conj adds to the front, then your collection is a list. If conj adds to the end, then your collection is a vector.

roelofw08:11:42

yep, I found it, I have forget to add a else statement

roelofw08:11:58

When I change that everything works fine

roelofw08:11:45

except for strings then I see this as output : '[\L \e \r \o \y] ` instead of "Leroy"

roelofw08:11:28

So I have to think how to make some changes here :

((fn [s] (reduce (fn[acc n]
                   (if (not= n (last acc)) (conj acc n) acc))
                 [(first s)] s )) 

roelofw08:11:51

I could use a if then for strings but then I see a lot of overhead

roelofw08:11:09

and I cannot use two anymous functions

roelofw08:11:58

some one a tip how to solve this without doing the reduce two times ?

rauh08:11:30

Your problems is NOT "how to solve this problem for strings", you already solved it. Your problem is "how to turn [\a \b \c] into "abc"" in case the input is a string

roelofw08:11:01

You can say it also that way

seancorfield08:11:32

@roelofw: he is giving you the tip you asked for

roelofw08:11:44

I know that I can use apply str to do this but then I have the reduce part two times

roelofw08:11:00

and I wonder if I can do it with one reduce function

seancorfield08:11:17

No you don't need reduce twice

rauh08:11:31

(let [res (reduce ...)] (if (string? input) ... ...), also cond->> if you wanna get fancy

seancorfield08:11:44

Why would you need to do reduce twice?

roelofw08:11:35

I was thinking about this :

(if (string? input) (apply str( reduce ..... )) (reduce ......) 

roelofw08:11:07

I thougt I could use let only with static things

roelofw08:11:46

learned another thing

roelofw08:11:24

@seancorfield I do not want to get fancy. I still have to study how --> works

roelofw08:11:48

the same with partial instead of fn[x] ( .......)

seancorfield08:11:03

๐Ÿ‘:skin-tone-2: always learning!

seancorfield08:11:53

(cond->> (reduce ...) (string? input) (apply str)) is rather nice @rauh

roelofw08:11:09

Im still a beginner so I have to learn a lot

roelofw08:11:18

@seancorfield that means that the reduce is executed and the apply str only if the input is a string ?

roelofw08:11:19

->> means that every part is executed after each other ?

roelofw09:11:15

@seancorfield if I do this :

(fn [s] (cond ->> (reduce (fn[acc n] (if (not= n (last acc)) (conj acc n) acc)) [(first s)] s ) (string? s) (apply str))) 

roelofw09:11:48

I see this error message : java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->>, compiling:(NO_SOURCE_PATH:0) on 4 clojure

moxaj09:11:53

@roelofw you have a space between cond and ->>

roelofw10:11:59

Then I see this error : java.lang.RuntimeException: Unable to resolve symbol: cond->> in this context, compiling:(NO_SOURCE_PATH:0)

moxaj10:11:16

4clojure uses clojure 1.4 for some reason and cond->> is available since 1.5

roelofw10:11:55

oke, then I use a let binding

roelofw10:11:06

@moxaj thanks

roelofw10:11:21

solved another one

roelofw10:11:53

and see now I could have done it more easy with partition with

roelofw10:11:29

Now the next one : calculating factorials

roelofw10:11:48

I think I use reduce another time

dev-hartmann12:11:23

hopefully some of you fellow clojurians can help me out

dev-hartmann12:11:56

i have a map that has an event keyword as key and a fn as a value

dev-hartmann12:11:53

in some of these pairs the i get this result :user.handler/confirm-invite #object[clojure.lang.Var$Unbound 0x31e50ab5 Unbound: #'users/confirm-invitation-handler]

dev-hartmann12:11:33

other pairs in the same map, coming from the same namespace do not have these issues

alexmiller12:11:52

I don't think we can answer that without knowing a lot more about how that map is built. Somehow you have an unbound var rather than a function

pawel.kapala13:11:08

Hey, how would you advice to write tests with clojure.spec? Do I need to wrap it with some other test framework like test.check or midje? How do you do that, I use spec in repl, but Iโ€™d like those verifications to be run from CI as well...

roelofw13:11:38

I have to re-implement interleave . Someone who has a tip how I can do this. IM thinking about a loop with a acc

dev-hartmann13:11:51

@alexmiller

(ns api.users ..)  (defn invite-user-handler []
  ...)

(def event-handlers {:frontend.users.profile.handler/user-profile                     get-user-handler
                     :frontend.users.list.handler/process-user-list                   get-users-handler
                     :frontend.users.list.handler/invite-user                         invite-user-handler})

(defn start []
  (doseq [[event handler] event-handlers]
    (println "event - handler" event handler)
    (ws/register event handler))) 

dev-hartmann13:11:03

@alexmiller all in the same namespace

dev-hartmann13:11:23

the println for the last event handler produces

:frontend.users.list.handler/invite-user #object[clojure.lang.Var$Unbound 0x31e50ab5 Unbound: #'api.users/invite-user-handler] 
whereas the other two are not unbound

dpsutton13:11:08

i don't see confirm-invitation-handler in your code at all

dev-hartmann13:11:28

sry, wrong copy paste

dev-hartmann13:11:38

i get that output for more than one handler

dev-hartmann13:11:53

but others are not unbound

dev-hartmann13:11:15

same namespace, fn definetly exist

dev-hartmann13:11:06

stacktrace:

:cause Attempting to call unbound fn: #'api.users/invite-user-handler
 :via
 [{:type java.lang.IllegalStateException
   :message Attempting to call unbound fn: #'api.users/invite-user-handler
   :at [clojure.lang.Var$Unbound throwArity Var.java 43]}]
 :trace
 [[clojure.lang.Var$Unbound throwArity Var.java 43]
  [clojure.lang.AFn invoke AFn.java 32]
  [ 

dpsutton13:11:55

is there any importance that above you have user.handler and here you have api.users?

dpsutton13:11:04

are you conflating different user namespaces?

dev-hartmann13:11:45

today i don't seem to get naming right ๐Ÿ˜‰ i just wanted to shorten the namespaces for readability and screwede that up

dev-hartmann13:11:44

just assume it's (ns api.users)

dpsutton13:11:00

was this working earlier and you are shortening the namespace?

dpsutton13:11:02

what does that mean

dev-hartmann13:11:36

i shortended in the snippet, not in actual code ๐Ÿ˜‰

dpsutton14:11:26

oh i see sorry

dev-hartmann14:11:21

no biggie, my error, i edited in the messages

dpsutton14:11:20

resolve invite-user-handler from your repl?

dev-hartmann14:11:33

same thing

api.users=> (invite-user-handler ....)
IllegalStateException Attempting to call unbound fn: #'api.users/invite-user-handler  clojure.lang.Var$Unbound.throwArity (Var.java:43) 
`

dev-hartmann14:11:14

another handler from the same namespace

api.users=> (get-users-handler "")
2016-11-23 15:11:46,877 WARN [....] 
goes straight to my db and tries to find a blank stringed user ๐Ÿ˜‰

dev-hartmann14:11:46

ok ok, found the error... wrong parens -.-'

roelofw14:11:00

When I have to re-implement interleave , do I need to use a anymous function ?

roelofw14:11:22

I know no other way I can hold the outcome

roelofw15:11:47

How do I get the first item of s1 and the first item of s2 in the anymous function. Here my code so far : fn [s1 s2] (reduce [acc n ] (conj acc n1 ..) [] s1 s2 ) ?

dpsutton15:11:02

your reduce form doesn't seem to have a function form inside of it

dpsutton15:11:54

and it looks like you have the signature of reduce off

roelofw15:11:59

sorry , (reduce (fn [acc n1] (conj acc n2 ) [] s1)

dpsutton15:11:09

what is n2?

roelofw15:11:19

n2 must be n1

dpsutton15:11:38

so you are just appending to a vector?

dpsutton15:11:50

you'll just end of with (vector s1)

roelofw15:11:04

n1 schould be a number of the first seq and n2 schould be the first number of the second seq which I want to interleave

roelofw15:11:33

I have to interleave 2 seq without using interleave

roelofw15:11:50

and I try some things out how to solve that

dpsutton15:11:08

can you reduce over two collections?

roelofw15:11:56

I do not think so

dpsutton15:11:28

so your fundamental approach is off here then

roelofw15:11:31

so this idea can be trown into the trash can

dpsutton15:11:38

not necessarily

dpsutton15:11:48

you could put them into the same "thing" and then work over that single thing

dpsutton15:11:57

just the point is that the signature of reduce only takes one parameter

dpsutton15:11:04

so you could put it into a map, but this seems a little clunky

dpsutton15:11:21

you could put them into a vector as element one and element two

dpsutton15:11:28

but again, it seems like we are kinda twisting stuff

dpsutton15:11:53

it seems like what we want to do is "for each" element in each list, combine them

dpsutton15:11:58

so to me, i hear a map function

roelofw15:11:12

yep, that is why I try to find a way this can work

dpsutton15:11:38

so if we had [a b c] [d e f] as our lists, if we wanted an intermediate step, we could easily end up with ([a d] [b e] [c f])

dpsutton15:11:47

by just mapping a function over both collections

dpsutton15:11:05

and if we had that form, is there a way to easily make it look like the final result that we want?

dpsutton15:11:22

which function?

roelofw15:11:10

my first quess schould be interleave and I m not allowed to use it

roelofw15:11:24

I will take another look at the cheat scheet

dpsutton15:11:37

which function does ([a d] [b e] [c f]) => (a d b e c f)

st15:11:17

concat ?

agile_geek15:11:14

@dpsutton yep flatten or (mapcat identity ....)

roelofw15:11:22

o, I was looking at zipmap

dpsutton15:11:32

well, mapcat kinda does flatten

dpsutton15:11:47

but i definitely would not have thought of that one

agile_geek15:11:58

It's the equivalent of flatMap in other langs

dpsutton15:11:06

so @roelofw if we know how to get from the intermediate step to the final step, do you know how to get to the intermediate step?

dpsutton15:11:24

([a b c] [d e f]) => ([a d] [b e] [c f])

agile_geek15:11:26

i.e. map a fn and concat the results

roelofw15:11:13

@dpsutton zipmap maybe ?

dpsutton15:11:39

don't overcomplicate it

dpsutton15:11:47

but think about it

dpsutton15:11:05

and its a very common function but used in a way that's not used as much, ie, over two collections rather than over just one

roelofw15:11:52

oke, I will think about it

roelofw15:11:13

I will leave and think about it

dpsutton15:11:24

these are better if you mull it over for a while

agile_geek15:11:08

BTW Once you can do it in two steps- with the intermediate result ([a d] [b e] [c f]) it's easy to make it one step using something I mentioned above.

dpsutton15:11:48

and i think your idea of a reduction makes sense, you just need to figure out how to begin. This should be nicer as it only traverses your collection in one pass

alexmiller15:11:30

If anyone is interested in picking up Clojure Applied, itโ€™s 40% until Dec 2 the Pragmatic Pressโ€™s annual Black Friday sale - https://pragprog.com/book/vmclojeco/clojure-applied - use code turkeysale2016

alexmiller15:11:42

other Clojure books can be had with the same

roelofw17:11:40

@dpsutton can you any tips about the function I have to use for my problem

dpsutton17:11:21

You want to "for each" over two collections

dpsutton17:11:26

and that's a definite map

dpsutton17:11:38

map can go over one collection, taking each element at a time

dpsutton17:11:54

or if passed multiple collections, takes an element at a time from each and passes them in to your function

dpsutton17:11:15

so if we want to make some vectors so that we get ([a d] [b e] [c f]) we are making vectors

roelofw17:11:06

oke, I never seen that map could take multiple collections

roelofw17:11:15

I will google for some examples of that

dpsutton17:11:41

use your repl

dpsutton17:11:45

and read the docstring

roelofw17:11:42

so [f c1 c2] does a function with 2 colls c1 and c2

dpsutton17:11:14

> Function f should accept number-of-colls arguments

dpsutton17:11:23

and just make sure your mapping function can accept that many args

roelofw17:11:24

oke, then I have to think what f must be

dpsutton17:11:43

what must f take and what must it output

roelofw17:11:37

f must take the 1 element of c1 and one of c2 and the output must be [ element c1, element c2]

dpsutton17:11:14

know of any functions like that? or must we build it

dpsutton17:11:28

we just need to make a vector of our input args

roelofw17:11:26

that would be vector

roelofw17:11:55

the only thing I have to figure out is how to get the elements

dpsutton17:11:03

map does that for you

dpsutton17:11:16

(map vector [1 3 5] [2 4 6])

roelofw17:11:29

normally I would do [acc , n] where acc is the output and n the current number

dpsutton17:11:45

that's a reducing signature

dpsutton17:11:08

map calls the function you provided with the successive elements of the collection(s)

dpsutton17:11:37

so here, map is calling vector with (vector 1 2), then (vector 3 4) then (vector 5 6)

dpsutton17:11:54

vector is varyadic and handles the function call with two arguments

dpsutton17:11:36

And now flatten it and we did our two step process

dpsutton17:11:04

There you go

dpsutton17:11:19

And now that you get that two step process look up mapcat

dpsutton17:11:18

To do it in "one" step

agigao18:11:53

Hey guys, whatโ€™s difference between -> and ->>?

pkova18:11:55

-> is the thread-first macro, where the result is put as the first argument of each subsequent expression

pkova18:11:39

whereas with ->> the result gets put as the LAST argument

pkova18:11:16

the commas are equivalent to whitespace, just to show where the result goes

roelofw18:11:20

@dpsutton thanks, time for thinking how to flatten a seq without using flatten

roelofw18:11:38

the easy challenges are becoming harder now

dpsutton18:11:42

Well it kinda did anyways

dpsutton18:11:56

That's why I said you're doing it in "one" step

dpsutton18:11:09

You're using one form but it's calling concat underneath

dpsutton18:11:18

That's why I like your reduction form from earlier

roelofw18:11:22

@dpsutton you mean the fn[s] reduce (fn [acc n] (conj acc n)) ?

roelofw18:11:58

I use that often when I have to calculate or count things and im not allowed to use count for example

roelofw20:11:13

If I have to flatten a seq and not allowed to use flatten, the only way is to use recursion with a if then ?

donaldball22:11:21

You could probably use a loop form