#clojure log - May 17 2014

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

0:11 emacsnoob: Emacs Live help. I opened a core.clj file from a Leiningen project in Emacs Live then M-x cider-jack-in but still getting nRepl not connected error when tryiung to evaluate forms

0:34 ty_hayden: Test

0:58 kenrestivo: hmm, i wonder if openjdk will be forced to disappear now? i kind of like using it, or at least having the choice vs the oracle java, for clojure projects

1:01 arrdem: well... Oracle owns Java (and apparently the Java API/JVM) so they're the first ones to fall if they start closing off their platform.

1:02 Wouldn't be the first time they've shot themselves in the face WRT open source software.

1:18 arrdem_: arrdem: ping

1:31 TEttinger: kenrestivo: what is this about openjdk disappearing?

1:32 kenrestivo: TEttinger: dunno, just saw the oracle vs google lawsuit result and wondered what that means for openjdk

1:32 TEttinger: they solved it?

1:32 kenrestivo: broke it

1:33 apparently in this case the API is copyrightable (not all cases, just this one), if i'm reading it right

1:33 so yeah, if i ended up in a world where "to use clojure you must buy a license from oracle" i'd be unhappy

1:34 looking a couple steps ahead into the future, that is.

1:35 TEttinger: more likely, there'd be some new licensing scheme for OSS code that makes the friggin' API open source... grumbling about why it's needed...

1:36 Pandachips: Read the verdict, just.. wow.

1:36 kenrestivo: yep. i hope the OSS world routes around this as if it were damage (which, in my view, it is)

1:36 arrdem: Well 1) Google's gonna appeal. 2) Oracle can't really turn around and sue anyone else until they've beaten Google fair and square (or however lawyers beat people)

1:37 so... who knows.

1:37 TEttinger: the damages could also be 0 dollars

1:38 kenrestivo: yeah, hard to say. i used to follow the world of free software very closely, was a bit of an activist, EFF and FSF supporter, but haven't been paying attention in recent years. stuff like this makes me stick my head up and wonder if i need to pay attention again

1:39 arrdem: can I get a ping? testing irssi notifications

1:39 kenrestivo: arrdem: yo

1:39 arrdem: kenrestivo: cheers. working.

1:41 kenrestivo: arrdem. glad to help. irssi + znc + notification-daemon here. (also andchat on phone and yaaic on tablet, etc)

1:42 arrdem: kenrestivo: ah. I'm running irssiproxy on the server I'm connected from and then using erc over a vpn to get to it.

4:21 TerranceWarrior: patent a vm? just change the mnemonic labels of the vm.

4:59 kzar: Kind of dumb question but I'm trying to figure out how to make an infinite sequence of different combinations of a sequence. Say given the input "abc" you'd get [[\a] [\b] [\c] [\a \a] [\a \b] ...]

5:00 I'm trying to do it in a way that doesn't blow up when things get huge. How I was doing it before I think I mapped the previous items adding the new ones but at a certain point it got too much for my computer

8:10 zerokarmaleft: kzar: (mapcat #(clojure.math.combinatorics/selections "abc" %) [1 2 3])

8:15 clgv: $karma zerokarmaleft

8:15 lazybot: zerokarmaleft has karma 0.

8:19 wagjo: (inc zerokarmaleft)

8:19 lazybot: ⇒ 1

8:19 zerokarmaleft: I don't feel right

8:20 wagjo: (dec zerokarmaleft)

8:20 lazybot: ⇒ 0

8:20 zerokarmaleft: better!

8:30 scape_: how many threads is core.async willing to use on a system when using go blocks? I counted 58 on mine which more than I expected

8:31 unless I am trying to figure this out using an incorrect method

8:31 https://www.refheap.com/85568

8:36 dongl: hi folks. I want to implement a kind of clojure for educational purposes, and trying to do by small steps with tests. How would you go about implementing the compiler or reader?

8:38 scape_: dongl: take a look first at eval and read-string. might get you started, until someone wakes up :)

8:38 dongl: I'd like as a first step for it to evaluate a number to itself, and run adding of integers, so I want to test that '4' evaluates to 4, and (+ 2 3) evaluates to 5. Not sure "evaluate" is the right term.

8:38 scape_: also macroexpand, which helps you understand how many of the core clojure methods expand and look like internally

8:40 perhaps assert will be of help?

8:40 ,(assert (= 4 4))

8:40 clojurebot: nil

8:40 scape_: ,(assert (= 4 3))

8:40 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (= 4 3)>

8:40 zerokarmaleft: dongl: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html#%_sec_4.1

8:40 for scheme, but the concepts transfer easily

8:41 dongl: scape_: maybe. I'll look at your references. I just want a first step that reads a .clj file with "4" or (+ 2 2) etc.

8:41 zerokarmaleft: i'll have a look

8:41 clgv: dongl: what exactly is your educational goal?

8:42 which java matrix library is recommended with respect to calculation speed?

8:42 dongl: clgv: to understand clojure better and how it's built. I can read the source and commits but I want to try myself

8:43 I mean, I read the source and commits, but I need the actual writing to internalize it

8:43 clgv: dongl: I'd write applications/algorithms with it for that goal

8:43 well in fact I did ;)

8:45 scape_: dongl: read-string would technically read a file, using slurp to parse the text. then eval would evaluate

8:45 clgv: scape_: why not just use `read` together with clojure.java.io/reader?

8:46 scape_: because it seems like he wants to do this step-wise clgv .. altogether seems slightly silly since it's not as common as just learning at the repl itself

8:46 but that's my opinion :)

8:47 clgv: huh what?

8:47 dongl: i already know clojure. I want to understand it under the hood

8:47 gfredericks: ways of learning are not silly just by virtue of being uncommon

8:48 clgv: gfredericks: you got any idea what java matrix lib is preferrable?

8:48 gfredericks: I don't think I've ever used any of them

8:50 dongl: what do you mean by implementing a compiler? you want to compile your own simple variant of clojure to proper clojure? or to something else?

8:53 dongl: gfredericks, i guess i want to compile it to whatever clojure is compiled to.

8:54 gfredericks: that's jvm bytecode

8:54 dongl: or at least interpreted as a first step

8:54 gfredericks: that's a much easier first step :)

8:54 dongl: ok, so that one.

8:55 gfredericks: would you rather start by writing your own reader, or use clojure's reader and write your own interpreter?

8:57 dongl: gfredericks: I'm not sure. I want to pretend clojure isn't available as a tool

8:58 But I see rich himself used lisp

8:58 gfredericks: but you're going to write this code in clojure? or in something else?

9:01 kzar: zerokarmaleft: Sorry was afk there, thanks for the tip

9:02 dongl: gfredericks, my constraint is that i can't use clojure and i write the runtime in java

9:03 i will use my clojure variant as soon as i can bootstrap it though

9:04 clgv: dongl: I see you ending up copying frustatedly clojure's java impl ;)

9:04 dongl: i might :)

9:06 what i usually do is decide on some differences. For example, I want everything to be a function, including values. I don't know where it will take me

9:13 zerokarmaleft: dongl: could try gutting Compiler.java, leaving the most primitive bits and adding stuff selectively back in

9:15 crispin: greetings all!

9:17 dongl: zerokarmaleft: very interesting

9:17 crispin: I'm having problems with java interop

9:18 there are two static methods of the same arity, but different types

9:18 and clojure keeps calling the second one, and I want to call the first

9:18 I want to call this: http://rsb.info.nih.gov/ij/developer/api/ij/IJ.html#createImage(java.lang.String, int, int, int, int)

9:18 but it calls the following one

9:18 both are 5 arity

9:19 heres my code: https://bitbucket.org/retrogradeorbit/jamtools/src/1b0ac63c28991be06a4efa00f10d88723515aba0/src/jamtools/core.clj?at=master

9:19 line 69

9:19 I create the right types, but I get java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

9:20 how can I call the first createImage static method?

9:21 dongl: LispReader.java is also interesting. Anyway, I have a lot to look at now. Thanks people

9:22 clgv: crispin:first switch on *warn-on-reflection* then add type hint for string and add conversions for int

9:23 crispin: I have int conversions. Will add the others

9:25 how do I hint the string?

9:25 clgv: ^String

9:25 crispin: ^String and #^String dont work

9:25 do I need them in a vector?

9:25 Im getting Metadata can only be applied to IMetas

9:25 clgv: crispin: line 69?

9:26 crispin: (IJ/createImage ^String "scaled" (int (* w scale)) (int (* h scale)) (int 1) (int depth))

9:26 yeah

9:26 clgv: no there is string constant you dont need a type hin then ;)

9:26 it should work as is

9:26 crispin: ok. then its not working :P

9:26 clgv: do you get any reflection warnings?

9:26 crispin: readong up on how to switch that on now

9:27 clgv: (set! *warn-on-reflection* true)

9:27 then recompile the namespace

9:27 or just that function

9:28 crispin: ok got a bunch

9:28 but on other lines

9:28 clgv: well then that line should work. you can aot compile that namespace and check with a java decompiler that the correct method is called...

9:29 crispin: ok let me see

9:31 man I used one recently but I forgot its name

9:32 clgv: procyon with luyten?

9:32 jd-gui?

9:33 crispin: trying procyon

9:33 i think that was it

9:33 clgv: luyten is GUI for it

9:38 crispin: yep its calling the wrong one

9:38 $ java -jar ~/Downloads/procyon-decompiler-0.5.25.jar target/classes/jamtools/core\$_main.class | grep createImage final Object scaled = IJ.createImage((String)"scaled", (String)RT.intCast(Numbers.multiply((long)w, scale)), RT.intCast(Numbers.multiply((long)h, scale)), RT.intCast(1L), RT.intCast(depth));

9:39 the second (String) intCase

9:39 intCast

9:39 do I need an int type hint, on my int?

9:40 nope that didn't work

9:41 is it the ij clojar?

9:51 ok. tried changing the dep from a clojar ij library to the actual maven one

9:51 no difference. Still calling the wrong method.

9:55 clgv: crispin: no that might be a clojure bug, the auto cast to string

9:55 crispin: are you sure you have the correct version of the library where both methods exist?

10:02 crispin: ok I think I got it

10:02 I decompiled IJ.class

10:02 and there is only one static method createImage

10:03 so the docs are wrong and clojure is working ok

10:03 clgv: crispin: maybe the library version you have is outdated or newer than the docs

10:05 crispin: yeah the api docs on the website could be old

10:11 clgv: so using MTJ (=matrix toolkits java) now

10:25 kras: HI looking for some examples of using read

10:25 trying to read and EDN file

10:25 an*

10:32 martinklepsch: kras (read-string (slurp "file.clj")))

10:34 kras: martinklepsch: thank you

10:35 Just stumbled on this soln on stackoverflow

10:35 (with-open [rdr (reader "/Users/krajoli/gate_parser_dict/sample.edn")] (doseq [line (line-seq rdr)] (println line)))

10:35 trying to understand why we need a doseq here?

10:36 although martinklepsch soln is what I need exactly

10:39 martinklepsch: the reader line-seq reads the file line by line, slurp just reads the complete file at once

10:43 clgv: there is a significant fetish for slurp it seems

10:45 (read (clojure.java.io/input-stream "file.clj"))

10:46 ah well better use with-open around that ;)

10:46 scape_: :)

10:47 clgv: (with-open [s (clojure.java.io/input-stream "file.clj")] (read s))

10:48 kzar: Can you destructure a list to get all but the last items, the last item and then the entire list?

10:50 scape_: drop-last and pop may help

10:50 or peek rather

10:50 clgv: scape_: no peek does that only for a vector ;)

10:50 kzar: no you can not

10:50 kzar: not via destructuring I mean

10:51 kzar: OK

10:51 ty

10:51 scape_: oh right clgv

10:54 clgv: kza: but if you had a vector and not a list you could efficiently (i.e. in constant time) build all these 3 values

10:54 kzar: ^^

10:54 kzar: for a list you'll need linear time

10:55 kzar: clgv: Cool OK I'll use a vector

10:55 :) ty

10:56 clgv: kzar: you'll need peek and pop

11:08 kzar: Is there something like repeatedly that passes in the result from the last call into the next one?

11:10 noidi: ,(doc iterate)

11:10 clojurebot: "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

11:10 kzar: noidi: Ah thanks

12:13 any ideas? https://gist.github.com/kzar/a4a5bfec3105da6077ab

12:13 (When I call my function manually each time it works OK but using iterate like shown it blows up)

12:26 justin_smith: kzar: concat creates a seq

12:26 you want to keep things vectors to use peek and pop

12:27 kzar: ,(concat [1] [2])

12:27 clojurebot: (1 2)

12:27 kzar: ahh

12:27 justin_smith: that's what that exception means - it is saying that you are trying to peek or pop on a seq

12:28 kzar: justin_smith: there a more elegant way than (conj (conj [1] 0) 0) ?

12:28 ,(conj [1] 0) 0)

12:28 clojurebot: [1 0]

12:28 kzar: oops

12:28 ,(conj (conj [1] 0) 0)

12:28 clojurebot: [1 0 0]

12:29 kzar: sweet it's working :)

12:30 tudd: does anyone know much about java interop: specifically around gen-class

12:31 ddellacosta: tudd: go ahead and ask and see. ;-)

12:31 tudd: does :exposes-methods only expose protected superClass Methods..

12:32 scape_: ,(conj [1] 0 0)

12:32 clojurebot: [1 0 0]

12:32 kzar: oh cool

12:32 ty

12:33 ddellacosta: tudd: as opposed to private? Sorry, I don't know...

12:33 tudd: referencing this: https://groups.google.com/forum/#!msg/clojure/H0jg1PQulf0/BnswT4OheLUJ and http://clojuredocs.org/clojure_core/clojure.core/gen-class

12:34 I have a protected Java method ... clojure can find the class but not the method. don't know why...

12:34 and can find the public methods just fine...

12:35 scape_: ,(reduce conj [1] [0 0])

12:35 clojurebot: [1 0 0]

12:37 justin_smith: ,(apply conj [1] [0 0]) another case where apply and reduce do the same thing

12:37 clojurebot: [1 0 0]

12:37 scape_: good point

12:38 tudd: actually just trying to roll a clojure wrapper around bitcoinj : https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java line 185

12:40 via https://github.com/tuddman/bitcljoin/blob/master/src/bitcoin/walletappkit.clj line 32

12:44 sritchie: hey all - has anyone here checked out ztellman's new automat library?

12:45 amalloy: sritchie: i proofread the readme, but haven't tried actually using it

12:46 sritchie: amalloy: I'm writing some code to manage state transitions for various payment transfers to-from stripe, a bank acct, paypal, etc

12:47 amalloy: I'm having trouble figuring out how to map the automat concepts onto a stateful representation - for example, loading up a map out of a database and defining other database operations as state transitions

12:48 bja: in the past, Clojurescript seemed to support compiling .cljs files without namespaces (essentially limiting you to the core language and js interop). Is this still available somehow?

12:48 sritchie: ztellman mentioned in his announcement that he wanted to see folks use this for complex logic on websites - the conceptual leap is pretty big, was hoping to track him down in here

12:48 it's clearer how to use https://github.com/cdorrat/reduce-fsm, for example

14:08 robink: I'm trying to read in a large hashmap (clojure.lang.PersistentArrayMap, hash-map, {}) from a file using edn, but when I do, Clojure complains: "CompilerException java.lang.RuntimeException: Map literal must contain an even number of forms, compiling:(form-init4894105984598281844.clj:1:10)". I'm pretty sure the file (generated with (with-open [edf (io/writer "./outputfile.edn")] (binding [*out* edf] (pr mybighashmap))) ) has an even number of forms in

14:08 the {}, but I'm not completely sure. Would there be something other than an uneven number of forms in a serialized hashmap that would cause that problem?

14:10 Bronsa: robink: you probably have *print-length*c set

14:10 ,(binding [*print-length* 2] (pr {:a 1 :b 2 :c 3}))

14:10 clojurebot: {:c 3, :b 2, ...}

14:11 robink: Bronsa: Oh!

14:11 Bronsa: I had no idea pr limited itself

14:13 Hm, except there's no ... in the EDN output file

14:16 Bronsa: and *print-length* nil

14:16 s/\snil/\ is\ nil/

14:17 Bronsa: robink: then it might be something like ##(pr {(symbol "foo bar") 1})

14:17 lazybot: ⇒ {foo bar 1}nil

14:17 robink: hm

14:22 Huh, works now

14:22 I'll just scrap the files that didn't parse

14:22 maybe I interrupted pr when I was writing the older edn file.

14:23 and the close brace I'm looking at belongs to a child of the root {}

14:23 lemonodor: it does seem like it would be nice to have an edn-writing function, or even just something like CL’s with-standard-io-syntax

14:27 robink: but I'm definitely interested in edn as a way to pass data around between different Clojure(Script) processes or other languages that have EDN support.

14:29 Beats the heck out of Bencode or PHP's serialize.

14:29 I mean, give them points for succinctness but they're pretty ugly formats

17:39 Glenjamin: i never really understood what EDN brought over json

17:42 bbloom: Glenjamin: a big part is right in the name: E is for Extensibility

17:42 how do you encode a date in json?

17:42 whodidthis: + not just stoppid string keys in maps

17:43 Glenjamin: bbloom: i've seen that argument - but what is the difference between "something_date": "2014-01-01" and :something_date #inst 2014-01-01

17:43 either way, i need out of band information to know what to *do* with the date

17:43 bbloom: in the former case, you need out of band information about the schema. in the later case you need out of band information about the "inst" tag

17:44 Glenjamin: but to do anything clever with a date value, i'd need to know what it represents - the schema

17:45 bbloom: but where does that cleverness go?

17:45 Glenjamin: into the application i guess

17:45 bbloom: and that's a problem...

17:45 the important bit is that extensible tags create a phase shift

17:46 if your application cares about dates, or uuids, or precise fixed point numbers, or database connection strings, or whatever other thing you make up....

17:46 you can address the data conversion ONCE rather than at each location you interpret data

17:47 inst is interpreted at read time, not at data analysis time

17:47 for example

17:47 ,(class (quote #inst "2014-01-01"))

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

17:47 Glenjamin: but that's just a richer deserialisation abstraction, isnt it?

17:47 bbloom: Glenjamin: sure, but json doesn't offer that capability

17:47 and it's an important one

17:48 &(class (quote #inst "2014-01-01"))

17:48 lazybot: ⇒ java.util.Date

17:48 bbloom: clojurebot: get your shit together

17:48 clojurebot: Excuse me?

17:49 Glenjamin: so edn readers are forced to have a richer deserialiser, whereas with json you'd have to choose to do that

17:49 and it would be implementation specific

17:49 i can see that

17:50 bbloom: Glenjamin: no, you can't choose that with json

17:50 how would you choose that?

17:50 lemonodor: you write a read-data function that reads JSON then applies further semantics.

17:51 Glenjamin: (expand-types (parse-json '{"abc": "#inst 2014-01-01"}'))

17:51 bbloom: and if i want a string that starts with #inst ?

17:51 Glenjamin: fair point

17:52 bbloom: there are many other wrong solutions one could propose too

17:53 such as looking at keys for a regex /_date$/ -- what happens if i want a date in an array?

17:53 lemonodor: i think offering some additional data types as standard is useful. though i wonder about the utility of #uuid.

17:53 Glenjamin: lemonodor: #whatever is extensible itself

17:54 lemonodor: right, i’m just wondering what motivated someone to include #uuid in edn.

17:54 bbloom: *shrug* i use uuids rarely, but often enough for it to be annoying that json can't represent them as a unique type

17:54 scottj: lemonodor: datomic.

17:54 lemonodor: ah

17:55 bbloom: plus rich did C# development for many years... spend enough time with COM and you'll be acutely aware of how many systems can't handle tagged 128 numbers :-P

17:55 Glenjamin: i'm sold that edn is richer, but i still think that you'll have a part of your application responsible for handing incoming serialised data

17:55 and that part will know about the schema, and how to hydrate into application supported data

17:56 and it seems to me that would cancel out the advantages

17:56 Jaood: Glenjamin: you mean is less practical?

17:57 Glenjamin: Jaood: i'm not sure what you mean - which statement are you referring to?

17:58 bbloom: what about intermediate processes that don't know anything about the schema but still want to offer useful tools?

17:58 Glenjamin: thats an interesting angle i hadn't considered

17:58 bbloom: what about when the schema changes?

17:58 lemonodor: i don’t underestimate the value of a a literal syntax that supports a rich set of types. i feel like one of the best things about programming these days is how many languages finally have a syntax for map literals.

17:59 bbloom: should i always have to support /_date$/ keys even when somebody adds /_time$/ or /_at$/ suffixes?

17:59 lemonodor: i had to listen to common lispers argue that i didn’t need that since you could extend the lisp reader to build hash tables from a custom syntax.

18:00 bbloom: the CL reader seems silly to me

18:00 lemonodor: …for far too long

18:00 Glenjamin: i'm saying i'm unconvinced by generic rich data serialisation, because IME you need schema knowledge to interpret rich data

18:00 bbloom: why have programability if you're not going to go all out? if you have some gimpy weak progamable parser, might as well just cut the power off & gain features... like reliable universal tagging of literals & context-free parsing

18:00 Glenjamin: it wouldn't be /_date$/, it'd be "created_date" => (parseDate)

18:01 bbloom: Glenjamin: right... until you want "important_dates": [....]

18:02 none of the techniques for interpreting data are invalidated by having extensible tagging

18:02 but entire classes of data decoding problems GO AWAY for the 90+% use cases

18:03 Glenjamin: presumably for any incoming data you still need to do a validation pass

18:03 bbloom: nevermind the fact that JSON can't even handle the most basic of deserialization tasks

18:04 Glenjamin: since it's untrusted

18:04 and that pass needs schema knowledge

18:04 anyway, you have convinced me that edn has advantages i hadn't considered

18:05 bbloom: > JSON.parse('23372036854775807')

18:05 23372036854775810

18:05 whoops!

18:05 Glenjamin: heh, that's a javascript issue

18:05 bbloom: which JSON inherits

18:05 Glenjamin: yeah, i see your point there

18:06 of course, if you're sending it to clojurescript you can't win there

18:07 bbloom: Glenjamin: but if you "fix" JSON, you're no longer spec conforming

18:07 Glenjamin: can you put comments in edn?

18:07 that's one of the annoyances of json's ubiquity, people using it for config

18:08 lemonodor: i frequently want to send binary data efficiently, so i tend to start with protocol buffers anway

18:09 and actually, protocol buffers text format is a pretty nice way to do config...

18:11 lots (most?) of google’s internal config is written in protocol buffer text format

18:17 gfredericks: the edn spec says the \; character is a line comment

18:17 and #_ is there as well

19:06 numberten: is there a way to get a random element from an unordered collection such as a set?

19:06 'rand-nth' only works on lists and vectors afaik

19:10 fortruce: when using mongodb + monger, should you def a global connection or use a let in every function to connect to the database?

19:12 gfredericks: numberten: well (comp rand-nth seq) would work of course, but a performant way...

19:28 amalloy: numberten: no; the way sets are stored (as trees) makes it impossible to implement a rand-nth that performs well and selects uniformly at random

19:29 so if you want to choose at random many times, you need to pour it into a vector first

19:29 numberten: alright thanks

19:41 arkh: if I'd like to store code for later execution, e.g. (let [x [] y (conj x '(filter #(= 3 %) (range 1000)))] (comment "blah blah")) , how do I "call" it?

19:41 it's for a query engine, of sorts

19:42 gfredericks: amalloy: if the tree had counted nodes it would be doable

19:42 at least from inside the class

19:42 amalloy: gfredericks: right, if it were a finger tree

19:43 i think it'd be too expensive to just add a count to one of the existing tree types? because then updating a subtree isn't isolated

19:43 dbasch: arkh: probably what you want is letfn

19:44 gfredericks: amalloy: isolated? like in a threading sort of way?

19:44 dbasch: arkh: or inside your let, y should be a fn

19:44 amalloy: no, in that for a persistent collection you only have to update the path from your update back to the root

19:44 gfredericks: I saw an AtomicReference<Thread> inside the node class of PersistentHashMap and wasn't sure why that was needed

19:44 amalloy: gfredericks: that's for transients

19:45 gfredericks: oh of course they use the same nodes

19:45 arkh: dbasch: I need to store the code as functions ... not sure why I didn't think of that first! thank you

19:45 amalloy: maybe i'm wrong, though. it seemed to me like a counted node would necessitate changing the counts of lots of nodes when you update

19:45 gfredericks: amalloy: my gut says the opposite

19:45 amalloy: i think you're probably right

19:45 gfredericks: it could still be a perf issue, just not an assymptotic one

19:46 arkh: dbasch: the idea will be to store a vector of fn's and call as needed

19:47 gfredericks: we need a shorter word for nonassymptotic performance issues

19:48 justin_smith: gfredericks: google hit for "assymptote" http://spikedmath.com/437.html

19:48 amalloy: gfredericks: "uninteresting"?

19:49 fortruce: justin_smith: that's beautiful :p

19:50 hyPiRion: gfredericks: constant factors

19:54 fortruce: how do i find out the version for clojure contrib so that I can include it in my lein project.clj?

20:20 gfredericks: fortruce: clojure contrib is deprecated

20:21 justin_smith: that'll help me remember how not to spell it

20:35 jsk: hey i was wondering if someone could give me a little push. I'm trying to do a hello world app with ring and following a couple examples but I'm getting 'unable to resolve defroutes in this context' error and AFAIK all my imports are setup right and my class path seems to be right

20:36 https://gist.github.com/jskulski/577d8dad63f1fc90b8a1

20:49 gfredericks: jsk: defroutes presumably comes from compojure, which you're not requiring

20:50 jsk: gfredericks: yes! I knew it was something dumb

20:50 thanks so much

21:00 numberten: does lein repl have a shortcut for auto reloading the current namespace?

21:24 fortruce: does anyone know of a good example of a well tested restful api?

21:24 I'm having a hard time figuring out the best way to test my endpoints

21:35 dbasch: fortruce: twitter is the first one that comes to mind

21:35 fortruce: dbasch: thanks, i'll give it a look

21:46 joshhead: There are no refs or dosync in ClojureScript, but since it is single threaded, am I correct that I can deref or swap! on several atoms in the same function without fear of conflicts? Not sure if that's clear, I can try to come up with an example.

21:50 bbloom: joshhead: you're right... modulo asynchronous callbacks

21:51 joshhead: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L7203

21:51 joshhead: thanks bbloom that's what I thought but I didn't want to gamble on it :)

21:51 bbloom: you'll see no STM or CAS or anything like that

21:57 eraserhd: Is there a useful way to `extend` PersistentVector? I'll have to extend other types as well, right?

21:59 bbloom: eraserhd: clojure doesn't believe in deriving from concrete types - you have to implement all of the interfaces/protocols it implements

22:00 eraserhd: and since all the data types predate protocols, that means there's no good way to use clojure.core/extend or anything like that to mimic mixins or the like... so sadly that means you're on your own to implement the interfaces

22:03 eraserhd: Hrmm. I'm trying to make a splice method which works on strings and persistent vectors. I could use defmulti instead, but ...

22:03 bbloom: if you only want it to work on strings and vectors, there's always if or cond :-)

22:04 eraserhd: ... I'm not sure how to make a dispatch fn that allows it to be extensible.

22:04 Yeah... I could.

22:04 bbloom: sounds like you're coming from an OOP background where you want to add a method to an object to extend it

22:04 ... we don't do that :-P

22:04 just use regular functions

22:05 it only makes sense for something to be a method or protocol or the like if you want fast single dispatch by type

22:05 you can also argue that it needs to be a method if you want encapsulation, but we don't really believe in that all that much either here... on account of immutability and all :-)

22:06 if you only expect to have a few cases, use if or cond. if you expect to have many, use a multimethod. if you know what you're doing, consider protocols if you need fast single dispatch

22:06 eraserhd: I'm really curious about what's going to happen with encapsulation as my project gets larger... :)

22:07 Oh, and you've made me realize the protocol/defmulti is, er, premature extensibility.

22:07 bbloom: yup

22:07 encapsulation is overrated :-)

22:08 kenrestivo: i don't see too many clojure projects that are obsessed with encspsulation the way so much java is

22:08 it's like java is a game of tetris where the peices never fit together

22:14 eraserhd: Hey, I'm at 980 lines of clojure. Not bad.

22:15 Not counting tests.

22:17 dbasch: kenrestivo: I wonder what’s the largest clojure project out there, from an organizational standpoint

22:17 in Java there are codebases shared by hundreds / thousands of developers

22:18 fortruce: as I beginner to clojure I have a hard time figuring out the best way to structure my projects though :/

22:18 eraserhd: ,(empty "hello?")

22:18 clojurebot: nil

22:18 eraserhd: ?

22:18 bbloom: fortruce: the answer is 1 big file until it hurts

22:18 fortruce: a few thousand lines in a single .clj file isn't that unusual

22:19 dbasch: (doc empty)

22:19 clojurebot: "([coll]); Returns an empty collection of the same category as coll, or nil"

22:19 dbasch: (doc empty?)

22:19 clojurebot: "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

22:20 fortruce: bbloom: seriously? or am I being trolled...that seems like a great way to accidentally have name collisions

22:20 bbloom: fortruce: i'm totally serious

22:20 fortruce: bbloom: okay, just checking haha. Maybe I'm just too stuck in the OO thinking with encapsulation

22:21 bbloom: fortruce: i'm not recommending a few thousand lines per file.. i'm saying it's not that unusual

22:21 fortruce: if you're coming from java with one class per file, or ruby/rails with tiny partials each getting their own file, or whatever... stop thinking that way

22:22 you can use namespaces/files to separate out entire subsystems

22:22 fortruce: bbloom: how would you recommend structuring a simple crud rest api?

22:22 bbloom: how simple? if it's a few dozen endpoints, i might just have it all in one file :-)

22:22 fortruce: at the moment its a simple demo application so just 2-3 endpoints

22:22 bbloom: one file.

22:22 period.

22:23 clojure makes it's very easy to move functions between files, what with the pure functions & good namespace support

22:23 so defer that decision until you have to make it

22:23 fortruce: interesting, i'll give it a go. Only 1 namespace per file though?

22:23 Frozenlock: 'only' :-p

22:23 bbloom: yeah, one file == one ns form at the top

22:24 eraserhd: OK, so in lisp... hell, back in Scheme in 2004, I have always wanted tests right below each function.

22:24 fortruce: alright, thanks, i'll throw it all in 1 file and see what happens :)

22:24 eraserhd: People often leave (comment ...) there, I think this shows that people actually want this ...

22:25 Has anybody done it in clojure?

22:25 bbloom: eraserhd: big (comment ...) blocks at the bottom of files are common too

22:25 eraserhd: I saw the ^{:test ...} thing. That's really cool, but nobody seems to really use it.

22:25 bbloom: inline tests are not common at all

22:28 fortruce: i was just thinking about tests inline right after the functions but it feels like it would just make it hard to navigate and see all the code

22:28 but would probably be a better way to motivate me to write the tests

22:32 KeithPM: Good day. Could someone help me out of this fix? I am trying to implement memoization in a map but the map is immutable, how can I overcome that? https://gist.github.com/06d638428479e2f759ac.git

22:33 bbloom: KeithPM: use something that *isn't* immutable! like an atom

22:34 fortruce: does 'wrap-json-body' middleware have to come before the api handler? (stupid question)

22:34 KeithPM: OK. I was checking to see whether there was animmutable solution. Usually in a recursive setting we could pass an accumulator but it doesn't fit this model.

22:34 quizdr: anyone in here used the webbit webserver in clojure?

22:36 dbasch: KeithPM: any reason you’re not using memoize?

22:36 KeithPM: Oh I didn't remember it. Let me take a look.

22:39 dbasch: fortruce: I think it probably doesn’t matter, the compojure api wrapper deals only with parameters

22:40 fortruce: so it won’t alter the body of the request

22:41 fortruce: dbasch: thanks, I was actually just forgetting how the threading macro worked for a minute 0_o

23:02 KeithPM: dbasch: Thanks I used memoize and it worked wonderfully

23:02 dbasch: KeithPM: np

23:24 lemonodor: anyone know of an existing emacs flymake mode for clojure? (compiling, not just kibiting)

23:43 johnjelinek: hihi all

23:43 how's it goin'?

23:44 does anyone have a recommendation on getting a live coding environment with om + emacs?

23:44 the tutorial assumes lighttable

23:44 I think maybe austin is the key, but wanted to get y'alls feedback

23:45 jsk: If anyone has any info on mocking out the file system, I would like to see. Google is coming back blank.

23:53 joshhead: johnjelinek: I have gotten one going. Not sure it's the best way but happy to share. Maybe someone will set me straight

23:54 johnjelinek: joshhead: got it up on github?

23:56 joshhead: johnjelinek, I was thinking it was online, but that was another project. I could upload an example pretty soon

23:57 johnjelinek: joshhead: great! I look forward to reviewing it

23:57 joshhead: I went for minimal dependencies, I think there are some more sophisticated setups

Logging service provided by n01se.net