Fork me on GitHub
#beginners
<
2017-01-04
>
bones03:01:26

I feel like this is solved already but I can’t find anything about it: I want to match a certain sequence of keys coming off of a channel, and drop keys that did not conform to that sequence

bones03:01:57

when the sequence is finally met, I return a particular state or whatever

seancorfield03:01:22

What do you mean by “sequence of keys”?

bones03:01:37

Well, any value really

seancorfield03:01:46

(a channel just produces values)

bones03:01:48

I’m just using keys as an example

bones03:01:20

Am i really just talking about filtering a channel?

bones03:01:36

And building up a result?

seancorfield03:01:48

Do you mean a set of predicates or a strictly monotonic sequence of predicates? (for accepting the values)

seancorfield03:01:00

(and what if a value you receive from the channel matches multiple predicates in order?)

bones03:01:26

If i had a channel that produced random alphabet characters, is there a way I could describe a sequence, say ‘ACDC’ , to match upon?

seancorfield03:01:34

In case you hadn’t guessed, I’m trying to show how application-specific your need seems to be...

seancorfield03:01:54

How you write this depends on the exact rules you have in mind for accepting and dropping values, and how you determine you’ve reached the end state. Essentially you have a FSA (Finite State Automaton) and the rules are going to be entirely application-specific.

seancorfield03:01:17

(sorry that probably wasn’t the answer you were looking for — I think it’s an interesting problem by the way!)

bones03:01:55

No problem. I just thought it might have been solved and I could learn from someones solution

kevinbheda08:01:30

what is the argument for running leinigen in verbose mode ?

abhishekamralkar08:01:23

Do anyone have emacs setup recommendation for Clojure?

sb08:01:56

@abhishekamralkar depend on your operation system..

abhishekamralkar08:01:13

I am on Fedora 25

beppu08:01:15

One of these days, I need to make a blog post about Spacemacs. It's a very radical reconfiguration of emacs that brings the good parts of emacs and vi together but also adds some nice ideas of its own.

sb09:01:24

Somebody, have experience with Redis (carmine) and compile to java with uberjar? (maybe that is Carmine bug, but I would like to know 100%..)

roelof09:01:10

Is there something wrong with my repl in cursive :

(defn set-intersection
      "Write a function which returns the intersection of two sets.
      The intersection is the sub-set of items that each set has in common.\n"
      [s1 s2]
      (reduce (fn[item, acc] (if (contains? s2 item) (conj item acc))) {} s1  ))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: defn in this context, compiling:(C:\Users\rwobb\AppData\Local\Temp\form-init5325766479843326056.clj:1:1) 
 

val_waeselynck09:01:52

@roelof have you loaded the namespace ?

roelof09:01:39

@val_waeselynck yep, see here :

Starting nREPL server...
"C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.3\jre\jre\bin\java" -Dfile.encoding=Cp1252 -XX:-OmitStackTraceInFastThrow -Dclojure.compile.path=C:\Users\rwobb\Desktop\clojure\forclojure\target\classes -Dforclojure.version=0.1.0-SNAPSHOT -Dclojure.debug=false -Didea.launcher.port=7534 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.3\bin" -classpath "C:\Users\rwobb\Desktop\clojure\forclojure\test;C:\Users\rwobb\Desktop\clojure\forclojure\src;C:\Users\rwobb\Desktop\clojure\forclojure\dev-resources;C:\Users\rwobb\Desktop\clojure\forclojure\resources;C:\Users\rwobb\Desktop\clojure\forclojure\target\classes;C:\Users\rwobb\.m2\repository\org\clojure\clojure\1.8.0\clojure-1.8.0.jar;C:\Users\rwobb\.m2\repository\org\clojure\tools.nrepl\0.2.12\tools.nrepl-0.2.12.jar;C:\Users\rwobb\.m2\repository\clojure-complete\clojure-complete\0.2.4\clojure-complete-0.2.4.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.3\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain clojure.main -i C:\Users\rwobb\AppData\Local\Temp\form-init1675104803961926111.clj
Connecting to local nREPL server...
Clojure 1.8.0
nREPL server started on port 63683 on host 127.0.0.1 - 
(in-ns 'forclojure.easy3)
=> #object[clojure.lang.Namespace 0x15414a1 "forclojure.easy3"]
(defn set-intersection
  "Write a function which returns the intersection of two sets.
  The intersection is the sub-set of items that each set has in common.\n"
  [s1 s2]
  (reduce (fn[item, acc] (if (contains? s2 item) (conj item acc))) {} s1  ))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: defn in this context, compiling:(C:/Users/rwobb/Desktop/clojure/forclojure/src/forclojure/easy3.clj:59:1) 
 

val_waeselynck09:01:30

@roelof try adding (require 'forclojure.easy3)

val_waeselynck09:01:46

before the in-ns

roelof09:01:24

it becoming more wierd:

CompilerException java.lang.RuntimeException: Unable to resolve symbol: require in this context, compiling:(C:\Users\rwobb\AppData\Local\Temp\form-init1675104803961926111.clj:1:1) 
 

roelof09:01:44

when I do (require 'forclojure.easy3)

val_waeselynck09:01:14

do this from user

roelof10:01:16

sorry, what do you mean exactly ?

val_waeselynck10:01:44

from the user namespace in the REPL

roelof10:01:53

oke, on a fresh repl it worked well

roelof10:01:32

and now it worked fine

roelof10:01:56

(require 'forclojure.easy3)
=> nil
(in-ns 'forclojure.easy3)
=> #object[clojure.lang.Namespace 0x17806f1 "forclojure.easy3"]
(defn set-intersection
  "Write a function which returns the intersection of two sets.
  The intersection is the sub-set of items that each set has in common.\n"
  [s1 s2]
  (reduce (fn[item, acc] (if (contains? s2 item) (conj item acc))) {} s1  ))
=> #'forclojure.easy3/set-intersection  

roelof10:01:13

why does this returns nil :

(defn set-intersection
  "Write a function which returns the intersection of two sets.
  The intersection is the sub-set of items that each set has in common.\n"
  [s1 s2]
  (reduce (fn[item , acc] (if (contains? s2 item) (conj acc item))) [] s1  )) 
`

roelof10:01:45

for this in repl (println (set-intersection #{0 1 2} #{4 2 5}))

roelof10:01:34

where if I try it in pieces it seems to do what I thought It would do

(contains? #{4 2 5} 2)
=> true
(conj () 2)
=> (2)  

roelof10:01:51

and this one :

(if (contains? #{4 2 5} 2) (conj [] 2))
=> [2] 

rauh10:01:32

@roelof You'v eswitched item and acc and also don't use a set for acc but a vec

roelof10:01:50

the outcome needs to be a set according to the 4clojure challenge

roelof10:01:58

but that one I can solve

roelof10:01:51

someone a tip how to make this work with 3 sets :

(defn set-intersection
  "Write a function which returns the intersection of two sets.
  The intersection is the sub-set of items that each set has in common.\n"
  [s1 s2]
  (set (reduce (fn[acc item] (if (contains? s2 item) (conj acc item))) () s1  ))) 

roelof10:01:38

I could make another clause which checks for contains s3 but then it fails when there are no more then 2 sets

val_waeselynck10:01:57

@roelof set intersection is an associative operation, so you can just use reduce

roelof10:01:51

oke, make a function that takes multiple arguments arrays

roelof10:01:01

never thought of that one

val_waeselynck10:01:59

@roelof btw, this operation is already implemented in clojure.set 🙂

roelof10:01:29

@val_waeselynck thanks

roelof10:01:51

what do you mean is already implemented in clojure,set ?

val_waeselynck10:01:33

this is part of the core library

roelof10:01:04

yes. but the challenge was to not use clojure.intersection

roelof10:01:22

so I have to re-implement it

roelof10:01:41

oke, the solution could be a lot smaller when using filter and set I see from other solutions

roelof10:01:56

@val_waeselynck thanks again

val_waeselynck10:01:07

yeah, stuff like (into #{} (filter s1) s2)

roelof10:01:24

or just #(set (filter % %2))

val_waeselynck10:01:32

but that'd require you to understand transducers etc.

roelof10:01:59

I think I have to think about solutions which are not using map or reduce

val_waeselynck10:01:56

It depends what your learning objective is. I mean, in real life, you would just use clojure.set anyway 🙂

roelof10:01:24

that is also a good point

roelof10:01:52

my learning objective is to learn to solve things the fp/clojure way

peter.d14:01:08

Hi! Anyone got any experience with the following beginner-course? https://www.udemy.com/clojure-fundamentals-for-beginners/ I'm looking for a good (video-based) beginners course in Clojure... 🙂

yogidevbear14:01:24

Not sure about the Udemy course, but I've heard really good things about https://tbaldridge.pivotshare.com/. You might also want to look at https://www.youtube.com/watch?v=9A9qsaZZefw&amp;list=PLAC43CFB134E85266

yogidevbear14:01:42

Unrelated to video tutorials/courses, but I got Living Clojure for Christmas and am extremely happy that I did. The book covers a lot of fundamental concepts in the first half of the book that I feel I'd be a lot poorer not reading and understanding before jumping head first into actual coding

yogidevbear14:01:54

I am coming from a procedural / OOP background, so people from other FP backgrounds may feel differently, but many concepts covered are largely Clojure specific

sb15:01:07

@peter.d I have acces to this course. What is the question?

sb15:01:17

I think, you can access to this course via http://SarafiBooksOnline.com with free 14 days trial. (I bought with 99% discount in 2016.. just check that is a same course or not)

sb15:01:25

@yogidevbear that is cool link (tbaldridge), I didn’t see before this.

peter.d15:01:02

@sb I just wonder if it's any good. Would you recommend it ?

sb15:01:18

@peter.d there is all Clojure course.. I don’t know what is your background and what do you would like to reach. Many options there.. video courses and books too (and really free to check everything with free registration). By the way if you are really beginner, then it could help for you: the http://purelyfunctional.tv/

sb15:01:20

I’m beginner too, so that is my experience. The best path.. follow the easiest way.. what lot of people use.. because in this case they can help for you. I didn’t do that.. and maybe that isn’t a best way 😉

sb18:01:47

Possible to create from “user” string to an #{user} object?

seancorfield18:01:28

@sb not quite sure what you’re asking there…?

sb18:01:01

(def users {"admin" {:username "admin"
                    :password (creds/hash-bcrypt "pass")
                    :roles #{::admin}}
            "dave" {:username "dave"
                    :password (creds/hash-bcrypt "pass")
                    :roles #{::user}}})

sb18:01:23

friend roles.. but I can get from monger just “admin” string

sb18:01:38

I can’t store #{user} just like a string

seancorfield18:01:43

(use three backticks to introduce a block of code)

seancorfield18:01:57

Remember that ::user is a qualified keyword for a specific namespace, so you’d create that use the two argument form of the keyword function: (keyword “my.namespace” “foo”) => :my.namespace/foo

seancorfield18:01:38

I would expect you to be storing a sequence of such things in MongoDB for the roles? Is it a sequence or just a single string?

seancorfield18:01:02

(since it’s potentially more than one ‘role’)

sb18:01:19

I store this kind of infos (this is just a test now):

{:_id #object[org.bson.types.ObjectId 0xa4c1b07 "586d3e268aaed4460e2a9134"], :username "admin", :password "$2a$10$qP4TO3pAN8pxOk2ZCEkEwuzAhNmLxnNgHrzyicfD3eSHVnhfg9m1q", :roles [”admin”]}

sb18:01:47

(let [conn (mg/connect)
 db   (mg/get-db conn "monger-test")]
(mc/insert db "users" {:username "admin" :password (creds/hash-bcrypt "pass") :roles #{::admin}}))

seancorfield18:01:51

Cool, so ‘roles’ is a sequence of strings and you need a set of keywords

sb18:01:34

.. but I will store just the “admin” string later.

seancorfield18:01:43

So starting from a sequence of strings, you’ll want to map a function over them to convert each one to a (qualified) keyword, like I showed above, and then convert the sequence to a set.

sb18:01:18

Thanks the infos!! I try it now!! :+1::+1:

kamillelonek18:01:13

what is the difference between different apps template with lein new?

kamillelonek18:01:28

e.g. app vs default one

seancorfield18:01:44

lein new app something creates an application skeleton, lein new something creates a library skeleton, lein new plugin something creates a skeleton for a Leiningen plugin

kamillelonek18:01:01

yes, this is what I know from help

kamillelonek18:01:15

the question is what are the differences between them

kamillelonek18:01:24

what is a plugin compared to library

kamillelonek18:01:30

because I can assume what an app is

seancorfield18:01:38

It’s exactly what the help says...

seancorfield18:01:46

I’m not sure what you’re asking?

kamillelonek18:01:04

what exactly is plugin?

kamillelonek18:01:08

what is it used for?

kamillelonek18:01:15

how is it different from a library?

seancorfield18:01:39

A plugin is specific to Leiningen.

kamillelonek18:01:54

thanks for clarification

seancorfield18:01:16

for things you would specify in the :plugins vector in your project.clj file.

kamillelonek18:01:28

ok, I wasn't sure, now I know

seancorfield18:01:35

An application has a -main function so you can run it from the command line.

kamillelonek18:01:47

thank you again

seancorfield18:01:59

Sorry, I wasn’t sure which words you needed explained...

kamillelonek18:01:14

ok, now I know everything

seancorfield18:01:54

lein new lets you create a skeleton based on any template. A few are built-in (`app`, default, plugin, template) but most are published as libraries on Clojars: https://clojars.org/search?q=lein-template

manutter5118:01:26

Short answer is “you can’t” — clojurescript runs in a Javascript-ish environment, and clojure runs on the JVM, so they live in different worlds

manutter5118:01:49

Depending on what you want to do, though, you may find .cljc files to be useful

dhruv118:01:01

hmmm. thank you

dhruv118:01:29

i’ll have a look at it. thank you

dhruv118:01:45

just fyi, I am trying to use clj-rethinkdb library i am trying to share data between cljs part of the code with clj. ie, there is some data added by the user, i want to save it in the rethink db. created async channel, but i cannot access the channel from my clojure code

manutter5119:01:29

Yeah, if you have data in a cljs environment, and a database in a clj environment, you’re going to have to wrap the data up in EDN or JSON or something and send it over to the clj environment

manutter5119:01:23

So if it’s a web browser using a cljs client, and a web server running a clj app, you’ll need to make an AJAX call or something similar.

manutter5119:01:21

You’d have the same thing even if it were a cljs-based browser app talking to a cljs-based NodeJS server. It’s nice both programs are written in the same language, but they’re still two separate environments, so they don’t share the data.

dhruv120:01:57

@manutter51 gotcha thanks!

dhruv120:01:19

i am new to web-dev and kind of new to cljs so just trying to get my feet wet

sb21:01:55

@seancorfield hello I created the script, but not so nice..

(def users  
   (into {} (for [x testm]
             {(x :username) 
             (assoc x :roles 
             #{(keyword "fu.handler" (x :roles))})} ))
  )
I would like to use more Clojure friendly script. How possible to solve in different way?

dpsutton21:01:33

sb, just ask the channel. you don't have to ping individual people

sb21:01:06

Ok, Sorry! Just Sean helped to me before this.

dpsutton21:01:17

its not problem

dpsutton21:01:37

just ask people here who have the time

sb21:01:05

Ok, if you have time, just please help me to understand better, how to use clojure. I know that script not a best.

dpsutton21:01:29

I'm afraid I don't have time right now

notanon21:01:29

i dont see anything wrong with it sb

notanon21:01:07

well nvm yeah i do

sb21:01:09

Yes, I know, that is works. But maybe I can use like reduce or similar? or nicer?

notanon21:01:29

reduce is probably what everyone would use

notanon21:01:18

your reducing function would take 1 user out of testm and assoc a new key into the map

notanon21:01:40

pass your testm data structure and i will write it

sb21:01:30

many thanks!!

sb21:01:02

Thanks!!!

notanon21:01:43

do you need to handle multiple roles?

sb21:01:14

I just use the friend example, which use different roles.

sb21:01:40

Later I would like to use, of course (for different user roles).

notanon21:01:57

(reduce (fn [results input] (let [username (:username input) password (:password input) role (keyword "fu.handler" (:roles input))] (assoc results (:username input) {:username username :password password :roles #{role}}) )) {} testm)

notanon21:01:01

this does just one role

notanon21:01:12

i can show you how to handle mutliple too, one second

sb21:01:41

Many thanks the video, very very helpful! :+1: :+1:

notanon22:01:01

np, writing clojure code is fun 🙂

sb22:01:18

Thanks, that is really cool!! I see!! :+1:🙂

notanon22:01:31

it took me a while to wrap my head around reduce, loop/recur when i first switched over from java

notanon22:01:02

but after writing a couple functions for a real use case (instead of contrived examples like calculate fib sequence)

notanon22:01:54

it's becomes clear very quickly... you're just building something up, like the results argument to the reducing function in this example

notanon22:01:28

kind of funny since it's called reduce 🙂

notanon22:01:07

probably has a math background for the name reduce... i slept thru calculus so i probably missed that bit

sb22:01:26

Yes, a little bit hard for me the first baby steps. Very helpful the results, inputs word in the code. Now, I understand better how I need to use reduce. I could use hopefully next time.

notanon22:01:24

yeah i've found that using very descriptive variable names and breaking things into separate functions makes things so much easier to read

notanon22:01:53

just because you can write very very very concise code, doesnt mean you have to write it as concise as possible

notanon22:01:18

i will use let blocks when i don't have to, for example

notanon22:01:51

just because it's easy for someone (probably me) to come back later and figure out what is going on when each bit of data is clearly defined up front

sb22:01:38

Yes, that is really helpful and good idea, I will use that too.

sb22:01:38

Thanks again!