#clojure log - Jun 22 2012

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

1:47 SrPx: Can I use a clojure program as a clojurescript program without any modification?

1:48 bbloom: SrPx: sometimes

1:48 SrPx: clojurescript is not a strict subset of clojure

1:48 SrPx: for example, clojurescript does not have it's own macro system, it uses clojure's

1:48 SrPx: hm

1:48 bbloom: mostly up to date: https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure

1:49 SrPx: good, thanks

2:37 Shambles_: What is the significance of this "core" I see appended everywhere? I originally thought it was just for things built into Clojure, but Leiningen projects create files with that suffix automatically, and I see them in some other projects.

2:38 amalloy: Shambles_: single-segment namespaces are not allowed (or, at any rate, are a very poor idea) for reasons that are somewhat complicated; "core" most of the time means "i couldn't think of a clever second segment"

2:38 borkdude: core, main, default, etc

2:38 Shambles_: amalloy: I see. That helps me understand.

2:39 amalloy: it's often the main "entry point" or exposed-api namespace of an application/library, as well

2:39 Shambles_: I would have expected something like "main".

2:39 borkdude: amalloy the directory structure <-> namespace naming, is that something dictated by clojure or leiningen?

2:40 amalloy: that implies executibility, Shambles_

2:40 borkdude: clojure (and also java, sorta)

2:40 (require 'x.y.z) looks on the classpath for a file named z.clj located in /x/y

2:41 Shambles_: amalloy: I see.

3:18 tsdh: Why won't the second sequence comprehension terminate in http://pastebin.com/aDHY3XEK ?

3:19 The placement of the :while test shouldn't make a difference here, right?

3:24 hiredman: tsdh: for every x you are iterating over y and z, and y and y are infinite

3:24 err

3:24 y and z

3:25 tsdh: hiredman: No, (range 10) ends at 9.

3:25 hiredman: oh, right

3:26 the it is the placement of the :while

3:27 tsdh: Yes, but it shouldn't make a difference here, does it?

3:27 hiredman: for every element of infinite sequence bound to x, create a sequence whose element is bound to y, …

3:27 vs.

3:27 for every element of infinite sequence bound to x, while x is less then 10, create a sequence whose element is bound to y, …

3:28 the creates a infinite sequence of y's before the while kicks in

3:30 tsdh: Hm, well, I somehow agree. But creating an infinite seq is nothing that would block with lazyness.

3:32 I mean, the :while/:when should be tested in every iteration anywap.

3:51 amalloy: tsdh: that :while is only tested when "choosing" a new y

3:51 and only terminates the inner-most (immediately preceding) iteration, in this case the ys

3:52 so xs continue to grow without bound, and zillions of ys are created, each finding that the x you started with is invalid. so that y is discarded, and a new x is tried

3:53 tsdh: amalloy: Ah, ok, that makes sense. I've thought :while would terminate the complete for.

3:53 amalloy: i've thought that too, but no

3:54 tsdh: But does that make sense? I mean, there's nothing more for can compute if any seq is exhausted.

3:54 amalloy: nonsense

3:54 wink: anyone on EC2? Could it be that I lost an Elastic IP because it wasn't associated for 24h?

3:55 amalloy: &(for [xs [[1 2 3] [] [4 5 6]], x xs] x)

3:55 lazybot: ⇒ (1 2 3 4 5 6)

3:55 tsdh: amalloy: Oh, yes, sure.

4:02 bartj: is there any way I can associate a function/protocol to a defrecord ?

4:04 tsdh: bartj: (defrecord Foo [x y] BarProtocol (bar [this] ...)) ?

4:04 bartj: Or what do you mean with "associate"?

4:04 bartj: I mean like in Java classes/interfaces

4:05 I *know* that this is not a functional way to think...

4:06 I would like to write a couple of functions that work on a defrecord

4:06 tsdh: Then define a protocol with the desired signatures, and provide implementation in your (defrecord ...) form.

4:08 bartj: tsdh, I thought defrecord only allowed attributes

4:09 tsdh: No, check (this silly) example: http://clojuredocs.org/clojure_core/clojure.core/defrecord#example_748

4:11 bartj: tsdh, cool, thanks!

4:11 tsdh: bartj: You're welcome. And happy "drinky-drinky" ;-)

4:12 bartj: one last thing

4:13 how is it possible for a defrecord to contain a vector of a other defrecord ?

4:14 example maybe a zoo containing multiple animals

4:14 tsdh: Sure

4:14 bartj: (defrecord Zoo [Animal])

4:14 would be like a single animal in the Zoo :)

4:15 tsdh: bartj: Only implied by the name. (->Zoo [:tiger :snake :pengin]) is a zoo with three animals (happening to be keywords)

4:17 amalloy: bartj: if you want to write a couple functions that work on a defrecord, then...write a couple functions that operate on a defrecord. there's no need to have them be a "part" of that record type with a protocol, interface, or whatever

4:18 (defn count-animals [zoo] (count (:animals zoo)))

4:18 the-kenny: Are namespace-qualified keywords broken in ClojureScript?

4:18 (Those starting with :: in the code)

4:19 tsdh: amalloy, bartj: Unless you are going to have a record per species and the functions act differently depending on an animal's type.

4:19 s/record /record type /

4:19 bartj: amalloy, ok

4:20 amalloy: *shrug* polymorphism is a separate concern, which you can address with multimethods or, indeed, protocols. but if he just wants some functions, that's why rich gave us defn

4:20 bartj: but, like tsdh says, the functions act differently based on the animal's type

4:21 so I thought it would be best to couple the defprotocol to the defrecord

4:24 amalloy: there's nothing wrong with that. but starting with maps and multimethods is an easier, more flexible way to get polymorphism; defrecords are often used (even by me) as just a way to pretend you're still doing OOP

4:25 bartj: ok, thank you amalloy and tsdh for your inputs, much valued

4:25 amalloy: (defn zebra [num-stripes] {:type :zebra, :stripes num-stripes}) (defmulti coolness-factor :type) (defmethod coolness-factor :zebra [zebra] (:num-stripes zebra))

7:50 clange: I'm trying to read in binary data from a file using Gloss:

7:50 (def buffer (byte-array 8)) (.read (input-stream "/home/clange/workspace/first-clj/data/fid") buffer) (decode-all fid-codec buffer)

7:50 The result is vastly negative, but I presume from known data, it should be around zero.

7:51 How can I handle different endianness w/ Gloss (or any other means)?

7:51 cshell: you shouldn't use def there, but rather let

7:52 ie. (let [buffer (byte-array 8)] (.read ....))

7:52 doesn't the jvm handle endianness for you?

7:55 clange: Oh, I see w/ 'let' ...

7:56 I wouldn't think jvm _could_ handle endianness, because I just have an array of bytes whose endianness was defined by the author of the file writing software.

7:57 And now I define codec w/ gloss ... oh, just a moment! I forgot to send the codec-defining gloss line:

7:58 defcodec fid-codec :int32)

7:58 But how could gloos or the jvm know about the endianness of the data read?

7:58 s/gloos/gloss/

7:58 cshell: My understanding is that that is a hardware thing

8:00 ah if you're using a byte array then probably not - but if you had a file of integers or strings, you wouldn't worry about endianness

8:00 clange: Right. And that's why I have to be able to change endianness in decoding data from a file, in case it was produced on a diffently endian hardware (or: "system" in general)

8:01 I do have a file of bytes, where each four bytes comprise one integer ...

8:03 cshell: not sure, but i've never had to worry about byte order when reading in a file - maybe I've only worked with the same endian machines, but they've been a variety from sun, linux, ms

8:07 borkdude: what reasons do hardware designers have to choose big endian over little endian or the other way around - why not always the same?

8:11 cshell: unless those defs are outside of a function, you shouldn't be using def, use let instead or it will slow you down

8:12 borkdude: cshell a common thing that my students did when they first learned clojure

8:13 cshell the expressions clange showed are all outside a function though

8:14 clange: Yes, they are, since I'm only testing. But they'll surely end up in functions, and then your remarks will be of great use. THX.

8:20 borkdude: more coffee!

8:22 foxdonut: borkdude: what roast? milk, sugar, or black?

8:23 <-- medium roast, black

8:31 borkdude: foxdonut espresso, black, a little sugar

8:35 foxdonut: borkdude: an espresso man, huh-- nice! do you use a machine, or one of those little things you put on the stovetop that makes the water shoot up through the coffee and into the receptacle?

8:37 borkdude: foxdonut I have a machine -- I use these beans btw: http://www.italybymail.com/item_list/coffee/segafreda_espresso_casa_beans.html

8:38 foxdonut they are not as expensive here as on that website though

8:42 ro_st: sorry to interrupt an important conversation, but what's the correct way to read values out of the env?

8:42 System.getProperty?

8:42 foxdonut: ro_st: :-)

8:43 borkdude: I've seen those.. are you in Italy/

8:43 ro_st: also, whoever made it so i can seamlessly read the contents of .jar files in emacs needs a -ing medal

8:43 borkdude: ro_st yes, I believe

8:43 ro_st: and some of borkdude's coffee

8:43 borkdude: for example (System/getProperty "user.dir")

8:44 foxdonut no I'm in The Netherlands

8:45 foxdonut: borkdude: ah ok, cool

8:45 ro_st: so if i have an env var of MY_SUPER_DB_URL i can read out "MY_SUPER_DB_URL" ?

8:46 foxdonut: ro_st: is this another one of your crackhead experiments? ;)

8:47 ro_st: oh dear

8:47 borkdude: ro_st hmm good question, or was it System/getenv..

8:48 ro_st: have i already gained a reputation?

8:48 borkdude: ro_st I think I read something about getenv being deprecated, but now I'm confused

8:48 ro_st this is why I need more coffee

8:51 foxdonut: ro_st: it's all good, I have the same reputation in other channels..

8:51 ro_st: -grin-

8:52 foxdonut: nothing wrong with trying stuff out.. that's what nice about software, you can tinker and experiment with little risk of actual physical damage..

8:52 Shambles_: Yesterday someone mentioned that it was a bad idea to have a un-dotted ... I guess it would be a class path or something (e.g. myproject.core is dotted). I've gotten curious as to why that is a bad thing.

8:52 borkdude: ro_st I think getenv is the one

8:53 ro_st I tried this: - in bash: export FOO=123 - in lein repl: (System/getenv "FOO") ;;=> "123"

8:55 _nmmn: , (System.getenv "SHELL")

8:55 clojurebot: #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: System.getenv, compiling:(NO_SOURCE_PATH:0)>

8:55 _nmmn: , (System/getenv "SHELL")

8:55 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getenv.SHELL")>

8:55 _nmmn: hehe =]

8:55 borkdude: ,(System/getProperty "java.version")

8:55 clojurebot: #<AccessControlException java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.version" "read")>

8:55 borkdude: no can do ;)

8:55 _nmmn: well it was worth a try ;]

8:57 ro_st: thanks borkdude

8:58 foxdonut: borkdude, ro_st: getenv is not deprecated, but the Javadocs say getProperty is preferred because system properties are less global, have less side effects, and less subtleties in semantics than environment variables.

8:59 borkdude: foxdonut I now read they were once deprecated, but undeprecated in Java 1.5

8:59 foxdonut: borkdude: ah ok, just to make sure we're confused!

8:59 ro_st: what should i use to read heroku env props? getenv?

8:59 borkdude: foxdonut I have gap in Java history though, last used it around 2003 or so, and I only reached back into the Java world because of Clojure

9:00 ro_st: i'm going to use getenv. to hell with caution. -grin-

9:00 borkdude: ro_st I think you should ask technomancy to make sure

9:03 foxdonut: borkdude: I see.. what were you using in between?

9:03 Shambles_: borkdude: You asked why there were variations in byte order. It's because some operations are faster with one byte order than another. For example, it's faster to do bignum operations on little-endian. It's faster to do numeric comparison and networking (IP networking uses big-endian byte order, so on big-endian hardware there's no need to swap bytes around) on big-endian.

9:03 borkdude: foxdonut Common Lisp, C# and SAS (don't ask about that last one)

9:04 foxdonut: SAS? oh.. never mind. :D

9:05 borkdude: foxdonut also a bit of playing in F#, etc

9:05 foxdonut: borkdude: I have always been in the Java world and yearning for functional programming..

9:06 borkdude: Shambles_ ah tnx for the explanation

9:06 _nmmn: haha borkdude i have similar "situation" with java, havent developed anything on it since 2004 or so

9:06 foxdonut: _nmmn: .net in the meantime?

9:08 _nmmn: nah, trying to move to erlang a bit, would like to get more time for clojure thou :/

9:10 borkdude: gotta go

9:22 Shambles_: Others have probably seen this Clojure video, but I found it entertaining: http://www.youtube.com/watch?v=7XUWpze_A_s It might be something worth showing people who wonder "what the point" is.

9:25 Fossi: nifty

9:31 Shambles_: Fossi: The advantage granted by the ease of redefining stuff on the fly, and spawning the REPL in most IDE's, and not having to wait for a big compile phase, come through in that. I love the 'sticky' bug in the video.

9:33 Fossi: well, it's a little more than that

9:33 clgv: Shambles_: that's the lighttable birth project, so to say ;)

9:34 Fossi: i totally adore the "stop current state" key

9:34 in your usual mutable game engine that wouldn't be possible

9:39 dgrnbrg: what is more() used for in the seq API? i understand first, next, and cons, but it seems like more == next

9:40 cshell: ,(doc more)

9:40 clojurebot: It's greek to me.

9:40 dgrnbrg: it's a method on the java api

9:40 cshell: ah

9:40 dgrnbrg: since ISeq is an interface

9:40 it has 4 methods, but i don't know what more is for

9:41 cshell: is it just leveranged by next or rest?

9:41 er, leveraged even

9:41 i don't have my code up but does more take an int argument?

9:42 dgrnbrg: ah, i see--it looks like it returns empty seq instead of nil

9:42 cshell: if so, maybe it's for getting the nth next

9:44 dgrnbrg: well, i just remembered seqable

9:44 which is a much easier api

9:44 for me, at the moment :)

9:47 dnolen: dgrnbrg: cshell: more is leveraged by rest.

9:47 dgrnbrg: dnolen: what's the difference between next and rest?

9:48 they seem so similar

9:48 dnolen: dgrnbrg: next will return nil if there's nothing left, rest will return the empty list.

9:49 dgrnbrg: that seems like a trivial difference--what's the motivation for them both?

10:03 _nmmn: hm was wondering if its ok if default test suite does not pass 100%?

10:03 sorry wrong room :/

10:05 Shambles_: I'm watching the Light Table video and starting to wonder if this means dataflow programming will see a comeback soon.

10:06 dgrnbrg: Shambles_: it's the only way to program modern hardware, you know?

10:09 Shambles_: dgrnbrg: Well, I dunno about that. Concurrency got 'figured out' quite a while ago (just most programmers didn't get the memo), and the things that seem to work well are dataflow and message passing. At least that. Then there's the option of not using mutable data so a 'race condition' doesn't really matter. I do think it's kind of sad that Lucid just basically died out.

10:11 wastrel: what's lucid

10:12 Shambles_: wastrel: Lucid was a rather nice (i.e. readable, and fairly easy to explain/understand) dataflow programming language.

10:12 clgv: wastrel: http://en.wikipedia.org/wiki/Lucid_%28programming_language%29

10:14 wastrel: thx

10:14 added to my to-read list

10:14 ldopa: dgrnbrg: i *think* next has to actually evaluate it's return value to determine if it's empty and return nil, whereas rest is fully lazy

10:15 dgrnbrg: ldopa: i see

10:16 RickInGA: ,(rest [1])

10:16 clojurebot: ()

10:16 dgrnbrg: ,(next [1])

10:16 clojurebot: nil

10:17 RickInGA: ,(if (rest [1]) 'true 'false)

10:17 clojurebot: true

10:17 RickInGA: ,(if (next [1]) 'true 'false)

10:17 clojurebot: false

10:24 dnolen: dgrnbrg: ldopa: that's correct.

10:24 Shambles_: wastrel: If you're really interested you might want to download this. The physical book is nearly impossible to find now: http://plaice.web.cse.unsw.edu.au/~plaice/archive/WWW/1985/B-AP85-LucidDataflow.pdf

10:24 wastrel: im not that interested :]

10:25 if i had infinite time ... :]

10:25 but thanks

10:26 Shambles_: Okay.

10:26 dnolen: Shambles_: definitely worthy of more investigation. One of Alan Kay's fave langs.

10:28 ldopa: ,(do (rest (repeatedly #(prn :foo))) nil)

10:28 clojurebot: :foo

10:28 ldopa: ,(do (next (repeatedly #(prn :foo))) nil)

10:28 clojurebot: :foo

10:28 :foo

10:29 mytrile: Hey, guys. How can I make list of 1000 elements all 0, then replace 10 of them with 1 and then filter those 10 ?

10:30 gfredericks: mytrile: the way you explain it it makes no sense

10:30 Shambles_: dnolen: It's almost forgotten outside spreadsheets. It has applications in hooking up GUI components (the Cells system for Common Lisp), simulations (things like the fluid simulation in Terraria), and, in tree (no loop dependencies) arrangements, heavy automatic optimization (SAC programming language for supercomputers). Other than SAC everything is pretty 'special case' though. :/

10:30 gfredericks: 1) "filter out" or "filter all but"?

10:31 2) if that's all you wanted to do you could just start with 990 0's or 10 1's

10:31 mytrile: gfredericks: https://gist.github.com/971051827fd54ce6248b

10:31 I want to see what this code will look in Clojure

10:32 gfredericks: mytrile: well (repeat 1000 0) gives you 1000 0's

10:32 you don't normally update data structures in place though, so there's not an exact analogue in idiomatic clojure

10:33 but we can do this with a vector

10:33 ,(let [idx (take 10 (repeatedly (rand-int 1000)))] idx)

10:33 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn>

10:33 gfredericks: ,(let [idx (take 10 (repeatedly #(rand-int 1000)))] idx)

10:33 clojurebot: (548 88 866 248 802 ...)

10:33 gfredericks: so that gives us the indices

10:34 dnolen: Shambles_: I thought some of the ideas were preseved in Mozart/OZ?

10:34 gfredericks: ,(let [idx (take 10 (repeatedly #(rand-int 1000))), data (vec (repeat 1000 0)), updated (reduce #(assoc %1 %2 1) data idx)] (filter #{1} updated))

10:35 clojurebot: (1 1 1 1 1 ...)

10:35 gfredericks: mytrile: ^ there you go

10:35 mytrile: gfredericks: thanks :)

10:36 gfredericks: mytrile: it uses a vector instead of a list, which is much better for random updates

10:36 mytrile: gfredericks: I've read that vectors are optimized for random access

10:37 gfredericks: random access/updates, and adding/removing from the end

10:37 Shambles_: dnolen: There's dataflow variables in it. I think Mozart/Oz is no longer maintained though.

11:10 solussd_: hmm, nailed down a weird "bug". If I call a macro (e.g. in another namespace) from within a (noir) defpage and its expansion refers to a namespace that isn't 'require'd in the current namespace (but is 'require'd in the namespace that the macro is defined in), and I'm using skip-aot: true in my project.clj, I will get a java.lang.ClassNotFoundException for functions in the macro expansion.

11:11 gfredericks: solussd_: the macroexpansion gets evaluated in the namespace that you call the macro from

11:12 solussd_: so that sounds like expected behavior

11:12 solussd_: gfredericks: I understand, but the macroexpansion contains the fully qualified namespace, yet the namespace doesn't get loaded. That is incorrect behavior

11:12 plus, loading the namespace that the macro is in should load that namespaces dependencies

11:13 gfredericks: oh hm

11:13 solussd_: and it only happens in my defpage. :) everything works like a charm in my tests. :/

11:13 gfredericks: solussd_: so outside a defpage it's not an issue?

11:14 solussd_: gfredericks: afaict, yes.

11:14 I can "fix" the problem by 'require'ing all namespaces in the macro's expansion in the namespace that the macro is being expanded in

11:15 this is probably something I should create an example project of demonstrating

11:16 wonder if it is a symptom of some laziness on the part of defpage's expansion(s)?

11:16 TimMc: solussd_: That would be a bug, yeah. However, there's a related known problem: Macroexpansions that use private vars in the macro's ns.

11:17 gfredericks: TimMc: that's unintentional?

11:17 solussd_: TimMc: what's wrong with that?

11:18 does it just not work?

11:18 TimMc: Yeah, just doesn't work.

11:19 solussd_: yeah, that's unexpected

11:19 TimMc: Some other lisps handle that case properly -- I think Racket does.

11:19 gfredericks: solussd_: in the same way that calling the private var directly would not work

11:19 solussd_: well, maybe not, considering how vars are qualified in the expansion

11:19 right

11:19 TimMc: I haven't run into this personally, but it's definitely a bug.

11:20 Well... mis-design.

11:20 gfredericks: I've run into it a number of times

11:20 so I started convincing myself it must be right

11:20 solussd_: TimMc: "this" being my bug, or the private var bug?

11:22 guess you can just intern all private symbols in your macroexpansion in your macro. :)

11:28 ivan: heh, this confused me for a minute until I remembered laziness was going on:

11:28 user=> (with-open [reader (clojure.java.io/reader "/etc/passwd")] (let [lines (line-seq reader)] lines))

11:28 IOException Stream closed java.io.BufferedReader.ensureOpen (BufferedReader.java:115)

11:29 bordatoue: is there a way to get object inputstream reader

11:29 clojure way

11:31 l

11:31 ;*ns*

11:32 could anyone please help me with my query. I need to find out the most suitable way to get access to objectinputstream to deserialise java object or is there any other fn that does deserialisation or should i just use java API

11:34 solussd_: might take a look in the clojure.java.io namespace

11:34 bordatoue: solussd i did that

11:34 solussd: couldn't find anything that would deal with objectinputstream

11:35 solussd_: hmm.. guess use the java api then.. maybe wrap it all in a "with-open"

11:36 ynniv: I'm having issues with java.jdbc and catching SQLExceptions

11:37 bordatoue: solussd: there is a reader that returns bufferedreader

11:37 ynniv: transaction* claims to aid this by rethrowing RuntimeExceptions as their SQLExceptions causes, but this doesn't appear to be the reality

11:42 TimMc: solussd: "this" == private var bug

11:56 bordatoue: is there any command to load all the jar files in a directory

12:01 hello, how to load a set of external .jar files in clojure

12:02 dbushenko: idiomatic way is in using leiningen and adding the jars to your local maven repository

12:02 bordatoue: dbushenko: thanks, do you know anyway i coulod load it from the repl

12:03 nDuff: bordatoue: ...if you're _not_ doing it the idiomatic way... well, make sure they're in your classpath when you start the JVM. But "use leiningen" is definitely the easy solution.

12:03 bordatoue: nDuff: is it possible to dynamically load it from the repl

12:03 dbushenko: bordatoue, you can't load them from the repl if they aren't on your classpath

12:03 and if they are, then the task is solved

12:03 hiredman: https://github.com/hiredman/clojurebot/blob/master/src/clojurebot/plugin.clj

12:03 nDuff: bordatoue: pomegranate is the usual tool used for dynamic classloader updates; it doesn't just add things, it downloads them for you too.

12:03 dbushenko: the easiest way is to use leiningen for that

12:04 S11001001: bordatoue: why do you want to do it the hard way?

12:04 nDuff: bordatoue: ...I mean, you _can_ build your own classloader with the jars you want added in and attach them to the thread...

12:04 bordatoue: ...but you're just making your life harder trying to do it that way.

12:04 bordatoue: S11001001: ah not keen on doing it in the hard way, just wanted to see clojure's capablities

12:05 nDuff: bordatoue: *nod*. Basically comes down to "same things you can do with the JVM directly"

12:05 bordatoue: S11001001: basically I thought i could use a repl to debug java program

12:05 S11001001: you can, that has nothing to do with adding jars w/o restart

12:05 but if you want some craziness

12:05 https://github.com/cemerick/pomegranate

12:06 ***not for normal usage in normal programs***

12:06 nDuff: ...now, if you want _fun_, you can try to make pomegranate and nREPL play well with OSGi :P

12:06 bordatoue: S11001001: well, java program i need to debug depends on these jars, so i need to get reference to these jars dynamically

12:06 S11001001: bordatoue: because the java program picks up the jars dynamically?

12:06 nDuff: bordatoue: ...err, why dynamically? Why not have them already there when you launch the JVM?

12:06 bordatoue: ...not saying you _can't_, again, just that it's extra work.

12:07 bordatoue: okay, let me try by adding class path

12:07 hiredman: you can, in fact, use urlclassloaders to load code out of jars over http (right out of maven repos)

12:07 if you are so inclined

12:08 bordatoue: hiredman: urlclassloader, i will take a look

12:08 hiredman: I'd suggest looking at the url I pasted

12:08 bordatoue: i can't see any url you pasted

12:09 hiredman: it was several minutes ago

12:09 bordatoue: hiredman: found it , sorry

12:09 * nDuff notes that he suggested the "replace the classloader" approach several minutes earlier.

12:12 cemerick: nDuff: *snort* @ "the usual tool used for dynamic classloader updates"

12:12 I hope it's not a usual sort of thing for most people. ;-)

12:15 xeqi: I find myself dealing with it in several projects

12:15 technomancy: iiiinteresting: https://twitter.com/xpaulbettsx/status/216003572163297280

12:17 nDuff: cemerick: Heh.

12:18 ...anyone have thoughts on what would be a decent place to discuss changes in building jars with Clojure source in them to make things more OSGi-friendly? I have a fork of clojure.osgi with relevant changes at https://github.com/charles-dyfis-net/clojure.osgi/commit/c355e1f4e05147cf7f99c5579dca4e5c80bddb79, but actually _creating_ bundles that take advantage of this is thus far something only I do.

12:19 cemerick: xeqi: Gawd, I'm so sorry. :-|

12:26 N8Dawg: hi, all. I'm a bit stuck, i'm trying to debug some non-trivial clojure code

12:26 what good debuggers are there?

12:26 i'm looking at swank-cdt but i can't work out how to step into anonymous functions

12:27 or put breakpoints on them

12:31 jedmtnman1: if I want to return two keys from each map in a list, is there a function I should be looking at specifically at? like 'get-in' but not for nested data?

12:32 bhenry: how can i make leincljsbuild work with the latest release of clojurescript?

12:32 jedmtnman1: sorry, not two keys, but to vals by key lookup ^

12:34 xeqi: &((juxt :a :b) {:a 1 :b 2})

12:34 lazybot: ⇒ [1 2]

12:36 jedmtnman1: xeqi: ty

12:37 Bronsa: ,(vals {'a 1 'b 2})

12:37 clojurebot: (1 2)

12:37 xeqi: &(select-keys {:a 1 :b 2} [:a :b])

12:37 lazybot: ⇒ {:b 2, :a 1}

12:37 xeqi: jedmtnman1: migt be btter ^

12:37 &(select-keys {:a 1 :b 2 :c 3 :d 4} [:a :b])

12:37 lazybot: ⇒ {:b 2, :a 1}

12:38 jedmtnman1: xeqi: select-keys might be what i was thinking of, but juxt might work better in this context. ty again Bronsa too

12:39 amalloy: &(map {:a 1 :b 2} [:a :b])

12:39 lazybot: ⇒ (1 2)

12:39 gfredericks: amalloy: but that doesn't use juxt

12:45 it does have the advantage of working for more than just keywords though

12:45 amalloy: it also exercises all three of clojure's brace types

12:53 charliekilo: /join #datomic

13:05 dnolen: bhenry: bug emezeske

13:05 bhenry: dnolen: i'm bugging him on his github repo. i just am impatient.

13:06 dnolen: bhenry: did you try specifying the CLJS version explicitly in your :dependencies?

13:07 bhenry: yes. it appears there are breaking changes? i'm not really sure, but i tried both of his suggestions here with the same results: https://github.com/emezeske/lein-cljsbuild/issues/101

13:08 dnolen: bhenry: oh yeah, warning flag he was using got moves to the analyzer namespace. easy fix of course.

13:11 foxdonut: dnolen: you are currently the main developer of ClojureScript, is that correct?

13:12 dnolen: foxdonut: not the "main" developer. I do actively review/apply patches as well occasionally optimize things.

13:13 foxdonut: dnolen: I see.. so who is/are the "main" developer(s) then? RH?

13:14 dnolen: foxdonut: http://github.com/clojure/clojurescript/graphs/contributors

13:15 foxdonut: dnolen: thanks for the info, and thanks for your contributions!

13:17 dnolen: foxdonut: np

13:36 taterbase: Could someone recommend a good beginner book on clojure?

13:36 technomancy: taterbase: clojurebook.com for sure

13:36 borkdude: +1 on clojurebook.com

13:37 I call it the Clojure book with batteries included ;-)

13:37 taterbase: "batteries included" <- that's what I like to hear, thank you :)

13:43 borkdude: cemerick can I ask a question about clojurebook.com btw?

13:45 cemerick: shoot

13:46 borkdude: what coordinate system is used for the hex grid game of life on page 144

13:54 cemerick: borkdude: it's still cartesian (you can see the [x y] coordinates being defined for each vertex)

13:55 The only difference between a rectangular and hexagonal maze is the shape of the cells centered on the vertices

13:57 borkdude: cemerick this is about the game of life, not a maze

13:57 cemerick I'm slightly confused, because there are several ways to do this: http://keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/

13:57 cemerick maybe you can show on that page which one is used?

13:58 cemerick: heh, I may be too — it's been about 9 months since I had that example loaded in my head :-)

14:09 borkdude: sometimes when I define a function that does something to a JFrame in Mac OSX a "clojure.main" menu item appears

14:09 this is strange, because I haven't even called the function, just defined it

14:11 cemerick: borkdude: so, after a quick glance: the coordinate system is still just two-dimensional. Because only immediate adjacency needs to be determined (not arbitrary distance), the third dimension introduced in the link you have isn't necessary.

14:12 borkdude: cemerick yes, but even with only two dimensions you can do the numbering in different ways: straighten the axes or not

14:13 cemerick it seems that straightening the axes is the cleaner way - but I tried both ways and tried to reproduce the examples from clojurebook, but couldn't figure it out - it might be my foolish brain

14:14 Guest98851: Hello, I have a Problem to set up Clojur eREPL on Mac OSX 10.5 I cant use arrow cursor to navigate the CLI, any pointers?

14:14 technomancy: Guest98851: need to either install rlwrap or upgrade to lein 2.x

14:14 Guest98851: I downloaded clojure 1.4 jar

14:15 so thats not included there , it works in windows, hm

14:15 technomancy: oh, ok. that's probably not what you want, but I can see how you would make that mistake

14:15 best to start at http://leiningen.org

14:15 borkdude: nice to see something that works in windows but doesn't in OSX for once ;)

14:16 Guest98851: do i really need leiniging JUST to get a REPL?

14:16 ivan: no, you can use rlwrap as mentioned

14:16 technomancy: depends on whether you want a good repl or not

14:16 borkdude: Guest98851 +1 on leiningen, it is the most flexible way to get a repl running for your projects

14:16 Guest98851: how do i set up rlwrap?

14:17 ivan: rlwrap java ...

14:17 Guest98851: I dont want projects, yet just a REPLok

14:17 ivan: I'm sure all 3 package managers on OS X have it

14:17 borkdude: Guest98851 also for a standalone repl I can recommend it, do it all the time

14:17 nDuff: Guest59394: You'll shortly want that REPL to have some libraries loaded, unless you're programming in a vacuum

14:17 Guest98851: ...so having a project defined (taking all of one leiningen command to do) is well worthwhile.

14:18 technomancy: I recommend not programming in a vacuum; it's very confined and difficult to see the keyboard

14:18 jodaro: and dusty

14:20 michaelr525: programming in a vacum can get your tits squashed

14:20 Guest98851: I just want to tinker no need for librarys

14:20 borkdude: less bit rot though

14:21 Guest98851 take our advice, just use leiningen even for something simple like a REPL, you will be happy.

14:21 technomancy: weird dejavu from yesterday

14:21 clojurebot: installing clojure?

14:21 clojurebot: Clojure isn't like most languages in that it doesn't need to be installed; it's just a library. Once you have a JVM, you can set up a project with something like Leiningen (http://j.mp/leiningen), which will pull Clojure in for you.

14:24 Guest98851: I wonder what I would do if I had it to setup on a machine without internet :/

14:26 michaelr525: i think you can run something like: java -cp clojure.jar clojure.main

14:26 TimMc: Guest98851: Be in pain.

14:26 Even if you didn't have lein, you'd still have to fetch dependencies to test or run anything.

14:27 cemerick: Much all of modern computing assumes a network connection, for better or worse.

14:27 brainproxy: Guest98851: getting starte w/ lein is a no brainer, the .sh script bootstraps leiningen automatically

14:27 cemerick: bah, s/all/

14:28 michaelr525: actually i've started with just clojure.jar and was happy with it until i discovered lein later

14:28 brainproxy: Guest98851: then you just do `lein repl`, and you'll hice a nice repl to tinker around with, inc. some helpful keyboard shortcuts

14:28 you'll *have

14:28 Guest98851: thats what i get

14:28 http://pastebin.com/0jKky8Xb

14:29 etosch: Anyone have issues using recur in a cond-match clause with matchure?

14:29 Guest98851: actually I DID run the clojure REPL i just cant use arrow keys which makes it unable to use :/

14:30 I guess there must be something to it since the scala guys where also mumbling how painfull it is to deliver a multi OS CLI

14:31 etosch: I have a clause that structured like this: [[false true] [something-false something-true] retvaue, but in the following clause after its match I have a call to recur

14:31 borkdude: bash: command not found.. hmm

14:31 etosch: when I run just (cond-match [[false true] [false true]] 'asdf) in the repl, I get 'asdf

14:31 borkdude: Guest98851 try ./lein instead

14:32 technomancy: Guest98851: the `java` command-line launcher is a joke

14:32 as far as I can tell, the jdk developers try to pretend unix doesn't exist

14:32 etosch: and when I remove the line from the clauses in cond-match my function compiles fine

14:32 dnolen: etosch: I think matchure may generate intermediate fns to prevent code size explosion - breaking usage of recur.

14:32 borkdude: interesting things happen when I type ". lein", my terminal even disappears :)

14:33 Guest98851: noname:Documents mich$ . /lein gives: -bash: /lein: No such file or directory

14:33 etosch: dnolen: so is it not closing over something?

14:33 borkdude: Guest98851 omit the space

14:33 Guest98851: sorry thats it

14:33 its working now

14:33 etosch: dnolen: The error is very weird - it's saying that I'm providing too many arguments to recur

14:34 borkdude: Guest98851 if you put the script on the PATH, you don't have to type ./lein , that is much easier

14:34 dnolen: etosch: core.match avoids this, but is very alpha status and has some issues (AOT, mostly around maps and using multiple types in the same column).

14:34 etosch: matchure is broken, you can't use recur.

14:34 Guest98851: borkdude: yes but i dont want it on my path

14:34 dnolen: etosch: there's nothing you can do to make it work as it expected far as I know.

14:34 borkdude: Guest98851 it's up to you..

14:35 Guest98851: so now this: http://pastebin.com/MB7nTVbL

14:35 I am on an old mac osx 10.5...

14:35 etosch: dnolen: hrm, I'll give core.match a try

14:36 wkelly: Guest98851: export HTTP_CLIENT="curl --insecure -f -L -o"

14:36 dnolen: etosch: expect to encounter a different set of issues there (as I mentioned) ... patches welcome.

14:37 etosch: dnolen: alrighty, i shall commence with caution

14:37 Guest98851: :wkelly do I have to type this?

14:37 wkelly: Guest98851: yup! just type it in the same shell you are running lein from

14:37 then run the command again

14:39 technomancy: next version of lein will have a better error message explaining that

14:39 oh, never mind; you got the error message

14:40 borkdude: technomancy is this only on "older" systems?

14:40 technomancy: borkdude: yeah, ancient libopenssl

14:40 Guest98851: wkelly: tried both suggested commands : insecure and no certificate, both dont work...

14:42 is there a swing UI for the REPL?

14:42 really i just want arrow key navigation and command history, thats all...

14:42 borkdude: Guest98851 if you can paste the error msg, we can find out maybe what doesn't work

14:43 wkelly: borkdude: it is pasted

14:43 borkdude: Guest98851 I'm sorry things don't go as smooth as promised… ;-)

14:43 technomancy: you should see if you can get a newer libssl

14:43 Guest98851: np its my OS fault obviously

14:43 technomancy: I'd be nervous running something that old

14:44 borkdude: how old is old?

14:44 technomancy: but still, exporting HTTP_CLIENT should work

14:44 2005-ish I think?

14:44 macosecks is never EOL'd =(

14:46 Guest98851: so im using: http://incanter.org/downloads/ incanter now but is only on 1.2

14:46 does such a GUI REPL exist with 1.4?

14:49 well anyway thx for your help I can do now some basic stuff with cloure 1.2

14:50 nDuff: ...err, can't you just tell leiningen to pull Incanter in for your Clojure runtime of choice?

14:50 * nDuff doesn't know -- hasn't poked at Incanter in upwards of a year -- but would be at least a bit surprised if that weren't doable.

14:50 borkdude: nDuff he went back to the past

14:51 these people visiting here from the past and future are confusing sometimes

14:52 technomancy: nDuff: really old openssl can't bootstrap leiningen's self-install because it doesn't trust github's SSL cert =\

14:52 and for some reason he couldn't disable curl's cert checks

14:54 nDuff: ...err, isn't that curl -k?

14:54 *shrug*.

14:55 technomancy: more or less

14:57 wkelly: Guest59394: can you run mkdir -p $HOME/.lein/self-installs/

14:57 Guest59394: and then wget https://github.com/downloads/technomancy/leiningen/leiningen-2.0.0-preview6-standalone.jar --no-check-certificate -O $HOME/.lein/self-installs/leiningen-2.0.0-preview6-standalone.jar

14:57 borkdude: maybe for bootstrapping an interactive question could be put it: are you sure you want to do this?

14:57 wkelly: without the line wrap

14:57 technomancy: wkelly: wrong guest, I think

14:58 wkelly: haha

14:58 so it is!

14:58 arrdem: good catch

14:58 technomancy: the magic of nick highlighting =)

14:58 wkelly: oh well

14:58 mmarczyk: dnolen: ping

14:58 dnolen: mmarczyk: pong

14:58 mmarczyk: dnolen: hi! so, where do you think we're at with :import ?

14:59 dnolen: mmarczyk: been a bit busy - I didn't know if you were coming up with another patch.

14:59 xeqi: borkdude: curious, what are you trying to use the hex coordinates for?

14:59 borkdude: xeqi just trying to understand the example from clojurebook

15:00 mmarczyk: dnolen: sure. I think the original goog.provide patch should work fine

15:01 dnolen: mmarczyk: it's also preferable that there's only one patch on the ticket. can we remove the others?

15:01 xeqi: everything is kept in rect coords, so the underlieing hex coords aren't ever used

15:01 dnolen: mmarczyk: so the working patch works at the REPL and relies on GClosure for errors?

15:01 under compilation?

15:02 mmarczyk: dnolen: the working patch only emits goog.provide calls when compiling files

15:02 dnolen: no goog.provide at the REPL

15:02 borkdude: xeqi I think a picture would clarify this all for me

15:02 dnolen: mmarczyk: k let's remove the other patches from that ticket.

15:03 xeqi: heh, wish I had a peice of graph paper

15:03 mmarczyk: dnolen: ns forms receive special handling from the repl, I believe -- in particular, goog.provide is not called

15:04 dnolen: hm, in this case I think the basic patch introducing :import for GClosure classes is so simple it can't be wrong

15:05 dnolen: whereas I think the approach to cljs records/types should work too, but may still be refined so the implementation is prettier

15:05 dnolen: hence the two patches

15:05 dnolen: but sure, I can squash them, give me a minute :-)

15:07 dnolen: mmarczyk: I would prefer a single patch that handles deftype/record

15:07 borkdude: xeqi is it this system? http://keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/hexgridsquiggly/

15:09 dnolen: mmarczyk: if the patch needs some refinement, then by all means refine :)

15:09 mmarczyk: dnolen: :-)

15:11 xeqi: no, not every rect coord maps to a hex coord

15:14 ynniv: wow… does map wrap any non RuntimeException in a RuntimeException?

15:18 borkdude: xeqi I see it now…

15:18 oskarth__: how do I call clojure functions from clojurescript?

15:19 dnolen: oskarth__: what do you mean?

15:19 oskarth__: dnolen: I mean using a clojure library and calling it from clojurescript, like clojure and java fns

15:20 xeqi: borkdude: heh, an I had just put together http://postimage.org/image/pqnu8vbjn/ with some random online image editor

15:20 mmarczyk: dnolen: squashed patch attached

15:21 dnolen: oskarth__: are you talking about client/server communication?

15:21 mmarczyk: thx

15:21 borkdude: xeqi so the axes are straightened, only differently

15:21 mmarczyk: dnolen: the *emitted-provides* thing might be misnamed, since I'm not emitting them for ns forms (that would be useless at this time)... no idea for a better name, unfortunately

15:21 borkdude: xeqi no,nm, but I get it now

15:22 xeqi tnx!

15:22 oskarth__: dnolen: in a way yes, but we want a certain js thing to change when a file has been updated on the filesys

15:22 dnolen: oskarth__: need more details ... what are you trying to do?

15:23 cgag: technomancy: is deployment mullet your term? that's great

15:23 oskarth__: dnolen: we do a POST which starts to generate an image in quil, but we want to watch the file-system for changes so we know when to update the image div

15:23 dnolen: previously we tried to do it with java threads, but the request comes back before the image is generated then

15:24 does that make sense?

15:25 jweiss: is there a recommended way to print readably so taht there are no embedded objects like #< clojure.lang.AFunction$1@7b3825bf> ? I know i can write a defmethod, but that will change it system-wide.

15:25 xeqi: borkdude: for extra fun, consider 1,0 as your starting rect coordinate

15:25 oskarth__: it's quite possible we don't understand how the thread is working with the web server and are thus trying to do thing in a unidiomatic way

15:26 dnolen: oskarth__: yes, depending on how robust of a solution you want - you could poll, you could use WebSockets. Perhaps GClosure browser channel, etc.

15:26 xeqi: and how that compares to 0,0

15:26 oskarth__: dnolen: right now we are using polling, thought about switching to web sockets but want to get this working ok first

15:26 borkdude: xeqi just to make sure: (hex-neighbours [0 0]) -> ([-2 0] [-2 2] [-1 -1] [-1 3] [0 0] [0 2])

15:26 dnolen: oskarth__: the problem is sounds like that the request completes, and the file is getting updated on a different thread.

15:26 oskarth__: exactly

15:27 so we thought of having a dir-change watcher

15:27 borkdude: xeqi probably there is just a tiny difference in rotation here

15:27 oskarth__: dnolen: does that sound like a bad idea to you?

15:27 xeqi: borkdude: https://www.refheap.com/paste/3292

15:28 consider pulling https://github.com/clojurebook/ClojureProgramming

15:28 dnolen: oskarth__: so if you're making something simple for demo purposes you could just return something (a token) that the client can then poll for.

15:28 oskarth__: if you're doing something fancy you'll want some kind of bidirectional channel. Lots of JS uploaders rely on Flash for this.

15:29 borkdude: xeqi ok.. tnx for your help, I'm off now

15:29 oskarth__: dnolen: hm ok, but how would the js know when the file has been created if it's started in another thread?

15:30 dnolen: oskarth__: it starts polling with the token.

15:30 oskarth__: aha I think see now

15:31 dnolen: thanks

15:31 dnolen: oskarth__: again not something I really recommend for anything real. If I recall correctly, Aleph has WebSocket support and integrating it with Noir / Compojure / Ring shouldn't be hard.

15:32 oskarth__: dnolen: yeah, we were thinking about doing something like aleph or netty if we were to continue working with it

15:37 Chiron_: Hi, should I do something special when importing and using a "generic" type such as com.netflix.astyanax.AstyanaxContext<Entity> ?

15:40 and how to import a static class defined within another class?

15:40 xeqi: Chiron_: leave the generic type signature off

15:41 and use $ between the names

15:43 Chiron_: something like (import [com.netflix.astyanax AstyanaxContext.Builder]) ?

15:43 (import [com.netflix.astyanax AstyanaxContext$Builder])

15:44 xeqi: I think that'll work

15:46 &Thread$UncaughtExceptionHandler

15:46 lazybot: ⇒ java.lang.Thread$UncaughtExceptionHandler

15:56 Chiron_: How to access an Enum? NodeDiscoveryType/None ?

15:57 mattmoss: Ya.

15:57 Chiron_: are doto and -> are replaceable when working with Java objects?

15:58 mattmoss: Not entirely.

15:58 -> will return the last evaluation as its result

15:58 brainproxy: be wary of this mattmoss character, he's a little tricky

15:58 mattmoss: (doto (java-obj) ... ...) will return the java-obj

15:59 Chiron_: Oh

15:59 * mattmoss smirks.

15:59 mattmoss: Otherwise, I *think* -> and doto are fairly similar... at least for calling a chain of java ops.

16:00 Chiron_: I c. thanks!

16:00 clojurebot: Haskell!

16:00 clojurebot: "you have to see features like that in the context of Haskell's community, which is something like Perl's community in the garden of Eden: detached from all shame or need to do any work." -- ayrnieu

16:00 Chiron_: wow, one word deserve two lines response

16:00 brainproxy: Chiron_: in a doto chain, any number of the steps may involve methods which don't themselves return the object that the methods are operating on

16:01 mattmoss: Ah yes, good point, bp. I had forgotten that.

16:01 brainproxy: but doto makes sure that each step along the way operates on the object you're passing in

16:02 -> is a way of composing functions together, where the return value of one step is an argument in the next step

16:02 which argument position depends on whether you use -> or ->>

16:03 Chiron_: that is imformative

16:04 btw, would you please explain to me clojurebot response to "haskell" ?

16:04 brainproxy: ,haskell

16:04 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: haskell in this context, compiling:(NO_SOURCE_PATH:0)>

16:04 muhoo: anyone run datomic on heroku yet?

16:04 brainproxy: ,"haskell"

16:04 clojurebot: "haskell"

16:05 brainproxy: nvm, I see above, the "garden of Eden..." text

16:06 Chiron_: yes that one

16:06 hiredman: it's a quote, someone said it once

16:06 what more is there to explain?

16:07 Chiron_: didn't understood it, don't bother :)

16:07 * muhoo puts on cowboy boots and hat, and whistles ennio morricone tunes

16:09 muhoo: hm, maybe not, looks like it'll work http://webcache.googleusercontent.com/search?q=cache:87T33B5UsR8J:http://groups.google.com/group/datomic/browse_thread/thread/e3cea68ce2595552%2Bdatomic+heroku&hl=en&ct=clnk

16:15 dgrnbrg: hey clojurians, i'm having some fun in class loader hell. I have a groovy script that's invoked by a magic class loader, and i need to run some clojure code in that class loader too.

16:15 Also, i cannot add clojure to the claspsath at jvm startup, so i'm creating a urlclassloader and adding clojure to that as a URL resource

16:16 then, i am creating a new GroovyShell with the URLClassLoader as its class loader, and then i'm setting the clojure.lang.Compiler.LOADER as this.classLoader in the GroovyShell's string, and then i'm trying to run the clojure program

16:17 etosch: dnolen, I'm having an issue with core.match. Not sure where/how to report on JIRA

16:17 dgrnbrg: i'm having a problem where it cannot find clojure/core.clj, even though it can find clojure.lang.*

16:18 does anyone have any ideas for my class loader hell?

16:19 adu: dgrnbrg: clojure+groovy! good choices

16:20 (add1 dgrnbrg)

16:23 dgrnbrg: adu: thanks :)

16:23 have you dealt with class loader hell?

16:25 adu: dgrnbrg: http://www.liferay.com/community/forums/-/message_boards/message/13323232

16:26 dgrnbrg: i am legacy

16:26 so, so legacy

16:26 i cannot control the command line

16:26 i cannot export CLASSPATH

16:26 everything has to be dynamically done

16:28 adu: do you know how I can defer resolving the clojure classes until i've had a chance to set up the runtime?

16:28 in groovy, that is

16:28 i do clojure.lang.RT.loadFile

16:28 adu: what's wrong with CLASSPATH?

16:28 dgrnbrg: but i haven't added clojure.lang.RT to the class loader yet, so i can't put it as text in the program, b/c the groovy compiler won't accept it

16:29 it's not possible to have it work in my environment :(

16:30 adu: how about System.setProperty("java.class.path", "…")?

16:31 dgrnbrg: can you do that and have the class loader work?

16:31 adu: no idea, worth a try

16:32 jweiss: dynamically loading libs doesn't work, so if it was that easily solved, it would work :)

16:32 nDuff: create a new URLClassLoader

16:32 add URLs to the jars to it

16:32 set as your thread context classloader

16:33 Raynes: http://github.com/flatland/classlojure

16:33 dgrnbrg: i'm trying to bootstrap clojure in a groovy environment

16:34 so i have a URLClassLoader with all the clojure jars added to it

16:34 is there some way to do something like:

16:35 Class.forName("clojure.lang.Compiler", true, urlClassLoader).LOADER.bindRoot(urlClassLoader); Class.forName("clojure.lang.RT",true,urlClassLoader).loadResourceScript("my-script")?

16:35 because Class.forName returns a Class, but I need the Compiler so that I can start my work

16:38 etosch: dnolen, I'm having an issue with core.match. Not sure where/how to report on JIRA

16:38 dnolen: etosch: http://dev.clojure.org/jira/browse/MATCH

16:39 etosch: what is the problem you're encountering?

16:41 etosch: dnolen, not sure how to describe it without examples. Doesn't look like the extant issues match up. Should I open a new issue and paste code?

16:42 dnolen: etosch: can you give an example first - there several different tickets about various problems - it may already exist.

16:43 etosch: dnolen: sure. I want to do this: let [x '() y '()]

16:43 | (match [(seq x) (seq y)]

16:43 | [([_] :seq) nil] 'a

16:43 | [_ _] 'b))

16:43 (pasting from emacs, sorry

16:43 (let [x '() y '()]

16:43 (match [(seq x) (seq y)]

16:43 [([_] :seq) nil] 'a

16:43 [_ _] 'b))

16:43 cshell_: you can use refheap.com

16:43 dnolen: etosch: use a paste service, refheap, gist

16:44 etosch: k, gimme 5

16:44 dnolen: etosch: you're expecting 'b and getting 'a?

16:44 muhoo: somewhat OT, but why wouldn't datomic work with heroku's free postgres, only with it's $50/month postgres?

16:44 s/it's/its/

16:48 etosch: dnolen: no, i'm getting a runtime exception

16:48 dnolen: etosch: what is it?

16:48 solussd: how can I get the pre/post conditions from a function?

16:49 etosch: dnolen: https://www.refheap.com/paste/3294 it says it can't resolved the symbol - it looks like the product of a gensym or something

16:50 dnolen, in the "want this" part i actually want x to be nonempty, but its moot currently due to it throwing an excpeiton

16:51 Chiron_: Korma creates a db object and it looks like afterwords, all other functions have access to the db object without explicitly being passed https://github.com/ibdknox/korma

16:51 how to achieve something like that?

16:51 technomancy: Chiron_: some would argue that's the biggest flaw of korma

16:51 Chiron_: really?

16:52 what would be a better approach? I'm creating something like that

16:52 not creating, want to create

16:53 technomancy: it's best to create your API so the base connection object or whatever is accepted as an argument to every function that needs it

16:53 dnolen: etosch: yeah that's probably a real bug, though :seq matching will probably go the way of the dinosaur ...

16:53 technomancy: then optionally create an alternate API based on that one that offers a with-* macro that performs the bindings

16:54 Chiron_: I was thinking about with-*

16:54 dnolen: etosch: feel free to make a ticket, I have no plans on addressing the ticket anytime soon too busy with other things. If you supply a patch I'll happily apply.

16:55 etosch: dnolen, okay, thanks for taking a look

16:55 akhudek: technomancy: my solution to that problem with korma was to wrap each table in (database entity conn) every time the entity is used.

16:56 there is some syntactic sugar there so that calls look more like (select (db my-table) (where …..))

16:57 technomancy: cgag: I can't remember where I first heard the term "deployment mullet" but I <3 it

17:03 goodieboy: does anyone know what the standard response keys are for ring? Does ring *only* recognize :status, :body and :headers?

17:05 steveo_: I have a java library i'm interoping with that wants a uri of a resource to load, the thing I need to load is something I have in memory though, anybody know if there is a way to give a URI to a memory location or something so I don't have to spit this to a file just so it can be read again right away?

17:05 ystael: is there a 'standard' choice of idiom for (zipmap coll (map f coll)) or (into {} (map #(vector % (f %)) coll)) ?

17:06 cshell_: steveo_: no, that's a bad api - it should take an inputstream rather than a uri to avoid things like this

17:10 steveo_: damn, yeah I wish it did

17:12 S11001001: ystael: juxt

17:12 (into {} (map (juxt identity f) coll))

17:13 technomancy: as much as I love juxt, I pine for map-keys and map-vals

17:13 S11001001: eh, map-keys is weird

17:14 llasram: maybe?: (reduce #(assoc %1 %2 (f %2)) {} coll)

17:14 No intermediate vectors!

17:14 S11001001: llasram: that's slower

17:14 technomancy: I guess keywordize-keys is nearly the only use case for map-keys

17:14 llasram: S11001001: Is it?

17:14 S11001001: llasram: into speaks transient internally, that reduce doesn't

17:14 dnolen: etosch: thx for the ticket. These will get addressed eventually - all part of a bigger project.

17:14 llasram: S11001001: Ohhh. Hmm.

17:14 S11001001: I had not considered that angle

17:15 hiredman: technomancy: I have theory about map-vals

17:15 gtrak`: ystael: mapmap?

17:15 S11001001: technomancy: anyway, map-vals wouldn't do that thing

17:15 baoist: Has anyone had an issue with VimClojure freezing after opening any ".clj" file when the setting "let vimclojure#WantNailgun = 1" is on?

17:16 S11001001: technomancy: unless you're thinking of a different map-vals than me :)

17:16 cshell_: How do i define a protocol method named 'find' so that it won't conflict with clojure.core/find?

17:16 S11001001: oh, well you said keywordize-keys, so we meant the same one

17:16 etosch: dnolen, cool; i have some suspicions about where the problem might be and i really really really want to use pattern matching for a particular problem, so i'm going to hack at it for a little bit

17:16 hiredman: the need for maps vals arise when you combine two things in to a single thing, those two things are 1. a collection of things 2. an index of those things for fast/easy retrival

17:17 technomancy: S11001001: I'm thinking of the one in my head that works like the above =)

17:17 gtrak`: hiredman: is that bad?

17:17 hiredman: if you combine those two things in to a single thing, and decide you want to map over the first thing, you think you need map-vals

17:17 S11001001: I wish keys and vals would yield in different orders occasionally, just to mess with people who assume they have same order

17:17 dnolen: etosch: cool! core.match is not the most straightforward Clojure library out there ... would like be more explicit how about we implemented the paper one day.

17:17 S11001001: there is no implementation reason to do this...

17:18 wait, false

17:18 hiredman: if you pull the two things a part you get a map for and index, and a vector

17:18 and we have mapv

17:18 technomancy: hiredman: so zipmap is simple because it's explicitly about combining those two things and nothing else?

17:18 dnolen: etosch: feel free to ask any questions you may have about the implementation.

17:19 hiredman: zipmap is about building a map out of two seqs

17:19 cgag: baoist: i haven't, it's either worked or warned me when the nailgun server isn't started

17:19 etosch: dnolen, what's the lay of the land on pattern matching in clojure? Are the major libs just core.match and matchure?

17:19 dnolen: etosch: yes.

17:20 cgag: though occationally i'll try to enter an expression in the repl and it'll insert thousands of spaces

17:20 baoist: cgag: hrmm, out of curiosity what version of vimclojure are you using? I tried with 2.3.3 and 2.3.0

17:20 hiredman: technomancy: so really you should either a. decide you can take the performance/ease hit and search a linear structure (which is easy to map over) or 2. keep two structures a map of keys indices and a vector of values

17:20 keys => indices

17:20 dnolen: etosch: core.match implements a clever algorithm from an OCaml paper - but it's also extensible a la Racket. it also handles the recur case.

17:20 gtrak`: hiredman: that's kind of a pain. Why not just call the complection a proper abstraction?

17:21 cgag: baoist: I don't know actually, I set it up according to this https://github.com/daveray/vimclojure-easy, modified to fit in with vim janus

17:21 baoist: looking in the lib folder, it looks like it's 2.3.0

17:21 baoist: cgag: thanks, I think I'll look into this.

17:22 hiredman: technomancy: I say this in large part as an extended explanation of why I don't think map-vals will ever land in core

17:24 technomancy: hiredman: yeah, it seems consistent with some of the other design decisions when you put it that way

17:25 hiredman: it is also my experience people tend to be wayyyyyyy biased towards {:id1 {:data v2} :id2 {:data v2}} over #{{:id :id1 :data v1} {:id :id2 :data v2}} (or same as a seq)

17:25 where the second form is more extensible, and self descriptive

17:26 technomancy: it's definitely underrated, especially for large data sets

17:27 ipostelnik: hiredman, your 2 examples are not the same

17:27 {:id1 example1} is very fast

17:27 gtrak`: this is somewhat similar to the k-v store vs RDB argument, yes?

17:27 hiredman: thats my point

17:28 people are heavily biased towards fast indexed access, over ease of extensibility and self description

17:29 without consciously weighing the tradeoffs

17:29 ipostelnik: when I'd wanted map-vals, it was always in scenarios where index access was the 90% case and map-vals was the 10%

17:47 Chiron_: what is the best way to represent a couple of fixed values? (like enum)

17:49 hiredman: keywords

17:49 shawnlewis: Hello. What's an idiomatic way to model a many to many relationship between "classes" in clojure? In say, java, class C1 could have a list of references to class C2. In clojure you might have a vector of maps that represent C1, each map having a vector of C2s as one of its attributes. But in order to update a C2, since you can't update it in place, you'd need to update each C1 that refers to it. I could use a vector of refs from C1s to

17:49 Hope that makes some semblance of sense

17:50 Chiron_: I need to mimic something like this: http://netflix.github.com/astyanax/javadoc/com/netflix/astyanax/connectionpool/NodeDiscoveryType.html

17:50 hiredman: shawnlewis: pretend you had the whole thing in a sql db and do it that way

17:51 Chiron_: keywords

17:53 shawnlewis: hiredman: so use unique identifiers as references yeah?

17:53 hiredman: shawnlewis: dunno, I didn't really read what you said, but it's a good rule of thumb

17:54 clojure is about manipulating data, so is sql

17:54 java is not

17:59 gtrak`: sounds like what shawnlewis is talking about is a tradeoff like hiredman described?

17:59 Chiron_: use keywords and maybe make a set for validation?

18:00 like (def valid-keys #{:k1 :k2 :k3}), I did something like that recently

18:01 Chiron_: gtrak`: indeed

18:02 dnolen: Chiron_: namespaced keywords work pretty well for that too I think.

18:03 gtrak`: if you want usage to be statically verifiable I suppose you could use a macro keyword-factory

18:03 Chiron_: dnolen: I'm creating an open source project, do u suggest to use qualified keywords?

18:03 gtrak`: my last comment <- probably a terrible idea

18:05 dnolen: Chiron_: if you want something like an enum and other people use them - yes.

18:05 "other people will use them"

18:07 Chiron_: so is it recommended to use only qualified keywords when creating open source projects (sorry still learning) ?

18:08 gtrak`: Chiron_: I've seen examples of regular keywords, I don't think it's that big a deal

18:08 technomancy: Chiron_: depends on who is allowed to put things into the map

18:10 Chiron_: means?

18:10 clojurebot: forget Clarity of mind means clarity of passion, too; this is Clarity of mind means clarity of passion, too; this

18:11 Chiron_: clojurebot: what is your uptime?

18:11 clojurebot: I don't understand.

18:11 S11001001: Chiron_: I use qualified to mark implementation details and things that have to mix with other things (e.g. global-hierarchy entries), unqualified otherwise

18:11 gtrak`: technomancy: do you mean allowed as in you can't from the outside or it's just slightly less convenient?

18:11 dnolen: mmarczyk: ping

18:11 mmarczyk: dnolen: pong

18:12 hiredman: clojurebot's uptime is not so good recently (more restarts) I moved it to a t1.micro with some other things, and the oom killer keeps killing stuff

18:12 dnolen: mmarczyk: looking at the patch, so you don't clear the *emitted-provides*, problematic for watch build processes I'd think.

18:12 technomancy: gtrak`: parse error

18:13 nathansobo: i was hoping someone could help me with a conceptual question about programming with values... how large a system should i attempt to model as a value. like say i was building a text editor. would i model the state of the screen, the cursor, what's selected, etc all as a single value?

18:13 mmarczyk: dnolen: well, it's only bound for the extent of compile-file*, same like *position*, *data-readers*, ana/*cljs-ns* etc.

18:13 same as

18:13 Chiron_: clojurebot: are you divorced?

18:13 clojurebot: Titim gan éirí ort.

18:14 gtrak`: technomancy: you said 'allowed', that implies that something disallows it, but I can do this:

18:14 &(into {} [[:clojure.core/a-keyword :val]])

18:14 lazybot: ⇒ {:clojure.core/a-keyword :val}

18:14 dnolen: mmarczyk: oops sorry missed that bit of the patch.

18:14 gtrak`: just want to make sure I'm not missing something

18:15 technomancy: gtrak`: I'm talking about maps used as inputs

18:16 gtrak`: oh, I think I get it, thanks

18:16 old code won't know about your namespace

18:17 api consumers can read your docs and figure it out

18:18 dnolen: mmarczyk: so I am somewhat concerned about the behavior of (:import goog.numbers.Long) and the lack of (:import [goog.numbers Long]), what if I make a deftype called Long and I want to import it as well?

18:18 mmarczyk: dnolen: that wouldn't work in Clojure either

18:19 dnolen: also, how would [goog.numbers Long] help?

18:19 hiredman: and you should use parens for grouping inside :import

18:19 mmarczyk: dnolen: also, I love prefix lists, wouldn't mind implementing them for all libspecs :-)

18:19 hiredman: (makes it indent correctly)

18:20 gtrak`: nathansobo: if you scroll up a bit in the log we were just talking about nestedness

18:20 mmarczyk: dnolen: haven't done so here for the sake of consistency

18:20 dnolen: mmarczyk: you are explicit that you want to use the name. but perhaps I misunderstood how it works in Clojure JVM, does import mean you don't have to qualify?

18:20 technomancy: nathansobo: it's a hard problem; I don't think there's a one-size-fits-all answer

18:20 mmarczyk: dnolen: it does

18:20 dnolen: if you import a class, you can omit the package throughout the namespace

18:21 dnolen: *and* there is no :import :as :-(

18:21 dnolen: mmarczyk: huh ... so it's not possible to import two classes of the same name?

18:21 hiredman: it maps the symbol to the class object

18:21 ,(intern *ns* 'Foo java.lang.String)

18:21 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

18:22 hiredman: clojurebot: jerk

18:22 clojurebot: you cut me deep, man.

18:22 mmarczyk: dnolen: no, one needs to be referred to using the fully-qualified name

18:22 gtrak`: nathansobo: I'm currently staring at examples in our own code of vectors of atoms... so it can be done that way... but it seems painful

18:22 hiredman: import works by assocating the symbol of the classname with the class object in the namespace's map

18:23 so you certainly can do that, it just isn't support by ns or import

18:23 mmarczyk: right

18:23 dnolen: mmarczyk: hmm ... I think we should start a thread on the dev ML ...

18:24 mmarczyk: I'm already way more excited about :refer in :require than I am about :use in CLJS. so perhaps another opportunity for improvement here.

18:24 mmarczyk: dnolen: :-)

18:24 dnolen: one thing I wanted to do with the :import patch is tidying up parse 'ns a bit

18:25 dnolen: mmarczyk: yes it's a monster now :)

18:25 mmarczyk: dnolen: indeed. :-)

18:25 dnolen: so I think I've taken a step in that direction with spec-parsers

18:26 dnolen: next step would be to factor out all the local functions

18:26 dnolen: mmarczyk: speaking of which ... I should clean up emit :invoke ...

18:26 mmarczyk: sounds good

18:26 mmarczyk: dnolen: cool

18:26 dnolen: so

18:26 nathansobo: thanks guys let me catch up with that dialog

18:26 gtrak`: when folks write code the *data* way like '#{{:id :id1 :data v1} {:id :id2 :data v2}}' above, do they tend to model things as triples or something?

18:26 mmarczyk: dnolen: I could split out all this into a separate patch and rewrite the :import patch to build on that

18:27 dnolen: *or* we could say that :import works pretty much as it does in Clojure, minus prefix lists which are not supported in any other libspec, and then start a clojure-dev thread about improvements :-)

18:27 dnolen: mmarczyk: not necessary. if the refactor is part of the :import patch I'm ok with that - no one else is working on the ns form far as I know.

18:27 mmarczyk: dnolen: ah, true

18:29 dnolen: mmarczyk: it could be just like Clojure, but I think better to go ahead and start the conversation while you make your desired changes to ns.

18:29 gtrak`: maybe you do it like sql with pk/fk? It sounds like an interesting thing to think about

18:29 mmarczyk: dnolen: sure, I'll go on tinkering :-)

18:29 nathansobo: gtrak`: vectors of atoms would seem to introduce coordination issues... like in hickey's talk "simplicity made easy" he says that if you have multiple variables representing a single entity, that you introduce coordination problems

18:30 gtrak`: nathansobo: yes that's a tradeoff

18:31 nathansobo: i guess if the separate variable facilitate coordination it helps

18:31 gtrak`: refs somewhat address that, but there's still an issue

18:31 nathansobo: variables*

18:31 dnolen: nathansobo: gtrak`: in putting refs types into immutable data structures seems to defeat the whole idea.

18:31 gtrak`: ya

18:31 I want to understand the *extensible* way :-)

18:32 nathansobo: one thing i'm having a hard time wrapping my head around is say you're modeling all this state as a value... and you want to capture *changes* to the state and say, draw them to the screen... you need some sort of abstraction for representing events

18:32 gtrak`: nathansobo: we have that already, refs, atoms and agents have watch-lists

18:33 nathansobo: like i need a succinct representation that says "this value you're observing changed in this way" so i can turn around use imperatively mess with the DOM

18:33 dnolen: nathansobo: yes, someone needs to work on that. lots of design notes and a half finished library. ClojureScript seesms like it's getting the wheels turning faster on that front.

18:33 nathansobo: okay let me take a look at watch-lists

18:34 mmarczyk: dnolen: I'm hoping to redo the CLJS-246 patch sometime this weekend too

18:34 gtrak`: nathansobo: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/add-watch

18:34 mmarczyk: dnolen: also, if nobody beats me to it, I'll be taking the "recursion in PersistentVector" ticket

18:35 dnolen: nathansobo: lots of people pondering this, add-watch is really not enough from what I can tell. kovasb, ibdknox, lynaghk and ohpauleez have various solutions which should be considered.

18:35 nathansobo: gtrak`: okay that looks like a cool way to see *that* the value changed, but i'm still searching for a way to model *how* it changed. maybe i'm thinking about this all wrong. for performance reasons i'd like to avoid treating the state of the entire display (the DOM) as a value

18:36 dnolen: mmarczyk: excellent!

18:36 mmarczyk: dnolen: the ticket description (CLJS-299) mentions earlier experiments by Laszlo -- got any links?

18:36 nathansobo: dnolen: cool. glad to know i'm not thinking along the wrong lines. any pointers to public exposition of their thoughts?

18:37 dnolen: mmarczyk: I still like to get the "satisfies? protocol carrying" in.

18:37 gtrak`: nathansobo: ah, yea.. you'd need some concept of a diff for each type of value, and you can use either time/space to implement it. Don't know if there's a generic way to do that

18:37 dnolen: mmarczyk: hmm, not handy, might want to ping on the old Laszlo thread on the ML, he seems to be around.

18:38 nathansobo: nothing in writing from them - mostly chatting.

18:38 mmarczyk: dnolen: k

18:38 gtrak`: the smallest example I can think of, if an int changes value, I suppose you may want to kick-off a smoothly moving slider or something?

18:39 mmarczyk: dnolen: yeah, I'd like to see protocol tagging too

18:39 gtrak`: that would require the slider to have its own state, maybe a view-model

18:39 mmarczyk: dnolen: haven't figured out a clean way to do that though

18:40 nathansobo: gtrak`: yeah that makes sense... like for a given value change i guess i want the old value, the new value, and a domain-specific diff describing the nature of the change. then my view layer can perform imperative updates on the basis off the diff, referencing the old/new values as needed

18:41 aperiodic: nathansobo: lynaghk has been working along those lines with bind! & unify in the experimental branch of c2: https://github.com/lynaghk/c2/tree/undom

18:41 nathansobo: basis *of*, not "off"

18:41 aperiodic: thanks, i'll give it a look

18:42 aperiodic: nathansobo: there's a simple demo here: https://github.com/lynaghk/c2-demos/tree/master/todoMVC

18:42 gtrak`: nathansobo: if you haven't read it already maybe check out the fowler UI arch articles http://martinfowler.com/eaaDev/SupervisingPresenter.html

18:42 nathansobo: thanks guys. this is really helpful and i very much appreciate your time

18:43 aperiodic: basically, you use them to associate a hiccup-producing expression that derefs some atoms with a DOM node, and when those atoms change, bind! and unify take care of walking the DOM and updating anything that's changed

18:44 i don't know what performance is like with that, though

18:45 nathansobo: aperiodic: interesting. perhaps the approach could lend insights valuable in something more ad-hoc / domain-specific.

19:00 zach_: I'm having some trouble upgrading a project to clj 1.4. 1.2.1 seems to be sticking around in the lib/ of the lein project.

19:00 technomancy: zach_: upgrading to lein 2 might help

19:00 1.x has some corner cases where plugins can interfere

19:00 zach_: technomancy: That's fine, I have lein2 installed. Is there any barrier to "switching"?

19:01 technomancy: clojurebot: upgrading to leiningen 2?

19:01 clojurebot: upgrading to leiningen 2 is easy with this handy upgrade guide: https://github.com/technomancy/leiningen/wiki/Upgrading

19:01 technomancy: zach_: hopefully not ^^

19:01 zach_: technomancy: Thanks!

19:01 technomancy: np

19:02 jodaro: man i love handy upgrade guides

19:02 jlewis: hi! can I use IPersistentMap from java, reasonably? if not, can you recommend another more java-friendly implementation of persistent maps?

19:07 lucian: jlewis: there was a project for making clojure's data structures available to java more nicely

19:08 S11001001: jlewis: check functionaljava; ipm not so great for java as it is unparameterized

19:12 zach_: technomancy: So, I installed lein-precate, which basically told me to add a min-lein-version, which I did. Unfortunately, it doesn't seem that lein2 deps is rectifying the problem. Am I missing something? (I'm sure I am!)

19:14 technomancy: zach_: are you sure it's actually a problem?

19:14 zach_: technomancy: Unfortunately, yeah -- trying to play around with datomic, which seems to be dependent on 1.4.0

19:15 I'll start a new project with lein2 from the ground up and see if the problem seems to persist

19:15 technomancy: and you've confirmed that having old jars in the lib/ directory breaks datomic?

19:16 zach_: technomancy: Every classpathed repl I run is running clj 1.2.1, and datomic just kinda isn't working, which a couple mailing list threads I've found seems to be a symptom of not running 1.4

19:17 technomancy: oh, ok; in that case use `lein deps :tree` to see what's pulling in 1.2

19:22 zach_: technomancy: Sorry it took so long. It was a really dumb problem. I apparently had a lein project that contained a bunch of projects... ugh

19:22 technomancy: Got rid of that, solved the 1.2.1 problem, but noir is still pulling 1.3

19:23 technomancy: you can add :exclusions; see `lein help sample`

19:23 * technomancy grumbles at noir

19:24 zach_: technomancy: Yep, found it. Thank you for your help.

19:24 technomancy: sure

19:24 should probably add a faq entry for that

19:25 oh, it's there already; oops

19:26 zach_: technomancy: I just need to learn to read faqs first :). Thanks for your patience anyways.

21:55 mindbender1: hi All

21:57 adu: hi

22:21 calvados: is there a way to log stdout and stderr with log4j in clojure ? i just searched some about it and found a solution for java but wondering if there is a way in clojure http://stackoverflow.com/questions/1200175/log4j-redirect-stdout-to-dailyrollingfileappender

22:25 xeqi: calvados: looks like tools.logging has a function to do it

22:32 calvados: xeqi: hm let me check it thanks

22:34 oh neat yes it looks like.

22:34 thanks again

22:39 Shambles_: Yesterday when I asked about the reason for .core to be appended someone said it was because having a undotted path was a bad idea. Would someone explain why, please?

22:55 uvtc: Shambles_, hi. I think it's just to avoid name collisions. If you've got a project named "foo-bar", you start off by putting your code into foo_bar/core.clj, and those functions are in the foo-bar.core namespace.

22:56 If you then want to add more namespaces (namespacen?) to your project, they can go under the top-level name as well (foo-bar.util, foo-bar.whatever).

22:57 When people use your project, everything lives under foo-bar (foo-bar.core, foo-bar.whatever). Nice and neat.

22:58 In the Perl world they address the issue by making dir names the same as module names. That is, FooBar.pm (the module), and FooBar/Baz.pm (the submodule -- FooBar::Baz).

23:00 Shambles_: uvtc: So there's no 'root' namespace in a project. All of them start under the project directory name? You can't have a a -main under foo-bar? It has to be foo-bar.<something>?

23:01 xeqi: also when using aot it would create a java class in the default package, which can cause confusion

23:01 uvtc: Shambles_, I follow the example that Leiningen sets. :)

23:02 Shambles_: uvtc: Yes. Python works that way, and made sense to me. It also forced you to use namespaces (every file starts a namespace), which has turned out to be a benefit much like forcing people to indent their code properly.

23:03 I can't puzzle out what "aot" would be.

23:03 xeqi: ahead of time compilation

23:03 Shambles_: uvtc: I'm just trying to figure out why it 'sets that example'. I don't see any inherent problems with having things defined under the project's namespace.

23:05 cgag: Shambles_, do you mean you want your main file to to just be called foo-bar, rather than core?

23:05 mmarczyk: that happens even when not doing aot, e.g. (defn foo ...) at the REPL causes a class called user$foo to be created in the default package

23:07 that's not to say that it's a good idea; putting stuff in the default package causes serious weirdness to ensue

23:16 Shambles_: cgag: Well, I suppose what I'd be used to, and expect, is to have a directory named <your project here>, with a file named <your project here>.clg and then subdirectories for the subsystems in my project under that, with matching file names. Each file having a matching namespace.

23:16 I'd like to know about the serious weirdness.

23:20 cgag: i think the way it works is the namespace translates to a filename, so if your namespace was just foo-bar, clojure would look for foo_bar.clj in your source directory

23:20 so i think you could do that, and have your subdirectories have the namespace subdirectory.filename

23:21 Shambles_: cgag: Yes.

23:21 Sorry, that was a reply to something a way back there.

23:22 mmarczyk: yeah, it should mostly work, until it breaks :-)

23:22 the most seriously weird issue I personally experienced was with profiling

23:22 xeqi: is there a way to list the dynamically generated class names?

23:22 Shambles_: mmarczyk: So if I do what I just described I might see strange things in the profiler?

23:24 mmarczyk: I think the code actually worked, but I couldn't watch some methods of interest... it's a hazy memory though

23:24 what is certainly out of question is Java code being able to import a class from the default package -- that is disallowed by the language spec

23:25 admittedly not a big deal for Clojure code most of the time

23:28 I'll also admit that I'm not sure if the profiling issue could have been solved by a knob in visualvm -- adding ".core" was easier than investigating that

23:28 Shambles_: mmarczyk: So what I described wouldn't work in Java? Java programs always have a 'extra' name in front? I hope they don't have a <extra>.<useful-name> for every sub-directory (with "extra" being the directory part, and "useful-name" being the file part).

23:29 mmarczyk: they do, actually

23:30 Shambles_: mmarczyk: Oh my... I'm going to have to work to blugeon things into a reasonable looking hierarchy then.

23:31 mmarczyk: Java classes tend to be called things like com.google.whatever.Foo or org.apache.commons.Bar

23:32 Clojure projects tend to use a core.clj namespace much like Python uses __init__.py files, except you can't leave out the .core part in a :require

23:33 local conventions

23:34 technomancy: .core generally stems from a lack of imagination more than anything else

23:35 gfredericks: technomancy: are you calling The Core unimaginative?

23:35 mmarczyk: arguably this lack of imagination is helpful when trying to get a rough idea of what a new project's public api looks like

23:36 Shambles_: Thanks to everyone for helping me.

23:36 technomancy: gfredericks: absolutely: http://en.wikipedia.org/wiki/The_Core

23:36 gfredericks: The definitive science fiction film of the 21st century?

23:37 technomancy: > Elvis Mitchell, of the New York Times, said, "The brazen silliness of The Core is becalming and inauthentic, like taking a bath in nondairy coffee creamer."

23:37 nice metaphor

23:37 gfredericks: simile?

23:37 technomancy: oops

23:37 * gfredericks waits for xkcd link

23:38 technomancy: "On March 30, 2009 it was reported that Dustin Hoffman was leading a campaign to get more real science into science-fiction movies." <- go Hoffman!

23:38 gfredericks: ? who do you talk to about getting that done?

23:38 bono?

23:38 Shambles_: I can tell I'm going to have trouble getting used to Java's way of doing things. Fans of most languages would not approve of the 'extra' bit on the namespace, (com.big.non-semantic.wad.here.before.what.you.care.about) especially given the pain involved if you wanted to always use the full path (considered good practice in at least Python, since it makes it clear 'where things come from').

23:38 technomancy: gfredericks: who else?

23:39 mmarczyk: Shambles_: some people do use the Java convention, though (using an organization name or sth along these lines to prefix namespace names and no .core namespace; e.g. net.cgrand.enlive-html)

23:39 gfredericks: Shambles_: using the full path is not idiomatic clojure

23:39 technomancy: Shambles_: it's especially fun when the project transfers to a new owner and you have to update all your code that depends on it

23:39 gfredericks: (:require [com.big.non-semantic.wad.here.before.what.you.care.about :as about])

23:39 * technomancy worked at a place that had a full freeze on the svn repo to do that over 2 days

23:40 Shambles_: gfredericks: I think I'd have to do it that way for my sanity, even if people did poo-poo me. :P

23:40 cgag: gfredericks, yeah i think that's how it's usually done in python as well isn't it?

23:40 xeqi: technomancy: was sed broken?

23:40 gfredericks: cgag: I know nothing of python

23:40 xeqi: I was thinking the same thing

23:40 technomancy: xeqi: apparently!

23:40 mmarczyk: Shambles_: Python does use __init__.py files, so the directory structure of more complex packages is pretty much the same

23:40 gfredericks: "...two days of downtime due to a massive sed outage..."

23:42 Shambles_: cgag: You /can/ do that in Python. You can also import everything directly into your namespace, or only certain parts, so it has no prefix at all, but it's generally been found to be more readable if you type the path out, since they're short in Python, and it tends to make it clearer where everything is defined.

23:42 mmarczyk: Shambles_: importing the main namespace is shorter, but :require :as is perfectly idiomatic Clojure (I actually think :require specs w/o :as are the minority)

23:42 eggsby: mm, packages in python you just have on your $PYTHONPATH

23:43 mmarczyk: Shambles_: you can also pull in individual names or all names from a namespace into the current namespace with :require :refer or :use (same result, different syntax)

23:43 eggsby: site-packages or w/e

23:44 Shambles_: mmarczyk: The only difference between Java and Python's way of namespace handling is the 'extra' path due to every directory (in the Java way). That's the part that's giving me "heartburn of the brain" at the moment.

23:44 mmarczyk: Yeah, so that part is like Python.

23:48 mmarczyk: Shambles_: well what I'm saying is that any Python "package" (a collection of modules -- I realize this is an overloaded word in Python lingo) complex enough to be split into multiple files will likely have the same structure

23:48 Shambles_: for example the pygments module is defined in a file called pygments/__init__.py

23:49 Shambles_: with ancillary modules called pygments.foo defined in files called pygments/foo.py which live alongside it

23:50 Shambles_: mmarczyk: Right, but to refer to things I'd type "pygments.thing_I_care_about" not "pygments.__init__.thing_I_care_about".

23:51 eggsby: I'm not sure what the correlary is, you don't do that in clojure either.

23:51 mmarczyk: Shambles_: sure, and you can do that in Clojure at the cost of a few extra characters (and in fact everybody does it) -- far from a big deal

23:52 eggsby: Python just uses the file structure for its module namespacing, clojure explicitly defines it in the ns macro

23:52 Shambles_: mmarczyk: What I'm thinking about, for example, is wanting to have a "main" file with my "main" procedure to set up a program, and then say a subdirectory for the GUI stuff. Unfortunately the Java way this makes me have to type "project.main.main" and "project.gui.gui", with the stutter due to the directories forcing their way into the namespace path.

23:52 mmarczyk: I could work around this, except for the 'main' issue, now that I know about it. I'd probably try not to have something with the same name as the directory in subsystem.

23:53 mmarczyk: Shambles_: what main issue?

23:53 Shambles_: you need to have one dot in your namespace names to be safe

23:53 Shambles_: mmarczyk: the "main.main" part instead of just "main".

23:53 eggsby: oh, rename the core part of your module 'core'

23:53 isntead of project/gui/gui.clj use project/gui/core.clj

23:54 mmarczyk: Shambles_: so you'd call your main namespace project.main

23:54 Shambles_: and you can totally call the gui namespace project.gui

23:54 Shambles_: eggsby: Yes, I was trying (and apparently failing) to get my issue across. Basically I don't like directories causing names to be inserted in the namespace path. I'm not used to that.

23:55 mmarczyk: Shambles_: just don't use "project" (with no dot) as a namespace name

23:56 Shambles_: mmarczyk: I'm aware I can call them that, but I won't want to. I don't want functions to have the same name as the directory, since it reads bizarrely. I'll do my best to 'hide' the fact that the directories are being included in the path, to avoid the stutters you'd get with a directory and function having the same name.

23:56 eggsby: Shambles_: I came from python exclusively to clj, I've enjoyed it a lot

23:56 Shambles_: mmarczyk: And yeah, I'm sure I could hide the stutter with import notations, but I'd rather not.

23:57 mmarczyk: whatever floats your boat

23:57 just trying to give you all the options.

23:57 cgag: moving from python to clj feels to me the way moving from c++ to python did

23:58 Shambles_: I've found I 'need' Lisp occasionally, but rarely, which is why I'm trying to move to it from Python myself. I ended up with Racket for the programming features (I'm having issues with the I/O though), and Clojure for the fancy I/O. At least that's what I'm trying to settle on.

23:58 Raynes: Man.

23:58 All you Python guys should do me a solid.

23:59 eggsby: Shambles_: I think that defining your namespace per file is cleaner than defining one global module/namepsace per directory w/ __init__.py

23:59 Raynes: If you want a fun little project that exercises both your Clojure and python skills, change refheap to not shell out to pygments and instead call it directly via jython.

Logging service provided by n01se.net