#clojure log - Mar 03 2016

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

2:51 qsys: How do clojurists organize large projects with respect to DIP? Having different 'levels' in a large application, where d'you use 'high order function injection', protocols, multimethods, core.async, ... to comply dependency inversion?

3:05 ridcully: component and mount are popular choices

3:12 qsys: yeah, component does not really come for free... it feels too much 'you have to do it this way', to me. Checked 'mount', it's more about state management, isn't it?

4:21 zipper: What are plugins in a project.clj?

4:22 What would a :ring key mean in a project.clj?

4:22 Here's the file https://github.com/weavejester/compojure-example/blob/master/project.clj

4:28 CStorm: @zipper

4:28 read here: https://github.com/weavejester/lein-ring

5:02 zipper: CStorm: Thanks

5:52 Keksike: I have a JSON in my clojure. This JSON has an array inside it. I'm using cheshire to select fields from the JSON. How can I map/iterate/for through the array-field in the JSON?

5:53 when I tried mapping it, it mapped every single letter in the json rather than every object in the array

5:54 Kneiva: Keksike: have you parsed the string into a map?

5:54 Gonzih: did you get completely parsed data structure?

5:54 Keksike: ill give you a gist example of the data

5:58 Gonzih: better show your code, i think you are parsing it incorrectly

5:58 Keksike: https://gist.github.com/Keksike/c99a112d79de7ba8508a here, so I basically want to map the objects inside the events field

5:59 what I did was '(map mapperFunction (get-in (parse-string myJson) ["events"]))'

5:59 the mapperfunction got every letter as a parametre

5:59 so mapperFunction was ran like a hundred times

6:00 although there is only two objects inside the events array

6:01 Kneivo I dont think so

6:03 Kneiva: Keksike: in plainjson.txt the event value is a string not an array

6:05 Keksike: Kneiva: what should I do, other than using Cheshire parse-string?

6:06 ridcully: ,(get-in [:a :b] ["events"])

6:06 clojurebot: nil

6:07 Keksike: ridcully: I didnt quite catch that

6:07 sorry, im quite new with clojure :)

6:08 Kneiva: Keksike: Can you change the input (plainjson) so that it actually has an array instead of a string representation of an array? If not the you can parse the input and the parse again the value of "events".

6:09 Keksike: Kneiva: I'm not sure if I can. I'll try to find out.

6:10 Kneiva: so something like this might work?: (debug (get-in (parse-string (parse-string myJson) ["events"])))

6:11 Kneiva: (parse-string (get (parse-string myJson) "events"))

6:11 Keksike: ah

6:11 whats the difference between get and get-in btw

6:12 Kneiva: Keksike: Also you can turn the keys into keywords for easier access: (parse-string (:events (parse-string myJson true) true)

6:13 oops, missing one )

6:13 Keksike: do I have to do something to make that work?

6:14 Kneiva: Nope. But it's nicer. (get data "events") vs. (:events data)

6:15 Keksike: yeah its alot nicer! :) thanks

6:20 I got that working! :)

6:21 another question, about map though

6:21 if I want to send a 'static' param to map, what should I do

6:21 so basically I want to send two parametres to the map function, one which is an array to map and another which is just a string that is needed in the map function

6:31 Kneiva: Keksike: You want to add stuff to a map?

6:32 Keksike: Kneiva: nah, I just want to give my map function (map delete-one-event (parse-string (:events (parse-string events true) true))))

6:32 a second parametre (in addition to the array)

6:32 the delete-one-event function that is

6:36 Kneiva: Keksike: Can you give an example again of what is the input and what is the desired output?

6:36 sunset-shimmer: hello

6:37 Keksike: Kneiva: this is an example of what I want to basically do, but this doesnt work https://gist.github.com/Keksike/6d597c568f8b10e5470c

6:37 sunset-shimmer: can you tell me please where I can put commands that should be injected in the nrepl after connection via lein

6:37 Keksike: so the chainId is just a plain string

6:37 which I want to send to the delete-one-event function

6:39 sunset-shimmer: in the project.clj in figwheel settings

6:44 Kneiva: Keksike: You can use partial on delete-one-event. Btw. Your example is missing the ) I forgot from my example. It should be like this: (parse-string (:events (parse-string events true)) true)

6:45 Keksike: yeah its on different row accidentally

6:45 can you give me an example of using partial here? or I can just google :)

6:51 Kneiva: https://clojuredocs.org/clojure.core/partial

7:28 Keksike: woo I got it working, thanks alot Kneiva!

7:28 im starting to like clojure

7:29 though my working with it is still extremely slow

7:30 Kneiva: Keksike: np

7:44 renl: Hi do people use clojure in robotics in any form?

7:48 kwladyka: renl the answer is the same if they use Java.

8:23 MasseR: renl: yes

8:23 renl: finnish firm zenrobotics is a clojure firm

8:58 oracle: I have the following map. And give a parameter of sex, need to pickup the user without the most money for that sex. How to do it?

8:58

8:58 {:user1 {:money 400 :sex :male}

8:58 :user2 {:money 300 :sex :female}

8:58 :user3 {:money 200 :sex :male}

8:58 }

8:58

8:58

8:58

9:16 mpenet: :gender would be a nicer key name :>

9:16 (sort-by (comp :money val) {...})

9:18 jgertm: am i correct in assuming that core.logic/membero doesnt work with sets?

9:59 patham9: hi

9:59 how do I get IntelliJ to overwrite the old definitions in REPL on "send to repl"?

10:02 ah found

10:35 cortexman: i am getting Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: :db.error/lookup-ref-attr-not-unique Attribute values not unique: :some/id

10:35 i have confirmed that the attribute value is unique

10:35 TimMc: MasseR: I was seriously considering applying to them. :-)

10:55 solatis: ehrm, noob question

10:55 i'm having a vector

10:56 but the standard sequence functions (for example, `for`) don't seem to work on it

10:56 is that by design? or am i doing something wrong?

10:56 Gonzih: ,(for [i [1 2 3]] (* i 10))

10:56 clojurebot: (10 20 30)

10:56 Gonzih: this works solatis

10:57 solatis: hmmm

10:58 ,(type [1 2 3])

10:58 clojurebot: clojure.lang.PersistentVector

10:58 solatis: i'll be damned

10:58 i'm doing something wrong then...

10:58 Gonzih: ,(class [1 2 3])

10:58 clojurebot: clojure.lang.PersistentVector

10:58 Gonzih: probably :)

11:03 solatis: ok, so, i'm doing something stupid, probably:

11:03 https://www.refheap.com/115469

11:04 is it because of laziness?

11:04 what am i missing here

11:04 * solatis feels like a noob again

11:06 schmir: use doseq instead of for

11:07 solatis: finally!

11:07 i knew there was something like that

11:07 so, for is lazy, because of infinite lists ?

11:07 schmir: solatis: also you don't the need the extra '(do...)'

11:07 solatis: yeah i know

11:08 that's just debugging

11:08 schmir: solatis: for is lazy

11:08 Gonzih: yeah lazy seq

11:08 you can also wrap for in to doall call

11:08 solatis: which forces evaluation?

11:08 Gonzih: ,(doall (for [i (range 10)] (prn i)))

11:08 clojurebot: 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n(nil nil nil nil nil ...)

11:08 Gonzih: yeah

11:36 sunset-shimmer: hm... I've created an atom: (defonce test (atom (func-that-returns-lazy-seq param)))

11:36 now I am trying to reset it but have got only "clojure.lang.Cons cannot be cast to clojure.lang.IAtom"

11:38 reset with (reset! test (func-that-returns-lazy-seq new-param))

11:38 did you know how to handle that?

11:38 cortexman: Unable to resolve symbol: !swap in this context

11:39 (def some-atom (atom {})) (defn some-fun [] (let [blah ...] (do (!swap some-attom assoc blah))))

11:39 when i just type !swap in the repl i get the same error

11:40 oh god, i have it backwards :)

11:40 it's that damn datalog notation

11:40 sunset-shimmer: cortexman: swap!

11:43 kriyative: @sunset-shimmer -- test resolves to clojure.core/test, try a different name?

11:44 sunset-shimmer: kriyative: "test" was chosen just for example purposes, In a real code I have normal name.

11:45 kriyative: @sunset-shimmer actually, i take that back ... still doesn't explain why the reset! fails

11:45 maybe the defonce?

11:47 is it possible you defonced test to something not an atom in your repl?

11:47 sunset-shimmer: kriyative: good question. I will try it now...

11:48 yes, seems possible, https://www.refheap.com/ee8ef3eeabce17b7a99c51646

11:49 wait

11:50 kriyative: sunset-shimmer: was that value of @test, my question was whether you'd defonce test to be something other than an atom

11:53 sunset-shimmer: kriyative: no! The same error

11:59 cortexman: how can i get if to return nothing on false

11:59 not nil - but rather nothing

11:59 kriyative: sunset-shimmer: is this similar to what you're seeing: https://www.refheap.com/115474

12:01 cortexman: (if (get @test-atom "balh") "success" do-not-return-anything-not-even-nil))

12:01 kriyative: sunset-shimmer: if you defonce'd test to be something other than an atom, you'll have to `(def test ...)` to change it back to an atom, at least in the REPL

12:01 cortexman: how to achieve that?/

12:02 luma: cortexman, there's no way to do that. in clojure, all forms evaluate to some value.

12:02 kriyative: cortexman: not sure you can do that, every Clojure expression has a value

12:02 sunset-shimmer: kriyative: yes, it was like an error after the second statement in your example. I see you point, thank you, it helps. But now stupid question: how can I use atom from different namespace, like test-ns/@test-atom (that didn't work)

12:03 kriyative: sunset-shimmer: @test-ns/test-atom

12:12 sunset-shimmer: kriyative: great! all works fine now. Thank you!

12:27 justin_smith: add -auto

13:06 bhsiao: when you run "lein repl" are you not in the main thread?

13:06 apparently glfw windows can only be created in the main thread, is there any way to get around this?

13:07 justin_smith: bhsiao: the main thread will be the one that launches the repl itself iirc, the process you interact with is a client sending messages over a network socket

13:07 bhsiao: you could use lein run -m clojure.main and not have the nrepl features, but be in the main thread

13:08 cortexman: if i generate my tempids with (d/tempid :db.part/my-partition) i get :db.error/not-a-partition Entity id -1000967 is not in a valid partition. if i instead specify {:db/id ;#db/id[:db.part/mypartition] ...} in my transaction, i get :db.error/datoms-conflict Two datoms in the same transaction conflict

13:09 bhsiao: justin_smith: sweet, the clojure.main repl worked

13:09 what does nrepl have that this doesn't besides client/server?

13:10 justin_smith: bhsiao: readline support, C-c as interrupt of current task rather than kill the process

13:10 those are the two big ones

13:10 readline being the library that allows convenient command line editing and history

13:11 bhsiao: hm, rlwrap seems to work so far

13:11 the C-c thing is annoying though

13:12 might there be any workaround

13:13 zeebrah: Wondering if it's possible to add a method to an existing object (that i created using proxy). Specifically i have a JPanel and i wish to add a method to it

13:13 ridcully: also tab completion in lein repl

13:18 justin_smith: zeebrah: you can extend a protocol for that Class, but not the specific object

13:19 zeebrah: justin_smith: ok, then i'm screwed..

13:20 does that mean you can't compose together things made using proxy?

13:20 justin_smith: zeebrah: proxy makes a brand new singleton Class

13:21 zeebrah: what i mean is can you proxy something you made using proxy

13:21 justin_smith: sure but that's making a different Object and a different Class, which wasn't what I thought you were asking for

13:22 zeebrah: no you're right, im just trying to solve this problem another way now.. i asked a different question initially

13:24 so how would that look, (proxy [(proxy [javax.swing.Panel] [] ...)) ?

13:25 justin_smith: zeebrah: wait, why do you even need the two layers of proxy here?

13:25 you know a single proxy can implement as many interfaces and protocols as you like, right?

13:25 zeebrah: justin_smith: beacuse im trying to avoid copying pasting code

13:26 so i have a create-modelled-JPanel method and i have a create-closable-JPanel method. now i want to make a composite of those two things without c-p the code

13:26 i do know that

13:26 create-modelled-and-closable-JPanel

13:27 justin_smith: oh, I think I was misled by your direct call of proxy inside proxy

13:27 this makes more sense if you have a use for both

13:28 zeebrah: yep

14:07 rhg135: ,(apropos "proxy")

14:07 clojurebot: (clojure.core/construct-proxy clojure.core/get-proxy-class clojure.core/init-proxy clojure.core/proxy clojure.core/proxy-call-with-super ...)

14:08 rhg135: I think you can

14:10 There's a function that takes a implementation map and the proxy object and let's you reimplement what it extends

14:10 justin_smith: rhg135: sure, you could do this with extend even

14:11 no, never mind that, that changes the protocol to work with that proxy, it doesn't make a new Class

14:11 rhg135: ,(doc proxy)

14:11 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, mus...

14:12 rhg135: At the end it mentions how it just delegates to functions

14:50 fantazo: is describing a map structure recursive complex or simple?

15:25 Shayanjm: Anyone know if java.util.regex is an NFA regex implementation?

15:25 TimMc: fantazo: Can you rephrase?

15:25 Shayanjm: I'm trying to build a 'compilation layer' for a bunch of regex to assess if any inputs are functionally equivalent - and the only way I can come up with to do that is by comparing the DFAs. Storing the subsequently 'compiled' DFAs and executing them directly would also be nice

15:26 TimMc: Shayanjm: From <http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html>: "The Pattern engine performs traditional NFA-based matching with ordered alternation as occurs in Perl 5."

15:26 Shayanjm: sweet, now to see if I can poke around and figure out how to build, store, and use DFAs

15:29 amalloy: i don't beliebe it. if you use any backreferences at all, regexes are too powerful to represent with a [DN]FA, and j.u.regex supports backreferences, so its engine can't be pure DFA

15:33 Shayanjm: amalloy: that's what I thought too

15:34 I'm trying to see where the NFA is actually constructed

15:36 fantazo: TimMc: say you put a hash into a hash with the key "obj", which itself has a key "obj" which is a hash that has a key "obj". and so on until there is no hash with a key obj.

15:38 TimMc, is that supposed to be complex or simple? I'm riddling around if one proposition I made to my coworkers to use such a description for describing a hierarchy of objects as "too complex".

15:38 rhg135: "NFA-based"

15:39 X-based usually means not X

15:40 TimMc: fantazo: When you say hash, do you mean a map?

15:40 fantazo: TimMc, yes a map.

15:40 TimMc: fantazo: And do you mean something like this? {"obj" {"obj" {"obj" 5}}}

15:41 fantazo: TimMc, correct.

15:42 the only difference would be that it would have a couple of more "attributes".

15:43 TimMc: So... what's the question?

15:43 fantazo: like in: {"name" "myself" "obj" {"name" "key" "obj" [{"name" "thing"} {"name" "stuff" {"obj" 5}}]}}

15:43 Shayanjm: amalloy: is it possible to call a private method on a regex Pattern object arbitrarily?

15:44 amalloy: why are you asking me instead of the channel at large?

15:44 fantazo: TimMc, more the philosophical if such a structure can be considered simple or complex.

15:44 rcassidy: That really depends on your thresholds for those considerations.

15:44 Shayanjm: err, that too - I tabbed habitually and your name happened to pop up

15:44 TimMc: I guess I don't really have enough information to say.

15:44 amalloy: haha

15:45 Shayanjm: anyway, you can do it with reflection if you want

15:54 justin_smith: fantazo left, but I think it's relevant to bring up the fact that with update-in, assoc-in, and get-in, the complexity of clojure code can stay managable with nesting, though overusing nesting can definitely be one symptom of overengineering, but you can only make that judgment in regards to a specific problem domain and a particular nesting...

16:40 WorldsEndless: I have an input stream. What's the easiest way to spit it to a file on disk?

16:44 TimMc: spit

16:44 wait, might be confused

16:45 WorldsEndless: Yeah, spit didn't work for me just now

16:45 I get a file with the name/memory location of "PipedInputStream"

16:46 TimMc: clojure.java.io/copy might do it

16:46 with a writer

16:49 WorldsEndless: TimMc: Hey! I didn't know about io/copy. With an output stream that worked wonders! thanks!

17:14 lumpkin: How do I get an OutputStream for *out* (which is an OutputStreamWriter)

17:29 hiredman: the value of *out* will depend on in what context your code is running

17:30 clojure by default binds it to something based on System/out, but different repls will bind it to other things

17:31 so writing to System/out doesn't always write to the same place as repls will print to

17:33 lumpkin: ok tnx

17:49 blake__: Is it customary to prefix "clj" and "cljs" to your code in a project that has both?

17:49 justin_smith: blake__: prefix where?

17:50 blake__: Sorry, namespaces.

17:50 cljs.myproject.whatever and clj.myproject.somethingelse

17:50 justin_smith: clojure.core does this with cljs vs. clojure

17:50 blake__: 'cause if it were cljs.myproject.whatever and clj.myproject.whatever, you'd sort of need to prefix or change the name.

17:53 I had some idea the namespace had to match the directory structure, too.

17:53 justin_smith: blake__: yes, namespace matching directory structure is neccessary if you want to call require or use in your code

17:55 blake__: justin_smith: Well, that's interesting. I turned a Clojure app into a mixed clojure/clojurescript app and put all the clj namespaces under a new clj directory, and changed nothing else and it seems to work.

17:55 With all of the namespaces requiring each other, that is.

17:55 So what used to be "myproject/src/core.clj" became "myproject/src/clj/core.clj".

17:56 er, "myproject/src/core.clj" became "myproject/src/clj/myproject/core.clj".

17:56 justin_smith: blake__: well, the directory structure restriction is inside the classpath, when you rename src to clj or src-clj or whatever you are changing classpath in lein along with it right? and the relative to classpath dir structure is unchanged

17:56 so likely you changed in lein from "src" to "src/clj" right?

17:57 blake__: right

17:58 So I guess that answers the original question, since those are relative paths as well, prefixing them is superfluous...unless maybe they (the clj and cljs) share code?

22:12 will_sm: Is it viable to run a basic clojure server on a BeagleBone black? ~ 1Ghz, 512MB Ram

22:13 rhg135: It's possible for sure

22:13 amalloy: you don't need anything close to 512MB to run a small webserver in clojure

22:14 lockdown: will_sm: just don't run it with lein

22:15 will_sm: I was really worried since I did `boot repl`, and that thing took 1GB on my system

22:15 But some apps do get greedy with my 32GB of ram

22:16 lockdown: s/lein/lein and boot/

22:18 rhg135: But I don't know what the response time is like

22:19 hiredman: I ran a little rest api written in clojure on a bealgebone to do home automation stuff, worked great

22:22 rhg135: Cool

22:35 hiredman: actually, at one of the conjs I gave a lightening talk about a little rover running clojure on a beaglebone that streamed video to the browser

22:35 https://www.youtube.com/watch?v=XMIKfOmAMjQ

22:39 I also have a compiler I started (written in clojure) for a basic like language for the programmable realtime units on the beaglebone

22:39 on short, beaglebones are fun

22:39 in

Logging service provided by n01se.net