#clojure log - Aug 11 2015

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

0:23 weebz: Hi, I'm having trouble figuring out how to interop with this Java maven project

0:24 The dependency in my project.clj is [org.seleniumhq.selenium/selenium-java "2.47.0"]

0:24 the import in the example java is import org.openqa.selenium.By;

0:26 Shoot, I feel silly. I forgot you have to use import for java things, not use/require

1:35 ttt_fff: how hard is datomic to implement?

1:35 i'm surprised no one has written an open source clone

1:37 oddcully: isnt datascript going that route?

2:01 Empperi: ttt_fff: how hard is postgres to implement?

2:01 hard

2:02 does that answer your question about datomic?

2:03 and datascript is far far away from what datomic is

2:04 it is very interesting though

2:24 wasamasa: well, production-quality databases generally are loads of code :D

3:17 Empperi: indeed

5:03 borkdude: I have a dependency problem in this project: https://github.com/borkdude/ring-problem

5:03 When I start the server (see README) I get java.lang.ClassNotFoundException: ring.middleware.not-modified, compiling:(matchmaker/api.clj:52:7)

5:09 justin_smith: borkdude: I'm confused as to why you would use ring.middleware.not-modified/wrap-not-modified but never require the namespace?

5:09 https://github.com/borkdude/ring-problem/blob/master/src/matchmaker/api.clj#L52

5:10 isn't the solution to require those namespaces?

5:11 borkdude: justin_smith I'll try it

5:11 justin_smith: there's another namespace right next to it that is referred to in full, but never required

5:13 borkdude: justin_smith sure, that's because I stripped down the code

5:13 That's it. Doh. I didn't even think about it, because it worked in a project where I borrowed this code from.

5:13 Thanks!

5:14 justin_smith: Iguess they were taking advantage of the fact that some other code had required the namespace?

5:23 borkdude: I guess so yeah (it was my own code btw)

6:20 axsk: i need to call (execute/run/eval?) some forms with side-effects over a vec of values but also want to construct a seq from their results

6:20 all i could find so far is a combination of doall for do, is there a more idiomatic alternative? should i use loop?

6:22 ,(def a (doall (for [n (range 2)] (do (println n) n)))))

6:22 clojurebot: 0\n1\n#'sandbox/a

6:22 axsk: ,a

6:22 clojurebot: (0 1)

6:29 opqdonut: axsk: yeah that's about it

6:35 spacepluk: where can I see some complex examples of clojure.pprint?

7:21 hellofunk: are there any obvious examples I can try at a REPL that show pmap actually performing better than map? i keep trying and cannot find one, using a 2-core machine

7:27 oddcully: hellofunk: you are doing something cpu intensive in your fn? otherwise the overhead for pmap eats up the gain in absolute time

7:30 ,(time (dorun (pmap (fn [_] (Thread/sleep 100)) (range 42))))

7:30 clojurebot: #error {\n :cause "no threads please"\n :via\n [{:type java.lang.SecurityException\n :message "no threads please"\n :at [clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkAccess nil -1]\n [java.lang.Threa...

7:31 opqdonut: user=> (time (let [fact (fn [n] (apply *' (rest (range (inc (bigint n))))))] (doall (pmap fact (range 1000 1010))) :done)

7:31 )

7:31 with normal map I get

7:31 "Elapsed time: 12.591812 msecs"

7:31 "Elapsed time: 6.443782 msecs"

7:31 :done

7:32 had to jump through too many hoops not to get overflow :P

8:27 noncom: if i have a fully qualified var like #'some.namespace/some-var - then how do i get its name? "some-var" in this example..

8:27 ?

8:29 opqdonut: I don't think there's a nice way to do that

8:29 you could always go via (str #'some.namespace/some-var) of course

8:57 noncom: is it feasible to create a swing gui with seesaw that is reconstructed on each application frame, as per the functional paradigm approach?

8:58 i want to make the changes to the gui instantly visible

8:58 or is swing too heavy for that? or maybe there'll be some issues with threading..?

8:59 tsdh: noncom: Concerning your first question: (:name (meta #'my-ns/my-var)) => my-var

8:59 tdammers: my gut feeling says you'd need to do some transparent diffing somehow

8:59 don't think swing components are built for rapid setup and teardown

9:01 noncom: thanks, guys!

9:37 crocket: When java 9 comes with Jigsaw, will clojure support jigsaw?

10:09 noncom: can anyone give an example, how do i subscribe a checkbox to conj or disj a values to a (atom #{}) ?

10:09 i cannot make seesaw accept my binding... it does not fit the protocol..

10:10 like No implementation of method: :subscribe of protocol: #'seesaw.bind/Bindable found for class: seesaw.core.proxy$javax.swing.JCheckBox$Tag$fd407141

10:14 talvdav: hi, anyone using eclipse with german keyboard layout and can tell me how to type a frickn >@< ??!!!!

10:14 oddcully: isn't that on alt-gr-q?

10:15 crocket: How do people load databases into maps and vectors without ORM in clojure?

10:15 There's table join

10:16 noncom: i've managed with my query, no probelm

10:17 talvdav: oddcully: yeah it is, but it dose not work

10:19 oddcully: deref then ;)

10:19 talvdav: oddcully: :/ or alt+64 on numblock....

10:19 it also dose not work on mac...

10:20 oddcully: at very first glance there is no compose-key-version

10:20 well on osx the "programmer"-keys are even more wierd on de-layout

10:20 talvdav: yeah i know

10:20 oddcully: went US a longlong time ago and never looked back

10:21 talvdav: i got used to it really quick

10:21 well i can't change my keyboard every time a key combo dose not work...

10:21 i can't find any solution on the web

10:21 it semse im the only one with this damn problem

10:21 oddcully: well i dont know how it's nowadays. but at G4 times you just "had to know". not even on third party keyboards

10:25 kavkaz: Whattup clojure fam

10:42 tmtwd: I'm not sure why this example from joy of clojure works : http://pastebin.com/utLrPcR1

10:42 anyone can explain?

10:43 scriptor: tmtwd: line 5 in particular, I'm guessing?

10:43 tmtwd: scriptor, exactly it doesn't make sense !

10:43 oddcully: ~destructuring

10:43 clojurebot: destructuring is http://clojure.org/special_forms#binding-forms

10:44 scriptor: tmtwd: look into clojure destructuring, it lets you extract data from more complex structures

10:45 tmtwd: well --- the example is from a chapter about destructuring .... :)

10:46 scriptor: sure, but joy of clojure isn't really meant for beginners

10:46 so if you aren't already familiar with destructuring, those chapters aren't very helpful, honestly

10:48 tmtwd: fair enough

10:49 socksy: tmtwd: map destructuring looks like {symbol-to-refer-to-keyword :keyword-in-map}, and if you put `:as blah` at the end, then you can refer to the map in general as blah

10:50 tmtwd: oh so in this example it just ignored the 'symbol-to-refer-to-keyword' part?

10:51 socksy: yes

10:52 also, since most people just do {keyword1 :keyword1 keyword2 :keyword2 :as map-name}, this is usually shortened to {:keys [keyword1 keyword2] :as map-name}, but I'm sure that comes up too

10:53 this is a good blog post explaining it: http://blog.jayfields.com/2010/07/clojure-destructuring.html

10:53 tmtwd: socksy, but in my example we still need a 'symbol-to-refer-to-keyword' even if we ignore it?

10:54 socksy, thanks I'll check it out

10:54 socksy: tmtwd: nope, don't need it if you don't refer to it

11:22 timvisher: all of our services are configured to run nrepl/http listeners directly from main. as such, we don't use lein ring or anything and just use `lein run`. our vms right now are getting crippled with all the memory baggage. do i loose anything important by going to `lein trampoline run`?

11:41 binjured: how can i get result# in this macro to reference the correct gensym in the let, instead of creating a new one?

11:42 (defmacro t [first-only]

11:42 `(fn [stuff]

11:42 (let [result# (some-func stuff)]

11:42 ~(if first-only (first `result#)))))

11:48 broma0: anyone familiar with the library Korma?

11:48 puredanger: binjured: get rid of the second `

11:48 binjured: puredanger: yeah, tried that, "Unable to resolve symbol result#"

11:49 so far the only way i've managed is to write a function that just takes result# and ~first-only and does the `if` in there.

11:51 chouser: binjured: You'll probably need to use gensym instead of a symbol#

11:51 binjured: chouser: for res?

11:51 justin_smith: binjured: also you need it to be (fn [stuff#] ...)

11:52 ,(defmacro t [f] `(fn [c#] (let [result# (range c#)] (when ~f (last result#)))))

11:52 clojurebot: #'sandbox/t

11:52 chouser: actually, there's a deeper problem

11:52 justin_smith: ,((t true) 8)

11:52 clojurebot: 7

11:52 justin_smith: ,((t fals) 22)

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

11:52 justin_smith: ,((t false) 22)

11:52 clojurebot: nil

11:52 binjured: yeah, my bad, the actual version has stuff#

11:53 justin_smith: that's essentially the macro you want

11:53 binjured: the thing is you only want to apply ~ to first-only

11:53 chouser: binjured: You can't, at compile time, call 'first' on the value of result, which will only *have* a value later at runtime

11:53 justin_smith: the rest should not be unquoted, it is generated inside the ` form

11:54 binjured: justin_smith: yeah, now i have (if ~first-only (first res#) res#) so it ends up looking like (if false ...) or (if true ...) rather than evaluating that at macro time, which seems less ideal but has the advantage of working.

11:54 justin_smith: chouser: I had assumed some-func was to be called at macro compile time

11:54 chouser: it would make sense that way

11:54 binjured: first-only is evaluated at macro time

11:55 binjured: yeah, not the `if` though

11:55 chouser: justin_smith: maybe I'm confused. Your example is calling range at runtime

11:55 justin_smith: binjured: sure it is, all the stuff in that if body is known at macro time

11:55 chouser: oh, wait...

11:55 binjured: the macro expands to (if false (clojure.core/first res__67032__auto__) res__67032__auto__)

11:56 chouser: ...and some-func's parameter isn't known until runtime either, so I'm quite confused.

11:56 ah

11:56 ok, first is to be run at runtime.

11:56 binjured: yes sorry to confuse

11:56 chouser: so, yeah, gensym.

11:57 binjured: if first-only is passed to the macro, i want the macro to emit (in part) (first <gensym var>) otherwise emit <gensym var>

11:58 chouser: right

11:59 (defmacro ... (let [result-sym (gensym)] `(let [~result-sym ...] ~(if ... `(first ~result-sym)))))

12:00 foo# is nice, but unfortunately can't always be used.

12:02 binjured: perfect, thanks! is it just because # is ambiguous given the scoping and evaluation?

12:02 i guess i couldn't move `result-sym` up to the macro let without using gensym

12:19 chouser: usages of foo# in different syntax-quote blocks generate different symbols. I suppose this is to keep them from capturing each other accidentally.

12:20 ...but it means that if you want the same generated symbol in more than one syntax-quote, you can't use foo# and have to reach for good ol' gensym instead.

12:53 {blake}: Wow, Java 8 is all about the lambdas.

12:54 arrdem: Lambdas, invokeDynamic and other cool invokeDynamic enabled things :D

12:55 {blake}: I feel like FP is winning the argument. =P

12:56 It's ridiculous how much Java code gets less boiler-plate-y.

12:56 arrdem: https://i.imgur.com/Sex1E8m.jpg

12:57 Licenser: Is updating clojurescript prjects incredible daangerous or am I doing things horriby wrong?

12:57 {blake}: arrdem: lol

12:57 Licenser: Yes?

12:58 Licenser: every time I try to do any kind of update it ends up with some impossible to treck errors like 'Can't dynamically bind non-dynamic var: clojure.tools.reader/resolve-symbol' (or others)

12:58 {blake}: What is "any kind of update"?

12:59 Licenser: I'm slowly creeping up but I think it's mostly related to nrepl/piggyback things like that but the error doens't give much hint

13:02 I did the big mistake to run a ancient upgrade w/o picking a single thing to update so I'm going through it one by one now trying to find out what exactly caused it but boy is that no fun :P

13:03 {blake}: Licenser: I concur! In my case, the error only turns up in deployment under Wildfly.

13:03 Track THAT down.

13:03 Licenser: oh boy

13:04 {blake}: But normally, I find updates pretty painless. The Clojure 1.7 upgrade was quite nice.

13:04 Licenser: they are great if they work

13:04 but with the whole cljs stuff there are so much things that depend on eachother and don't strictly enforce versions that argh it just keeps killing me

13:04 well partially perhaps because I have no idea what I'm doing ;)

13:05 {blake}: I hate it when that's the problem.

13:05 Licenser: yup

13:05 {blake}: Although, at least there's a solution. You're experiencing that solution right now. =P

13:05 dnolen: Licenser: fwiw trying to use cider/piggieback is a common source of frustration, but also easily avoided

13:06 Licenser: oh that is good to know

13:06 dnolen: some people have succeeded in getting that working in but in 8 months, it's not many people

13:07 Licenser: oh wow that doens't sound incredibly great

13:07 {blake}: dnolen is sort of the Batman of #clojure.

13:07 dnolen: I don't use Emacs for serious Clojure work anymore (all in with Cursive).

13:07 Licenser: :D

13:07 dnolen: I spent a good amount of time making sure that inf-clojure coul work with Emacs

13:07 Licenser: I love my emacs so but I'm happy without a reply for cljs stuff, reload is good enough for me really

13:07 dnolen: er inf-clojure could work with ClojureScript

13:07 {blake}: dnolen: Word to cfleming!

13:08 dnolen: so if you want a decent ClojureScript + Emacs setup, save yourself some time and use that

13:09 Licenser: right now all I want is my code to compile ;) the rest doesn't matter I've given up on REPLs already

13:10 I got started with chestnut but it turns out that was a bit of a mistake, too much magic to easy not to undertand what happens

13:10 {blake}: Licenser: Yeah! I had the same experience with it.

13:10 dnolen: Licenser: you're taking all the wrong turns :)

13:10 Read the Quick Start, figure out how ClojureScript actually works

13:11 Licenser: dnolen that is one thing I am really really really really good at that

13:11 dnolen: then decide what other indirection you want to add to your setup

13:11 Licenser: yea as it so often goes the "need something wokring now" got the better of me, not proud of it

13:12 chestnut was convinient I could easiley add a proxy middleware and just have all my API calls go through the same webserver w/o worrying about reloading the page, or adding nginx or something

13:12 dnolen: yeah I don't know about any of these things really

13:12 I don't use them

13:13 Licenser: I don't know about any of those things either that is a big problem I think

13:28 hellofunk: what is the best swap! strategy to push an item on a vector in something like (atom {:a []}) .. using assoc with conj feels awkward but perhaps best way?

13:29 opqdonut: assoc-in

13:29 justin_smith: hellofunk (swap! a update-in [:a] conj x)

13:29 opqdonut: is meant precisely for that

13:29 hellofunk: opqdonut: assoc-in would require knowledge of the index

13:29 justin_smith: opqdonut: assoc-in would just whipe out the vector

13:29 hellofunk: no?

13:29 clojurebot: no is tufflax: there was a question somewhere in there, the answer

13:29 opqdonut: ok right, update-in

13:30 hellofunk: cool thanks fellas

13:30 justin_smith: I like the way that swap! plus update-in leads to something like backward forth code

13:31 bja: would ((apply juxt fns)) or (map #(%) fns) be preferable?

13:31 clojurebot: Gabh mo leithscéal?

13:31 opqdonut: bja: I'd prefer the latter

13:31 justin_smith: bja: depends if you want it to be lazy I guess

13:32 bja: it's about to be fed into (apply merge), so laziness doesn't matter

13:34 puredanger: in 1.7+ you can use update instead of update-in here

13:35 (swap! a update :a conj x)

13:37 Licenser: dnolen {blake} the issue was, funny enough leiningen, 2.5.2 seems to have issue with org.clojure/tools.render

13:38 {blake}: huh

13:38 Licenser: yup

13:38 the moment I set leiningen to 2.5.2 it causes problems

13:39 dep: Is there any consensus on the best way to do password resets for a website?

13:39 I'm currently eyeing encrypted tokens with Buddy-auth.

13:45 justin_smith: Licenser: do you mean org.clojure/tools.reader?

13:46 devn: Whoa, it's Licenser

13:46 Long time no see

13:46 Licenser: devn indeed :)

13:46 justin_smith yea sorry

13:46 devn I've spend most of my time in erlang land

13:46 justin_smith: Licenser: for a moment I wondered if there was an official clojure raytracer or something

13:47 Licenser: care to bring up your tools.reader issue on #leiningen?

13:47 dnolen: Licenser: more complications, why I just as often as not use Maven directly

13:47 Licenser: haha

13:48 justin_smith sure but I'm not exactly sure what it is so I might not be incredibly much help

13:48 but let me get things actually working first before breaking them agian :P

13:49 justin_smith: I've got 99 problems and most of them are tooling

13:49 sveri: justin_smith: +100^1000000000000

13:51 devn: shortest way to generate an OOME in clojure?

13:52 like a legitimate one, not just throwing

13:52 Licenser: devn limit the memory of your JVM to 129k? (crazy idea)

13:52 opqdonut: yeah e.g. with ulimit

13:52 justin_smith: (iterate #(repeat 1000 %) [])

13:53 devn: justin_smith: good golfin' bud

13:53 justin_smith: that should run out of memory pretty fast :)

13:53 oh, and put a doall on it if you aren't in the repl

13:53 opqdonut: probably not that fast: it has sharing

13:53 justin_smith: (the repl will trigger via printing)

13:53 opqdonut: right?

13:53 justin_smith: ahh

13:53 yeah, the sharing

13:54 opqdonut: #(doall (concat (repeat 1000 %))) or something might work better

13:54 justin_smith: opqdonut: but that doesn't recursively get bigger

13:54 opqdonut: I think it'll still get big enough

13:55 the size grows 1000-fold every step after all

13:55 justin_smith: oh yeah, but put the doall on the iterate, now I see what you mean

13:57 devn: thanks

13:58 opqdonut: now that I'm testing it, I can't run out of memory

13:58 probably gets gc'd too fast

13:59 justin_smith: opqdonut: I'm getting a really tight loop, like not even responding to control-c

13:59 opqdonut: no, the mem usage does grow but pretty slowly

13:59 justin_smith: same here

13:59 devn: maybe ill just make `dd` a 2GB file and read it

13:59 or something like that

13:59 justin_smith: devn: I was being to clever

13:59 opqdonut: this seems easiest:

14:00 user=> (double-array 1000000000)

14:00 OutOfMemoryError Java heap space clojure.lang.Numbers.double_array (Numbers.java:1154)

14:00 justin_smith: yeah, that's the way to do it

14:00 much simpler, less "clever", actually works

14:00 devn: justin we've known eachother on irc long enough for me to recognize you're almost always being clever :D

14:00 justin_smith: hahaha

14:00 devn: opqdonut: nice

14:00 justin_smith: devn: it's a vice of mine

14:01 devn: i have another question for y'all

14:01 KafkaStream can be turned into an iterator, .hasNext will block while waiting for new elements, and .next, well, does what you'd expect

14:02 bja: sends it to the closest NeXT workstation?

14:03 devn: now, what i need is something that works the same way (can be cast to an iterator, has the same behavior on hasNext and next)

14:03 bja: hahahaha

14:03 (inc bja)

14:03 lazybot: ⇒ 3

14:03 justin_smith: devn: huh? I thought .hasNext was a predicate, and .next blocked

14:04 devn: you might be right, i guess i didn't check that, if im being honest

14:04 btw bja, we're a borland shop

14:05 chouser: devn: Maybe java.util.concurrent.ArrayBlockingQueue ?

14:05 amalloy: justin_smith: what if the sequence doesn't know whether it has a next?

14:05 ,(empty? (filter neg? (range)))

14:05 clojurebot: eval service is offline

14:05 devn: heh

14:05 justin_smith: amalloy: hasNext iirc tells you whether something is ready right now, not whether something will ever be ready

14:05 amalloy: no

14:06 justin_smith: no? OK

14:06 amalloy: that's .available() for streams

14:06 devn: chouser: hmm, does that really have the properties i described? I could swar I tried that out last night.

14:06 justin_smith: ahh

14:06 chouser: devn: Depends on how precise you're being, I think.

14:06 kwladyka: why clojure.pprint/pprint works only in REPL?

14:06 amalloy: hasNext is java's equivalent to (complement empty?) in any useful way i can think of

14:06 justin_smith: kwladyka: it works wherever, maybe you forgot to require it/

14:07 chouser: ABQ can't be cast to an iterator, but it has an .iterator method that returns one.

14:07 devn: chouser: maybe i could...reify iterator?

14:07 am i crazy?

14:07 kwladyka: justin_smith, hmm

14:07 devn: wait don't answer that.

14:07 chouser: you could totally reify iterator

14:07 kwladyka: justin_smith, ech my mistake

14:08 chouser: This is to mock kafka for testing?

14:08 devn: yeah, there's a "transceiver" that takes messages in, processes them in a go block, fires them off to the next topic

14:09 kwladyka: justin_smith, is too hot :)

14:09 amalloy: you are talking about mocking an Iterable. that's just a seq. here is an iterable mock: (list 1 2 3). or, (cons 1 (lazy-seq (Thread/sleep 5000 (cons 2 nil)))), if you want one that takes time for whatever reason

14:13 devn: amalloy: we were talking about this yesterday, and I tried to make (doseq [x (seq the-KafkaStream)] ...) work, but it didn't

14:14 im willing to give it another go with loop/recur. I understand what you're saying, just have been unable to get it to work. Probably an error on my part.

14:16 justin_smith: also, as far as i can tell it is hasNext that does the blocking

14:16 FWIW

14:16 justin_smith: devn: yeah, I was wrong

14:17 devn: github is being amazingly and frustratingly slow right now, but I am pulling up an open source part of my current project that might be applicable to what you are doing

14:18 devn: some of this (which has worked great for a while) might be helpful? https://github.com/littlebird/conduit/blob/master/src/conduit/adapter/kafka.clj#L142

14:19 devn: in particular that I need to use the .iterator method on the stream to get an iterator from it

14:19 devn: isn't conduit the old jim duey lib?

14:20 oh nevermind

14:20 justin_smith: devn: I might have unknowingly reused a name

14:20 devn: justin_smith: yeah, this might be interesting

14:20 right now i have a stuartsierra component that creates a consumer and a stream, with a go-loop inside of it that handles messages

14:21 justin_smith: devn: conduit is an abstraction I use in my current product that can wrap either a websocket stream or a kafka topic, with plans to also wrap vanilla core.async and http

14:21 but the meat of the kafka part might be useful for you I think

14:21 devn: justin_smith: so, this is basically identical to what im doing

14:21 justin_smith: haha, nice!

14:21 well mine is open source ;P

14:21 devn: :D

14:22 so here's the thing though

14:22 justin_smith: it's still young though, but it's been working great for a while

14:22 yes?

14:22 devn: write a test that your kafka wrapper works :D

14:22 justin_smith: oh yeah I need to make tests

14:22 devn: because that's the thing i was finding some pain in doing

14:22 i don't want to test with a running ZK and Kafk

14:22 Kafka*

14:22 justin_smith: ahh

14:23 yeah, then it's a question of what level of abstraction to test at etc.

14:23 devn: and it's kind of a pain to mock it out in a way that feels close to useful

14:23 justin_smith: devn: first you need a lib that replicates the kafka api in process, with integration tests that prove (against a running kafka and zk) that its behavior is identical

14:24 then you can write unit tests by swapping in that lib :)

14:24 devn: maybe the sad answer is that i should just set up CI with its own kafka/zk and then if people don't want to run those locally, they can just see how they fare in their PR

14:24 or VM it

14:24 justin_smith: devn: our team is just going to bite the bullet and we are all going to have kafka running on our dev machines, because it is going to be so vital to the architecture

14:25 devn: actually, we *have* a VM

14:25 but configuration matters!

14:25 which is why i was talking to you yesterday about forcing kafka to flush batched messages and such

14:26 justin_smith: yup, I am putting the config file into the repo, gonna have people symlink it

14:26 devn: because when you test 100 go in and 100 come out, and you're using test.check so your payloads are of variable sizes

14:26 justin_smith: right

14:26 devn: and there's batching...

14:26 it's just a colossal pain in the ass to test TBQH

14:27 justin_smith: but, i should back up a bit and say im still really new to kafka

14:27 and there is a *lot* to understand

14:28 there are also a lot of bugs, and that doesn't help

14:28 like, we ran into a bug that's been around for something like 2 years that deals with auto topic creation and topic.offset "largest"

14:29 i must have spent an entire day trying to figure that out, kind of inexcusable. but, again, arguing against myself: I loaded it up with 500,000 messages and wow, this thing screams.

15:07 amalloy: devn: what i'm saying is, if coll is Iterable but not Seqable (as most java/scala collections are), then (seq coll) just dispatches to (iterator-seq (.iterator coll)) internally anyway. see clojure.lang.RT/seqFrom, and compare to clojure.core/iterator-seq

15:08 if you think the two are behaving differently then something *else* is going wrong and waving iterator-seq over it is just a distraction from whatever the real problem is

15:11 arrdem: TIL about #^"" hints

15:11 chouser: arrdem: sorry you had to do that. :-(

15:11 amalloy: arrdem: well it's no different from ^"" hints

15:12 arrdem: amalloy: didn't know that was a thing either... manually specifying the internal name of an object array has sapped some serious will for the day

15:12 clearly we need a type inference engine that knows about into-array :P

15:12 amalloy: arrdem: quick, hack the compiler to add support for ^(array (array int))

15:13 arrdem: amalloy: probably a more useful undertaking than what I'm on right now

15:13 related: http://dev.clojure.org/jira/browse/CLJ-440

15:14 justin_smith: arrdem: the issue of course is that [Lmy.whatever.YOLO; isn't something the reader is going to handle elegantly

15:14 for at least two glaring reasons

15:16 amalloy: justin_smith: of course it's clear why some solution is needed. it's just too bad that specifying the internal name yourself in a string is the one that was chosen, instead of eg what i recommended, or even (defn foo [^[[long]] xs] ...)

15:16 well s/recommended/made up just now/

15:16 justin_smith: haha

15:16 yeah, a psuedo-syntax using vectors would be a nice way to do it

15:17 arrdem: my primary cow is that neither ^"" nor #^"" is mentioned here.. http://clojure.org/java_interop I found an old dnolen ml post from '09 where someone used #^"" and went "hope this still works".

15:17 amalloy: haha

15:20 arrdem: I was otherwise about to hack the compiler to add support for ^ tag fns so that the tag of into-array could be either Object[] or the array of the first parameter :P

15:20 which I was not pleased by

15:27 expez: fipp seems to be able to pprint clojure code now, in addition to EDN, anyone have any thoughts on it compares with say pprint+cljfmt?

15:27 Licenser: dnolen {blake} thanks for your help mates, I ended up ripping out all the reply stuff and it makes it a lot easyer

15:27 Seylerius: Anyone taken a look at clojure-scheme? It seems to be a potentially useful path to binary.

15:28 dnolen: Licenser: there's also a #clojurescript specific channel these days :)

15:28 Licenser: oh I dind't knew that, I feel so outdated

15:29 expez: dnolen: is this still the gold standard for testing if macro expansion is done in cljs context? https://github.com/Prismatic/schema/blob/40f4d623299ada0b99fc381b2bc724d6902602ae/src/clj/schema/macros.clj#L10-L19

15:29 arrdem: expez: I'd go with cljfmt just becuase it is actively maintained for the purpose of printing code whereas fipp just can.

15:29 Seylerius: it's outdated by a fair bit last I checked.

15:30 Seylerius: what do you want/need a binary for? I claim that you probably don't actually have a performance justification therefor, and if you want startup time there's Skummet

15:30 dnolen: expez: you can do it however you like, I don't recommend any particular way

15:32 expez: dnolen: Ok, let me rephrase a little, does that solution rely on what you'd consider implementation details?

15:32 dnolen: Seylerius: at this point Planck probably has the most realistic future for good C integration

15:33 expez: most definitely does, it that breaks we won't care

15:33 expez: dnolen: any chance of adding something for this purpose to core?

15:33 dnolen: expez: nothing specific to ClojureScript

15:34 if anything happens it will be like conditional reading and will apply at least to the three main Clojure dialects

15:35 expez: dnolen: sorry, I meant clojurescript core :)

15:35 dnolen: expez: and I said "no" + details

15:41 http://facebook.github.io/react/blog/2015/08/11/relay-technical-preview.html

15:45 devn: amalloy: ahhhh, i see what you're saying now. miscommunication. i didn't realize you were saying that (seq coll) would wind up being (iterator-seq (.iterator coll)) anyway

15:45 so yes, i cannot use (seq coll) because of the chunking

15:50 justin_smith: arrdem: I think Seylerius was talking about wanting to do systems programming in a lispy

15:51 Seylerius: arrdem: Outdated could be irritating. And no, it's not a performance concern. It's more of a desire to be able to use Clojure's style and data structures on a system level. Scheme can operate at that level, and you could write stuff to run on bare metal in it, but I don't /like/ scheme as much.

15:51 justin_smith is right.

15:52 It's true: once you really start learning a lisp, it starts to spoil you for other languages somewhat...

15:53 scriptor: eh, I liked using C in my OS class, in a masochistic sort of way

15:53 Seylerius: scriptor: Exactly.

15:53 To say nothing of C++.

15:53 Masochism indeed.

15:53 scriptor: the masochism bit was mostly tongue-in-cheek

15:54 * Seylerius grins.

15:54 scriptor: but just like fp can change how you think about programming

15:54 I feel that C and low-level programming in general has a similar effect

15:55 justin_smith: Seylerius: lush has an "interesting" take on doing low level programming in a lispy syntax. It lets you compile functions directly to assembly within the repl

15:55 Seylerius: but it is no scheme to be sure, not to mention being no clj

15:55 tmtwd: how can I change the directory of cider so I can load local files?

15:55 Seylerius: Thanks.

15:55 * Seylerius looks it up.

15:55 justin_smith: Seylerius: the main crux I think is gc

15:56 Seylerius: you'll want to be able to program at a level where the gc is not available yet / is not a reasonable choice (eg. interrupts, bootstrap) and that leads to a hella ugly programming style in a lisp

15:57 * Seylerius nods.

15:57 Seylerius: That makes sense.

16:04 justin_smith: Seylerius: lush is a semi-reasonable old-school lisp with the design goal of being able to do that kind of non-gc code

16:06 arrdem: also inactive... last release was in '09

16:08 justin_smith: yeah, sorry, didn't mean to represent it as current, just apropos to the whole low level systems programming in lisp thing, if I knew something as well developed but more recent I would cite that instead

16:08 arrdem: amalloy: https://www.refheap.com/108106

16:09 halfbaked but should support ^[[[[t]]]]

16:09 because reasons

16:09 justin_smith: arrdem: oh, nested? nice

16:10 amalloy: newInstance.getClass seems like a weird way to do it, but sure

16:11 arrdem: well so you need to reflectively make a new aray of an arbitrary class and get whatever the name for that class is

16:11 or you can string format the "[" weirdness

16:12 amalloy: i'm a little surprised that there's no method like: Class arrayOf(Class c)

16:12 arrdem: I didn't see one but that doesn't mean it doesn't exist.

16:12 amalloy: yeah, i don't see one either

16:13 interestingly the first promising google hit i found was by our own puredanger: https://dzone.com/articles/obtaining-array-class-java-ref (not at all helpful for this situation, as it happens)

16:14 puredanger: something here perhaps: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Array.html

16:15 arrdem: puredanger: that's exactly what I used :P

16:15 amalloy: yeah, it looks like that is the best you can do

16:15 it's just really weird to me that in order to get from a Class object to another related Class object you have to instantiate an instance of one of them

16:15 arrdem: I mean there's nothing stopping you lifting that into static class arrayOf(class)

16:15 amalloy: sure

16:17 arrdem: That patch should also probably have a length check so that ^[t] is OK but ^[t ...] isn't

16:18 sdegutis: ,(nth #{:a :b :c} 1)

16:18 clojurebot: #error {\n :cause "nth not supported on this type: PersistentHashSet"\n :via\n [{:type java.lang.UnsupportedOperationException\n :message "nth not supported on this type: PersistentHashSet"\n :at [clojure.lang.RT nthFrom "RT.java" 881]}]\n :trace\n [[clojure.lang.RT nthFrom "RT.java" 881]\n [clojure.lang.RT nth "RT.java" 847]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eva...

16:18 sdegutis: That should work right?

16:18 ,(rand-nth #{:a :b :c})

16:18 clojurebot: #error {\n :cause "nth not supported on this type: PersistentHashSet"\n :via\n [{:type java.lang.UnsupportedOperationException\n :message "nth not supported on this type: PersistentHashSet"\n :at [clojure.lang.RT nthFrom "RT.java" 881]}]\n :trace\n [[clojure.lang.RT nthFrom "RT.java" 881]\n [clojure.lang.RT nth "RT.java" 847]\n [clojure.core$rand_nth invokeStatic "core.clj" 6933]\n [clojure...

16:18 sdegutis: ,(first (shuffle #{:a :b :c}))

16:18 clojurebot: :a

16:19 sdegutis: Stupid. rand-nth should work here.

16:20 gfredericks: ,(rand-nth (seq #{:a :b :c]))

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

16:20 gfredericks: ,(rand-nth (seq #{:a :b :c}))

16:20 clojurebot: :c

16:20 sdegutis: ,(seq #{:a :b :c})

16:20 clojurebot: (:c :b :a)

16:20 sdegutis: I spose.

16:20 Still stupid.

16:20 ,(seq #{:a :b :c})

16:20 clojurebot: (:c :b :a)

16:20 sdegutis: Haha seq isn't so random after all.

16:20 puredanger: rand-nth uses *nth* which required indexed collection, which set is not

16:20 gfredericks: I don't think it's meant to be nondeterministic

16:21 puredanger: it is definitely not random

16:21 gfredericks: within a single process

16:21 amalloy: gfredericks: incidentally it's kinda a bummer that rand-nth does two traversals over collections which are neither counted nor indexed

16:21 when there is an algorithm available that avoids that

16:21 gfredericks: amalloy: an algorithm that uses a lot more randomness?

16:22 amalloy: well, i think in theory it's the same amount of entropy, but in practice since you only get entropy out 64 bits at a time or whatever, it will use more

16:22 hiredman: having a uniform prob of picking an element without knowing the count seems like it would be tricky

16:23 amalloy: hiredman: it turns out it's actually not

16:23 sdegutis: amalloy: So first/shuffle is efficienter?

16:23 gfredericks: I was thinking amalloy was thinking of (->> coll (map (juxt identity rand)) (apply max-key second) (first))

16:23 arrdem: amalloy: how so? that doesn't seem trivially possible to me.

16:25 hiredman: you could take one of those streaming reservoir sampling things and use it with a reservoir of size one

16:26 which would be pretty similar to that I guess

16:26 sdegutis: Hi amalloy.

16:26 amalloy: one sec while i double-check that i've implemented the algorithm right

16:26 justin_smith: &(reductions (fn [t [i c]] (+ (* t (/ (dec c) c)) (* i (/ 1.0 c)))) 0 (map list [10 9 8 7 6 5] (map inc (range)))) ; running average

16:26 lazybot: ⇒ (0 10.0 9.5 9.0 8.5 8.0 7.499999999999999)

16:27 hiredman: well, I was thinking of weight random sampling, which doesn't make sense in this context (the weighted bit) and without the weighted bit it is almost exactly what gfredericks said

16:29 amalloy: https://www.refheap.com/9b79f6941abe4011529157842

16:30 kwladyka: hiredman, i am not in the topic but maybe http://clojuredocs.org/clojure.core/random-sample ? you said something about random sampling

16:30 amalloy: you walk through the collection, keeping track of the count (N) so far and a candidate return value. at each step, you choose whether to replace your candidate with the current item, with probability 1/N

16:30 and at the end you return whatever candidate

16:30 arrdem: amalloy: nice!

16:31 amalloy: this avoids the multiple traversal, and thus also holding the head of the seq. so you can (random-choose (range 1e7)) if you really want

16:32 justin_smith: amalloy: I wish I had the mathematical / algorithmic vocabulary to describe what my running average example above and this random-choose have in common

16:33 random-choose is actually much more interesting

16:33 amalloy: justin_smith: that's a running average impl, right, not anything related to rand-nth?

16:33 arrdem: a proof of correctness for the one pass select would be really fun.

16:33 amalloy: arrdem: i'm sure it's been done. it's not like i invented the algorith

16:33 justin_smith: amalloy: right, but the common thing is that they both take an unknown number of inputs and can give you an answer at any point

16:33 amalloy: you can apply the same thing to a weighted choice, btw, by tracking the sum of all weights seen, instead of the count

16:33 justin_smith: online algorithm?

16:34 justin_smith: aha! I think that is it

16:34 (inc amalloy)

16:34 lazybot: ⇒ 291

16:34 arrdem: (inc amalloy)

16:34 lazybot: ⇒ 292

16:35 kwladyka: mmm i should do something like (+ 100 justin_smith) ;)

16:35 amalloy: i admit i don't totally get why my implementation is the one that works - i really expected it to start with (next coll), not (seq coll)

16:39 arrdem: amalloy: because you need to with certainty select the 0th element.

16:40 Okay I have the proof of this :D

16:41 if you consider the probability P that any element E is the _final_ selected value, that probability is the product of the telescoping series of the probabilities of not selecting any subsequent element which reduces to 1 over the final cardinality of the seq

16:41 sdegutis: amalloy: hi

16:42 You know, I go back and forth on whether nerd-sniping is unethical.

16:42 Just a single little obscure snippet of Clojure code, and you guys are often gone digging into Clojure's internals and experimenting for like 20 minutes.

16:43 I suppose it would come in handy whenever I need a diversion. But is it ethical? Probably not.

16:43 justin_smith: arrdem: aha, so it contains a similar hidden taylor series to the running average (though more artfully hidden)

16:43 gfredericks: sdegutis: that sounds pretty condescending

16:43 sdegutis: The statistics don't lie my friend.

16:44 gfredericks: okay

16:44 puredanger: I just to joke that the best way to kill an emacs user's productivity was to suggest that there was something that couldn't be done with emacs

16:44 s/just/used/

16:45 bja: I promised my manager that I wouldn't adopt spacemacs until after our next product ships.

16:47 amalloy: the version supporting weighted choice: https://www.refheap.com/ca84e5cc573053b38d23a439c

16:47 sdegutis: puredanger: oddly enough, sniping doesn't work in #emacs

16:47 puredanger: they're like "meh it's possible, go figure it out"

16:48 puredanger: that's a good first approx answer to most things :)

16:49 hiredman: ISample

16:49 arrdem: https://twitter.com/arrdem/status/631205747334885376 yep telescoping series proof

16:57 you could also use this same technique to maintain a buffer of N randomly selected elements...

16:57 justin_smith: arrdem: so for example maintaining a representative sample as a form of profiling?

16:58 arrdem: justin_smith: that was the idea

16:58 justin_smith: reminds me of that notorious mongodb code that used Math.random to decide whether to log or not

16:58 scriptor: justin_smith: you're kidding, right

16:58 amalloy: scriptor: one time in 10

16:58 justin_smith: scriptor: not at all, this is a thing

16:59 amalloy: because otherwise there is too much logging

16:59 justin_smith: I mean sampling of state is a useful thing for profiling, but mixing that up with logging was misguided

16:59 and that is not a thing they do in the current code

17:01 arrdem: hum... so I'm actually not sure how you can do the selection buffer thing without endangering the telescoping series property...

17:05 amalloy: i'm not sure the selection buffer problem is well-defined enough yet

17:08 arrdem: http://arthurdejong.org/rl/ does exactly this it seams...

17:10 amalloy: it's easier if the items don't have weights, as in that example

17:10 justin_smith: arrdem: haha, I started reading and looking at the examples and I was like "oh, I could use this where I use shuf now", then I read closer and saw the part where the author was like "lol, abandoned, use shuf instead"

17:11 arrdem: yeah shuf also appears to do exactly this

17:11 eh I'm not curious enough to clone down and read coreutils today

17:11 justin_smith: arrdem: fun game 'shuf -n 100 /usr/share/dict words'

17:12 or -n 10 even

17:12 then look up the weird ones, of course

17:12 shuf -n 10 /usr/share/dict/words # typoville

17:13 amalloy: justin_smith: the hidden gem in my dictionary appears to be turbinatostipitate

17:14 which i can't even pronounce

17:14 justin_smith: and google for it is very unhelpful too

17:15 amalloy: yeah i think it may not be a real word

17:15 justin_smith: wtf words? I trusted that file!

17:16 amalloy: I bet all the usages of that word on the web are from spambots who used the same dict file

17:16 arrdem: at some point I need to put my aspell dictionary under git control with the rest of my dotfiles because I expect new machines not to try and correct "clojure" or "conj" :P

17:17 amalloy: it looks that way, yes

17:18 justin_smith: you got my hopes up that i was going to learn a cool new word, not get turned into a spambot

17:18 justin_smith: then again, if it was eg. the most rare word of all time, and it was in /usr/share/dict/words and bots were picking words at random from that file, you would expect to see millions of spambot usages of the word for every actual non-spambot usage

17:18 amalloy: so sorry

17:18 amalloy: that shuf command has gotten me gems though, I swear, and in no time this exact chat log will be the top google hit for turbinatostipitate

17:19 amalloy: like schizogenic, just now, that's a word straight out of a ztellman talk

17:20 arrdem: don't say that too loudly he'll get ideas

17:21 justin_smith: oh cool, the "schizogenic double bind" is a concept from bateson, systems ftw

17:43 seangrove: ,(for [[i n] (map-indexed vector [:a :b :c])] [i n])

17:43 clojurebot: ([0 :a] [1 :b] [2 :c])

17:43 seangrove: Any better way to do that?

17:44 justin_smith: ,(map list (range) [:a :b :c])

17:44 clojurebot: ((0 :a) (1 :b) (2 :c))

17:44 seangrove: justin_smith: Constrained to the `for` form ;)

17:45 TEttinger: ,(for [c (map-indexed vector [:a :b :c])] c)

17:45 clojurebot: ([0 :a] [1 :b] [2 :c])

17:45 justin_smith: ,(for [[i n] (map list (range) [:a :b :c])] [i n])

17:45 clojurebot: ([0 :a] [1 :b] [2 :c])

17:45 TEttinger: ,(for [c (map vector (range) [:a :b :c])] c)

17:45 clojurebot: ([0 :a] [1 :b] [2 :c])

17:45 seangrove: Just trying to get an index in my for form

17:54 justin_smith: (apply > (map count "map-indexed vector" "map list range"))

17:54 ,(apply > (map count "map-indexed vector" "map list range"))

17:54 mistaBIZ: is there a way to do that with a str?

17:54 clojurebot: #error {\n :cause "Wrong number of args (2) passed to: core/count"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/count"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [clojure.core$map$fn__4545 invoke "core.clj" 2632]\n [clojure.lang....

17:54 justin_smith: ergh

17:54 ,(apply > (map count ["map-indexed vector" "map list range"]))

17:54 clojurebot: true

17:57 mistaBIZ: so range just counts elements int hat arg?

17:58 justin_smith: mistaBIZ: yeah, it's just a way to attach an incrementing number to each item

17:58 ,(map list (range) [:a :b :c :d])

17:58 clojurebot: ((0 :a) (1 :b) (2 :c) (3 :d))

17:58 mistaBIZ: you damn ninja

17:58 justin_smith: mistaBIZ: each call to list gets one item from each arg

17:59 mistaBIZ: is there a way to sew a str to inc like that

17:59 *get

18:00 justin_smith: it's trickier, are you thinking like [a b c d e] ?

18:00 mistaBIZ: more like "hi' to [[0 1]

18:00 justin_smith: so each letter is numbered?

18:00 mistaBIZ: or map into keys either way

18:01 or keyed

18:01 justin_smith: ,(map list (range) "hello")

18:01 clojurebot: ((0 \h) (1 \e) (2 \l) (3 \l) (4 \o))

18:01 johnnyrichard: how to create an typed java hashtable from clojure hash?

18:01 justin_smith: johnnyrichard: if it's a generic, don't even bother with the types, it's a compiler fiction

18:01 johnnyrichard: generics don't actually exist when you leave javac

18:02 johnnyrichard: justin_smith: thanks man

18:02 justin_smith: np

18:04 johnnyrichard: about hateoas, do you know some library? (cannonical library)

18:04 justin_smith: oh man I almost did a hateoas project once...

18:06 johnnyrichard: justin_smith: how do you make hypemedia for your apis today?

18:06 justin_smith: johnnyrichard: I'm not sure if there's anything really useful, but liberator might be a good starting place

18:06 johnnyrichard: I don't, not working on a publically accessible api atm

18:07 amalloy: i would support mmore cannonical libraries, in general. cannons are fun

18:07 justin_smith: and we have a small team / small app and the internal stuff is at a really ad-hoc stage

18:07 amalloy: trebuchet is taken, but those are super fun too

18:08 or wait, was I thinking of slingshot?

18:13 hiredman: my libraries are all ex cathedra

18:20 TEttinger: hiredman: all my libs need a catheter

18:23 mistaBIZ: to help them relieve themselves into a vector?

18:23 =n

18:27 dbasch: I just learned that if you are using the cookie store in ring’s session middleware and don’t provide an encryption key (which is the default), you might as well be storing the sessions in memory because the encryption key disappears when the server restarts

18:31 justin_smith: dbasch: better than a default key of "hunter2" I guess

18:33 dbasch: justin_smith: but worse than refusing to function if you don’t provide a key

18:34 justin_smith: dbasch: yeah, I guess that's where optimizing for "just run lein new ring my-app and it works" ends up hurting other priorities

18:35 dbasch: if it were a default that would be fine, but this is the wrap-session middleware that you had to include, and you had to tell it to use the cookie store

18:36 it would be perfectly ok for it to throw a “key missing” exception

18:36 justin_smith: oh so this isn't an it-just-works issue

18:36 dbasch: https://ring-clojure.github.io/ring/ring.middleware.session.cookie.html

18:37 amalloy: dbasch: well, it's not exactly the same as just storing the keys in memory. if you have large numbers of keys and a small server footprint, it could be a substantial improvement to make clients store their own cookies

18:37 dbasch: if you have a large number of keys I’m sure it’s important that they survive a server restart

18:46 TEttinger: mistaBIZ: no, because at the very least half of them doesn't work at any given time

20:00 devn: Is it possible to sneak around the fact that you can't pass `loop` as a value (since it's a macro) in this situation: `(with-redefs [my-loop loop] ...)`

20:08 amalloy: devn: in your ideal universe, where this sneak-around exists, what would the above snippet do? it's not at all clear to me what redefining something to be "loop" should mean

20:28 devn: amalloy: instead of running with a core.async/go-loop i was going to swap in loop for it

20:30 amalloy: so that is even more fundamentally unworking because go-loop is a macro, and you can't exactly redefine a macro after the code that's using it has already been compiled

20:31 devn: derp

20:31 * devn looks at the floor, embarrassed

20:47 justin_smith: new feature idea: time travel macros

20:48 TEttinger: I need your clothes, your boots, and your motorcycle

20:48 devn: Heh

21:59 binjured: is anybody aware of a way with prismatic/schema to construct nested records? if i define a record where one of the fields is another record type, map->Foo doesn't create an instance of the nested record.

22:00 justin_smith: binjured: map->Foo isn't part of prismatic/schema, that's a normal clojure record constructor, and clojure doesn't enforce the types of record fields at all

22:01 binjured: justin_smith: ok, well, strict-map->Foo then (AFAIK schema replaces the default map->Foo)

22:01 justin_smith: so you are using an alternate defrecord defined by prismatic/schema ?

22:02 because the definition of map->Foo is a side effect of defrecord

22:02 binjured: yes

22:02 (schema.core/defrecord MyRecord [bar :- BarRecord])

22:06 justin_smith: binjured: it looks like strict-map->Foo doesn't have any feature to auto-initialize fields https://github.com/Prismatic/schema/blob/master/src/clj/schema/macros.clj#L329

22:10 binjured: justin_smith: bummer.

22:12 never could figure out how to implement Schema in a record in a way that would be any use there, either. i'd basically need to walk a record after it's created which is dumb.

22:12 justin_smith: isn't schema more about verifying the structure of things at runtime?

22:13 binjured: yeah

23:45 emperorcezar: Does #clojure-beginners get much traffic?

Logging service provided by n01se.net