#clojure log - Mar 08 2013

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

0:00 n_b: and I assume that means last is eager as well?

0:03 alandipert: n_b: correct

0:05 jeremyheiler: Heh. It looks like peek and first + rseq pretty much do the same thing internally.

0:13 RazWelles: Anyone know what this is? -> ArgumentTypeException expected EventHandler`1, got EventHandler .CallSite.Target (:0)

0:18 seangrove: I can't get lein to run a project on my server, works locally though

0:19 Running `lein trampoline with-profile prod run -m zenbox.realtime.worker/start-working` gives an error: "Exception in thread "main" java.lang.ClassNotFoundException: zenbox.realtime.worker/start-working"

0:19 I'm pretty damn certain it's there

0:20 hiredman: seangrove: have tried to load that namespace from the repl?

0:21 seangrove: let me see

0:21 hiredman: most likely there is some error in it, and lein is helpfully trying to run it multiple different ways and failing

0:22 seangrove: Seems like it's working: this is from `lein repl` zenbox.server=> (require 'zenbox.realtime.worker)

0:22 WARNING: list already refers to: #'clojure.core/list in namespace: chinpu.export, being replaced by: #'chinpu.export/list

0:22 Mar 7, 2013 9:23:34 PM com.mchange.v2.log.MLog <clinit>

0:22 INFO: MLog clients using java 1.4+ standard logging.

0:22 WARNING: read already refers to: #'clojure.core/read in namespace: taika.core, being replaced by: #'taika.core/read

0:22 Mar 7, 2013 9:23:35 PM clojure.tools.logging$eval117$fn__123 invoke

0:22 WARNING: (:mailchimp :webhook-url) isn't a valid config

0:22 Resque configuration: {:host nil, :port 6379, :namespace "resque:Zenbox", :max-workers 20}

0:22 WARNING: test already refers to: #'clojure.core/test in namespace: zenbox.realtime.worker, being replaced by: #'zenbox.realtime.worker/test

0:23 sorry, paste vs kill ring...

0:23 Meant to paste https://www.refheap.com/paste/90df986fde178710c065edf40

0:23 Which is obviously redundant after flooding :P

0:25 Any reason why it would think the class isn't there?

0:26 And for some reason, it works locally, but not on a remote server

0:27 hiredman: and when you run start-working?

0:28 seangrove: Trying on the server now...

0:30 ah, yes, I see an error now

0:31 thanks hiredman, I think it comes down to a :source-paths config in project.clj

1:40 danneu1: /quit

1:40 pppaul: no

1:40 (quit)

1:44 frozenlock: Is there an idiomatic way to get a random element from a collection?

1:44 I was thinking (nth coll (rand (count coll))), but it feels kinda icky.

1:45 Oh...

1:45 nvm...

1:45 Thanks nrepl autocomplete :P

1:46 #(source rand-nth)

1:46 ,(source rand-nth)

1:46 clojurebot: #<SecurityException java.lang.SecurityException: denied>

1:46 frozenlock: Damn you bot!

2:09 vurma: So, whats the best way to currently execute commandline processes from clojure?

2:10 Iv found some old blog posts, but i asked just to see if there is anything new on that front.

4:31 tomoj: hmm, when I try to get a browser repl now it seems to load itself recursively

4:36 huh, went away

4:36 I must have been doing something stupid

4:36 hurray, in-ns works!

5:40 ro_st: is there a way i can lazily sort-by?

5:40 i've got a 300 map seq which i'm using sort-by on, with a depth of three sort keys

5:41 and it's taking 12 seconds to sort

5:42 oh, wait. a lazy seq is being passed to the sort. nevermind.

6:15 NeedMoreDesu: Can i REload .class files? I've tried using load with no success.

6:15 noidi: NeedMoreDesu, no

6:15 for that you'll need http://www.jrebel.com/

6:17 NeedMoreDesu: That's the only option? Commercial lib?

6:18 noidi: that's a limitation of the JVM

6:18 NeedMoreDesu: Which is somehow dealt with that lib?

6:19 pwned: they have a way of reloading classes in torquebox/jruby, perhaps they also support that in immutant/clojure

6:20 actually the reloaders are in sinatra and rails

6:20 in ruby you just call load to reload the class

6:21 tomoj: hmm, noone noticed that clojure.browser.dom spews logs to the console?

6:36 clgv: NeedMoreDesu: you could do something like that with classloader artistic ;)

6:37 NeedMoreDesu: you can use that lib as starting point https://github.com/flatland/classlojure

6:40 borkdude: question: does anyone ever use letfn instead of let?

6:42 cemerick: tomoj: always been like that AFAIK. Clearly just an experiment or something.

6:43 clgv: borkdude: only when definining only functions and more than one.

6:47 NeedMoreDesu: clgv: Wow, that's nice. I should try that.

6:49 corecode: is there a better idiom than (apply hash-map (mapcat fn hash))?

6:55 borkdude: corecode smth like this?

6:55 ,(zipmap (keys {:a 1 :b 2}) (map inc (vals {:a 1 :b 2})))

6:55 clojurebot: {:b 3, :a 2}

6:56 borkdude: corecode you can also use into here: http://stackoverflow.com/questions/1676891/mapping-a-function-on-the-values-of-a-map-in-clojure

6:57 noidi: into + for is a very common idiom

6:58 corecode: yea

6:58 i noticed

6:59 in the end i used ->>, map, into

7:00 is there something like #(->> % ...)? something that will take the passed arguments and apply in sequence? comp is close, but doesn't allow for partial functions

7:19 NeedMoreDesu: clgv: Yeah, I can have new clojure in clojure now. Bad thing, is that they don't reload inside classlojres.

7:20 clgv: NeedMoreDesu: my idea was that you do reloading by using a new classlojure with the same classpath - this way you should end up with the most recent class

7:21 NeedMoreDesu: and you always eval in the current classlojure...

7:22 NeedMoreDesu: clgv: Yeah, that sounds like it can work that way.

7:22 But I'm afraid of one thing: is it gc'd right?

7:24 I'll try to loop to check this out.

7:24 clgv: NeedMoreDesu: humm, that boils down to the question whether a classloader that is not referenced anymore gets gc'ed with all its classes and objects...

7:24 jcrossley3: NeedMoreDesu: you might look at Byteman as an open-source alternative to jrebel: http://www.jboss.org/byteman

7:24 not exactly the same, but possibly helpful

7:24 NeedMoreDesu: OutOfMemoryError PermGen space java.lang.ClassLoader.defineClass1 (ClassLoader.java:-2)

7:25 tomoj: is there some way not to have all the internal protocol fns in cljs.core?

7:25 clgv: NeedMoreDesu: humm? what exactly did you do?

7:25 tomoj: I guess I mean, not to have them auto-referred in all user namespaces

7:25 NeedMoreDesu: (loop [l 50000] (eval-in (classlojure "file:/D:/end06/cloj-reload/target/the.jar") '(do (load "/tratata") (eval 'tratata/nya))) (if (< 0 l) (recur (- l 1))))

7:27 clgv: ok, you do not hold references to them in this code explicitely. does it work with a (System/gc) in every iteration?

7:32 NeedMoreDesu: clgv: nope, it still hits the memory limit.

7:34 clgv: NeedMoreDesu: hhmm its pretty likely that you need to remove the classloader from its parent

7:34 NeedMoreDesu: Maybe thats because (System/gc) is not forcing gc, and it dies as soon as it have no memory.

7:34 Huh, how do I do that?

7:35 But well, no, it's not late gc problem.

7:36 clgv: NeedMoreDesu: classlojure.core/ext-classloader is the parent

7:37 ro_st: is there a clojure core fn that does this? (fn [bool] (if bool 1 0))

7:38 clgv: ro_st: dont think so

7:38 $findfn true 1

7:38 $findfn false 0

7:38 lazybot: []

7:38 []

7:38 ro_st: thanks

7:38 clgv: &(clojure-version)

7:38 lazybot: ⇒ "1.4.0"

7:40 NeedMoreDesu: clgv: So I need to write something to remove it from the parent? Is that possible?

7:41 clgv: NeedMoreDesu: I dont know. afaik you might be forced to write a classloader yourself that can remove its children. but that is just guessing...

7:41 NeedMoreDesu: what is your exact use case?

7:42 clojure's dynamicclassloader allows redefinition of classes which is used for deftype and such...

7:43 NeedMoreDesu: http://stackoverflow.com/questions/148681/unloading-classes-in-java

7:43 NeedMoreDesu: I want to have some extension points in code, and to be able to hot-update those.

7:44 clgv: and the extensions are provided by java classes and not clojure files?

7:44 NeedMoreDesu: By .class files.

7:44 Yes, .clj would be easy.

7:44 clgv: clojure files would have been trivial ;)

7:45 llasram: You can't ever *really* replace a Java class -- just load a new one with the same name

7:46 clgv: llasram: right. you notice that when your previous deftype instances don't work anymore after reloading the namespace with the deftype^^

7:47 llasram: Or at least you can't without doing especially crazy stuff. I think there are some commercial dev-oriented tools for hot-patching code in a running JVM

7:47 clgv: Ah, right. I should read more than a few lines of context before piping up

7:53 NeedMoreDesu: Hm, maybe I need to read classlojure code closely to find out what can be done.

7:55 clgv: NeedMoreDesu: I think you need the own classloader that can remove its child classloaders. then you could put that one between classlojure.core/ext-classloader and the classloaders created by classlojure

7:56 NeedMoreDesu: but what llasram said remains true, existing objects wont be hot-patched and not even accessible in the new classlojure classloader

7:59 NeedMoreDesu: Yeah. I've just tested that. eval-in returns strings.

7:59 clgv: NeedMoreDesu: huh?

8:00 NeedMoreDesu: (eval-in (classlojure "file:/D:/end06/cloj-reload/target/the.jar") '(do (load "/tratata") tratata/nya)) returns "#<tratata$nya tratata$nya@d81e23>"

8:01 clgv: NeedMoreDesu: ah ok they implemented that to work around the issue that you cannot return custom classes...

8:01 but you can serialize resultdata to string^^

8:01 NeedMoreDesu: lol

8:09 clgv: NeedMoreDesu: well, it seems as if classlojure serializes to string and reads from it again if possible

8:16 NeedMoreDesu: clgv: suddenly: (eval-in (classlojure "file:/D:/end06/cloj-reload/target/the.jar") '(do +) 1 2 3) => 6

8:18 kittylyst: Am having trouble with a restructuring form:

8:18 (defn map-from-httpd-logline [l]

8:18 (for [[full ip j1 j2 datetime req retcode size] (re-seq logline-regex l)]

8:18 (let [[f2 base params] (re-seq uri-regex req)] {:f2 f2 :ip ip :datetime datetime :req req :retcode retcode :size size :uri-base base :uuid ()})))

8:19 base ends up null, and f2 ends up with the entire vector

8:19 Any ideas what I'm doing wrong?

8:21 stuartsierra: kittylyst: Check that the return value of `re-seq` is what you think it is.

8:22 kittylyst: Aha! So it is returning a vector, and needs to be wrapped in an (nth)

8:22 s/vector/lazy seq/

8:23 stuartsierra: You may want `re-find` instead of `re-seq`.

8:30 kittylyst: stuartsierra: That's cleaned it up a bunch - thx. Good to see you btw.

8:31 stuartsierra: kittylyst: Same to you

8:35 NeedMoreDesu: clgv: (loop [] (let [^URLClassLoader cl (url-classloader ["file:/D:/end06/cloj-reload/target/the.jar"] ext-classloader)] (.loadClass cl "clojure.lang.RT") (eval-in* cl '(+ 2 3 4))) (System/gc) (recur)) -- (eval-in* cl '(+ 2 3 4)) is causing memory leaks

8:36 And there was '(require 'clojure.main) there

8:36 clgv: NeedMoreDesu: that was what I was talking about. you need an own classloader to be able to remove "old" classloaders you do not need anymore...

8:37 NeedMoreDesu: It works totally fine without that eval

8:37 No leaks

8:37 clgv: NeedMoreDesu: hence the initial comment of "classloader artistry" ;)

8:38 NeedMoreDesu: the "leak" is due to the fact that you do not remove that classloader from the classloader tree

8:39 NeedMoreDesu: When is it added there?

8:39 clgv: NeedMoreDesu: I am interested in this as well. but I have no spare time in the next days...

8:40 NeedMoreDesu: Oh, ok, sorry.

8:40 clgv: NeedMoreDesu: it is added in the `url-classloader` call

8:40 NeedMoreDesu: clgv, yet its totally ok to (loop [] (let [^URLClassLoader cl (url-classloader ["file:/D:/end06/cloj-reload/target/the.jar"] ext-classloader)] (.loadClass cl "clojure.lang.RT")) (System/gc) (recur))

8:41 It loops with no leaks.

8:43 clgv: NeedMoreDesu: thats because nothing is done. when you write it like that the class clojure.lang.RT is already loaded

8:48 NeedMoreDesu: hmm forget that last statement. it is loading the RT class

9:14 ambrosebs: Does this chrismgray happen to be around? https://github.com/chrismgray

9:14 In the chat I mean.

9:17 corecode: should i be using (line-seq (java.io.BufferedReader. *in*)) or (iterate read-line)?

9:31 stuartsierra: corecode: I don't think it matters.

9:32 But eventually you'll run into trouble if you're trying to read STDIN during a REPL session.

9:32 corecode: yea

9:48 jcromartie: someone help me stop overthinking everything

9:48 I just want a simple web API that keeps state in memory and writes it to disk when it changes

9:48 so, let me think out loud here

9:48 I'll have a web namespace, a data namespace, with top-level vars holding refs for the things that change?

9:49 where to put the refs, should I pass them explicitly to the functions that add/remove/update the data model?

9:49 should I just rely on bindings?

9:49 I don't want to be a pure-functional weenie

9:50 stuartsierra: Step One: no top-level Vars.

9:50 Pass the refs through your entire application.

10:03 solussd: could someone tell me why (binding [*ns* (create-ns 'another.namespace)] (defn blah [x] (println "hi"))) doesn't define another.namespace/blah, but instead adds it to my current namespace?

10:04 stuartsierra: All `def` forms use the *ns* binding in effect when they were *read*, not when they were evaluated.

10:04 If you want to create Vars in another namespace, use the `intern` function.

10:04 solussd: ah, thanks a lot.

10:04 stuartsierra: np

10:15 NeedMoreDesu: clgv: http://www.everfall.com/paste/id.php?ksikmr2fd38y thats where I'm now. I've dug those things and found out that commented line causes memory leak.

10:17 jtoy: is there a way i can see what version of library is loaded?

10:18 or does lein 1.x automatically install a newer version if i just do lein repl ?

10:19 NeedMoreDesu: Definetely no, because you can use old features.

10:21 jtoy: i founde some really f*cked up clojure/json issue, when i load some certain json with chesire, it interprets the data as an integer

10:21 stuartsierra: jtoy: With Leiningen 2.x you can call `lein deps :tree`. There was a plugin for that in lein 1 I think.

10:22 jtoy: stuartsierra: hmm, I just did lein repl and it installed the newer dependencies, weird

10:22 stuartsierra: jtoy: Are they -SNAPSHOTs? Those get updated automatically.

10:24 solussd: stuartsierra: is it possible to associate metadata with the var that is created with intern? If I use meta instead of defn I'd still like to associate a docstring in the var metadata

10:24 jtoy: stuartsierra: my project has snapshot in it: "1.0.0-SNAPSHOT" but I jsut changed [cheshire "4.0.0"] to [cheshire "5.0.2"]

10:24 stuartsierra: solussd: Yes, see the docstring of `intern`.

10:25 jtoy: So when you change the dependency, Leiningen downloads it the next time it runs.

10:26 jtoy: stuartsierra: thanks for the explanation

10:26 stuartsierra: np

10:27 solussd: stuartsierra: thanks again- i misunderstood the first time I read the doc. :)

10:27 stuartsierra: np

10:30 jtoy: I need to do type checking for some of my data, bc im finding bad data coming into my system, is it idiomatic to be doing (= (type data) clojure.lang.PersistentArrayMap) ?

10:31 the data is coming from cheshire json, sometimes I get bad json and cheshire parses it as an integer instead

10:31 stuartsierra: jtoy: You can usually use predicates like `list?` and `map?` more easily.

10:32 jtoy: stuartsierra: yes, a lot more concise, thx

10:45 clgv: NeedMoreDesu: humm afair thread local data could be the problem - there should be initialized thread local bindings when you load clojure

10:48 NeedMoreDesu: http://immutant.org/news/2012/05/18/runtime-isolation/

10:50 solussd: does anyone know what happened to clojure.core/protocol?

10:54 clgv: solussd: you mean defprotocol?

10:56 solussd: clgv: no, the predicate "protocol?", which tested if something was a protocol

10:57 clgv: solussd: did no know that it existed

10:58 tomoj: with the current protocol impl, that would be a very odd predicate

10:58 solussd: tomoj: did the implementation recently change?

10:58 tomoj: since a protocol is just a hash-map from clojure code

10:58 I dunno

10:58 solussd: CompilerException java.lang.IllegalStateException: var: clojure.core/protocol? is not public

10:58 still there.. just can't use it. :/

10:58 tomoj: (boolean (:on-interface maybe-p))

10:59 like I said, very strange

10:59 there's a reason it's private :)

10:59 solussd: i wondered about doing that, but it probably wouldnt work in clojurescript, given the lack of interfaces

10:59 tomoj: (that is the implementation of protocol? btw)

11:00 solussd: but they took it away from me! I was using it

11:00 algernon: it never was public, as far as I can see in git history

11:00 solussd: interesting.. I have some macros that do different things based on whether you pass them a protocol or otherwise.

11:00 even more interesting... wonder how I was ever using it. :/

11:00 tomoj: those macros sound evil

11:00 maybe I misunderstand

11:01 solussd: it's a conspiracy- the clojure.core team is rewriting [git] history!

11:01 tomoj: they're not, let me assure you. :)

11:01 clgv: solussd: dont they use signed commits?

11:01 tomoj: you resolve the symbol yourself and check if it's a protocol?

11:01 solussd: no more evil than the 'defrecord' macro or 'extend-protocol' or 'extend-type'

11:02 clgv no idea, I was just kidding

11:03 tomoj: they don't use protocol?

11:03 extend does, which is a function, not a macro

11:04 oh, do you mean you just call protocol? in the code the macro expands to?

11:07 borkdude: Isn't this old news on hackernews about the clojure reader

11:11 mpfundstein: is it possible to tell lein/clojure which java sdk to use? i have boht installed jdk 1.7 and 1.8 and need to use 1.8 for some project while 1.7 for another

11:12 nDuff: borkdude: Yes, very -- that's why we have EDN.

11:14 trptcolin: mpfundstein: you can set the environment variable JAVA_CMD

11:15 afaik it's not possible to specify in project.clj - it'd be a bootstrapping problem

11:17 jcromartie: stuartsierra said, a while back, that I should pass the refs through the app, and not have any top-level vars

11:17 but what about a web app, where the request only has the context of what came into the server?

11:17 surely I would have to "inject" the right refs into my functions inside the handler

11:18 but it does make sense… so, lilke, (defn add-foo [db foo] (dosync (alter db conj foo)))

11:19 and in the future, if db is an actual DB spec, I can change add-foo to do the relevant SQL calls

11:19 seems like a sane way to do it

11:20 and just use dynamic bindings around the handlers to access the refs?

11:20 danneu: what's the most popular way to generate sql with clojure?

11:20 jcromartie: i.e. (GET "/foos" [] (get-all-foos *db*))

11:21 tomoj: you can't really extend a protocol to functions

11:22 :(

11:22 nDuff: Hrm.

11:23 papachan: if i do (def n (25)) (println (/ n 2)) my output result is 25/2

11:23 why not my result?

11:23 * nDuff is getting truncated stack traces (using Avout in Clojure 1.5; trace not going past the alter!! call)

11:24 nDuff: papachan: That _is_ your result. If you want to cast it to a float, you need to do that explicitly.

11:24 papachan: nDuff thank you

11:24 tomoj: https://www.refheap.com/paste/94cd84ee74f05fed4e634b9a9

11:24 papachan: is there a math.ceil o math floor in cloj?

11:24 nDuff: ,(type (/ 25 2))

11:24 clojurebot: clojure.lang.Ratio

11:25 nDuff: ,(java.lang.Math/ceil (/ 25 2))

11:25 clojurebot: 13.0

11:25 papachan: clojure.lang.Ratio

11:26 waow, clojurebot is the repl here in irc?

11:26 borkdude: papachan I tend to use ##(int 132.32)

11:26 lazybot: ⇒ 132

11:26 NeedMoreDesu: clgv: thats integesting. I think I should have a look on their project.

11:26 tomoj: oh, and functions with metadata always apply in cljs..

11:27 clgv: NeedMoreDesu: unluckily they do not seem to use the removeThreadLocal function they define...

11:28 corecode: i'm trying to learn clj by processing some data i have, but it is being really slow (compared to a ruby implementation). could somebody give me some feedback on how to improve the code? https://gist.github.com/5117660

11:28 solussd: tomoj: yeah< i just call protocol? in the expansion

11:31 NeedMoreDesu: clgv: isn't using their runtime is enough?

11:31 clgv: NeedMoreDesu: probably not since they are doing something quite similar to classlojure...

11:31 llasram: corecode: Monolithic contrib is dead post version 1.2, which is ancient by this point. You should be able to just use (line-seq *in*) though

11:32 tomoj: solussd: so hopefully it's not reasonable to pass a non-protocol map with :on-interface key to that function?

11:32 corecode: llasram: fair enough.

11:32 tomoj: /macro-missing-a-function

11:32 clgv: NeedMoreDesu: but you can try. let me know if you succeed

11:32 corecode: llasram: i doubt that's the cause for slowness tho

11:32 solussd: tomoj: yeah, it isnt-- I'm just nitpicking at this point. :)

11:32 tomoj: then I retract my 'evil' estimate

11:33 llasram: corecode: I somehow missed your mention of an apparent performance problem... How large is the dataset? Are you sure the slowness isn't just JVM startup time?

11:33 solussd: ;)

11:33 corecode: llasram: 2 million lines

11:34 llasram: i couldn't wait for it to finish yet

11:35 llasram: i'm doing roughly 1000 lines per second, which is just way too slow

11:36 llasram: corecode: I'm not sure if this has performance implications, but is `:hosts` vs `names` a bug?

11:36 nDuff: Hrm.

11:36 corecode: ah i renamed stuff

11:36 :/

11:36 llasram: corecode: And FYI, `name` is the name of a `clojure.core` function. Aliasing works, but is a source of potential confusion/bugs

11:36 corecode: it was slow anyways

11:37 * nDuff gets his full stack trace, and eyes Avout (which was claiming that alter!! was called without an enclosing dosync!! -- a claim that stack trace denies) warily.

11:37 corecode: line-seq *in* doesn't work :/

11:38 fbernier: so, let's say I fall on a lib on github and I'd like to give it a quick try in the REPL, how is this possible?

11:39 do I need to create a new project, add it as a dependency, lein deps, launch the repl, import it and use it?

11:40 tomoj: I note that prismatic's graph works by putting metadata on fns

11:40 and relies on extending protocols to Fn

11:40 llasram: corecode: Is it a requirement to use *in* BTW? It's generally more common to operate on explicit file paths vs using stdin, although that may just be a side-effect of REPL-based development

11:41 blrm: fbernier: that is what I would do, yeah

11:41 corecode: llasram: not strictly

11:47 llasram: https://gist.github.com/5117884

11:47 llasram: still very slow :/

11:49 jweiss-afk: if i update a function in a var, i notice other functions calling it from partial do NOT use the new version, whereas functions calling it from #() or (fn ...) do get updated. why?

11:49 llasram: corecode: Hmm. I don't see anything obviously slow about the code :-/

11:51 jweiss: When you call partial, you pass the function as a value, which the returned function holds a reference to as a lexically-scoped local

11:52 jweiss: When you call the function via its var in an function created with fn (or #()), the new function references the original function via its var, which is updated with the new value on recompilation

11:52 papachan: oh my

11:53 ystael: llasram: is this ultimately a syntactic distinction between the head slot and other slots of an application form? or does it come from some other feature of the context?

11:54 jweiss: llasram: it was not at all obvious to me that fn used the var and not the value

11:54 corecode: llasram: odd, odd

11:55 jweiss: i think this totally reverses my preference for partial over fn. crap

11:55 partial doesn't generate new classes when you precompile, so i thought that was good enough reason for me to use it

11:56 but clearly it is less dynamic, i hadn't realized that

11:56 corecode: llasram: oh could it be that println is super slow?

11:56 llasram: ystael: Other. `partial` is a function, and when passed something as an argument, receives the value, which is what the created function has available to reference. `fn` is a special form (well, `fn*` is anyway), which creates a new JVM class, the code of which references everything resolving to vars via those vars

11:57 tomoj: symbol-macrolet with regexes. evil?

11:57 ystael: llasram: i see, thank you!

11:57 jweiss: arrggghh. why did it take me so long to realize this

11:57 llasram: corecode: It's possible. println -> prn -> pr -> print-method, which is a multimethod. Calling (.write *out* (str from-id " " to-id " " link-count "\n")) instead is something to try

11:58 corecode: i mean, that printing is in part just debugging

11:58 but i didn't realize it would be that slow

11:58 llasram: corecode: Oh. Hells yeah. IO is always slow. Especially in w/ strings Java vs other languages, because you always have UTF-16 -> whatever conversion

11:59 jweiss: You can always explicitly pass the var to partial: ##((partial #'+ 2) 2)

11:59 lazybot: ⇒ 4

11:59 solussd: nothing is evil if 1. you know what you're doing, 2. it is the "best" way to do it- best defined by these three things, in this order: 1. reduces repetition in your codebase so changes in the future don't require hunting down a bunch of duplication, 2. follows idioms of the language, 3. is readable to user's of the language. ;; made up on the spot. :D

11:59 nDuff: Hrm. avout's setRef and alterRef don't handle transactions in RETRY state so well...

12:00 clgv: NeedMoreDesu: yourkit java profiler points to the thread local variables as well. I profiled that one: (loop [] (eval-in (classlojure "file:///home/gv/.m2/repository/org/clojure/clojure/1.3.0/clojure-1.3.0.jar") '(clojure-version)) (recur))

12:00 corecode: llasram: write is equally slow

12:00 interesting.

12:00 the read seems to be quick

12:00 jweiss: llasram: interesting, seems like most clojure programmers eschew partial, i liked it ... until now. i'll have to decide if using the var is uglier than just using fn or #()

12:01 solussd: i love partial and comp- I try to avoid anonymous functions when possible

12:01 TimMc: (:refer-clojure :rename {partial pl}) or somethign

12:02 llasram: corecode: *out* is a line-buffered PrintWriter... You could try writing to a file via a fully-buffered io/writer instead.

12:02 papachan: why i cannot pass arguments to my function through script args?

12:02 https://www.stypi.com/papachan/main.clj

12:03 corecode: llasram: i'll try that.

12:03 llasram: corecode: Now that you've mentioned it, I have noticed that writing to *out* has seemed to be slower than I'd expected in the past

12:03 corecode: it is incredibly slow

12:03 llasram: corecode: But I didn't investigate further

12:03 corecode: i bound *flush-on-newline* to false (dunno if that is the right way to do it)

12:03 tomoj: solussd: hmm, regex-based symbol macros certainly don't follow the idiom

12:03 corecode: but that didn't help either

12:04 solussd: that's the second requirement though. :D

12:04 tomoj: although datomic cares about the prefix of symbols in query data

12:04 but that's just data..

12:05 incidentally I think a regex symbol macrolet could let you get syntax quote for datomic queries without breaking vars?

12:28 jtoy: why can you only do 2 arguments?

12:28 (if-let [x false y true] "then" "else")

12:28 corecode: llasram: yes, *out* seems to be extremely slow.

12:28 jtoy: and is there a better way to test with multiple variables? instead of multiple if-let's ?

12:29 technomancy: jtoy: there's never been consensus on whether the two logical values should be anded or ored together

12:31 jtoy: i want to do multiple lets where there next variables are bui previous, so that would be an and, can i still do that with one if-let ?

12:31 my terminal looks messed up

12:31 i dont think i can do it though

12:32 clgv: jtoy: just write your own `if-let-all` - then semantics are clear and you get what you want

12:33 TimMc: jtoy: https://github.com/timmc/handy/blob/develop/src/org/timmc/handy.clj#L8

12:33 jtoy: yeah, i will do that later, im not at the level where i feel comfortable writing my own macros

12:33 nice TimMc

12:36 ivan: if-all-let should AND and if-any-let should OR

12:36 jtoy: ivan: agreed!

12:36 TimMc: I've never wanted if-any-let.

12:36 ivan: right. I suspect no one would use it.

12:41 frozenlo`: "HN: Clojure's Default Reader is Unsafe "http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html#post-body-2898830171141471587

12:42 Hey got #=ed :P

12:42 Well, not a 'real' situation, but still.

12:43 solussd: could someone tell me why, on line 9 of this paste, x# cannot be resolved? (happens when you call the macro) https://www.refheap.com/paste/87d84be6d7ed8d1f3af54d677

12:44 Bronsa: solussd: lexical bindings don't work in defrecord/deftype AFAIK

12:45 cctennant: hey everyone, question about try/catch. I've got a try/catch around a cassandra cql statement execution inside compojure/ring. an (expected) exception gets thrown deep within netty, but I can't catch it — it appears to blow right past my (catch Throwable e) and shows up in my log file as a WARN: An exception was thrown by an exception handler.

12:45 solussd: well crap.

12:46 where is that documented. :P

12:46 Frozenlock: solussd: In #clojure, the official clojure doc.

12:47 Bronsa: solussd: "Note that method bodies are not closures, the local environment includes only the named fields, and those fields can be accessed directy."

12:48 in the docstring of defrecord

12:50 llasram: cctennant: Are you sure the exception is being thrown where you think it's being thrown from? Lazy sequences in particular can result in evaluation not actually occurring in the obvious lexical scope

12:51 cctennant: that's an excellent point. I have seen that before, with lazy seqs getting evaluated much later. in this case though I can see from the stack trace (which is getting dumped by something at WARN level) that the exception is happening where I think it is

12:52 I went so far as to code this: (try

12:52 (cql/execute-raw (str "use \"" keyspace "\""))

12:52 (catch Throwable e (println "caught exception inside binding " e) (throw e)))

12:52 technomancy: async error handling is a nightmare =\

12:53 cctennant: the exception is getting thrown at the (cql/execute-raw.. line, from the stack trace. but that Throwable doesn't catch s..t.

12:54 mpenet: it's datastax driver? anyway it's very likely to be an encoding/decoding issue

12:55 cctennant: yeah. datastax with some mods, it's not quite ready from prime time yet. driver works great — app is working, I'm just having this problem here.

12:55 mpenet: cctennant: most of the times you're better off using prepared statements with this driver, it will handle the encoding stuff for you and prevent these kind of errors

12:55 not to mention you dont pay for the query parsing everytime this way

12:56 cctennant: shamless plug: check https://github.com/mpenet/alia , it handles error nicely in asyn mode at least (you can provide an error callback)

12:56 cctennant: sure, but that still doesn't explain why it's not catching the exception. surely that's a straight up clojure/java problem? an exception is being thrown, but it's not being caught. it shouldn't matter what's throwing the exception (which is actually a java.util.concurrent.RejectedExecutionException fwiw, again, expected)

12:56 llasram: cctennant: Hmm. Is the exception being thrown from the same thread?

12:57 cctennant: aha

12:57 that may be it.

12:57 netty and async io.

12:57 doh.

12:58 thank you.

12:58 corecode: llasram: https://gist.github.com/5118449

12:58 llasram: how does that look?

12:59 llasram: cctennant: eyes, bugs, shallow, etc

13:01 corecode: Did replacing *out* speed things up? Idiom-wise -- you rarely/never want to call functions in namespaces you haven't yourself `require`d; and although (doall (map ...)) works, arguably `doseq` would be more clear, expressing the side-effect only intent

13:02 corecode: llasram: yes, writing to a file is enormously faster

13:03 llasram: i just replaced it with dorun; how would i use it with doseq?

13:03 use (doseq [... (->> ...)] ...) ?

13:04 llasram: Exactly

13:04 corecode: that sort of inverts the logical flow of operation though

13:04 or at least rips it up

13:05 llasram: That's true. I caged with "arguably" :-). Using `dorun` is probably the way to go

13:05 corecode: yea

13:05 thanks

13:05 jtoy: what is the proper way to convert this data to numbers? (map #((Long. %)) ["123" "543"])

13:05 llasram: corecode: np. I'm glad you figured out the perf problem

13:06 TimMc: jtoy: Yo uhave tto many parens around the Long. constructor.

13:06 corecode: llasram: that's scary stuff. who would have thought that java stdout is so extremely slow?

13:06 llasram: jtoy: usually Long/parseLong

13:06 TimMc: And I have keyboard issues.

13:06 jtoy: what is the proper way to convert this data to numbers? (map #(Long. %) ["123" "543"])

13:06 corecode: using writer System.out does not help either

13:06 jtoy: I see, is it better to use parseLong or Long is fine?

13:07 neotyk: good morning everyone

13:07 llasram: corecode: Yeah... I'm not really sure where that would come from. *files away to investigate in the future*

13:09 TimMc: jtoy: People generally use parseLong.

13:10 llasram: jtoy: Depends on context... If you might be able to use a primitive, parseLong does return the primitive. Auto-boxing (or explicitly calling Long/valueOf instead) may introduce optimizations by making use of an implementation cache of Long objects frequently-used numbers

13:12 This may not be true, but at least naively, calling the Long. constructor directly will always yield an entirely new object

13:20 kencausey: Does it make sense that searching duckduckgo for clojurescipts returns https://github.com/emezeske/clojurescript/ as the canonical URL?

13:20 jcrossley3: Bronsa: why is aot compilation required for clojure.tools.reader?

13:20 kencausey: s/clojurescripts/clojurescript/

13:20 Bronsa: jcrossley3: clojure.tools.reader.impl.ExceptionInfo needed for clojure 1.3 compatibility

13:21 and that's the only namespace that needs to be AOT compiled actually

13:22 jcrossley3: but there are a lot more in there than that

13:22 class files in the jar, i mean

13:27 Bronsa: jcrossley3: I don't think you can AOT compile only a namespace with maven like you can do in lein

13:29 jcrossley3: it looks like you actually can, I'll try to figure out how

13:29 jcrossley3: Bronsa: is aot the only option for 1.3 compat? could you reify j.l.Exception instead maybe?

13:29 Bronsa: Exception classes MUST get AOT compiled

13:30 mmh

13:30 hiredman: you cannot reify Exceptions

13:30 Exceptions have no interfaces

13:30 you have to gen-class

13:30 jcrossley3: what version of clojure?

13:30 have you looked at ex-info/ex-data ?

13:31 Bronsa: hiredman: he was asking regarding of my AOT compiling in tools.reader

13:31 hiredman: :(

13:31 aot compiling libraries is horrible

13:32 locks them to a single clojure abi

13:32 jcrossley3: yeah, i'd like to use tools.reader in immutant, but the aot classes are yielding strange errors in our runtime (which might support any version of clojure since 1.3)

13:32 Bronsa: that's the only way I can provide support for clojure 1.3 without giving up on ex-info/ex-data

13:32 jcrossley3: i need to dig in further. just trying to understand the reasoning behind them being there.

13:33 Bronsa: jcrossley3: I'll release another version with only ExceptionInfo AOT compiled once i can figure it out

13:33 technomancy: why not spin off ex-info-1.3 into its own lib?

13:33 jcrossley3: Bronsa: thx

13:33 technomancy: you're probably not the only one to want it

13:33 hiredman: technomancy: cause this is contrib, and doing that kind of thing is a pain

13:33 technomancy: oh

13:33 welp

13:34 Bronsa: that :(

13:34 abp: propose ex-info-1.3 as contrib library. :)

13:35 hiredman: it would be great if you could just slingshot, since it takes care of this for you

13:48 jtoy: should this work: (for [x iterable] (println "EACH" x)) I dont see anythig when I do that

13:49 nDuff: jtoy: it creates a lazy sequence

13:49 jtoy: so it won't print anything until you realize it.

13:50 jtoy: ...if you want side effects, use doseq instead of for.

13:50 alandipert: jtoy: 'for' is lazy, see 'doseq'

13:50 jtoy: ok

13:50 frenchyp: are there native clojure projects to interact with avro and hadoop, or do they wrap the java api?

13:51 Bronsa: jcrossley3: I think i got it

13:52 papachan: is it this correct? -> https://www.stypi.com/papachan/main.clj

13:52 jcrossley3: Bronsa: cool. this will be 7.3? soon-ish?

13:52 Bronsa: jcrossley3: as soon as I see test-matrix passes :)

13:53 jcrossley3: sweet

13:55 Raynes: Wow.

13:55 How many pastebins are there?

13:55 clojure-new: Hello, how can achieve this: (update-in {:entries '(1 2 3)} [:entries 0] inc) => {:entries '(2 2 3)}?

13:56 Raynes: As soon as I think I know them all, someone finds another one to use.

13:56 technomancy: clojure-new: needs to be a vector, not a list

13:56 Raynes: You really don't want to update a list by index.

13:56 clojure-new: technomancy: Yay, thanks.

13:57 corecode: should i be using (. method obj args) or (.method obj args)?

13:58 cemerick: corecode: the former is generally only emitted by macros, if that

13:58 corecode: ah ok

13:58 or rather (.. obj (.method args))?

13:59 cemerick: .. is a specialized threading macro for interop purposes; -> has taken its place except for rare circumstances (e.g. involving static method invocations)

14:00 If you just want the transliteration of object.method(args), then (.method object args) is it.

14:01 jtoy: what is the correct way to convert clojure.lang.PersistentVector$ChunkedSeq to a string? I do (str variable) but it adds chacters to it

14:02 Bronsa: , (.getName clojure.lang.PersistentVector$ChunkedSeq)

14:02 clojurebot: "clojure.lang.PersistentVector$ChunkedSeq"

14:02 corecode: cemerick: thanks!

14:03 jtoy: the string I am starting from is : "45\tyes,45,no,20" and I do (clojure.string/split (next (clojure.string/split string #"\t") #","))

14:03 Bronsa: jcrossley3: released 0.7.3, let me know if it works for you

14:04 jcrossley3: Bronsa: wdm

14:04 Bronsa: jcrossley3: it's not on central yet though

14:04 jcrossley3: i can install locally

14:05 jtoy: this is what I'm trying to do: (clojure.string/split ( next (clojure.string/split "1081\tyes,45,no,20" #"\t") ) #",")

14:07 and if i explicitly turn it into a string, gargage gets added: (clojure.string/split ( str ( next (clojure.string/split "1081\tyes,45,no,20" #"\t") )) #",")

14:09 dabd: is there any tail file utility for clojure that anyone is willing to share?

14:11 chronno: jtoy: (clojure.string/split "1081\tyes,45,no,20" #"\t|,")

14:12 jtoy: chronno: i guess I could do it that way, but it would be useful to understand why the other way doesnt work

14:15 chronno: jtoy: you are passing a ChunkedSeq as the first argument to split. What you want is to split the elements inside the sequence, no the sequence itself

14:15 chronno: in this case, the first element should be enough

14:16 jtoy:^^

14:16 jtoy: (clojure.string/split (first (next (clojure.string/split "1081\tyes,45,no,20" #"\t"))) #",")

14:16 amalloy: really if you want to split a string into "first part" and "rest part", pass string/split the extra optional numeric arg telling it how many splits to do

14:17 cemerick: jtoy: What's the question? next returns a seq, not a string.

14:17 amalloy: (-> "1081\tyes,45,no,20" (string/split #"\t" 2) (second) (string/split #","))

14:18 cemerick: holy laggy irc! :-P

14:19 NeedMoreDesu: ClojureRuntime.class.getClassLoader() -- how do I write this in clojure?

14:20 (. ClojureRuntime class) don't work

14:20 arcatan: now that *read-eval* is in the news, in what kinds of situations it's useful?

14:20 technomancy: NeedMoreDesu: I think calling .class in Java is just a weird quirk of the language since it's difficult for some reason to refer to classes directly.

14:21 NeedMoreDesu: in Clojure you can refer directly to the class without the extra call

14:21 NeedMoreDesu: technomancy: oh, really. Thanks.

14:21 auser: hey all

14:21 technomancy: Java is so weird

14:22 stuartsierra: arcatan: *read-eval* lets you construct arbitrary data structures at read-time, which is what makes *print-dup* possible.

14:23 The #= macro was never officially documented, but widely known.

14:24 amalloy: technomancy: it's easier to refer to int[][].class in java than in clojure :P

14:24 drewc: "the #1=(programmable . #1#) programming language"

14:24 NeedMoreDesu: stuartsierra: mostly besause it is causing security problems.

14:25 stuartsierra: It's just like what we went through with JSON, then YAML.

14:25 It will doubtless happen again.

14:25 technomancy: amalloy: again with the weird thing

14:25 stuartsierra: JSON?

14:25 gozala: Does clojure exports all the top level definitions by default ?

14:26 technomancy: YAML at least had it documented from the outsed

14:26 outset

14:26 stuartsierra: technomancy: Yeah, back in the dark ages when people used to call `eval` in JavaScript to "read" JSON.

14:26 hiredman: gozala: nothing is "exported"

14:26 technomancy: stuartsierra: that's not JSON though; that's JSONP

14:26 hiredman: gozala: you can refer things from other namespaces if you want

14:26 stuartsierra: Yeah, we know that NOW...

14:26 guestttt: hi there, I was curious - why does clojure employs macros and eager evaluation instead of implicit quoting and optional evaluation (as rebol does for example)

14:29 gozala: hiredman: ok so I meant you can import / use top level definitions form other namespaces ?

14:30 `fogus: guestttt: Clojure's heritage is more in Common Lisp and Scheme rather than something like Kernel.

14:30 gozala: if so what's ^:export for ?

14:30 hiredman: ^:export is a clojurescript thing

14:30 gozala: hiredman: yeah that's why I'm confused :)

14:30 hiredman: it tells the google closure compiler not to mangle the name so it is callable from other javascript libraries

14:31 gozala: oh I see

14:31 hiredman: the name mangling only happens if you do advanced optimizations I believe

14:32 TimMc: stuartsierra: The funny thing is that JSON has *never* been a subset of JS, so eval is a broken way of doing things anyhow. :-P

14:32 stuartsierra: All software is broken. Some of it is useful. ;)

14:33 TimMc: eval is fine for JSON config files.

14:33 stuartsierra: And `clojure.core/read` is fine for .clj config files.

14:34 TimMc: yep

14:35 If you start using user data, though, sooner or later you will run into U+2028 or U+2029 and eval chokes.

14:35 gozala: hiredman: thanks

14:35 RazWelles: is there a way to dump a clojure list to a file?

14:36 rabbit_airstrike: spit?

14:36 RazWelles: esp if it contains anonymous functions and defrecord's

14:36 technomancy: RazWelles: you can't serialize regular fns; you have to use serializable-fn

14:37 gozala: hiredman: although I'd expected to mangle names for defn- not the others

14:37 RazWelles: technomancy, ohh I didn't even know that existed

14:37 guestttt: `fogus: thx for response - ok, so again - from talks I saw Rich seems to be VERY pragmatic, I can hardly disagree with him on anything. If anything, it would be oop (offtopic for now) - so I am curious if there was a reason why lisp macros were preferred over smalltalk way of dealing with control structures (for example)

14:37 hiredman: gozala: the google closure compiler is a whole program optimizer, unless told otherwise it assumes it can do whatever it wants

14:37 RazWelles: technomancy, one more question- how do I put a directory into my load-file path? So i can load-file other clj source files?

14:38 technomancy: RazWelles: there is no reliable way to do that

14:38 guestttt: `fogus: smalltalk does solve control structures using blocks passed as arguments (and so it is form of lazy evaluation)

14:38 gozala: hiredman: no sure but it's possible to assume ^:exports in all top level forms unless opt-ed out via ^:private or defn-

14:39 RazWelles: technomancy, x.x so how do you split a clojure program into several files?

14:39 arcatan: i wonder if there's a case where it matters whether *read-eval* is true/false

14:39 nDuff: gozala: There's more control with the current approach: Whether a cljs function is visible from other namespaces is separate from whether it's visible from javascript after the program has been compiled into a blob.

14:39 gozala: ^:private thus provides distinct semantics from a lack of ^:export

14:39 borkdude: When I search a function name like this with apropos: (apropos #"\?$") I get among other blank? as a result

14:39 technomancy: RazWelles: oh, I thought you meant at runtime. you can set your classpath during the JVM boot just fine

14:39 amalloy: RazWelles: don't use load-file. use the namespace form, with require

14:39 guestttt: `fogus: anyway, thank you very much for that hint on kernel, I was not aware of that before!

14:39 nDuff: gozala: ...and, bigger-picture, having the defaults this way leads to much more tightly-optimized programs.

14:39 borkdude: how can I know from which namespace this function comes (probably string or smth, but that's not my point)

14:39 RazWelles: technomancy, ohh ok- well I'm using clojureclr...

14:39 technomancy: RazWelles: oh, no idea, sorry

14:40 RazWelles: I'll see if amalloy's require suggestion works in clojureclr then

14:40 amalloy: RazWelles: probably best to mention that *first*. you don't want to get a bunch of car-mechanic advice and then say "btw i'm riding a motorcycle actually"

14:40 technomancy: heh

14:41 RazWelles: amalloy, ahaha sorry

14:41 gozala: nDuff: oh right so it's just for js

14:41 nDuff: gozala: Exactly.

14:41 gozala: I get it know thanks nDuff hiredman for insights

14:41 RazWelles: I'm so used to looking through java-based solutions and trying to find the corresponding solution in clojureclr, that's been my tactic all last night with google

14:42 `fogus: guestttt: I talk about just that thing in my Necronomicon talk. Gotta run for now, but maybe that will answer your question if you have time. http://blip.tv/clojure/michael-fogus-the-macronomicon-5970233

14:43 * `fogus Lovecraftian slip

14:43 borkdude: isn't the output of apropos a little useless if the namespace isn't prefixed?

14:43 guestttt: `fogus: thank you! will have a look

14:45 RazWelles: Oh, does anyone know how to remove an event handler in clojureclr?

14:48 borkdude: RazWelles dunno, via interop?

14:49 RazWelles was it added via add-watch? there's also remove-watch

14:49 RazWelles: well I found ClojureCLR created .add_<fn_name> methods and .remove<fn_name> methods, but I don't know how to sue the remove counterpart

14:49 I tried doing .remove and supplying the same function, or even doing it on its own

14:49 I don't know what it expects as an argument

14:50 borkdude: RazWelles you should probably not pass the function, but the var

14:50 RazWelles because function values have no equality,

14:50 RazWelles: right even when I passed the function's symbol it didn't work

14:50 borkdude: RazWelles var isn't the symbol

14:50 RazWelles: ahh what is it then?

14:51 borkdude: RazWelles #'+ is a var, + is a symbol

14:51 RazWelles: ohhhh ok

14:51 borkdude: RazWelles var is the mutable storage location itself

14:51 RazWelles: I'll try that thanks

14:51 so I'd do something like `(fn-name)?

14:51 borkdude: #'fn-name

14:52 RazWelles: borkdude, thanks I'll try that :)

14:52 borkdude: RazWelles it's just a guess… good luck

14:52 RazWelles: ty x.x

14:53 chillenious: Hi folks. I have something I don't quite understand. If you look at my paste here https://www.refheap.com/paste/12293, the first code fragment which includes a dummy arg (or however you'd call that) just to print doesn't work as expected, but as soon as I remove the line, it does work. But I don't understand why this is. Any hints?

14:55 hiredman: doseq is sort of a side effecting for

14:55 nDuff: What's a more idiomatic way to write (every? (true? (for ...)))

14:55 hiredman: println returns nil, which is also accepted as an empty seq

14:55 so everything after the println is being done once for every item in an empty seq

14:55 (never)

14:55 chillenious: ah, that makes sense, thanks!

14:56 borkdude: nDuff (every? identity (for ..)) ?

14:56 nDuff or apply every?

14:56 no

14:57 (every? identity ["Dude" "Dude"]) => true, (every? identity ["Dude" nil]) => false

15:00 nDuff: *nod*. Originally wrote it as every? identity, but the code is meant to be read by Java developers, so I changed it to every? true?. Was hoping there would be a single construct that would have that effect, though.

15:02 borkdude: nDuff how about

15:02 ,(not-any? nil? ["Dude" nil])

15:02 clojurebot: false

15:11 papachan: somebody can help me?

15:12 borkdude: papachan just ask your question

15:12 jeremyheiler: ~anyone

15:12 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

15:12 nDuff: papachan: If you can't ask a specific question, you're beyond help.

15:12 papachan: sure nDuff

15:12 borkdude: now let's not get all grumpy ;)

15:13 papachan: i trying to understand why i cant have the output of a simple function which do a loop

15:13 at this moment i have this -> https://www.stypi.com/papachan/main.clj

15:13 jeremyheiler: *gumble grumble* :-P

15:13 nDuff: papachan: using def inside a function is bad news.

15:13 papachan: def creates vars; vars are global to your namespace.

15:13 papachan: ok

15:14 if i am inside of let

15:14 nDuff: papachan: ...and I don't know what you're trying to do calling "0" as a function.

15:14 Bronsa: also where is create-line defined?

15:14 borkdude: papachan first of all, ("0") isn't valid

15:14 too late

15:14 jeremyheiler: That site is neat.

15:14 nDuff: papachan: ...so, an explanation of what you want your code to do would be helpful.

15:14 papachan: oh i see i have too many errors

15:15 i am trying to get a list of "0"

15:15 and get the middle position with 1

15:16 borkdude: can everybody collaborate on that piece of code on that site?

15:16 I saw test written :)

15:16 jeremyheiler: borkdude, I just typed "Test" into the document.

15:16 papachan: i think yes

15:16 borkdude: cool]

15:16 papachan: yes

15:16 * nDuff still doesn't follow the English-language goal description.

15:18 jeremyheiler: papachan, Could you describe what you're trying to do with this program?

15:19 papachan: something basic, i am beginning with clojure

15:19 borkdude: if i is a range, how can you compare it with a number?

15:19 papachan: trying to have a list of "0"

15:19 Bronsa: borkdude: i is not a range, it's a number

15:19 papachan: and at middle position, change it for 1

15:19 Bronsa: it's inside an or

15:19 for*

15:19 borkdude: ah sorry, misread it

15:20 I read let instead of for, doh

15:20 papachan: i have remove the "def" inside my let statement

15:20 jeremyheiler: papachan, If you want a literal list, you need to quote it like this: '(1 2 3) so that it doesn't try to evaluate it as a function invocation.

15:20 Bronsa: heh

15:20 papachan: it compile goog

15:21 borkdude: papachan what is the point of deffing n if you don't use it as a result

15:21 which should be in a let, which is now the case in your oce

15:21 code

15:22 Bronsa: papachan: try it out now

15:22 papachan: i am trying

15:23 Bronsa: I'm not even sure :main true is a thing in gen-class

15:24 borkdude: Bronsa it is (looked up the docs)

15:24 Bronsa: borkdude: oh, ok

15:24 borkdude: Bronsa but I didn't see it before, maybe it's the default

15:25 papachan: it works

15:25 i understand now the code

15:25 thank for your help

15:26 durka42: any core.matrix people around here?

15:26 borkdude: papachan I can call the function -main now like this: (-main 3)

15:27 papachan but note that when called from the cmd prompt, the arguments will be passed a strings

15:32 Foxboron: Anything recommended for parsing HTML with Clojure?

15:34 corecode: Foxboron: ems...

15:34 what was the name

15:35 jeremyheiler: Foxboron, Laser. https://github.com/Raynes/laser

15:36 borkdude: https://github.com/davidsantiago/hickory

15:36 Foxboron: awsome

15:36 i'll look at those :)

15:36 Apage43: i was going to say I typically just use Jsoup

15:37 borkdude: Laser uses hickory if I'm not mistaking. Laser = templating, hickory = parsing

15:37 Apage43: hickory uses Jsoup though so =)

15:37 borkdude: lol

15:37 transitive dependencies ;)

15:37 * nDuff wonders if Jsoup is a straight-across port of the old BeautifulSoup parser; if so, he's not particularly impressed.

15:38 Apage43: Jsoup is pretty nice if you want to use css-like selectors

15:38 nDuff: (at least in the Python world, BeautifulSoup abandoned their old parser in favor of lxml.html -- and that decision was very much for the better).

15:40 Apage43: i think it's a more from scratch thing, at least as of their HTML5-compliant version

15:41 you get a "real" DOM, as it were.

15:44 neotyk: Foxboron: enlive works great

15:44 Foxboron: neotyk: i feel its kinda heavy for just parsing.

15:45 Which laser seems to be the solution for.

15:46 neotyk: Foxboron: have to look at laser than

15:47 Foxboron: neotyk: what i am doing :) It was suggested above.

15:54 zakwilso1: There look to be four database schema and migration libraries for Clojure that are somewhat active. Has anybody done a comparison recently or have information that would help me pick one faster than trying them all?

15:55 danlarkin: zakwilso1: yeah use migratus

15:55 it's pronounced maig-rah-toos

15:55 jimkcar: lol

15:55 pjstadig: mig-great-us

15:55 er

15:55 mi-great-us

15:55 whatever

15:56 danlarkin: no

15:56 maig-rah-toos

15:56 pjstadig: danlarkin: maybe your fork is pronounced that way

15:56 hiredman: mahi-grah-tous

15:57 my great house

15:58 danlarkin: it's a nice library no matter how you pronounce it (maig-rah-toos)

15:59 zakwilso1: danlarkin: do you have anything to say in its favor relative to the others aside from "I like it"?

16:00 danlarkin: it's just straight sql

16:00 which I like

16:01 yazirian: bah weep grah nah weep migratus

16:03 papachan: thank you borkdude just recent read your messages

16:04 zakwilson: I see that as neutral. I dislike SQL as a language, but whatever-to-sql compilers aren't always awesome.

16:07 pjstadig: zakwilson: the principles behind migratus are: 1) just use SQL (a database DSL) instead of inventing yet another database DSL, 2) be compatible with git based workflow

16:07 mostly

16:08 migratus also frames its transactions differently than ragtime so that with a database that supports transactional DDL (like postgres) you get the maximum projection

16:08 i think ragtime does not wrap a transaction around both running the migration and updating the these-migrations-have-run-table at the same time

16:09 drift's migrations are not compatible with git workflow

16:09 i don't really know much about others

16:10 technomancy will tell you to just use functions https://github.com/ato/clojars-web/blob/master/src/clojars/db/migrate.clj which i would also recommend to you, if that works for you

16:10 zakwilson: I think yet another DSL would be of use if it shared code with a query library like Korma.

16:11 pjstadig: that's a fine idea, and not one i support, so migratus may not work for you

16:12 zakwilson: It's good to have a clear sense of what your project should and should not do.

16:14 I might end up using migratus; drift doesn't seem to have great docs, ragtime seems similar to migratus, but nobody has said anything in its favor yet and Lobos' website is pretty out of sync, at least in terms of version numbers.

16:15 pjstadig: we use migratus at sonian

16:15 so it is being put to actual production use, and i have a vested interest in it

16:15 if that makes any difference

16:15 jaen1: a

16:16 zakwilson: That does suggest it won't go away quickly. This is for a client project, so stability matters.

16:16 jcrossley3: Bronsa: 7.3 looks much better, btw. it didn't solve my problem, but i think it's something on our side.

16:17 zakwilson: Another point in its favor: the author is easy to find in IRC if I need someone to choke.

16:17 Bronsa: mh

16:18 well jcrossley3 just let me know if you think I can do anything about it

16:18 jcrossley3: Bronsa: cool, thx

16:18 pjstadig: zakwilson: hehe

16:19 tboyt: https://github.com/clojure/clojurescript/wiki/The-REPL-and-Evaluation-Environments this article has some sample code for setting up a browser-based repl using the (require) function. but when i try to use this function in a clojurescript file, the function is apparently nonexistant ("cannot call method 'call' of undefined"). is there something i need to do to be able to access (require)?

16:19 sshack: Are there any decent references for data munging/cleanup in Clojure? (I'm cleaning up the contents of some CSV imports)

16:20 zakwilson: Ok, migratus it is, unless someone wants to try to talk me in to something else in the next ten minutes or knows of something that ties in with Korma.

16:20 hiredman: tboyt: that is clojure code meant to be run in a clojure repl

16:21 * nDuff suppresses his urge to go into a rant about Korma

16:21 tboyt: hiredman: not according to the sample's original src: https://github.com/clojure/clojurescript/blob/master/samples/repl/src/repl/test.cljs#L29

16:22 zakwilson: nDuff: rant if you like. I haven't used it in a while, but I liked it when I did.

16:22 hiredman: tboyt: that is in a comment

16:22 tboyt: hiredman: …i just noticed that as you said it. blegh. you'd think there'd be special syntax highlighting for a comment like that :p

16:23 still, though, i have zero idea how to get a working browser repl up and running with cljsbuild. is there some tutorial i'm missing?

16:23 nDuff: zakwilson: Short form: Korma is sufficiently dependent on macros that it's not at all friendly to function composition.

16:25 tomoj: oh, nice

16:25 zakwilson: nDuff: do you have something better to suggest?

16:25 tomoj: I thought I didn't like it just cus I'm prejudiced against sql

16:26 nDuff: zakwilson: Wrote my own, but (1) it's unreleased, and (2) it's only good enough for my own use cases, and nothing more -- and I haven't evaluated the other public alternatives in detail. So, short form: No.

16:26 zakwilson: I like the idea of relational databases, but SQL feels like it's from 1974.

16:27 nDuff: you should release it so other people can hack on it. In the mean time, I will use Korma for this project.

16:27 danlarkin: sql perfectly represents its domain

16:27 I don't understand the haters it attracts

16:28 nDuff: danlarkin: If I can't use function composition to build queries, I'm hamstrung.

16:28 danlarkin: ...and "perfectly" is a stretch. Extending korma to cover new syntax is much more of a pain than it has to be.

16:28 hiredman: danlarkin: imagine if you had to glue together javascript statements as strings to query some database

16:28 zakwilson: SQL isn't composable, and SQL schemas are imperative.

16:29 nDuff: zakwilson: I can even do composition with SQLAlchemy's query builder easier than with Korma.

16:29 zakwilson: Also, really irritating mix of prefix, infix and postfix.

16:29 nDuff: zakwilson: Can, and _have_.

16:30 zakwilson: SQL is somewhat composable using external tools. That may solve the problem, but I still see it as a valid complaint against the language.

16:30 hiredman: at an sql prompt writing sql is great, but when you have a 20 sql statement checked in as a string it is gross

16:30 20 line

16:30 scottj: is clojureql better than korma in this respect (using function composition to build queries)?

16:30 technomancy: oh come on, composability by string manipulation works great for metaprogramming in ruby; how bad can it be?

16:31 zakwilson: Glue together JS statements for queries? Isn't that half the "nosql" (I hate that term) databases out there?

16:31 sshack: zakwilson: It's fair to say SQL hasn't adapted with the times. It's suffered from crystallization.

16:31 pjstadig: with migratus you can modify sql in sql files, but of course that doesn't help with writing queries

16:32 technomancy: I would actively warn against drift and lobos because they trick you into thinking you can swap out the underlying DB implementation without changing actual code, which is not true

16:32 sshack: "I know what I know, and I don't want to change!"

16:32 pjstadig: if you want a functional take on databases then you should use datomic

16:32 if you're used an RDBMS, then SQL is the way to go

16:32 hiredman: you can run `lein check` to see if your code has any compilation errors, what do you do to see if your sql strings match your schema?

16:32 pjstadig: hiredman: you want static typing?

16:33 sshack: pjstadig: Yeah. Trick is people think RDMS=SQL. Nothing wrong with RDMS's, SQL just hasn't kept up.

16:33 hiredman: ~#35

16:33 clojurebot: 35. Everyone can be taught to sculpt: Michelangelo would have had to be taught not to. So it is with great programmers. -- Alan J. Perlis

16:33 hiredman: hmmm

16:33 ~#34

16:33 clojurebot: 34. The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information. -- Alan J. Perlis

16:33 * nDuff would love to use datomic, but the politics associated with an outlay for licensing (or on introducing a dependency on a single-vendor product) make it a very hard sell.

16:33 pjstadig: i guess generally you'd right tests to see if your queries match the schema

16:33 s/right/write/

16:33 hiredman: yeah

16:34 you would parse the queries, figure out what columns of what tables they reference then see if they exist

16:34 zakwilson: It would be really awesome to have a new RDMS that doesn't try to be backwards-compatible. It would probably never catch on.

16:34 pjstadig: zakwilson: datomic?

16:34 sshack: zakwilson: You are an oracle. We've reached a local optima. That's a hard rut to break out of.

16:34 nDuff: pjstadig: http://www.datomic.com/

16:35 pjstadig: hiredman: if you're parsing sql statements and trying to figure out what columns would exist at runtime you are in the same position as you are with static typing

16:35 you're trying to simulate the program with out actually running it

16:35 so just write tests against the db

16:36 hiredman: pjstadig: it is similar

16:36 zakwilson: pjstadig: probably not. That seems like a higher-level layer (and I think it's implemented that way).

16:37 sshack: it just needs to solve somebody's problem satisfactorily.

16:37 Some problem that has people setting their hair on fire, that is.

16:37 sshack: zakwilson: Well, that gets you an internal tool.

16:37 Now you have to get it to the public, and drive it.

16:38 zakwilson: Not trying to put you off or anything.

16:39 So are there any clojure tools/references for cleaning up messy imported data (CSV files, in this case)?

16:40 zakwilson: Well, I'll get around to it just as soon as I create a replacement for C in which to write it.

16:41 sshack: zakwilson: Haskell?

16:41 But not strict not lazy.

16:41 zakwilson: Haskell will do as soon as I find a good source for LSD.

16:46 sshack: Tried licking a toad?

16:47 abp: Twice, they taste like earth, don't understand the hype.

16:49 zakwilson: I'll take your word for it and not try.

16:50 I do want to make something kinda like C with Lisp syntax. Yes, I know people have done that sort of thing before.

16:51 rabbit_airstrike: where do you live that toads secrete LSD?

16:52 zakwilson: You could genetically modify a toad to secrete LSD, perhaps.

16:58 sshack: rabbit_airstrike: There are some breeds of toads that secrete some sort of slight poison people use to get high.

16:59 Apparently, those types of toads are invading the area around me.

16:59 I don't know though. The only drugs I take are Lambda's.

17:04 Foxboron: ,#java.io.FileWriter["hello_from_ljos"]

17:04 clojurebot: #<SecurityException java.lang.SecurityException: denied>

17:05 Foxboron: damn. It worked with my sandbox. hmm

17:05 Sgeo_: Try the other one

17:05 &#java.io.FileWriter["hello_from_ljos"]

17:05 lazybot: ⇒ #<FileWriter java.io.FileWriter@1ff5f75>

17:06 ljos: wait, that doesn't look good :D

17:06 rabbit_airstrike: sshack: but they're not secreting LSD :)

17:07 most of those poisons are likely deliriants, not psychedelics

17:07 Foxboron: hahaha

17:07 i think lazybot uses the same sandbox i am using

17:07 sshack: rabbit_airstrike: No, not technically. But would you really care? You'd still get high.

17:07 Raynes: Foxboron: clojail?

17:07 If so, then yes.

17:07 lazybot is mine and amalloy's. Turns out we are also the authors of clojail. Small world.

17:09 rabbit_airstrike: sshack: there are serious qualitative differences between deliriant and psychedelic experiences. Psychedelics can be conducive to mathematical thinking, whereas deliriants will make you stupid for the duration if they don't kill you

17:09 sshack: rabbit_airstrike: The lesson here is to never go tripping with me.

17:10 Foxboron: Raynes: i digged into the source. It dosnt use the default secure-tester i used. But it still evals the same line it did on my bot :)

17:10 netrealm: Hey, what testing frameworks are people currently recommending?

17:10 Raynes: clojure.test, midge, speclj.

17:10 Foxboron: Raynes: its clojure, it is a small world IMO :)

17:10 Raynes: In that order.

17:11 Foxboron: There are nearly 600 people in here.

17:11 $max

17:11 lazybot: The most users ever in #clojure is 578

17:11 netrealm: Raynes: Cool, thanks.

17:11 Raynes: Yeah, I should fix that.

17:11 lazybot is a huge liar.

17:11 amalloy: Foxboron: it actually isn't evaluating, it's just reading. it's definitely a security hole, but you can't *do* anything with that filewriter once you've created it

17:11 durka42: maybe it's just lazy

17:11 egghead: is there a way to get lein test failure to result in a non-zero exit code?

17:12 llasram: egghead: I'm pretty sure it does that already?

17:12 egghead: hm

17:12 Foxboron: amalloy: hah. Yeah i see. Might wanna patch the secure-tester if ya can. Else i gotta dig into how to make it skip the java.io stuff.

17:12 amalloy: Foxboron: nothing to do with the secure tester. we just have to upgrade to 1.5 and use edn/read

17:13 or perhaps do our reading inside the jvm sandbox, which would be harder

17:13 llasram: egghead: Yeah -- exit code should be the number of test errors + failures

17:13 egghead: llasram: maybe I need to update

17:13 https://www.refheap.com/paste/07abe22fcb473e0b028b14796

17:14 i'm on Leiningen 2.0.0-preview10 -- probably just an old version thing

17:14 llasram: No, that should be good

17:14 Your project does't :eval-in :leiningen, does it?

17:15 egghead: nah, very simple boilerplate project.clj

17:15 llasram: egghead: hmm. That's very odd. OUr CI system works w/ that version of lein just fine

17:16 egghead: Unfortunately I need to take off, but good luck sorting it out

17:16 ljos: amalloy: you can't do anythinh with the filewriter afterwards, but it is destructive if I hit a file that I know is there.

17:16 egghead: cheers llasram

17:16 amalloy: i know, ljos. i told you it's a hole

17:16 just instantiating it is dangerous

17:17 * Frozenlock bangs his head on the desk

17:17 Frozenlock: Lazyness and database are a bad combination :(

17:18 technomancy: laziness and dynamic scope in particular

17:18 looking forward to a c.j.jdbc release that doesn't force dynamic scope on you =\

17:19 egghead: ah, the error seems to be specific to expectations

17:19 Frozenlock: Indeed... I've been bitten once by dynamic variables... now I try to simply *never* use them.

17:20 They are hard to debug...

17:28 jtoy: is there a way to no im inside of the repl as opposed to a compiled jar from inside of clojure

17:28 know

17:32 mikerod: Does `extend-type` not support adding a doc string to the protocol method implementations? e.g. (extend-type SomeType SomeProto (proto-method "Impl for proto-method" [this] this))

17:32 e.g. (extend-type SomeType SomeProto (proto-method "Impl for proto-method" [this] this))

17:33 Frozenlock: jtoy: could re-ask your question, but this time with other words? :P

17:33 *you

17:36 zakwilson: I find it interesting that Clojure and the community in general doesn't seem to rely a lot on macros. I used them and saw others use them a lot more in Common Lisp.

17:37 jtoy: Frozenlock: can clojure know if its running code from a repl vs a jar ?

17:41 Raynes: Why would you want to do that, jtoy?

17:42 devn: yogthos: you around?

17:42 technomancy: how big of a pain is it to shell out to something like pygments from a clojure app on heroku?

17:42 Raynes: ^ Are you hosting on heroku?

17:42 zakwilson: Is it the general consensus that slime/swank isn't the way to go anymore and we should all use nrepl?

17:43 devn: zakwilson: it seems that way

17:43 Raynes: devn: I moved off of Heroku recently.

17:43 technomancy: devn: assuming python programs are installable via something similar to rubygems, pretty easy

17:43 Raynes: devn: However, shelling out to pygments was easy on heroku.

17:43 zakwilson: Meh. More change.

17:44 Raynes: technomancy, devn: pygments always got pulled in by my 'bootstrap' script, so pygments ended up in the slug. It's easy.

17:44 technomancy: zakwilson: if you have a setup with slime that works, keep using it till it doesn't.

17:44 devn: Raynes: word

17:45 Raynes: technomancy: I think that's terrible advice. "Oh, just wait until it breaks and then, even if you're busy with something else, move to nrepl and learn on the spot."

17:45 jtoy: Raynes: I want to know that so I can make my code have different defaults depending on where i am

17:45 Raynes: It makes more sense to me to just go to nrepl now and save yourself problems later, or at least plan for it.

17:45 amalloy: zakwilson: i'm clinging to slime for dear life, but you start using clojure 1.5 you'll have to either fix slime/swank or switch to nrepl

17:46 technomancy: I thought tcrawley fixed the 1.5 issues?

17:46 zakwilson: Well, I just tried it with 1.5 and it didn't work, so I guess I'm switching.

17:47 amalloy: technomancy: maybe. my version of slime/swank is probably about a year old

17:47 zakwilson: I guess that'll make it easier to use slime with CL though.

17:47 Raynes: technomancy: Don't encourage him.

17:48 technomancy: Raynes: not my problem any more... you have no idea how good it feels.

17:48 anyway, upgrade whenever you want

17:48 zakwilson: I get the impression slime-related code has been a pain in the ass to maintain.

17:49 technomancy: unless you want to take over maintenance of swank-clojure or something

17:49 zakwilson: yeah, I used to have semi-regular rants on the subject

17:49 tcrawley: zakwilson: last time I used it, the latest swank-clojure worked with 1.5

17:49 but I can't tell what version that was, because https://clojars.org/swank-clojure gives an error

17:49 technomancy: zakwilson: http://p.hagelb.org/slime-cvs-rant.txt

17:50 tcrawley: and if swank-clojure is broken now, I'm not going to fix it :)

17:52 trmsw: I have a namespace that's supposed to act as an API: a small number of public functions and a lot of horrible details. I've split the horrible details into several files - it seemed like a good idea at the time. That means lots of "(load x)"s in the main file and an "(in-ns 'api)" in every part file. Is there a better way?

17:53 n_b: trmsw: Look at clojure.org/libs

17:53 tjgillies: is there anything like http://reactivemongo.org/ for clojure?

17:53 n_b: You want to be using the :use and :require parts of the ns macro

17:55 Question of my own: Is there some reason the api-key in Line 26 seems to refuse to load from secrets.txt?

17:56 Code: https://www.refheap.com/paste/12305 - I've tried putting it in a (do) using (defonce) instead, but unless it's in the env var, it will not work

17:56 It seems to function at the REPL, but not when loaded in my Compojure handler

17:58 trmsw: n_b: I want callers to be able to use / require a single namespace (my-api), but the functions provided by that namespace are defined in several files / sub-namespaces, including a core that is used by all the others.

17:58 n_b: I'm not sure I follow; can you put up a gist or similar?

18:00 zakwilson: nrepl looks to be working, so I'll just stick with that.

18:03 jtoy: how can I load a string to be evaled in the current context and not in its own context? the docs day load-string "should any form have an effect on that var (e.g. `in-namespace), the effect will unwind at the completion of the load"

18:04 trmsw: n_b: https://gist.github.com/tomsw/5120775

18:06 jtoy: ah, read and eval

18:07 n_b: tmarble: Why can't you do in gui.clj (ns myapi.core.gui (:require [myapi.core :only (foo bar)])) ?

18:07 amalloy: jtoy: you cannot evaluate a form in any non-null lexical environment. you can bind *ns* to whatever you want to make vars available, but you can never make locals available

18:09 n_b: trmsw: Like this: https://gist.github.com/nickbarnwell/5120788

18:11 trmsw: n_b: I see what you mean. But that effectively means duplicating all the public functions

18:11 n_b: er

18:11 what

18:12 just require or :use what is needed

18:15 trmsw: n_b: I have a client namespace that wants to use my api. It should just be able to use / require a single namespace, myapi, to get access all the public functions in my api. These functions might not all live in the same place - eg myapi.gui, myapi.forms etc.

18:17 n_b: If you want all your functions to be in one namespace, they should be in one namespace.

18:20 trmsw: n_b: ok, so one namespace, several files = load + in-ns

18:21 Foxboron: Raynes, just gotta mention. Reading your blog and discovered you are actually as old as me. Very inspiring to read :)

18:21 yogthos: devn: sort of :)

18:22 Raynes: Foxboron: So you're how old then?

18:22 Foxboron: Raynes: 19 in june.

18:22 july*

18:22 i mess up those dates -.-

18:22 Raynes: So you're slightly younger than I am.

18:22 Very slightly.

18:23 ivaraase1: Raynes: you have the most awesome accent by the way

18:23 Raynes: orly

18:23 * mattmoss mutters something about young people and lawns and grumbles to himself.

18:23 Raynes: Did you listen to an interview or something, ivaraase1?

18:23 Foxboron: Raynes: indeed :) i did have an impression after hanging here a while that you where older :P

18:24 Raynes: Well, I'm only… 5 months older.

18:24 Foxboron: Raynes: hah, an IRC bot is also my first Clojure project :P

18:24 Raynes: and a few years more programming experience :)

18:24 and tons of other languages

18:25 No but really, inspiring read. Keep up the work ^^

18:25 ivaraase1: Raynes: correct

18:25 Raynes: Foxboron: So you've got more years of experience than I?

18:25 Get out of my internet.

18:25 I bet you're wrong about the languages part though.

18:26 I've used enough languages that I forget which ones I've used occasionally.

18:26 ivaraase1: Which one? :D

18:26 Foxboron: Raynes: noooo vica versa

18:26 Raynes: oic

18:26 Foxboron: hah, sorry if i pharsed it wrong :)

18:26 Raynes: I know people who started hacking when they were like 7 though.

18:27 ivaraase1: Raynes: it was some time ago, but I believe it was Mostly Lazy

18:27 Raynes: So I'm certainly not the standard for starting ages.

18:27 Yeah, that was the most recent thing.

18:27 Foxboron: Started at like... 16 with batch :/

18:32 ivaraase1: I started programming at 14 I think

18:32 but I think discipline is more important than when you start

18:34 patchwork: How do I access values from my project.clj from within my app?

18:34 Seems like this should be simple, but I can't find any docs on it

18:36 technomancy: patchwork: project.clj is isolated from runtime

18:36 typically that kind of config is done through environ or carica

18:37 jodaro: wow

18:37 weird

18:38 i was just looking at immutant docs about accessing the :project in the registry before i switched into this window

18:38 patchwork: technomancy: I see, is either one preferred?

18:39 environ seems to use the system environment, while carica seems to be more programmatic

18:41 hiredman: I think carica is a clear winner for large amounts of configuration

18:42 patchwork: Part of my issue is I have a variety of environments the app runs in, each with its own config for things like db, s3 buckets etc

18:42 I was hoping to use lein profiles for this

18:42 but I guess that is not an option

18:42 hiredman: sure, we do all that in carica at work

18:43 patchwork: Ah, so how do you select among the different configs?

18:43 hiredman: there is a set of default configs checked in that get built in to the final artifact (a jar) and then chef writes overrides to the filesystem for different stacks

18:44 carica merges configs found on the classpath

18:44 jodaro: https://github.com/typesafehub/config

18:44 patchwork: Ah, so you have another tool for that

18:44 jodaro: i used that for configs for a bit

18:44 not clojure specific obviously

18:44 but it was pretty easy to wrap what i needed in just a few lines of clj

18:50 alexbaranosky1: hey, does anyone know how to use leiningen to build a jar from Java source files, that will include the .class files?

18:51 hiredman: alexbaranosky1: https://github.com/sonian/Greenmail does that

18:51 then mail thing is the lein javac task, and :java-source-paths in your project.clj

18:51 main

18:52 alexbaranosky1: we're doing it like this: https://www.refheap.com/paste/b043c987a06e74941407f0ae6 and it only includes the Java source files for some reason

18:52 hiredman: because lein by default includes src/ (assuming src is clojure source) in the jar

18:53 and you are not running the lein javac task I bet

18:53 alexbaranosky1: ahhh… so if we change our source directory to be another location?

18:53 hiredman: if you change your java-source-path you shouldn't get java source in the jar

18:53 but the main thing is the javac lein task

18:53 otherwise the java isn't compiled

19:00 technomancy: patchwork: depends on your existing deployment infrastructure. environ is slightly simpler but only supports with string values; no nesting.

19:00 also carica supports reloading much better

19:00 patchwork: both environ and carica support switching by profiles

19:02 alexbaranosky1: @hiredman, thanks man, you're the man

19:02 that worked

19:11 Frozenlock: God my old code is awful. I'm sure I'll say the same thing in 10 months about my current code, but really... (when-not (empty? var) var)

19:14 amalloy: Frozenlock: what's wrong with that?

19:14 aside from demonstrating that you don't know about the not-empty function

19:15 Foxboron: One thing i kinda find...interesting with clojure, compared too other langs. There are functions for everything.....

19:15 which also relates too: thank god for auto-completion.

19:15 dxeh: there are functions for everything in a lot of languages, you just probably don't know em all :p

19:15 Frozenlock: amalloy: exactly that. `seq' is much more compact. The more I learn clojure, the more I find it so incredibly dense.

19:16 amalloy: Frozenlock: seq doesn't do exactly the same thing

19:16 rabbit_airstrike: <3 the cheatsheet

19:16 amalloy: which is why i said not-empty, not seq

19:16 Foxboron: dxeh: well, comming from python where you got....12'ish builtins, and tons of libs its kinda new.

19:16 amalloy: &((juxt seq not-empty) "abc")

19:16 dxeh: Foxboron: ah, i know many languages but python isnt one of em yet ;p

19:16 Frozenlock: Really? It really _seems_ like it's the same thing :s

19:17 lazybot: ⇒ [(\a \b \c) "abc"]

19:17 Frozenlock: O_o

19:17 God my current code is awful

19:17 amalloy: indeed

19:17 Foxboron: dxeh: Python is cake. But Python got tons of stuff in its standar library, the problem is tho that they are either hard too use or a fuckload of OO stuff. Where Clojure got small neat functions for everything.

19:17 metellus: &((juxt seq (comp list not-empty) "abc")

19:17 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

19:18 technomancy: Frozenlock: FWIW I find empty? to be more readable than using seq as a predicate

19:18 metellus: &((juxt seq (comp list not-empty)) "abc")

19:18 lazybot: ⇒ [(\a \b \c) ("abc")]

19:18 brehaut: Foxboron: ironically the priority queue implementation in pythons standard lib is more like a clojure lib, and its worse than the big OO soup :P

19:19 Foxboron: brehaut: hahahahahaha. urllib tho....huge mess.

19:19 brehaut: blerk ಠ_ಠ

19:20 Frozenlock: Eh after looking at `not-empty' source, `seq' really isn't that far away.

19:21 Still, I'll try to use not-empty instead of seq, it's more readable as pointed out by technomancy.

19:22 technomancy: the "official" recommendation is to use seq as a predicate. I just don't think it's a good recommendation.

19:22 TimMc: &((juxt seq not-empty) "")

19:22 lazybot: ⇒ [nil nil]

19:24 amalloy: Frozenlock: no, use seq instead of not-empty for the predicate. i'm pointing out that (when (seq x) x) or your actual (when-not (empty? x) x) is just (not-empty x)

20:30 ToBeReplaced: is https://gist.github.com/michalmarczyk/468332 currently the best way to implement a DefaultMap ? I'm looking for a solution to (merge-with conj a b) when a might be nil

20:32 auser: curious… what's the difference between {:name "World"} and :name "World" ?

20:33 xeqi: &(merge-with (fnil conj [] []) {:a []} {:b []})

20:33 lazybot: ⇒ {:b [], :a []}

20:33 xeqi: &(merge-with (fnil conj [] []) {:a [1] :b [1 2]} {:b [3 4] :c [1]})

20:33 lazybot: ⇒ {:c [1], :a [1], :b [1 2 [3 4]]}

20:34 xeqi: ah, not quite

20:37 amalloy: auser: one of those is a single value (a map), the other one is two separate values

20:37 auser: interesting...

20:38 amalloy: ToBeReplaced: a DefaultMap that behaves like that really breaks several promises of the map interface

20:38 ToBeReplaced: xeqi: fnil is cool, i hadn't looked into that before

20:39 amalloy: auser: it's about the same as the difference between [1 2] and 12, i suppose. one is a number, and one is a list of two numbers

20:40 ToBeReplaced: amalloy: yeah. i don't think i fully appreciate those issues yet, but it is much simpler to just write a merge-with-conj since that's the only use case i'm talking about

20:40 auser: gotcha amalloy

20:40 ToBeReplaced: especially since you have to make an assertion anyway as to the datatype of the coll to conj to

20:41 auser: amalloy: I'm attempting to get this string interpolation working for maps https://gist.github.com/auser/7776f3c507d78823da7c

20:41 hiredman: that is not a map

20:42 #{} is a set

20:42 auser: oh yes

20:42 (new)

20:43 xeqi: ~contrib

20:43 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

20:44 auser: hm

20:44 xeqi: also, clojure.contrib.* namespaces have been deprecated and split up. looks like strint ended up in [org.clojure/core.incubator "0.1.2"]

20:44 auser: hm, basically I just want to do string interpolation using a map

20:47 hm, anyone doing string interpolation using a map and clojure.contrib.strint?

20:48 Raynes: I'd probably do ##(apply format "foo %s bar %s baz %s" ((juxt :foo :bar :baz) {:foo 1 :bar "a" :baz "hi"}))

20:48 lazybot: ⇒ "foo 1 bar a baz hi"

20:48 Raynes: String interpolation wouldn't occur to me.

20:48 Not that there is anything wrong with strint.

20:48 ToBeReplaced: if I wanted more sophisticated string interpolation, i'd prob use clostache

20:48 Raynes: Never used it, so I wouldn't know.

20:48 auser: interesting

20:48 Raynes: s/clostache/stencil/

20:49 ToBeReplaced: https://github.com/davidsantiago/stencil

20:49 ToBeReplaced: what makes stencil preferable over clostache?

20:49 Raynes: Faster.

20:50 ToBeReplaced: fair enough

20:50 Raynes: I also know the guy who made stencil. He lives a few miles from me. :p

20:50 auser: oh yeah?

20:53 thanks Raynes

20:55 ToBeReplaced: amalloy: re merge-with-conj... or even better... don't do that, because that makes little sense for multiple maps

20:55 i think a good rule for me would be "if you think you want to do something that isn't already very easy, convince yourself why you don't"

20:56 Raynes: ToBeReplaced: Well, with that rule no nice things would ever be created again.

20:59 yogthos: hehe I'm still a fan of clabango myself :P

20:59 mustache can get very mustachy :P

20:59 ToBeReplaced: my comment is within scope of course... and i probably should have said simple rather than easy

21:01 Raynes: I'm a fan of that cool laser lib.

21:01 yogthos: hehehe

21:01 Raynes: I was thinking of giving a talk about it at the next LA Clojure meetup.

21:01 yogthos: do it!

21:01 Raynes: Not sure I want to write a talk though. The conj talk I did was brutal.

21:02 yogthos: it's a lot of work

21:02 Raynes: And it has been long enough since I used keynote to make it very possible that I've entirely forgotten how to use it.

21:02 yogthos: I want to do a luminus presentation at dev TO http://www.devto.ca/contact-us/

21:02 basically, build a simple app in 15 min and put it on heroku :)

21:03 people like it when things work out of the box like that

21:03 20 min is tight though :)

21:04 Raynes: My problem is more along the lines of figuring out interesting things to say about laser for 40 minutes to an hour.

21:04 yogthos: well you do some background, then some examples, and before you know it :)

21:04 plus you have some q/a right

21:04 Raynes: That's true.

21:04 I actually ran way out of time at the conj.

21:04 yogthos: 40 min goes by pretty fast

21:06 but yeah the reason I'm liking the clabango thing specifically is cause it's familiar to noobs

21:06 it's like check this out, it's stuff you already know, definitely helps get interest :)

21:12 amalloy: Raynes: that won't be a problem at all. i'd worry a lot more about accidentally taking more than 90 minutes

21:13 Frozenlock: Raynes: Did you talk this year, or are you refering to previous conjs?

21:13 amalloy: previous

21:13 he gave a clojail talk in 2011

21:14 ToBeReplaced: yogthos: that was why i brought up mustache... because people who are used to built-in string interpolation from, say, python, can use it right away.... templating as its own topic feels religious

21:15 yogthos: ToBeReplaced: my only problem with it is that it takes the whole no logic in the templates business a little too seriously :

21:15 :)

21:15 ToBeReplaced: the django style templating seems a bit more pragmatic in that respect

21:16 amalloy: ToBeReplaced: python's built-in string interpolation is just ##(doc format), right? i don't know why you'd involve mustache

21:16 lazybot: ⇒ "([fmt & args]); Formats a string using java.lang.String.format, see java.util.Formatter for format string syntax"

21:16 amalloy: &(format "%s is bigger than %s" 10 5)

21:16 lazybot: ⇒ "10 is bigger than 5"

21:16 Frozenlock: Oh that's gold "a new massively parallel, ...uhm... concurrent, ...uhm... AI-driven, ...uhm... ToDo list application." https://www.youtube.com/watch?v=ROor6_NGIWU

21:17 amalloy: like, i could see the argument for rubyists, who have some inline string interpolation

21:18 ToBeReplaced: amalloy: you can also do "Hello {name}".format(name='amalloy') in python

22:12 dabd: I'd like to write a simple program to continuously tail a log file with something like (take-last 10 (line-seq (clojure.java.io/reader "some file")) .How should I wrap this tailing function? in an agent?

22:31 twiles: I'm trying to write some code to parse some emails, does anybody know how I could save a jpg attachment that looks like it's some kind of BASE64DecoderStream?

22:32 Here is where I'm stuck:

22:32 (.getContentType (.getBodyPart (.getContent (get-message email-5)) 1))

22:32 --> "image/jpeg; name=\"tinyvices_wayne.jpg\""

22:32 (.getContent (.getBodyPart (.getContent (get-message email-5)) 1))

22:32 --> #<BASE64DecoderStream com.sun.mail.util.BASE64DecoderStream@419e74>

22:33 Raynes: Since it is a stream, you can probably clojure.java.io/copy it to a file.

22:34 Something like (clojure.java.io/copy (clojure.java.io/reader your-stream) (clojure.java.io/file "your-file.jpg"))

22:36 twiles: oh word

22:36 technomancy: except don't use reader for binary datas

22:38 Raynes: technomancy: Eh?

22:39 technomancy: Raynes: reader assumes it's working with data that can be safely round-tripped to/from UTF-16

22:39 which is not true of jay pee gee files

22:40 Raynes: Oh, right. I didn't think about what we were reading here.

22:40 twiles: yeah technomancy that's correct

22:40 it didn't work out

22:40 Raynes: I think you can just copy the stream directly.

22:41 I'm don't think it is necessary to actually have a reader in between.

22:41 technomancy: yup

22:41 Raynes: twiles: ^

22:41 I'm just so used to wrapping everything in reader.

22:41 :p

22:43 twiles: do I have to do any decrypting? I'm not 100% sure how the attachment file is stored, and it looks like the output file didn't get written correctly

22:44 I tried: (def stream (.getContent (.getBodyPart (.getContent (get-message email-5)) 1)))

22:44 (copy stream (file "/tmp/delme.jpg"))

22:44 returned nil

22:44 but then the /tmp/delme.jpg file doesn't open

22:46 sorry *decode, not *decrypt

22:47 hiredman: the body part of an email is almost certainly not a jpg

22:48 email messages and attachments can be nested in all kinds of creative ways

22:50 twiles: yeah, I think I've taken care of that nesting issure here: (.getContentType (.getBodyPart (.getContent (get-message email-5)) 1))

22:50 -->"image/jpeg; name=\"tinyvices_wayne.jpg\""

22:52 hiredman: I would try .writeTo then, and look at the output

22:55 RazWelles: how do I set the clojure.load.path variable?

22:58 technomancy: RazWelles: I don't think anyone in here knows clojure.clr

22:58 RazWelles: technomancy, damn :\

22:59 how do you set it from inside the java clojure repl?

22:59 maybe its the same

22:59 technomancy: you don't; you have to set it before the process boots

22:59 java -cp ...

22:59 RazWelles: ahh I see

23:01 Frozenlock: Is clojure.clr a complete clojure?

23:10 *crickets*

23:10 I guess there clojure.clr isn't that popular :P

23:11 ambrosebs: IIRC it's not too popular but there are people using it in production

23:11 No personal experience though.

23:11 It's certainly active.

23:23 RazWelles: technomancy, I discovered the solution, you have to create an environment variable called CLOJURE_LOAD_PATH and add your project directory there for 'require to work

23:35 I don't suppose offhand anyone knows the general frequency for the formation of an inhibitory synapse

23:55 technomancy: RazWelles: depends on whether you can reverse the polarity of the neutron flow

23:57 RazWelles: technomancy, whoops, that was meant for another channel but, I never heard of neutron flow in terms of synapses o.o

23:57 technomancy: well once the tachyons are emitted of course there's a much greater range of flux

23:58 RazWelles: ok now you're just being silly :P

23:58 Frozenlock: That wouldn't work anyway; the warp drive would fail before that, cause the dilithium crytals couldn't handle this change.

23:58 RazWelles: xD

23:58 Frozenlock: But you could ask Q.

23:58 technomancy: https://en.wikipedia.org/wiki/Third_Doctor#.22Reverse_the_polarity.22

23:59 Frozenlock: What about the tachyons?

23:59 RazWelles: I still need to watch the older episodes of dr who

Logging service provided by n01se.net