#clojure log - Sep 22 2015

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

0:21 rritoch: If there any shortcut, short of looping, to convert a vector of vectors into double[][] , such as [[1 2] [2.1 0]], into-array doesn't accept dimensions so it doesn't seem suitable.

0:24 For now I'll use doseq + into-array but it seems like there must be a faster way.

0:31 Well doseq won't work, there's no counter

2:43 elvis4526: Why I can't redef a function used in (partial) with (with-redefs) ?

6:40 visof: hi guys

6:40 https://gist.github.com/aibrahim/f1f08c22f7b8b2a764eb

6:49 neurostorm: howto write a boolean? function?

6:51 noncom: neurostorm: what do you mean?

6:52 neurostorm: like string?

6:52 noncom: visof: what do you mean there?

6:52 neurostorm: ah, you mean predicates

6:52 neurostorm: function which tests if argument is a boolean...

6:53 noncom: boolean? and fn? or ifn? (depends on your particular need)

6:53 neurostorm: oh wait, they did not yet implement the boolean? predicate...

6:53 neurostorm: so it will be (or (true? x) (false? x))

6:53 yes. it looks stupid :D

6:53 neurostorm: thx. got it :-)

6:54 visof: noncom: you didn't get what i meant?

6:54 noncom: neurostorm: this one ticket i opened looong ago: http://dev.clojure.org/jira/browse/CLJ-1298

6:54 visof: oh, wait, i read again

6:54 visof: noncom: ok

6:56 neurostorm: btw, like the ticket.

6:59 noncom: visof: hmmm read again, really, the text is hard to follow, sorry... as i see, you need to rearrange a vector according to some complex rule. i cannot clearly make out the details of algorithm from this text, but from the first glance i think that i would go with a loop-recur over original vector indices

7:00 then you can freely peek into any other elements in the vector, relative to your current index

7:00 with (nth coll idx)

7:00 xeqi: I

7:00 noncom: xeqi: You

7:01 xeqi: I'm still getting used to writing on my atreus and hit the wrong thing

7:02 noncom: xeqi: don't worry, that was cool :D

7:02 xeqi: what is atreus btw?

7:03 xeqi: noncom: http://atreus.technomancy.us/

7:04 noncom: xeqi: wow. how does it feel ?

7:07 xeqi: I like it so far.though getting my hands used to being held in a different position took some time. I've gotten used to it for most writing prose. not quite there for code yet

7:17 visof: i'd end up doing a loop/recur with an accumulator where each pass would read more off the list based on your movement criteria. something like https://www.refheap.com/109836

7:20 noncom: xeqi: oh, you write prose! anything published or available for reading? :)

7:30 irctc: Hi all.

7:31 noncom: irctc: hello

7:31 irctc: Hi noncom. :)

7:32 I am new to Clojure and I just discovered this channel.

7:32 noncom: irctc: that's great! welcome!

7:33 irctc: Thanks. :)

7:33 I really like the language. I want to create my first web application in Clojure.

7:34 noncom: irctc: so it will be clojure + clojuresctipt then i guess :)

7:34 irctc: Yea, that's the plan. :)

7:34 Although I am still strugling to get a grasp of all the tools out there.

7:35 noncom: irctc: so, be sure to also manifest your presense in #clojurescript

7:35 irctc: I just did. :)

7:35 noncom: irctc: yeah, tools, libs, things... you can always ask here. usually there's somebody around, it's very likely you'll get some answer or advice

7:36 irctc: I've been learning Clojure for about a month and I finally feel ready to dive in to a real project. But I don't know how different Clojurescript really is.

7:36 Is it basically Clojure just compiled to JS?

7:36 Thanks noncom. :)

7:37 noncom: irctc: well, yes.. but there are differences https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure

7:38 irctc: Thanks. :)

7:39 I am planning on using Compojure. I see a lot of people in the community like it and it seems like a good choice for a newcomer like me.

7:39 Along with Leiningen ofcourse. :)

7:40 noncom: irctc: yeah it is also kinda a standard - compojure is for http routing

7:40 and leiningen is the project management tool , you won't get far with any clojure app without it

7:40 there's also boot, an interesting tool, but i had no chance to look at it yet

7:40 irctc: That's what seems to be the theme of all the tutorials and books I've read. :)

7:41 noncom: ^)

7:42 oops

7:42 :)

7:42 irctc: I like what I read about this tool called Hiccup. It seems like a cool and easy way to generate HTML.

7:43 noncom: yeah, i use it all the time now

7:43 and reagent

7:44 irctc: Do you use JDBC to connect to your databases or is there another more idiomatic way to do it in Clojure?

7:44 What is reagent?

7:44 noncom: i am also a noob in clojure web dev. i have always been more non-web dev. and i still am. but recently i decided to take a web project too

7:45 there are clojure wrappers for jdbc, but if you use db like sql or mongo you can use like korma lib or monger lib or other similar

7:45 reagent is a wrapper for facebooks react

7:45 makes updating components on the page easier... but it all depends on your architecture

7:45 irctc: maybe you should read what's there under the Documentation section here: http://www.luminusweb.net/

7:45 irctc: I am thinking of just using a MySQL db as I am not very familiar with other DBMS out there.

7:46 noncom: irctc: if you plan to use mysql then try the korma lib

7:46 rritoch: Does anyone happen to know the ideal 'frames per second' for video? I made a small 3D rendering engine for clojure by all of my cores are near maxxed when it's running. I didn't do anything to slow the engine yet but I need to. The loop uses Thread/yeild but that doesn't do much.

7:47 noncom: rritoch: if you're talking about games, then there are 2 possible max fps

7:47 1) capped, usually to 60hz or 30hz or 25hz, 2) uncapped - that's as far as you can go

7:48 but the 3d engines that i was using never load CPU up to 100% even if they give 3000fps on a simple scene

7:48 rritoch: noncom: Thanks. Right now it's uncapped and I'm probably cooking my CPU when it's running.

7:48 noncom: rritoch: is your engine software?

7:48 or opengl?

7:48 rritoch: noncom: Just software/swing

7:48 noncom: rritoch: then yes, you can cook your CPU with it, you should limit the fps

7:49 rritoch: you could use adaptive limiting

7:49 irctc: Thanks for the advice noncom. Korma seems cool. I'm gona go try out some of these tools you recommended. :)

7:49 rritoch: noncom: I may offload it to GPU eventually, but for now this is just for fun to re-familiarize myself with clojure.

7:49 irctc: Take care everyone and have a nice day. :)

7:49 noncom: irctc: yeah, the luminus website i referenced, can give you a very easy introduction. thanks, you too :)

7:50 rritoch: nuncom: I'll try 60hz and see if that lowers my cores any.

7:50 noncom: rritoch: so, if i get you correctly, you do all this polygins, matrix, projections 3d stuff in software and reder polygons, right?

7:52 rritoch: noncom: Well, it's a simplifed engine, it just uses projections and bufferedimages for tripple-buffering. It does have a double[] to hold a z value eventually to manage overlaying.

7:53 noncom: rritoch: i see. just wanted to know what amount of computations you're assuming

7:53 try adaptive capping, like when game logic (not rendering) takes more, you sleep less

7:59 rritoch: Other than the cores being maxxed, i'm just happy to see that clojure handles it well. We'll see what happens when I start building more complex objects.

8:00 noncom: rritoch: yeah, an interesting experiment. i did not have enough guts to perform vertex transformations and all algebra in clojure, i used java for these parts

8:03 rritoch: noncom: Same here, I offloaded all of the heavy lifting to java. Clojure is providing the self-rendering objects and calling java side transformations.

8:05 I'm not particularly familiar with any clojure support for matrix operations so it was a quick solution. The Projections are all persistent so they play nice with clojure.

8:06 noncom: well, there is a matrix lib which ppl say is very neat

8:06 but interesting insight into your experience, good to know :)

8:19 rritoch: Wow, that helped! Thanks noncom. I reduced it to 60hz and CPU usage is now ~ 15%

8:24 noncom: cool :)

8:31 rritoch: if you want your rendering remain at 60fps even when you add logic, you can calculate the length of required delay. like estimated is 1000/60, but with some logic you get real 58 fps, so you measure it and take 1000/58, and 1000/60 - (1000/60 - 1000/58) is your new delay

8:31 if i remember all the numbers right

8:34 rritoch: noncom: I'm using System/nanotime and precalculate the rendering time of 1/60 seconds in nanoseconds. If there's time remaining it sleeps for the remaining time (reduced to milliseconds) otherwise it just yields.

8:37 noncom: yeah, something like that :)

10:16 dxlr8r: hello, something really easy but strange. when I run lein uberjar, and then run the jar, the jar won't print to stdout with the "print" function, only with "println". even if I append "\n" to print it won't work

10:16 you have any clues to why?

10:18 noncom: dxlr8r: idk, maybe you need (.flush *out*)

10:18 maybe "\n" is not enough

10:18 dxlr8r: sometimes I don't want to use \n though.

10:19 noncom: my only guess is that println also does flush on *out* and maybe *err*

10:20 dxlr8r: also if you need advanced terminal output control, look at ncurses and lantern

10:20 ah, btw, clojure has (flush) function

10:21 dxlr8r: don't need advanced :)

10:21 noncom: which is precisely (.flush *out*)

10:21 did flush work for you?

10:21 dxlr8r: ok

10:21 no

10:21 noncom: :(

10:21 dxlr8r: (do (flush) (print errors?))

10:21 like that?

10:21 noncom: no

10:21 ,(do (print "heeey") (flush))

10:22 clojurebot: heeey

10:23 dxlr8r: thx noncom , seems to work :)

10:23 akabander: Does clojurebot behave more like a repl or more like a jar?

10:23 noncom: cool!

10:23 akabander: hmmm to me repl and jar are orthogonal concepts... :/

10:24 even unrelated

10:24 akabander: Yeah, I'm probably conflating. Just wondering if (print "hey") on the repl might be misleading because the repl does a (flush)?

10:25 So does clojurebot also do a (flush) before returning?

10:25 noncom: akabander: yes, clojurebot seems to create a separate output channel for each interaction

10:25 ,*ou*

10:25 clojurebot: #error {\n :cause "Unable to resolve symbol: *ou* in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: *ou* in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: *ou* in this co...

10:25 noncom: ,*out*

10:25 clojurebot: #object[java.io.StringWriter 0x55f97cd8 ""]

10:25 noncom: ,*out*

10:25 clojurebot: #object[java.io.StringWriter 0x627f8247 ""]

10:25 noncom: ,*out*

10:25 clojurebot: #object[java.io.StringWriter 0x11c4c01a ""]

10:25 noncom: ,*out*

10:25 clojurebot: #object[java.io.StringWriter 0x352378f3 ""]

10:25 noncom: see, different, each time

10:25 so it utilizes it, flushes and releases

10:25 akabander: Aha. Enlightening. Thanks!

10:56 sdegutis: Why this not work?

10:56 ,(->> [:a 1 :b 2] (reduce into {}))

10:56 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core$seq__4116 invokeStatic "core.clj" 137]\n ...

10:57 noncom: sdegutis: coz:

10:57 ,(into {} :a)

10:57 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core$seq__4116 invokeStatic "core.clj" 137]\n ...

10:57 sdegutis: oh

10:57 Thanks noncom.

11:02 jeremyheiler: ,(->> [[:a 1] [:b 2]] (reduce into {}))

11:02 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 4...

11:02 jeremyheiler: ,(doc into)

11:02 clojurebot: "([to from] [to xform from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. A transducer may be supplied."

11:03 sdegutis: I'm very confused. How do you turn [[:a 50] [:a 10] [:b 20]] into {:a [50 10], :b [20]} ?

11:03 Oh wait, merge-with I think

11:04 jeremyheiler: ,(->> [[[:a 1]] [[:b 2]]] (reduce into {}))

11:04 clojurebot: {:a 1, :b 2}

11:04 sdegutis: ,(->> [[:a 50] [:a 10] [:b 20]] (map (partial hash-map)) (apply merge-with conj))

11:04 clojurebot: #error {\n :cause "No value supplied for key: [:a 50]"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No value supplied for key: [:a 50]"\n :at [clojure.lang.PersistentHashMap create "PersistentHashMap.java" 77]}]\n :trace\n [[clojure.lang.PersistentHashMap create "PersistentHashMap.java" 77]\n [clojure.core$hash_map invokeStatic "core.clj" 374]\n [clojure.core$hash_map doIn...

11:04 jeremyheiler: ,(into {} [[:a 50] [:a 10] [:b 20]])

11:04 clojurebot: {:a 10, :b 20}

11:05 jeremyheiler: oh i see what you're doing

11:05 ,(doc merge-width)

11:05 clojurebot: Titim gan éirí ort.

11:05 jeremyheiler: ,(doc merge-with)

11:05 clojurebot: "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)."

11:07 sdegutis: Yeah I *almost* got it.

11:07 This is the closest I have gotten, but it's still not right:

11:07 ,(->> [[:a 50] [:a 10] [:a 30] [:b 20]] (map (partial apply hash-map)) (apply merge-with vector))

11:07 clojurebot: {:b 20, :a [[50 10] 30]}

11:08 sdegutis: Maybe I need some intermediate step that creates vectors out of all its vals? That would suck though.

11:08 jeremyheiler: (reduce (fn [m [k v]] (update-in m [k] #(if (vector? %) (conj % v) [v])) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

11:08 ,(reduce (fn [m [k v]] (update-in m [k] #(if (vector? %) (conj % v) [v])) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

11:08 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:08 jeremyheiler: ,(reduce (fn [m [k v]] (update-in m [k] #(if (vector? %) (conj % v) [v]))) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

11:08 clojurebot: {:a [50 10 30], :b [20]}

11:09 sdegutis: ,(->> [[:a 50] [:a 10] [:a 30] [:b 20]] (map (fn [[a b]] [a [b]])) (map (partial apply hash-map)) (apply merge-with concat))

11:09 clojurebot: {:b [20], :a (50 10 30)}

11:09 jeremyheiler: ,(reduce (fn [m [k v]] (update-in m [k] #(if (nil? %) [v] (conj % v)))) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

11:09 clojurebot: {:a [50 10 30], :b [20]}

11:09 sdegutis: This one I just did works, but it requires a custom function which I almost always consider an inferior solution.

11:10 Granted, it does it for destructuring and embedding into a new vector, so it's not that bad.

11:10 akabander: Is there an elegant way to get '( :a :a :c :c :c :b ) => { :a 2 :c 3 :b 1 } ?

11:10 oddcully: isn't the last one just group-by?

11:11 jeremyheiler: ,(doc group-by)

11:11 clojurebot: "([f coll]); Returns a map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."

11:11 sdegutis: oddcully: which one?

11:11 jeremyheiler: (group-by identity [:a :a :c :c :c :b])

11:12 ,(group-by identity [:a :a :c :c :c :b])

11:12 clojurebot: {:a [:a :a], :c [:c :c :c], :b [:b]}

11:12 akabander: Close, I can do another pass to get what I want

11:12 jeremyheiler: ,(group-by first [[:a 50] [:a 10] [:a 30] [:b 20]])

11:12 clojurebot: {:a [[:a 50] [:a 10] [:a 30]], :b [[:b 20]]}

11:14 jeremyheiler: ,(reduce-kv (fn [m k v] (assoc m k (map second v))) (group-by first [[:a 50] [:a 10] [:a 30] [:b 20]])

11:14 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:15 jeremyheiler: ,(reduce-kv (fn [m k v] (assoc m k (map second v))) (group-by first [[:a 50] [:a 10] [:a 30] [:b 20]]))

11:15 clojurebot: #error {\n :cause "Wrong number of args (2) passed to: core/reduce-kv"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/reduce-kv"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [sandbox$eval254 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbo...

11:16 schmir: how about frequencies?

11:17 ,(doc frequencies)

11:17 clojurebot: "([coll]); Returns a map from distinct items in coll to the number of times they appear."

11:17 jeremyheiler: ,(frequencies [:a :a :c :c :c :b])

11:17 clojurebot: {:a 2, :c 3, :b 1}

11:17 jeremyheiler: ta da!

11:17 nice call, schmir

11:17 akabander: Sheesh

11:17 That was easy! :^)

11:17 Thanks, schmir

11:18 It seemed like something that would have already been written...

11:19 jeremyheiler: ,(reduce-kv #(assoc %1 %2 (map second %3)) {} (group-by first [[:a 50] [:a 10] [:a 30] [:b 20]]))

11:19 clojurebot: {:a (50 10 30), :b (20)}

11:19 jeremyheiler: sdegutis: ^

11:19 sdegutis: Nice, thanks.

11:21 jeremyheiler: still has a custom function tho :-/ lol

11:21 i think a map-kv would be nice in this case

11:22 maybe...

11:23 separate map-keys and map-vals

11:24 oddcully: many libs have those. e.g. plumbing

11:25 jeremyheiler: yeah

11:25 cool

12:12 justin_smith: jeremyheiler: ,(reduce (fn [m [k v]] (update-in m [k] #(if (nil? %) [v] (conj % v)))) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

12:13 err

12:13 jeremyheiler: ,(reduce (fn [m [k v]] (update-in m [k] (fnil conj []) v)) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

12:14 jeremyheiler: I know you found group-by, but the fnil pattern is still sometimes applicable

12:14 jeremyheiler: ah, i always forget about fnil!

12:14 justin_smith: ,(reduce (fn [m [k v]] (update-in m [k] (fnil conj []) v)) {} [[:a 50] [:a 10] [:a 30] [:b 20]])

12:14 clojurebot: {:a [50 10 30], :b [20]}

12:19 amalloy: ,(apply merge-with into {} (for [[k v] [[:a 50] [:a 10] [:a 30] [:b 20]]] [k [v]]))

12:19 clojurebot: #error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :at [clojure.core$key invokeStatic "core.clj" 1499]}]\n :trace\n [[clojure.core$key invokeStatic "core.clj" 1499]\n [clojure.core$merge_with$merge_entry__4637 invoke "core.clj" 2932]\n [clojure.l...

12:19 amalloy: ,(apply merge-with into {} (for [[k v] [[:a 50] [:a 10] [:a 30] [:b 20]]] {k [v]}))

12:19 clojurebot: {:a [50 10 30], :b [20]}

12:20 jeremyheiler: heh, nice

12:20 justin_smith: for a given task, justin_smith will find a way to solve it with reduce, and amalloy will find a way to solve it with for

12:20 amalloy: sounds about right

12:21 i think if you took away every clojure function but into and for, i'd still be content

12:22 sobel: you only need fold anyway

12:23 justin_smith: sobel: AKA reduce

12:27 hiredman: you'll pry clojure.set from my cold dead rsi mangled stumps

12:28 amalloy: i use clojure.set pretty rarely. what gems am i missing?

12:28 hiredman: clojure.set/index

12:30 the doc string is a little too terse

12:31 amalloy: most of the docstrings in clojure.set are not very approachable because they use rel and xrel without ever defining them

12:31 hiredman: clojure.set has the makings of a nice in memory relational database that you query using for

12:33 https://github.com/sonian/Greenmail/blob/master/src/clj/greenmail/db.clj uses clojure.set/index to index facts and provides a core.logic relation to query them (not even terse doc strings)

12:35 sobel: justin_smith: basically, yeah

12:36 huh, i rolled my own JOIN and WHERE functions for a very limited purpose. sounds like i might have benefitted from clojure.set

12:36 vec of map became my PMDB

12:37 (poor man's database)

13:25 sjl: I'm trying to figure out how nrepl's session middleware works. Right now I'm attempting to puzzle out how sessions get created/deleted/expired.

13:25 Empperi: sniff, I wonder if Cursive has stopped supporting community edition of idea

13:25 that would be sad if so

13:26 sjl: What I've found so far seems to be: if you don't include a "session" in the request map, one gets created for you but NOT saved into the main "map" of sessions, and so "expires" when that request finishes

13:26 (and it gets GC'ed)

13:26 Alternatively you can send a "clone" op, which will clone the current (temporary, autoadded) session and will register that into the sessions map

13:27 so that it won't get GC'ed

13:27 and that will stick around forever, or until you send a "close" op

13:27 is that roughly correct, or am I missing something fundamental?

13:27 amalloy: Empperi: that would surprise me

13:30 Empperi: just downloaded it by hand since it wouldn't work via idea plugin management

13:30 and tried to install it from there

13:30 "Plugin 'Cursive' is incompatible with this installation"

13:30 :(

13:31 sad

13:31 noncom: Empperi: jet brains have changed their licensing policies

13:31 maybe it has something to do with cursive

13:31 Empperi: maybe

13:31 I do have ultimate edition on my work laptop

13:31 noncom: this company can go nuts, really... too much jet for their brains..

13:32 Empperi: but would like to use cursive on my home desktop too where I have only community edition

13:32 oh well, guess I won't be programming at home today then

13:33 xeqi: sjl: sounds right, though clone can take an id to clone an existing one as well

13:33 Empperi: they are trying to tell me to use la clojure

13:33 sjl: where "existing" means "registered" right?

13:33 Empperi: which has even got an update, omg

13:33 noncom: Empperi: blog.jetbrains.com/blog/2015/09/03/introducing-jetbrains-toolbox/

13:34 Empperi: noncom: yeah I was that

13:34 wasn't really happy about that

13:34 sjl: e.g. if I just send a bare {eval (something}} op, it will have a "session" but there's really no way to access that session

13:34 if I want a session I can do anything with, I need to clone first

13:34 noncom: Empperi: well, there's always eclipse + ccw, emacs, vim... :)

13:34 Empperi: used eclipse+ccw combo quite enough

13:35 ccw is actually pretty nice but eclipse - ain't going back

13:35 sjl: xeqi: concrete example: I do {"op" "eval" "code" "(+ 1 2) (Thread/sleep 10000) (+ 2 3)"}

13:35 noncom: Empperi: i'm on it right now. yes, eclipse sometimes gives pain.

13:35 sjl: I get back a response for the first form, which contains a session id

13:35 Empperi: after one has tasted idea you won't want to go to back to eclipse

13:35 really

13:35 snowell: +1

13:35 sjl: but I can't actually do anythingwith that ID because it's not registered

13:36 noncom: cursive was not straight too - too many problems with key shortcuts, problems with project dependency, strange behavior sometimes... too much...

13:36 Empperi: 89€ for the first two years for the idea ultimate edition

13:36 snowell: Eclipse should be considered torture

13:36 noncom: yeah, idea might seem cool but not always so. eclipse just works.

13:36 Empperi: that's not THAT bad but considering I manage to do programming at home maybe two times in a year currently with baby girl in house...

13:37 noncom: Empperi: i had to program at nights when everyones sleeping to satisfy my addiction

13:37 Empperi: I need to sleep at nights to be able to function at work

13:37 sjl: xeqi: yeah ok I just tested it and that is indeed the case. makes sense (kinda)

13:37 Empperi: and I can write clojure at work full time so no biggie

13:40 hiredman: that is just really weird to me

13:42 Balveda-3: What would the Clojure equiv for Number n = Integer.parseInt(field) be?

13:42 Alternatively, a coercion to Number

13:42 luma: ,(Integer/parseInt "123")

13:42 clojurebot: 123

13:42 Empperi: clojure does not implement it's own parseInt

13:43 hiredman: to say, such and such editor isn't working so I won't be programming today

13:43 akabander: IDEA is the first IDE I've liked using. Except for maybe TurboPascal back in the Borland days....

13:43 justin_smith: Balveda-3: we don't have typed variables, so you can just use (def foo (Integer/parseInt field)) and you might need the ^Number hint at the place of usage for interop

13:43 Empperi: hiredman: well, I have about 1h time to do any programming this evening

13:43 so I launch idea, it doesn't work

13:43 spend 30 mins finding out why

13:43 Balveda-3: And how would the hint work in use?

13:43 (^Number foo)?

13:43 justin_smith: (.bar ^Number foo)

13:43 Empperi: now I have 30 minutes left to install some other IDE or similar and learn to use it to do the programming

13:43 hiredman: Empperi: sure, and far be it from me say you have to or should be working

13:43 Empperi: oops, ran out of time

13:44 justin_smith: Balveda-3: hints only make sense in the context of a method or function call

13:44 Empperi: hiredman: I'm at home

13:44 hiredman: Empperi: sure

13:44 Empperi: and I do have a full time job and I do have a work laptop right there with intellij ultimate edition...

13:44 hiredman: sure

13:44 Empperi: so not really getting your point here :)

13:44 justin_smith: Balveda-3: (^Number foo) would attempt to call foo, which should throw an error if foo is really a number

13:45 ,^Number 1

13:45 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

13:45 justin_smith: oops!

13:45 amalloy: Empperi: hiredman's point is you can write clojure with a dumb text editor and a repl

13:46 Empperi: sure I can

13:46 you can write any language with a dumb text editor

13:46 amalloy: justin_smith: prediction: some object somewhere will implement IFn and extend Number

13:46 Balveda-3: (^Number 1)

13:46 ,(^Number 1)

13:46 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

13:46 Empperi: it's completely different thing if I want to do that

13:46 hiredman: which, I am not say you should, I just would never think to say "my editor isn't working, so no code today"

13:47 dxlr8r: when we are at the topic of editors, LightTable ain't bad :)

13:47 hiredman: and that is all I am saying, we have a different stance

13:47 Empperi: yeah, been meaning to learn lighttable for a long time

13:47 dxlr8r: comming from ccw and emacs

13:48 Empperi: so guess now is the time

13:48 I backed it back during the kickstarter

13:48 dxlr8r: nice

13:48 hiredman: (no moral judgement about stances implied or expressed)

13:48 snowell: I used Light Table for quite a while. It was pretty good. I prefer cursive now

13:48 Balveda-3: ,(.Number "1")

13:48 clojurebot: #error {\n :cause "No matching field found: Number for class java.lang.String"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching field found: Number for class java.lang.String"\n :at [clojure.lang.Reflector getInstanceField "Reflector.java" 271]}]\n :trace\n [[clojure.lang.Reflector getInstanceField "Reflector.java" 271]\n [clojure.lang.Reflector invokeNoArgInstanceM...

13:48 Balveda-3: ,(.Number (Integer/parseInt "1"))

13:48 clojurebot: #error {\n :cause "No matching field found: Number for class java.lang.Integer"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching field found: Number for class java.lang.Integer"\n :at [clojure.lang.Reflector getInstanceField "Reflector.java" 271]}]\n :trace\n [[clojure.lang.Reflector getInstanceField "Reflector.java" 271]\n [clojure.lang.Reflector invokeNoArgInstanc...

13:48 dxlr8r: I used some time setting it up. and installing plugins. nice paredit support

13:48 Balveda-3: better read those docs

13:50 dxlr8r: the "best" editor is emacs though, most features, best paredit support etc. but I can't stand the editor

13:50 justin_smith: Balveda-3: an Integer is always a Number

13:51 Balveda-3: Yeah, the problem itself is weird

13:51 I'm calling a query and giving it arguments, but apparently it's a little too specific in what it requires

13:51 justin_smith: Balveda-3: you might need to explicitly tell a jvm method that an arg is Number

13:51 hiredman: I've never used a proper debugger(printlns everywhere), so I never felt the lack of one, but I know in the early days lots of people using clojure keenly felt the lack of one that integrated well with their editor of choice

13:51 justin_smith: Balveda-3: otherwise, clojure doesn't care

13:51 snowell: Wait, there's a better method than printlns? :D

13:52 Balveda-3: {:id1 a :id2 b :num c}

13:52 hiredman: and that difference seemed hard to bridge, they always said "no, seriously how do you do anything without a debugger?" and I said "I dunno, I just do, what is so great about debuggers?"

13:52 justin_smith: snowell: I find that putting some data inside a mutable container mid execution, and then playing with the data directly in the repl is often superior to a either a println or a debugger

13:53 Balveda-3: a and b are ints, the postgre columns in the db are an int and a serial respectively

13:53 justin_smith: Balveda-3: {:id1 a :id2 ^Number b :num c} perhaps?

13:54 but if it is of type serial, clojure.java.jdbc should accept a long...

13:55 dxlr8r: I usually just split my functions up so I don't need debuggers. so that each one is simple and can be tested from repl with testdata and I see errors quick then

13:55 hiredman: and it seems like there is something sort of similar to that divide around more advanced ide functionality, and I wonder what the underlying difference between those two stances is, and how it arises

13:56 justin_smith: you can do everything with a repl + ed, after that it's all about conveniences, and you don't miss any of them if you haven't tried them

14:01 akabander: This seems relevant to an article in the latest LispCast, "The Pain We've Forgotten"

14:01 Balveda-3: Ok, I got the problem. It was something else entirely

14:01 Thanks justin_smith

15:26 akkad: OH: "you use clojure at uber?" "yeap" "Is your uber ever a jar?" "ahh uberjar cute"

15:29 domokato: i've noticed that doing a keyword lookup in a record is slower than just referencing the field (i.e. (:key record) vs (.key record))

15:30 surely this can be optimized at compile time. are there any plans for this?

15:32 hm, actually, I'm not sure if it could be optimized since it requires the type hint to be faster (i.e. (.key ^Type record))

15:33 opqdonut: indeed

15:58 Empperi: did end up writing my hobby piece of code in LightTable instead of Cursive (the problem I had earlier)

15:58 felt like I was handicapped lol

15:58 was constantly wishing I had my ordinary repl

16:00 the whole instarepl is nice for learning clojure but kinda useless for anything serious

16:10 rvsv: Does anyone know what a "java.io.UnixFileSystem" error means? I'm trying to use send-message from the postal library to send an email.

16:10 It worked just fine last week, but I upgraded my jvm from 1.6 to 1.8 in the meantime.

16:17 Empperi: 1.6 -> 1.7 brought NIO

16:17 it changed how I/O is done in java, of course there's still the old APIs etc but lot of stuff changed

16:19 java.io.UnixFileSystem is a package private class in the java.io package

16:19 would you mind giving the full error?

16:19 rvsv: Sure, just a minute while I get a pastebin.

16:24 Empperi: waiting :)

16:24 need to go to bed soon, it's 23:24 here and got an early wake up tomorrow morning

16:30 rvsv: Sorry, I'm seeing some other interesting stuff in the error log. I think I'll try to unravel this myself a bit so I don't embarass myself too badly. Have a good night, and thanks for being willing to help!

16:31 Empperi: np :)

16:31 night

16:31 justin_smith: rvsv: when you create an instance of FileSystem, the jvm creates an instance of UnixFilesystem (if you are on a *nix box)

16:31 rvsv: of course there's a good chance you aren't yourself directly using any FileSystem objects

16:36 rvsv: justin_smith: ok, the thing I noticed is that I'm getting a similar error on a windows box

16:36 I was expecting a java process builder error (I don't have sendmail installed), but instead I got the java.io error

16:36 And I didn't recently upgrade the jvm there.

16:36 lpaste_: sds pasted “sds” at http://lpaste.net/141496

16:37 rvsv: hmm, I'm just thinking out loud. I'll see what I can see.

16:37 lpaste_: sds revised “sds”: “No title” at http://lpaste.net/141496

17:06 elvis4526: Is there a way to use (with-redefs) against a function I use in (partial) ?

17:06 jeremyheiler: elvis4526: try it out?

17:07 justin_smith: elvis4526: no, because partial does not resolve the var when called (unless you provide partial with the var instead of the function (in which case yes, but it's clumsy))

17:07 hiredman: partial is a function, its arguments are evaluated before the function is invoked

17:07 if the argument is a name, the name is resolved to a value in the environment then the value is passed to the function as an argument

17:07 with-redefs temporarily rebinds a name to another value

17:09 justin_smith: ,(do (def 42+ (partial + 42)) (with-redefs [+ -] (42+ 42)))

17:09 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 42+>

17:09 justin_smith: ergh

17:09 ,(do (def +42 (partial + 42)) (with-redefs [+ -] (+42 42)))

17:09 clojurebot: #error {\n :cause "First argument to def must be a Symbol"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.RuntimeException\n :message "First argument to def must be a Symbol"\n :at [cloju...

17:10 justin_smith: (do (def plus42 (partial + 42)) (with-redefs [+ -] (plus42 42)))

17:10 ,(do (def plus42 (partial + 42)) (with-redefs [+ -] (plus42 42)))

17:10 clojurebot: 84

17:11 justin_smith: ,(do (def plus42 (partial #'+ 42)) (with-redefs [+ -] (plus42 42)))

17:11 clojurebot: 0

17:11 justin_smith: elvis4526: note the difference between those two calls ^

17:11 hiredman: given this program (def a (atom 0)) (def x (+ @a 5)) x where do you have to change the value that the atom in refers to in order for x to be a different value?

17:11 elvis4526: Yeah I get it, thanks

17:11 hiredman: in a

17:18 irctc: Hi everyone. :)

17:19 I have a question about compojure. I am new to Clojure web development and I want to create a web app in compojure.

17:20 sritchie: irctc: ask away!

17:21 irctc: When I create a new project with Leiningen: lein new my-project I would get a file in the src directory called core.clj, but when I create it using compojure I don't get that.

17:21 justin_smith: irctc: core is just a convention

17:21 irctc: I get handler.clj. Is that my new default file to which all app requests will be coming from now on?

17:21 justin_smith: with compojure, iirc handler will be the primary ns

17:21 the handler will be tasked with handling all incoming http requests

17:22 irctc: Oh, ok, so my primary ns is the handler now.

17:22 justin_smith: if your primary task is handling http requests, yes :)

17:22 irctc: And then from the handler I would direct those requests to other namespaces with corresponding functions?

17:22 justin_smith: irctc: you would define routes, and each route can call whichever function(s) it sees apropriate

17:23 irctc: usually it makes sense to break up the routes into categories of similar tasks, and put each group of related tasks in their own ns

17:23 irctc: Well, yes it is, since it is a web application I need a way to handle http requests. I am completely new to Clojure, started learning it a month ago and I just created my first compojure project.

17:24 That's what I figured justin_smith.

17:24 justin_smith: irctc: the handler handles requests, with compojure you use defroutes to create a handler, and each route can call whatever function you like

17:24 I hope that's clear enough

17:24 irctc: Cool, thanks. :)

17:24 It is. :)

17:27 Is jetty the standard for a web server for Clojure development or can you use something else like Apache?

17:27 jeremyheiler: jetty is a common choice

17:28 justin_smith: irctc: that's modular, you can decide later, the code will be the same

17:28 jeremyheiler: for dev time maybe

17:28 irctc: Well once I compile all my code to java it won't really matter what server it runs on but I never used Jetty before and was just wondering if this is the standard for Clojure development.

17:29 justin_smith: the point of ring is that you can switch out ring server implementations at any time, it is common to use embedded jetty during dev then deploy to a container, or use embedded aleph or http-kit in prod

17:29 irctc: lein-ring will make you use jetty automatically, unless you force it to do something else

17:30 if you are using websockets that will likely rule out jetty I think, otherwise it's convenient

17:39 irctc: Thank you very much for your help justin_smith. :)

17:42 Btw, is there a better editor for Clojure than Eclipse/Counterclokwise?

17:43 talios: IntelliJ + Cursive

17:43 aaelony: What's the best way to convert a [ [ [] [] [] ] [ [] [] [] ] ] to [ [] [] [] [] [] [] ] ? Using flatten is overkill (e.g. [] ). Is it some combination of mapv, merge-with, and conj?

17:44 justin_smith: aaelony: (vect (apply concat v))

17:44 aaelony: bless you justin_smith

17:44 justin_smith: ,(vec (apply concat [ [ [] [] [] ] [ [] [] [] ] ]))

17:44 clojurebot: [[] [] [] [] [] ...]

17:44 justin_smith: clojurebot: seriously? that's like all but one of the elements, and ... is longer than [] is to print out!

17:44 clojurebot: 'Sea, mhuise.

17:45 justin_smith: haha

17:45 aaelony: haha

17:45 super

17:45 justin_smith: aaelony: I just thought of another way too

17:45 aaelony: cool

17:45 justin_smith: ,(apply into [ [ [] [] [] ] [ [] [] [] ] ])

17:45 clojurebot: [[] [] [] [] [] ...]

17:45 aaelony: I almost did that

17:45 justin_smith: if it's uniform that will work

17:46 aaelony: I started with a mapv though so nixed the into.

17:46 maybe (apply mapv ... )

17:46 nope...

17:47 WorldsEndless: unc

17:48 aaelony: thanks again justin_smith

17:49 amalloy: justin_smith: uniform here meaning "exactly two elements"?

17:52 irctc: Thanks for the help everyone. :) Take care and have a nice day! :)

17:53 justin_smith: amalloy: oh right, reduce into it is

17:54 Bronsa: I hate that into doesn't work for multiple collections

17:54 justin_smith: ,(reduce into [[[]] [[]] [[]] [[]]])

17:54 clojurebot: [[] [] [] []]

17:54 justin_smith: but reduce into does!

17:54 Bronsa: and now thanks to transducers it never will

17:54 even worse

17:54 ,(into [] [] [])

17:55 clojurebot: #error {\n :cause "Key must be integer"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Key must be integer"\n :at [clojure.lang.APersistentVector invoke "APersistentVector.java" 298]}]\n :trace\n [[clojure.lang.APersistentVector invoke "APersistentVector.java" 298]\n [clojure.core$transduce invokeStatic "core.clj" 6575]\n [clojure.core$into invokeStatic "core.clj" 6591]\n [...

17:55 Bronsa: the error message is awful :(

17:55 justin_smith: yes, that is a terrible message

17:56 Bronsa: i wish transducers werent direct functions but reified some protocol, that way all those weird messages could at least be $thing cannot be cast to ITransducer

17:58 amalloy: Bronsa: but then you'd need to call a function to compose them! isn't it amazing that you can write ((map f) (filter even?))?!! imagine how dreary it would be to write (t-comp (map f) (filter even?))!

17:58 justin_smith: aaelony: anyway, hopefully you caught the thing about using reduce into instead of apply into

17:58 aaelony: yes, very cool

18:02 Bronsa: amalloy: ah you might have an actual point there, composing transducers via `comp` wouldn't work anymore

18:02 I'd be totally fine with that though.

18:02 amalloy: well, yes, i was attempting to take that stance as absurdly as i could

18:02 there's no reason they should compose with comp instead of with some transducer-specific operator

18:03 Bronsa: agreed

18:06 and you could even "fix" the backwards aspect of composing them IUC (yeah I know it's not a bug to fix but I still feel it's unnatural & just a leaky implementation detail)

18:18 m1dnight_: Does anyone know how I can use the insert statement from honeysql?

18:19 I cant get it to work. I know the queries work manually and reading works.

18:19 This is how I feed it to jdbc:

18:19 (jdbc/db-do-commands (read-db-config) (-> (insert-into :karma) (values [{:nick "bar" :karma 100}]) sql/format)))

18:19 Reading from the db works, so the config is correct..

18:24 aaelony: m1dnight_: I'm likely alone in this, but if it's easier to issue the insert statement via jdbc, that's what I'd do...

18:24 m1dnight_: Well, I had it working with java-jdbc.sql before but I figured I would use one of the projects that are explicitly supported like HoneySQL.

18:24 But the docs are unclear on how to do it.

18:25 So Im going back to java-jdbc.sql then I guess

18:38 cfleming: Empperi noncom: Cursive will always support the community edition of IntelliJ. That error normally means that you have the wrong Cursive version for the IntelliJ version (i.e. trying to install a Cursive that supports IntelliJ 14.1 in the v15 EAP or something).

18:46 hlolli: Is there any tutorial online on how to use tags for someone that is unfamiliar with tags in the first place? Or more percise, how to use tags to destructure function arguments?

18:47 hiredman: that isn't a thing

18:47 I am assuming by tags you mean type tags, which have nothing to do with destructuring

18:48 hlolli: ok I am hoping to find a way to sequence trough [& rest] argument input and align the functions in correct order depending which function is tagged to which thing.

18:56 neoncontrails: hlolli: what you're describing sounds like a design pattern called dispatching on type

18:56 Are you familiar with the pattern?

18:58 mungojelly: is there any way to just have it detect everything, i want to just dump in the parts i want to connect and then if there's a function that returns an int and another function that takes an int then those would connect because duh.

19:01 how about if there's just a big pile of input data and instead of waiting to be asked, as soon as you write a function it just starts going around the input trying to find yummy things to process and spitting its results back out for other functions to try.

19:03 hlolli: sorry, went away for a sec.

19:04 mungojelly: is there a frame that will let me run a task and get like status reports on how it's doing.

19:04 hlolli: dispatching on type... sounds something I will google.

19:07 triss: I'd really like to have `defn` associate messages with `:pre` and `:post` conditions just like we can with assert.

19:08 Is it worth raising a ticket on the JIRA thing or is something thats been discussed before?

19:08 mungojelly: oh so defn has pre/post conditions? yay good news

19:09 triss: mungojelly: yep. lovely feature.

19:09 I just think they could provide better error messages.

19:09 mungojelly: it's a map? {:pre ...?

19:09 triss: Yup. :pre and post are just list of predicates over your arguments.

19:10 if they all pass the fn can run.

19:10 if they don't you get an assertion error

19:11 puredanger: triss: there is a ticket for this

19:12 triss: I'd love it if you could say stuff like: `{:pre [{(map? m) "m must be a map"} {(sausagey-enough? z) "Z is not sausagey enough. Have you added all sausages?"}]}

19:12 ah puredanger... i couldn't find it

19:13 could you point me in the right direction?

19:13 mungojelly: wait what i have to say [{(?

19:14 triss: no sorry mungojelly this is all going on in a dreamworld/the future

19:14 you just do {:pre [(map? m) (number? n)]}

19:15 puredanger: Sorry on my phone

19:15 mungojelly: ok well maybe that's enough )}]}) already :p

19:16 ok yay now i got it to work thanks

19:17 defn seems to do a zillion things i should just read it and see what all it does

19:18 what documentation can you put into your functions? there's a doc string, error messages, assert messages

19:27 justin_smith: type hints, comments

19:29 mungojelly: are there any of those tricky things where you read out particular formats of comments into documentation

19:29 justin_smith: not built in, but there are tools that do something like that

19:31 mungojelly: here are the ways i know of so far to poke a function (1) give it input, (2) ask for its doc string, oh and (3) dig around through its other metadata, anything else?

19:33 rhg135: Functions don't usually have metadata ##(meta +)

19:33 justin_smith: ,(meta +)

19:33 clojurebot: nil

19:33 rhg135: ,(meta #'+)

19:33 clojurebot: {:added "1.2", :ns #object[clojure.lang.Namespace 0x2ab76179 "clojure.core"], :name +, :file "clojure/core.clj", :inline-arities #object[clojure.core$_GT_1_QMARK_ 0x18b4c088 "clojure.core$_GT_1_QMARK_@18b4c088"], ...}

19:33 rhg135: But vars do

19:34 mungojelly: that's funny, you can get a function to do absolutely anything, but you have to come in through that one door

19:34 rhg135: Yup

19:35 It's all .invoke()

19:35 mungojelly: you can be like "argument that breaks into the other part of the function" and you're in, but you have to start by getting through there. it doesn't seem quite entirely fair somehow, i wonder if there's a better way.

19:35 justin_smith: mungojelly: this is because it keeps things straightforward

19:36 mungojelly: imagine if for example you could look at the insides of a function and change things, if the function calls you

19:36 or if functions could modify their arguments

19:37 mungojelly: what we do is reduce the number of moving parts so that understanding new code is tractible

19:37 mungojelly: oh sure of course always

19:39 rhg135: ,(meta (with-meta + {:awesome-key true}))

19:39 clojurebot: {:awesome-key true}

19:40 rhg135: They CAN have metadata, but it creates a shim

19:50 mungojelly: i guess we call wrapping functions in another function to give them another interface "monads" and don't do it much

19:52 the monad interfaces i've tried are all clunky, it's a simple idea and then somehow something goes wrong in the execution. why do you have to manually lift things, why not have a wrapper that lifts-if-unlifted and do it to everything. i just want to use things and mostly not know or care if they know all the interfaces i'm using them in.

19:58 you could have functions that know how to answer questions about their interface, like you say to them {:implements? :interface-i-want} or whatever, and if the function responds with an error or nonsense or says no then wrap it

20:12 are there no ways yet to publish a single paragraph of clojure that'll be interesting and useful to people, do you have to publish a whole independent project with its own dependencies and everything before anyone will listen to anything you say

20:12 isn't there anything that accepts plugins in clojure so you can write a simple part for it

20:15 pbx: mungojelly, what's your use case? i.e. what programming task are you finding frustrating and what specifically are you wishing for as a remedy?

20:16 from the words "before anyone will listen to anything you say" i take it this is some kind of cultural fit problem

20:16 mungojelly: pbx: well, i find it frustrating that everything is wrapped in a zillion levels of wrapping always even though it's possible for a paragraph to be meaningful and useful, so what i'm wishing for is for someone to say "oh sure, this project over here would love some contributions"

20:17 pbx: mungojelly, i'm sure there are lots of projects that would like contributions. a pull request doesn't have to be an indpendent project. i really don't understand what you're getting at. elaborate on "zillion"

20:19 mungojelly: sure well i can try to find places where i can randomly change things, but there's very little opportunity provided for participation in anything, no one's asking for any particular help making anything

20:20 ok like my project i'm working on the working title is tile-toybox and it just gives you simple 2d tiles, one thing i'm going to ask for help with is making tile sets, i'm going to include some tile sets to play with, but then you could make another set based on those examples

20:27 i'd like if we made a bot together that makes bizarre cut-up blog posts, everyone could contribute a few random functions from strings to strings and then we'd hook them all up into a fun spaghetti and give it a blog

20:28 then you could just say a function that turns every "banjo" into "armadillo" and hook it up to the thing that gives a string of musical instruments so now it says "cello armadillo violin piano"

20:29 the appropriate response to a function that turns banjos into armadillos shouldn't be that nobody ever does such a thing functions are for Business Logic, it should be to direct someone to a fun project where their contribution will be appreciated

20:36 ,((fn [str] (clojure.string/replace str #"banjo" "armadillo")) "cello banjo violin piano")

20:36 clojurebot: "cello armadillo violin piano"

20:36 mungojelly: there i wrote it. but it has no home. :(

20:41 pbx: mungojelly, if the fun project you are dreaming of doesn't exist, nobody is stopping you. like i said, there are plenty of open source projects that would welcome contributions.

20:42 you can even do both at once. make your own fun spaghetti blog project, and find something else to contribute to

20:42 mungojelly: pbx: ok well you don't know of or need any particular easy contributions? obviously everyone's happy if i go dig through docs and implement some transport protocol somewhere or something. but i'm still learning and i just want to have fun and say simple things.

20:43 should i worry about what kind of project i make with leiningen or just say lein new. i don't understand this junk it makes you. :/

20:44 justin_smith: mungojelly: the options allow optional library specific templates

20:45 mungojelly: are those composable? like if you have multiple libraries they can't work together to make you a template for combining them can they?

20:45 justin_smith: not really, I would try making a project from each template and then combining them by hand - you'll quickly find out if it's doable or not

20:46 mungojelly: it feels like complexity to have a program spitting out a bunch of files for me. i feel odd if i want to write a few lines to have a bunch of folders spit out for me and then go into one of them and put my couple of lines and seal it back up. why didn't i just say those few lines and another line that implies the rest of the shit.

20:47 justin_smith: mungojelly: nothing stops you from making a file yourself, putting some crap in it, running "java -jar clojure.jar" to start a repl, and using load-file to load the file contents

20:47 it's just that that doesn't scale well

20:47 so lein tries to make you do the "right thing" from the start

20:47 mungojelly: i don't need to know what target/classes/state/META-INF/maven.. maven this is stuff to tell maven what to do, tahnk god someone's abstracitng over maven for me anyway

20:49 ./resources is just a suggestion for good structure right, like, if you have other assorted resources put them here?

20:49 justin_smith: right - anything in the resources will by default be included with your code if you make a jar

20:50 and that way you can distribute miscellaneous files you need with your code

20:50 target/ is for cached stuff - it is always safe to entirely delete that directory, all it does is hold partial results for multi step builds and speed up startup

20:51 mungojelly: does it treat test/ differently, is that not included in production builds or something?

20:51 justin_smith: it's not included in a jar if you make a jar - but is used when you run "lein test"

21:08 mungojelly: ok well i feel now like i understand what lein new makes for me, but y'all really should look at it with fresh eyes every once in a while and see that there's no simple way here to make and share anything

21:10 on TIOBE clojure is the they-don't-bother-to-count-anymoreth on the list of most popular languages, 51-100 somewhere. number 24 is scratch. scratch is clearly and significantly worse than clojure in i'd say every single respect except one: scratch has a "publish" button which causes the thing you made to be shared.

21:10 justin_smith: mungojelly: lein do jar, clojars

21:11 mungojelly: it's true that clojure's not easy, but the tooling is actually pretty decent once you get over the first few weird aspects

21:11 err, s/clojars/deploy clojars/

21:11 mungojelly: i do fully intend to learn how to do that, but i didn't at any point put any effort at all into learning how to share scratch projects, it just simply has a large "publish" button

21:14 if the instructions for saving a word or pdf document were "it's easy, just say to a terminal "word/adobe save make awesome thing deploy!" and then it'll give you what you need" then there would be very few word or pdf documents in the entire world and they would all be about geeky things

21:18 justin_smith: mungojelly: I refuse to use a language that has the UI paradigm of a word processor, and if clojure adopted that I would stop using clojure

22:12 rritoch: If java class files change is there some way to get clojure to start using the new class files, possibly automaticallly, without restarting?

22:14 mavbozo: rritoch, you mean like vinyasa's reimport https://github.com/zcaudate/vinyasa#reimport ?

22:17 rritoch: mavbozo: Thanks. That is basically what I'm looking for. While not automatic it looks like it'll get the job done. I'll need to read up on that project.

22:21 I was thining of using JRebel, but it's probably useless in clojure due to the interning of classes.

22:22 thining = thinking

22:25 Would it possible to use JNotify with it to automate updates?

22:25 it = vinyasa

22:28 Well this reimport :all looks like it does most of the work, but calling it on every namespace could be problematic.

22:30 kavkaz: zippers saved my life

22:30 or project you could say

22:43 what's up amalloy

22:47 rritoch: mavbozo: Thanks, looks like vinyasa does a lot more than just reimporting.

23:03 aconz2: I'm a soon to be college grad looking for opportunities w/ clojure; would love to chat

23:15 TEttinger: aconz2: there are probably many!

23:16 pad your github with sweet and savory contributions to existing open source projects!

23:20 aconz2: TEttinger: why haven't recruiters just mined github yet?? I will try and do so over the next month

23:20 TEttinger: oh they do

23:20 aconz2: slightly difficult since most of my current work is in Python/C++ land

23:20 TEttinger: I think many people here have gotten unsolicited emails from github miners

23:20 justin_smith: I assume that's where the unsolicited job offers from google in my inbox came from

23:21 well, not straight up job offers, but inqueries or whatever

23:22 TEttinger: for me it's ironic since I think nothing I have done on github is commercially relevant. 466 day streak though.

23:22 aconz2: hah who knew! I think the whole repo-as-a-CV is nice - - but the lack of a shiny github doesn't imply a bad/incompetent dev

23:23 justin_smith: nor does a skimpy resume, but if you have a good resume or a good github account, both are going to get you better results

23:24 TEttinger: yep. it's often a factor in consideration if the company hiring values open source, that or at least some open source contribution (don't need a github account to have a contribution to the linux kernel in the past, for instance)

23:28 aconz2: hard to know what to make public -- random one-off toys/experiemnts? -- and I'm not always using the most bleeding-edge in-need-of-help libs. or I'm naiive

23:29 rritoch: aconz2: The market for clojure developers is very small. When it comes to clojure you usually need to make your own market. Either by developing your own apps under some kind of business model, or applying to non-clojure jobs and convincing your employer that you NEED clojure to develop efficiently since platform X doesn't provide macros or a REPL.

23:29 aconz2: Employers need to be told what to think *evilgrin*

23:31 TEttinger: you can totally be hired as a java dev in some shops and convert them to using clojure bit-by-bit

23:31 assuming they give leeway on certain things

23:31 aconz2: rritoch: which is a con in some respects, but a plus in filtering the market as well. hard to predict what company/role gives that leeway

23:32 TEttinger: https://github.com/rschmitt/collider is a good example of java that is halfway to clojure

23:32 rritoch: aconz2: It isn't a con, a con artist doesn't believe in what he's selling, a good bussiness person does.

23:32 TEttinger: pro and con

23:32 aconz2: pro and con

23:32 words are hard

23:34 rritoch: aconz2: It is really a fact that development in clojure is more efficient, insanely so if your using macros. In one specific example I was able to reduce a specific type of project from 16 hours to 3 hours just by using clojure.

23:38 aconz2: oh I'm already convinced its a good system for certain domains; that's why I'm here :)

23:38 rritoch: aconz2: While I have a lot of "pet" projects, one project I'm toying with is making code generators for clojure, comparable to how clojurescript works, so I can just automate my work in any other language from clojure.

23:38 arrubin: rritoch: You implemented it in Clojure and another language and compared?

23:40 rritoch: arrubin: I've been asked to do these projects in various languages, most average about 16 hours, in clojure I was able to get it down to 3 hours average.

23:50 I also work with common-lisp and have an open-source implementation @ https://github.com/rritoch/jrelisp , it is good for highly mutable algorithms, but fails miserably at multi-threading, since they both run on the JVM they can be used together as long as you don't leak other threads from clojure into it (Since it's multithreading support is garbage).

23:51 Developing common-lisp vs clojure is incomparable, it takes 2X as long to do in common-lisp, and in many cases common-lisp just can't get the job done.

23:51 I'd like to further bridge the two, but lack of funding has put an end to my common-lisp development.

23:57 arrubin: rritoch: How much of that is due to Clojure having the JVM to fall back on?

23:58 TEttinger: common lisp has the JVM too using armed bear common lisp

23:58 so the advantage I assume is due to immutable/persistent data structures and the easier reasoning about state they entail

23:58 rritoch: arrubin: As I stated, the common-lisp implementation runs on JVM.

23:59 arrubin: rritoch: Sure, but does it have the same level of interop?

23:59 I am not trying to be difficult. I have no vested interest in CL.

23:59 Just curious why your claims might be true.

Logging service provided by n01se.net