#clojure log - Jul 20 2015

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

0:35 crocket: Does anyone know how to step into java instance methods in a clojure debug session?

1:26 Does anyone use :fill-rolling appender inb unilog?

1:26 Does anyone use :fill-rolling appender in unilog?

1:26 Does it ever work for you?

4:27 divya: `(for [x# ["one" "two"]] ~(symbol (str "(calculate-" x# ")"))) .. I'm trying to evaluate dynamic functions based on values passed, but the auto-gensym causes trouble. Can anyone please help to solve ?

6:20 tgoossens: i'm unable to create a table (H2 database) using clojure.jdbc

6:20 I can select tables from information_schema

6:20 so the connection is there

6:20 (j/execute! db ["CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"])

6:20 => [0]

6:24 kwladyka: tgoossens, are you sure it didn't create this table?

6:24 if not exception error it should success

6:24 i guess

6:24 and be sure to not have this table before run this command

6:25 and... use migrations, don't create database structure in that way

6:31 tgoossens: kwladyka, the table does not appear in information_schema.tables

6:32 kwladyka: tgoossens, did you refresh GUI? did you try paste this SQL directly and check errors?

6:33 tgoossens: kwladyka, {:subprotocol "h2", :classname "org.h2.Driver", :subname "mem:test", :user "", :password ""}

6:33 i'm using H2 in memory btw

6:35 kwladyka: cant be sure how it looks with H2 in memory but for postgresql (def db {:subprotocol "postgresql" :subname "//localhost/clojure" :user "clojure" :password "secret"})

6:36 tgoossens, maybe user cant be empty?

6:36 but still you should get some exception i think

6:38 if not try use this SQL directly in H2, i don't have better idea :)

6:52 crocket: Is there a better way to write https://www.refheap.com/106730 ?

6:53 I want it to be more concise.

7:01 (reduce-kv #(assoc %1 %2 (name %3)) overrides)

7:16 lodin_: crocket: You can do (map #(update 1 name) a-map) instead of using for.

7:16 err, #(update % 1 name)

7:17 crocket: But I'd just write a map-vals (or use any utility library that defines it already), and do (map-vals name a-map).

7:20 crocket: I used (reduce-kv #(assoc %1 %2 (name %3)) {} overrides)

7:21 lodin_: crocket: Personally I have a utility function map* that is a multimethod that essentially is (into (empty xs) (map f xs)), but it doesn't reverse the order for seqs and lists.

7:21 crocket: lodin_, (map #(update % 1 name) a-map) emits a sequence.

7:21 lodin_: crocket: for does too.

7:22 crocket: lodin_, (reduce-kv) is the most concise.

7:22 lodin_: crocket: I think map-vals is if ever do it more than once. :-)

7:24 (map-vals name a-map). Hard to beat.

7:25 crocket: Write a macro

7:27 (defmacro map-vals [fn & maps] `(into {} (map ~fn ~@maps)))

7:27 Ha

7:28 oops

7:28 lodin_: Why macro?

7:29 wasamasa: drunk with power

7:29 lodin_: haha

7:30 wasamasa: looks like apply could solve that one

7:34 lodin_: crocket: I would guess that using into would be more efficient since it uses transients, but I don't have anything to support that.

8:30 Ah. kv-reduce uses Java methods for built-in data types.

9:49 kwladyka: How to write this code more beauty? https://www.refheap.com/52cb9e4cae3109242f39b4731

9:50 i don't like the way how i use concat 3 times

9:53 Lollypop_: hey does anyone know if you can make spigot plugins with clojure?

10:41 tgoossens: I have no idea where the nullpointer comes from. https://gist.github.com/tgoossens/1c4506e7c36b4409fbe4 . When I manually execute thsis function step by step in reple no problem.

10:41 BUt when I run it

10:41 (.getTuple t key)

10:41 gives nil

10:41 is there a problem with using let in doseq or something,

10:52 crocket: hi

10:54 Can I justok

10:54 It seems I can load new clojure modules during runtime.

10:55 If the current directory is in classpath, I put some .clj files in the classpath and let my program dynamically require them.

10:55 Or, I could use an integrated REPL to (require them)

10:56 Brilliant

11:05 noncom: what's the clojure way to get a base64 of a string?

11:12 dstockton: noncom: data.codec has an encode function https://github.com/clojure/data.codec/blob/master/src/main/clojure/clojure/data/codec/base64.clj#L230

11:12 noncom: yeah, well, ended up with this: https://github.com/xsc/base64-clj it is simpler...

11:12 dstockton: or that, yes

11:13 noncom: i just thought it'd be present out-of-the-box, but no

11:13 dstockton: you could use some java interop

11:13 noncom: yeah, java :)

11:46 Empperi: it's not bad after java 8

11:46 it has built in base64 encoding

11:47 some javaisms though like you need to get an encoder first before you can encode

11:47 but nothing terrible

11:56 noncom: Empperi: yeah, but i thought, you know, like (one-word-fn-does-all-magic ...) like they wrap the java.io ...

11:57 i have a basic cli utility architecture question

11:57 say, i am building a jar, and from the cli i want to be able to launch different fns from different nses

11:57 what is the best way to organize this?

11:57 currently i am passing something like "(my-ns/my-fn {args})" as the string arg and eval it

11:57 maybe there are better alternatives?

12:02 justin_smith: noncom: use java -cp your.uber.jar clojure.main your.ns/your-fn

12:12 noncom: justin_smith: alright, waht about apssing params? them just go next?

12:12 do i write them in quotes like " ?

12:12 justin_smith: noncom: hmm - I'm gonna have to experiment

12:12 noncom: well, i think, i will experiment, since it's my task to realize this :D

12:13 justin_smith: noncom: I'm also interested in knowing the answer

12:13 noncom: cool, then someone of us will do it faster.. i'll get to this today, when i finish the script

12:13 and upload it to the CI

12:13 btw, are you using any CI?

12:15 justin_smith: noncom: java -cp your.uber.jar clojure.main "(require 'my.ns) (my.ns/foo \"some arg that is a string\" 1 :a)"

12:15 noncom: i've managed to push it to use clojure on our CI :D

12:15 oh, that

12:15 justin_smith: noncom: CI? no, I should be

12:16 noncom: yeah, I think unless your function is called -main, that's the one way to do it

12:16 if it is called -main, you can just pass the namespace name, followed by args (all will be passed as strings)

12:17 noncom: I definitely do the "more than one ns has a -main" thing, to support different launch profiles

12:17 noncom: well, my current way is java -jar myjar.jar "(my.ns/foo {argzz})" and i require the my.ns into the main ns beforehand ...

12:17 our approaches are similar

12:17 justin_smith: yes

12:18 the -jar thing works? it doesn't just hand that string to your -main in your main ns?

12:33 egogiraffe: quick question: was reading ch.6 in Joy of Clojure and punching in these lines of code for comparing rest vs. next into my repl, and i get, well, not what the book expects me to get. http://i.imgur.com/bpGJA6h.png book/repl side by side in the image.

12:35 elvis4526: Is it possible to use extend-protocol on a class, and all its derived classes ?

12:36 I used extended-protocol on the JSONWriter protocol with the java.lang.Exception class - is there a way that all derived class from Exception get the same implementation too ? (like PSQLException grr...)

12:38 egogiraffe: this is the second edition of the joy of clojure, as well, so perhaps, although i would find it a bit of a leap, that the mechanics of laziness behind rest & next changed at some point between publication and the current version of clojure? but i'm just spitballing, because it is still v. odd to me that there is that discrepency.

12:42 danielpcox: egogiraffe: that's interesting. i just did it with clojure 1.6.0 and I get what the book expects

12:44 egogiraffe: hm. i shall try it with 1.6.0 as well, and see what it returns for me.

12:44 danielpcox: egogiraffe: and i get what you get when i retry it with 1.7.0

12:44 noncom: justin_smith: yes, it does pass it into -main

12:44 egogiraffe: more interesting yet!

12:45 noncom: justin_smith: there i just (-> args first read-string eval)

12:48 egogiraffe: danielpcox: yes, i get the expected results in 1.6.0 as well. given how recent 1.7.0 was, i thought it would be within the realm of possibility that it could have to do with versions.

12:49 i suppose i should send a mention of this to the authors, so that they can take a look at it and adjust/update accordingly.

12:50 danielpcox: egogiraffe: good plan. I notice there's no difference in next's implementation: https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/RT.java#L596 https://github.com/clojure/clojure/blob/clojure-1.7.0/src/jvm/clojure/lang/RT.java#L672

12:51 puredanger: iterate changed in 1.7

12:56 danielpcox: puredanger: that's interesting

12:57 thanks

13:27 divya: Hey guys.

13:27 why isnt this valid ?

13:27 ~(symbol (str "(function-name)"))

13:27 clojurebot: Huh?

13:31 amalloy: divya: why isn't ~5 valid?

13:32 justin_smith: noncom: OK, so the difference is with the -cp version, you don't need a -main that calls eval

13:32 noncom: justin_smith: turns out to be so!

13:33 divya: what are you trying to do, anyway?

13:33 divya: maybe you give us the full code and state your intent?

13:33 divya: i get your point. Do you see what i'm trying to do ? To construct fn names from a string and evaluate it in a macro. What's the best way to do that?

13:35 noncom: ummm.. something like `(eval (list fn (symbol ~your-string) ~@body)) ?

13:35 (did not test)

13:35 but all in all that does not look like a good idea...

13:35 consing fn names is almost never a good idea...

13:35 justin_smith: noncom: you really shouldn't need eval in a macro

13:36 noncom: ah, probably. there should be a better way

13:36 justin_smith: ,(defmacro dontdothis [] (list (symbol (str "print" "ln")) "foo"))

13:36 clojurebot: #'sandbox/dontdothis

13:36 justin_smith: ,(dontdothis)

13:36 clojurebot: foo\n

13:37 divya: Yeah, I realise it's not a good idea. But I'm just trying to find a way around that.

13:38 noncom: yes, and justing right, macros always have an implicit eval

13:38 *justin, sorry :)

13:39 justin_smith: ,(defmacro dont [s] (list (symbol s)))

13:39 clojurebot: #'sandbox/dont

13:39 justin_smith: ,(dont "newline")

13:39 clojurebot: \n

13:40 justin_smith: this is a terrible way to do things, it throws away nearly everything that is nice about clojure macros, and puts you back in the world of C macros.

13:41 what changed with newer ring versions such that endpoints returning a string cause the error "java.lang.String cannot be cast to java.util.Map" - older ring versions implicitly built a response map with the string under the :body key

13:41 was this functionality moved into compojure or something?

13:42 I mean I can make my own middleware that does that based on the type of the thing returned, of course, but I wonder if the middleware still exists and was moved or what.

13:44 amalloy: justin_smith: forget about terribleness, it just doesn't work because macros run at compile time and you don't have the avlue of this string until runtime

13:44 divya: Justin: Thanks, just curious.

13:44 justin_smith: amalloy: ahh, that too - yeah it will totally break if the arg is not a string literal

13:44 amalloy: justin_smith: do you perhaps have a middleware that expects a map before the point at which ring would have converted a string to a map?

13:45 (and if the arg *is* a string literal then this entire exercise is pointless)

13:45 justin_smith: amalloy: stack trace is in http-kit, with the caller being a future

13:45 amalloy: true

13:46 amalloy: at org.httpkit.server.HttpHandler.run(RingHandler.java:91) - older ring versions turn a string into a map before we get this far

13:46 amalloy: the moral of the story is to never upgrade anything

13:46 justin_smith: it's an implicit conversion that isn't happening any more, changing ring versions changes the behavior (1.3.0 -> 1.3.2+)

13:47 the version where the change happened makes me think it might not have been intentional...

13:48 amalloy: co-worker upgraded lib version (I assume he had a good reason...) he's on vacation now and things are broken on staging. Such is the life of a developer.

13:59 gfredericks: can cljc be used in libraries without requiring users of the library to be on clojure 1.7?

13:59 justin_smith: gfredericks: checking my all-cljc uberjar to see inside right now...

14:00 gfredericks: I'm betting not

14:00 justin_smith: gfredericks: the jar task does not create any clj/cljs tasks here, only cljc source files end up in the jar

14:00 so yeah

14:00 gfredericks: so there's either a several year period where high-profile libs can't use cljc or we need another tool

14:01 amalloy: what is this cljc thing

14:02 gfredericks: amalloy: https://github.com/clojure/clojure/blob/master/changes.md#22-reader-conditionals

14:03 amalloy: oh. it's cljx, blessed?

14:03 justin_smith: and simplified, yeah

14:04 gfredericks: well cljx doesn't have the problem I'm bringing up though

14:04 justin_smith: gfredericks: why several year, because it will take that long before the rest of the world is using 1.7?

14:04 gfredericks: yeah

14:04 justin_smith: gfredericks: I bet we could make a lein-cljc plugin for generating backward compatible jars...

14:04 gfredericks: maybe not, depends on your tolerance for forcing other people to upgrade

14:05 justin_smith: by reading the cljc file in the appropriate way and then prning it back out?

14:05 I'm not sure if a lein plugin would work in my case since it's a contrib project

14:06 justin_smith: gfredericks: yeah, generating clj and cljs which would be after the cljc on the classpath

14:06 ahh

14:09 gfredericks: hmm

14:09 well actually

14:09 if the lein plugin or whatever spit things onto the filesystem instead of just into the jar

14:10 that would probably be useable

14:10 I think you can have cljc/clj/cljs files all in the same jar

14:10 and 1.7 would load the cljc file and 1.6 would load the other files

14:11 justin_smith: gfredericks: right, that's kind of what I was thinking

14:11 puredanger: clj and cljs are loaded before cljc if both exist

14:11 gfredericks: wait

14:11 yes

14:11 puredanger: Regardless of classpath order

14:11 gfredericks: I just went to my gmail and typed "Alex Miller" into the search box in order to answer that question

14:11 because I knew it had come up recently

14:12 puredanger: am I correct that there is a bit more tooling necessary to use cljc from a contrib library w/o requiring users to upgrade to 1.7?

14:12 puredanger: Yeah, can't say that I thought about that enough

14:13 Although I expected it to be adopted much more slowly

14:13 gfredericks: I'm thinking just something that reads each .cljc and spits out a .cljs and a .clj

14:13 and ship all three in the jar

14:13 puredanger: Which is basically cljx

14:13 gfredericks: yep

14:13 well

14:13 puredanger: Ironic

14:13 gfredericks: puredanger: I'm wondering for test.check

14:13 where I suspect cljx doesn't work?

14:14 I'm assuming hudson is only looking at the pom.xml

14:14 puredanger: Yes

14:14 gfredericks: so the most practical thing would be to commit all the files

14:15 puredanger: Although I've been playing with a boot build for contrib (purely experimental right now)

14:16 Mixed platform builds in contrib are a mess, so that's gotta be fixed

14:17 gfredericks: right now we just have two copypasta'd source trees

14:18 so checking in generated files doesn't seem any worse than that

14:22 man just running tests with 1.6 is going to be difficult o_O

14:22 was trying to decide if I should update the generated files on each commit or just before a release :/

14:37 TimMc: It's 2015 and we still don't have a good way of handling generated code.

14:54 wasamasa: sweep it under the rug?

15:00 noncom: we still don't have many things

15:12 justin_smith: gfredericks: what about generating files as a pre-action for making the jar, not checking them into git, and making a test runner that operates on the jar rather than the source for 1.6? I guess that's kind of weird.

15:13 gfredericks: justin_smith: the building-the-jar part still needs to be compatible with lein-free-hudson

15:13 justin_smith: ahh - but it could require 1.7 right?

15:13 gfredericks: I guess...?

15:14 justin_smith: I'm thinking if the build task was abstracted so it could run without lein. But that's probably a pointless rabbithole.

15:15 gfredericks: and then call out to something from maven?

15:15 justin_smith: Yeah. But that's probably more trouble than all this is worth, the more I think about it.

15:16 gfredericks: I dunno, could be less hacky than anything else I was thinking of

15:17 justin_smith: like, if all it took was a read+spit using 1.7 for each cljc file to a new clj file - that could as easily be invoked by a maven task by loading your clojure dep as it could be by lein I guess?

15:17 gfredericks: right

15:43 what is the goodest way to run tests for a cljs lib that has nothing to do with browsers/dom?

15:43 in terms of js runtimes

15:59 justin_smith: oh my god logging library dep collisions are terrible

15:59 yuck

16:00 gfredericks: yay logging libraries!

16:00 or more accurately, yay, logging from libraries!

16:01 justin_smith: gfredericks: if libraries that aren't for logging stopped depending on concrete logger implementations, this could be avoided

16:01 maybe?? I hope.

16:03 gfredericks: I'd like to think that but I like structured logging

16:03 and none of the abstract libraries seem to support that

16:03 justin_smith: gfredericks: ugh.

16:03 gfredericks: maybe we need yet another proxy library

16:04 so your library logs to log-cabin which at runtime proxies to clojure.tools.logging which at runtime proxies to slf4j which proxies to logback

16:04 justin_smith: gfredericks: could call it yalp - yet another logging proxy

16:04 gfredericks: I was thinking log-cabin because it's structured

16:04 maybe just cabin?

16:05 justin_smith: whelp - well heres _ logging proxy

16:05 where _ starts with e and makes sense

16:05 TimMc: e is for underscorE

16:05 gfredericks: why not just whalp

16:05 justin_smith: gfredericks: that works too

16:06 oddcully: gwargl -- the sound you make the last time you had to deal with loggin stuff

16:06 TimMc: welp - we excrete logging proxies

16:07 (Please don't use that.)

16:07 justin_smith: ¯\_(ツ)_/¯ - ¯oggers \ucking _uck (ut ツe )ade _nother /hat ¯ver

16:10 gfredericks: I wonder if tools.logging would ever support structured logs

16:10 there's probably a lot of gross design questions

16:12 mostly related to how it interacts with the impl libs -- i.e., does it serialize before or after?

16:12 it's all terrible

16:12 justin_smith: gfredericks: the hard part is we want features that the old API can't provide, and the old API is made worse by the long list of half-assed improvements that didn't fix things (partially due to their attempts to be compatible with the original)

16:12 which makes me think "burn it all down"

16:13 gfredericks: you'll still have to deal with other people's libraries using slf4j or something

16:13 justin_smith: right, yeah

16:13 gfredericks: though we could implement the slf4j api I guess?

16:13 xemdetia: clojure 1.8.0 now with 4j based logging in core

16:13 * xemdetia dreams

16:13 justin_smith: xemdetia: at least that way we could just pick something I guess

16:16 redcoat: Okay, so something Rich Hickey said in a talk finally clicked with me

16:18 I was discussing STM with someone and how one would implement that for quite sizable data structures in a language without it. They mentioned that compare and swap wasn't the only necessary component; you would also need a write logging mechanism for the retries, and that makes sense to me.

16:18 So that's quite a lot of machinery. But then I remembered what Rich Hickey said about functional data structures: if you use them, then STM only needs to do a single compare and swap on the pointer.

16:20 And if the operations in your atomic block are pure functions, then you're guaranteed to have operationally valid retries. Am I correct in what I'm saying?

16:22 amalloy: that is certainly true for atoms. for multi-object transactions on refs or something, i think you need a bit more but i'm not sure what

16:23 gfredericks: people so rarely use the stm with multiple refs though

16:23 is cljs broken with clojure 1.7?

16:24 I'm getting "Wrong number of args (2) passed to: reader/read" from the cljs.analyzer namespace

16:24 it's probably something else

16:25 justin_smith: hmm, I thought atoms weren't STM? could be I'm misinformed and I am forgetting my source

16:26 amalloy: they're not

16:26 folks just usually don't distinguish between them

16:26 justin_smith: so only refs are STM, atoms and agents are their own things separate from that, right?

16:27 amalloy: no, refs and agents

16:27 gfredericks: with agents you can send things from a transaction and only have it really sent if the transaction completes

16:27 justin_smith: thanks for clarifying. I was going by the fact that clojure.org/refs did not mention agents at all

16:27 aha

16:29 Bronsa: gfredericks: that usually means you're pulling an older version of tools.reader than the one cljs needs

16:29 gfredericks: Bronsa: yeah that was it

16:29 my good ole user profile

16:34 I'm re-pondering rich numeric literals in cljs

16:35 my guess is there's still not a good way to do that

16:36 even with data readers

17:10 ed-g: Hello, does anyone have experience with sending vector data to a database, either as a set or a Postgres array object? I'm using clj-postgresql and attempting to use PGobject with type "anyarray", the postgres driver doesn't like it.

17:10 gfredericks: ed-g: I've done the postgres array thing with integer vectors

17:11 I don't know anything about clj-postgresql though, I was just using java.jdbc

17:11 ed-g: gfredericks, is any of your code open source? I'm trying to pose an intelligent question but I don't know enough context with java databases so it feels like I'm going in circles.

17:12 gfredericks: I think I did it by extending the SQLValue protocol in java.jdbc

17:12 and maybe manually creating the sql syntax for an array

17:12 it's not open source

17:13 ed-g: gfredericks, thanks :-) I'll look into the SQLValue protocol

17:13 (inc gfredericks)

17:13 lazybot: ⇒ 140

17:27 sobel: ed-g: i did this in a sandbox project, and it was pretty easy given a quick google search. it takes like 1-2 lines of code to add the protocol for arrays.

17:27 i'd share but it's at home. it was easy though.

17:32 ed-g: sobel, that's encouraging

17:32 * ed-g may just need to break down and get a book on JDBC

17:33 gfredericks: ed-g: reading the clojure.java.jdbc source is pretty instructive

17:36 sobel: i know jdbc from experience but have never had a book on it. the web got me through easily.

17:36 ed-g: yeah wish I could say the same, I've been working on this for two days now

17:37 gfredericks, thanks I'll check that out

17:37 (inc sobel)

17:37 lazybot: ⇒ 2

17:37 sobel: http://stackoverflow.com/questions/22959804/inserting-postgresql-arrays-with-clojure

17:37 gfredericks: dnolen: the clojure.test vs. cljs.test naming convention would somewhat preclude eventually using cljc in test.check, wouldn't it?

17:37 sobel: was the page that helped me, actually

17:38 dnolen: gfredericks: I don't how

17:38 er

17:38 "I don't see how"

17:38 gfredericks: conditional reading can happen anywhere including ns forms.

17:39 gfredericks: dnolen: but the filenames can't vary

17:40 dnolen: gfredericks: you're not saying anything that makes any sense to me yet.

17:40 gfredericks: dnolen: I'm talking about the test.check codebase, not a user's codebase

17:40 dnolen: gfredericks: still not making any sense

17:40 gfredericks: so currently it has two code trees

17:40 with mostly pasted code

17:41 and I figured merging those into .cljc files would eventually eliminate the copypasta

17:41 but doing (ns #?(:clj clojure.test.check :cljs cljs.test.check)) seems problematic

17:41 dnolen: gfredericks: just pick the same alias ... done

17:42 gfredericks: because the file can't be at .../clojure/test/check.cljc AND .../cljs/test/check.cljc

17:42 dnolen: gfredericks: for imports

17:42 gfredericks: for the main namespace itself you have to be OK with a breaking change.

17:42 but this is a search replace

17:42 gfredericks: you mean renaming cljs.test.check => clojure.test.check?

17:42 dnolen: so IMO not a big deal

17:42 yeah, why not?

17:43 gfredericks: it's fine with me, I wasn't sure how opinionated of a convention "cljs.test[....]" was

17:43 which is why I'm asking you since I figured you came up with it :)

17:43 but it sounds like you don't think it is a big deal from an ecosystem cohesiveness standpoint

17:44 so I will plan on namespace-changing being an option

17:44 dnolen: gfredericks: could have been same since the file extension is the differentiator

17:44 gfredericks: right

17:44 dnolen: but there wasn't a deep reason

17:45 gfredericks: dnolen: cool, thanks

17:46 dnolen: gfredericks: the only thing to be careful of is that test.check was written in a bit of a clean Haskell-ish style, lots of partial and comp instead of #(foo ...)

17:46 * gfredericks perks up

17:46 dnolen: in ClojureScript I made a bunch of smaller minor changes to remove that to get 10X perf bump.

17:46 gfredericks: oooh gotcha

17:46 dnolen: so you will regress perf (which currently is in the Clojure ballpark) if you're not careful.

17:47 ed-g: sobel, thanks! that stack overflow pointed me in the right direction.

17:47 gfredericks: dnolen: time to write some macros for partial and comp maybe :)

17:48 wits_end: I'm trying to get lwjgl3 working but am stuck with UnsatisfiedLinkError and could use a nudge. Has anyone gotten it to work since being released to Maven? Or able to give me a clue on what I'm doing wrong with the path?

17:48 gfredericks: dnolen: how did you do your perf testing?

17:49 dnolen: gfredericks: test.check is slow

17:49 gfredericks: I'm hoping to port the RNG soon so that will be relevant

17:49 dnolen: everything serious is measured in seconds already

17:49 so just ran it's own tests

17:49 and timed that

17:49 gfredericks: oh right I need to figure out how to run its own test suite first :)

17:50 dnolen: gfredericks: there's really nothing to do. lein cljsbuild once test-build-id

17:50 as long as you have Node.js installed, that's it

17:51 gfredericks: dnolen: okay thanks

17:51 dnolen: gfredericks: np!

18:04 ed-g: Ok one more dumb question. How do I create a java array of boxed integers? (make-array Integer/type [1 2 3]) is type [I when what I want is array of java.lang.Integer's

18:06 never mind. object-array is what I need. Thanks everyone for all the help today!

18:06 gfredericks: ,(type (make-array Integer [1 2 3]))

18:06 clojurebot: #error {\n :cause "clojure.lang.PersistentVector cannot be cast to java.lang.Character"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to java.lang.Character"\n :at [clojure.lang.RT intCast "RT.java" 1163]}]\n :trace\n [[clojure.lang.RT intCast "RT.java" 1163]\n [clojure.core$make_array invoke "core.clj" 3839]\n [sandbox$eval25 invoke "...

18:07 gfredericks: what

18:07 amalloy: gfredericks: it's not into-array

18:07 gfredericks: ,(type (into-array Integer [1 2 3]))

18:07 clojurebot: #error {\n :cause "array element type mismatch"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "array element type mismatch"\n :at [java.lang.reflect.Array set "Array.java" -2]}]\n :trace\n [[java.lang.reflect.Array set "Array.java" -2]\n [clojure.lang.RT seqToTypedArray "RT.java" 1719]\n [clojure.core$into_array invoke "core.clj" 3319]\n [sandbox$eval49 invoke "NO_SOURCE_FI...

18:07 amalloy: and of course 1 is a Long

18:07 gfredericks: whatever

18:07 ed-g: gfredericks, I ended up with #(object-array (map int %))

18:08 gfredericks: ,(type (into-array Integer (map int [1 2 3])))

18:08 clojurebot: [Ljava.lang.Integer;

18:08 amalloy: ed-g: that's an Object[] though

18:08 just replace object-array with into-array

18:09 ed-g: amalloy, ok my grasp of JVM is tenuous. I thought I wanted boxed integer but what I actually wanted was array of objects each of which is integer. This fits the protocol for jdbc .createArrayOf

18:11 (inc amalloy)

18:11 lazybot: ⇒ 288

18:11 ed-g: (inc gfredericks)

18:11 lazybot: ⇒ 141

18:11 gfredericks: is `lein test` broken for cljc test files?

18:17 how do you refer macros in cljs?

18:18 amalloy: gfredericks: require-macros with :refer, i'd guess?

18:18 gfredericks: that's what I thought too :/

18:18 wait

18:18 I Mean

18:18 I used

18:19 (:require [thing] :refer [what] :include-macros true)

18:19 I didn't actually try (:require-macros ...)

18:25 dnolen: gfredericks: :include-macros just loads a macro ns with the same name, it interacts in no other way with :require

18:26 gfredericks: you want :require-macros + :refer

18:27 gfredericks: well "interacts in no other way with :require" beyond :as support.

18:31 gfredericks: dnolen: cool, thanks

18:45 justin_smith: oh wow, how did it take me this long to discover this: ##(let [{:keys {a b c d}} {:a 0 :b 1 :c 2 :d 3}] (print a b c d))

18:45 lazybot: ⇒ nil nil nil nilnil

18:45 justin_smith: LOL

18:45 * justin_smith facepalms, head-desks, and goes for a walk.

18:46 justin_smith: the awesome thing is that it somehow makes sure a,b,c,d are all valid for access, but also they are all just nil

18:47 TimMc: justin_smith: That was a short walk and I'm not sure what you're talking about.

18:47 justin_smith: TimMc: ##(let [{:keys {a b c d}} {:a 0 :b 1 :c 2 :d 3}] (print a b c d))

18:47 lazybot: ⇒ nil nil nil nilnil

18:47 * justin_smith actually steps away from the computer now.

18:48 TimMc: justin_smith: Do you mean [a b c d]?

18:54 justin_smith: TimMc: I destructured, I used the wrong kind of brackets, instead of getting any sort of sensible error it just bound all my keys to nil

18:54 TimMc: leading to a lot of head scratching and shotgun debugging

18:55 TimMc: if I had seen the code and read it carefully, I would not have expected b and d to be bound to anything, and I would have been dubious about it running at all

18:55 *compiling

19:14 TimMc: justin_smith: Ah! I see, you're marvelling that it didn't error out.

19:14 justin_smith: right

19:15 the fact that it happily gives me nil so my usage of all those bindings fails...

19:15 it must tree-walk to find all the bindings in the destructure or something?

19:16 TimMc: nothing so fancy

19:16 &(destructure '[{:keys {AAAAA BBBBB}} _])

19:16 lazybot: ⇒ [map__13793 _ map__13793 (if (clojure.core/seq? map__13793) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__13793)) map__13793) vec__13794 (clojure.core/get map__13793 :[AAAAA BBBBB]) AAAAA (clojure.core/nth vec__13794 0 nil) BBBBB (clojure.core/nth vec__13794 1 nil)]

19:17 TimMc: &:[AAAAA BBBBB]

19:17 lazybot: java.lang.RuntimeException: Invalid token: :

19:17 TimMc: &':[AAAAA BBBBB]

19:17 lazybot: java.lang.RuntimeException: Invalid token: :

19:17 TimMc: Oooh, ##(keyword '[AAAAA BBBBB])

19:17 lazybot: ⇒ nil

19:18 TimMc: what is it even

19:19 justin_smith: ,(let [{:keys {a b}}] {(keyword (str '[a b])) 42}] #_#_ now what)

19:19 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>

19:19 TimMc: Some part of that macro knows that [AAAAA BBBBB] is a vector, and some part fails to understand that. :-)

19:20 justin_smith: an oddity

19:20 would be a fun trick for an obfuscated clojure contest

19:20 TimMc: &(let [{:keys {AAAAA BBBBB}} {(keyword "[AAAAA BBBBB]") [5 6]}] AAAAA)

19:20 lazybot: ⇒ 5

19:20 justin_smith: hahaha, of course

19:21 * TimMc takes notes

19:24 TimMc: It's that (if (keyword? %) % (keyword (str %)))

19:28 So it *extracts* the value by keywordizing the LHS, but it then looks at the LHS and sees that it needs to do further destructuring.

19:30 justin_smith: how babby wat is formd

20:53 rpaulo: clojure on my iOS device!

21:06 mfikes: rpaulo: Yeah, you can't really tell it is ClojureScript for most stuff.

21:11 rpaulo: I also dislike Rich's commit messages, but what can I do...

21:19 lvh: Huh. Does unquote-splice inside syntax-quote qualify all syms with clojure.core?

21:20 I have a test fixture macro, and it's complaining that it can't find shrieker.fixtures/is

21:20 err, sorry, qualify all syms with *the macro's ns*

21:21 justin_smith: lvh: that's what syntax-quote is for

21:21 lvh: justin_smith: But the `is` is being spliced in; not part of the macro

21:22 justin_smith: you can pull dirty tricks if you don't want that like ~'foo, or you can just not use syntax-quote

21:22 lvh: `is` is a thing in the calling namespace

21:22 justin_smith: lvh: then you should be properly interning is (I assume test/is)

21:23 lvh: Eh, okay; I'll do without the syntax quote then

21:23 justin_smith: lvh: you can use syntax quote, if you :use clojure.test, or :require clojure.test :refer [is]

21:23 lvh: justin_smith: In the calling namespace?

21:24 I'm already doing :refer :all there

21:24 justin_smith: lvh: in the namespace defining the macro, if you want to call is in the macro

21:24 lvh: justin_smith: `is` is inside the body I'm unquote-splicing into the macro

21:25 justin_smith: lvh: in that case you need to require / refer it in the namespace using the macro, yes

21:25 lvh: justin_smith: hm, adding it to the *defining* ns fixed the error

21:26 oh, *derp*

21:26 justin_smith: ?

21:26 lvh: OK, so I do remember how syntax quote works

21:26 I just forgot that I am actually using is in the macro...

21:26 and, it previously worked because I moved the macro around

21:26 yay global state

21:27 justin_smith: Sorry & thanks :)

21:27 (inc justin_smith)

21:27 lazybot: ⇒ 278

21:30 creese: I'm trying to create a leiningen template and hitting a snag.

23:09 crocket: Are there traps in dynamically requiring a clojure namespace?

23:09 justin_smith: crocket: you can call require at runtime

23:11 crocket: justin_smith, Does a standalone uberjar include the current directory in the classpath?

23:11 Ah, that depends on how I invoke java.

23:12 If I include a specific directory in the classpath, I'll be able to load clojure plugins dynamically on runtime.

23:12 Can I remove a namespace after loading?

23:14 Ah, there is remove-ns function.

23:14 Be careful

23:14 To emulate a plugin system, is it sane to include a directory in the classpath and require a namespace from that directory and remove the namespace later?

23:20 Does require compile .clj files during runtime?

23:23 justin_smith: crocket: yes, clojure always compiles files if you load them.

23:24 if you want to load a specific file, you might want load-file rather than require

23:24 for require to work, the file has to be on a relative path matching the ns

23:24 crocket: justin_smith, I created a .clj file after cider REPL launched and required it to see an e rror.

23:25 Does the namespace in a .cljfile have to match 'path.to.file.filename'?

23:26 justin_smith: yes

23:26 that's what I just said

23:26 that's why you probably want load-file

23:30 crocket: justin_smith, The file is on a relative path matching the ns.

23:30 Ouch

23:30 require failed because there was a typo in my .clj file.

23:30 justin_smith: :reload is your friend here, of course

23:31 but if what you explicitly want is to load a specific file at runtime, load-file might match that better anyway

23:31 if you used something like ScriptEngine with cljs you'd also get sandboxing etc., dunno if any of that matters. Clojure code can do wonky things to the vm / clojure itself.

23:32 crocket: It's weird

23:32 (require 'clojure-test.oho) returns nil without an error, but there is no actual clojure-test.oho namespace.

23:33 justin_smith: crocket: if you don't specify :reload, and it has already tried to load the ns, it will keep returning nil if you require it

23:34 whether it worked the first time, or not

23:34 crocket: ga

23:34 justin_smith: try (require 'clojure-test.oho :reload)

23:34 or you could just use load-file

23:34 crocket: ok

23:35 :reload

23:35 :reload is ok

23:38 It seems require and load-file evaluates .clj files without actually changing the current namespace.

23:38 justin_smith: yes, that's true

23:38 the namespace is changed while code from that file is loaded, and should remain the same in your repl

23:38 the namespace isn't changed if the file doesn't do anything to change the ns though

23:40 crocket: justin_smith, Each file calls (ns) at the top.

23:40 Calling (ns) in REPL changes the current namespace.

23:40 justin_smith: yes, it's different when evaluating files

23:41 crocket: I thought load-file would act as if everything in a file was invoked in REPL.

23:41 ,(doc load-file)

23:41 clojurebot: "([name]); Sequentially read and evaluate the set of forms contained in the file."

23:41 crocket: The explanation was misleading.

23:42 Probably, load-file and require remember *ns* and restore it after they finish.

23:43 This is great

23:43 justin_smith, Have you ever implemented a clojure script module system in any clojure program?

23:50 justin_smith: crocket: no, but I don't do the kind of code where I would ever trust a user to load source files

23:50 well except for some hacking I did on lazybot that is

23:51 crocket: ok

23:51 justin_smith, So, you need a sand-boxed plugin environment.

23:51 justin_smith: I don't think I need one, though lazybot does have one (had one before I worked on it)

23:51 I don't need users to load code at all ideally

23:52 crocket: justin_smith, hexchat has a plugin system.

23:52 It would be fascinating to add clojure scripting capability to hexchat.

23:52 Although hexchat is written in C or C++.

23:54 justin_smith: so you also need to load a jvm...

23:54 * crocket fizzles

23:54 crocket: I'll probably try to embed pixie.

23:55 Pixie is clojure on native platforms.

23:55 It is close to clojure.

Logging service provided by n01se.net