#clojure log - Sep 11 2009

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

0:15 claritas: anyone know where to adjust the indentation in slime? when I write nested hash/array literals it only indents by one space and makes it hard to read

0:54 travisbrady: ,(type '(1 2 3))

0:54 clojurebot: clojure.lang.PersistentList

1:01 travisbrady: what does the single quote do in the above?

1:06 JAS415: holds evaluation

1:06 otherwise it would be have to treat 1 as a function

1:07 ,(type (1 2 3))

1:07 ,(type (list 1 2 3))

1:08 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

1:08 clojure.lang.PersistentList

1:08 JAS415: ,(type (first '(list b c)))

1:08 clojurebot: clojure.lang.Symbol

1:09 JAS415: (,type (first (list 1 2)))

1:09 ,(type (first (list list 1 2)))

1:09 clojurebot: clojure.lang.PersistentList$1

1:10 JAS415: ,(type clojure.lang.PersistentList$1)

1:10 clojurebot: java.lang.Class

1:10 JAS415: ,(type 'list)

1:10 clojurebot: clojure.lang.Symbol

1:22 travisbrady: JAS415: thanks, but what does it mean to 'hold evaluation'?

1:31 JAS415: it means that for example, symbols aren't converted into the data they represent

1:31 which is why 'list returns type symbol

1:32 whereas the other one returns the persistentlist class

1:32 ,(type +)

1:32 clojurebot: clojure.core$_PLUS___4094

1:32 JAS415: ^^ function

1:32 ,(type '+)

1:32 clojurebot: clojure.lang.Symbol

1:32 JAS415: symbol

1:32 so is kind of like the opposite of eval

1:32 clojurebot: eval is sometimes useful - but only sometimes

1:33 JAS415: oh clojurebot, eval is always useful, but not normally in your code

1:34 so like you can do

1:34 (eval '(+ 2 3))

1:34 ,(eval '(+ 2 3))

1:34 clojurebot: DENIED

1:34 JAS415: ahh

1:34 clojurebot wont' let you use eval

1:34 as it can be used nefariously

1:34 but in your repl you can do that

1:36 ,(type '(fn [x] (identity x)))

1:36 clojurebot: clojure.lang.PersistentList

1:36 JAS415: ,(type (fn [x] (identity x)))

1:36 clojurebot: sandbox$eval__6948$fn__6950

2:28 travisbrady: anyone know of a simple example showing how to loop over stdin in clojure?

2:48 JAS415: loop over std in in what way?

2:48 like read a file?

2:48 look at clojure.contrib.duck-streams

2:48 can also do java calls if you must

2:56 manic12: is there a print-object function in clojure which can be extended/overloaded?

2:57 dms_: there is print-dup.

3:03 manic12: thanks

3:03 I'm not sure how to correctly add a method to it though

3:08 dms_: Its just a normal mulit-method. To modify printing strings for instance, you will have something like (demethod print-dup java.lang.String [x writer] (pr "my-string" "s"))

3:11 Hmm.. There also seems to be print-method which dispatches on (type..).

3:11 (doc print)

3:11 clojurebot: "([& more]); Prints the object(s) to the output stream that is the current value of *out*. print and println produce output for human consumption."

3:22 dms_: ok. i really dont understand print-dup and friends as much as i thought i did.

3:25 manic12: no, I figured it out

3:26 if you want to see it I'll paste it somewhere, I looked at the clojure source

3:27 dms_: I just looked at core_print.clj. Now it makes sense. Thanks.

4:10 Bercilak: Has there been anything like doctests done for clojure?

4:10 I read about the :test metadata in Programming Clojure, but it doesn't seem like anybody uses that in the wild.

4:19 eevar2: Bercilak: unit testing? :use clojure.test

4:20 Bercilak: I've been reading the clojure contrib docs, and I really *want* to like them but there just aren't enough examples.

4:21 I come from a python background, and I love what doctests have done culturally for python.

4:22 Simple, verified examples are weaved directly into the documentation...

4:22 Chousuke: I think with clojure it's more common to just test your function until you're sure it works ;P

4:22 and then move onto another one

4:23 eevar2: Bercilak: i'm sure the clojure api docs could use more examples, yea

4:23 Chousuke: but hm, while I'm not aware of any doctest stuff, Rich did add support for pre- and post-assertions at some point.

4:24 I haven't seen that used much either though

4:24 somnium: I think immutability + isolated side-effects remove a lot of the need for testing in languages like Python/Ruby

4:24 hiredman: oh yeah

4:24 * hiredman totally forgot about those

4:24 Bercilak: My name just showed up on the clojure contributor page so I'm giddy to do something useful. :-) Examples in documentation are always good.

4:25 Chousuke: did you already join Assembla and the dev group?

4:25 Bercilak: assembla yes, not the dev group yet

4:26 I'm not even really interested in the testing aspect of it. It's more about the documentation, but having the documentation verified as correct.

4:26 I was kind of hoping that :test was in wide use, because that could be pretty easily automatically converted into documentation.

4:27 I'll look at doing that with assertions, but I might also whip up some code for doing clojure doctests...

4:27 Chousuke: it shouldn't be too difficult. :)

4:28 Bercilak: :-). Nope. Just making sure there wasn't something obvious I was missing...

4:28 I really like clojure.

5:56 ol3`: hello, how do I define vars which should not be exported?

5:58 dms_: (def #^{:private true} myvar [1 2 3])

5:58 That keeps the var private. There is defn- for functions.

5:58 ol3`: dms_: thanks

5:59 dms_: might also want to see clojure.contrib.def. I remember seeing some related utilities.

6:42 ol3`: (doc ns)

6:42 clojurebot: "([name & references]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, defaults to :name correspo

6:52 ambient: danm, it's really slow to write the functional stuff, but the code is damn _compact_

6:52 just a few lines does more than 50 lines of Java

6:56 LauJensen: Hey guys

6:57 liwp: LauJensen: good morning

6:57 cgrand: hey!

6:58 liwp: it's pretty quiet here these days during the day (european time)

6:58 or at least it seemed busier a little while back

6:58 maybe it's all in my head

6:58 achim: hi!

6:58 does anybody know a decent java decompiler? most of those showing up on google seem to be either very old or dubious shareware gui apps

6:58 liwp: achim: doesn't the jdk include some sort of decompiler?

6:59 achim: do you want to decompile class files to java source or byte code (asm)?

7:00 achim: liwp: .class -> .java, preferably

7:00 liwp: the thingy in the jdk 'decompiles' classes to byte code so you can look at the byte code that the compiler produced, so possibly not what you were looking for

7:00 ok

7:00 LauJensen: liwp, I sense a little slowing down of our community as well

7:00 achim: i'm afraid i can't read asm all that well

7:01 liwp: achim: I think all the decompilers I've looked have always been a little clunky. Not a lot of commercial use for such a tool

7:01 achim: the java byte code is quite easy to read since the JVM is a stack machine

7:01 i.e. things are put on the stack and then subsequent instructions operate on the operands that are on the stack

7:02 it takes a little practise to get used to it (and I'm in no way an expert), but after that it's relatively simple. A lot easier than x86 asm

7:02 (lunch)

7:35 powr-toc: What's the syntax for accessing a java inner class in clojure?

7:37 (OuterClass/InnerClass.) doesn't work

7:37 nor does (OuterClass.InnerClass.)

7:39 arbscht: OuterClass$InnerClass

7:39 powr-toc: ahh yeah... just found it as you said :-)

8:03 LauJensen: Do we have an installer like izPack for Scala?

8:18 powr-toc: Is there a macro that allows you to def a var with a docstring?

8:23 LauJensen: Do you need a macro for that?

8:23 Chouser: powr-toc: in contrib there's a defvar

8:24 powr-toc: or you can say (def #^{:doc "my doc string"} foo 5)

8:47 AWizzArd: tomoj: so far there is not such a starter guide for fnparse. You can try the wiki, there is some documentation. And just try to use (lit ...) in the beginning, that can get you started.

10:17 ol3`: (doc ~io!)

10:17 ,(doc ~io!)

10:17 ,(doc io!)

10:17 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

10:17 java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

10:17 "([& body]); If an io! block occurs in a transaction, throws an IllegalStateException, else runs body in an implicit do. If the first expression in body is a literal string, will use that as the exception message."

11:23 rhickey: stuartsierra: latest rdfm is approaching the model I am looking towards, feedback welcome (I know, docs :)

11:29 lisppaste8: url

11:29 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

11:32 stuartsierra: cool

11:32 lisppaste8: rhickey pasted "fiddling with rdfm" at http://paste.lisp.org/display/86930

11:32 stuartsierra: I keep reading "rdfm" as "RTFM".

11:32 rhickey: now has transactions and assoc/dissoc model

11:32 stuartsierra: right, it's Brooklynese :)

11:32 stuartsierra: got it

11:33 rhickey: looking for better name

11:35 Chouser: ~I was trying to think of a better name, and getting nowhere, then suddenly it came to me:

11:35 clojurebot: CLABANGO!

11:37 Chouser: rhickey: would you have any interest in proxy generating automatically-named methods for base class's protected fields and methods?

11:39 rhickey: Chouser: my most recent thoughts were that I think it will be the best use of resources to layer reify/proxy, so the circumscribed part (reify) can be thought of as portable Clojure while the icky bits (protected access, ctors) part of the proxy superset, proxy being an interop construct

11:40 Chouser: I like the separation of concerns for refiy vs. proxy. Are you also saying that proxy would be re-engineered to be implemented using reify?

11:40 rhickey: putting more work into the (much slower) proxy seems a waste, and the pressure on reify to supplant proxy will be great

11:40 Chouser: yes, reify + more work == new proxy

11:41 Chouser: ok

11:41 rhickey: I don't think many are leveraging the dynamic aspect of proxy, but if so we can find a new name

11:42 Chouser: ok

11:42 so perhaps java-specific features as options to reify that are marked as non-portable?

11:43 rhickey: once based on reify you won't need generated wrappers for protected access

11:43 Chouser: then proxy can be just a macro that expands to java-only reify

11:43 oh. oh, right.

11:44 rhickey: Chouser: I think right now the distinction matters only to me. But what I fear is that people will write new code using reify/proxy as Java-in-parens. proxy should only be used for some-badly-designed-library-is-forcing-me-to-do-this situations

11:46 Chouser: would still have an issue with ctor args + closures

11:48 rhickey: that depends, right now proxy only let's you flow through ctor args to super ctor, it doesn't have exposed ctor of its own per se

11:49 Chouser: oh, right the ctor args issue was using reify to provide a base class.

11:51 * Chouser is imagining a proxy macro that generates (reify [Foo] {:allow-java-only-features true, :ctor-args [a b c]} ...)

11:52 Chousuke: maybe (reify [Foo] {:host java} ...)

11:54 Chouser: Chousuke: I was going for something sufficiently onerous that one would definitely prefer using 'proxy' instead

11:55 Chousuke: Chouser: okay, well {:allow-host-features #{feature1, feature2 ...}}

11:56 though that might be too onerous :P

11:59 Chouser: so the idea is to discourage the use of 'reify' for purely interop cases. But things like ctor args would likely be available for interop on almost all hosts

12:01 proxy even on reify would still need a way to call super class methods that have been overridden

12:01 which again reify may not need, depending on the design of the no-arg ctor base class.

12:01 rhickey: (.super-whatever this ...)

12:02 Chouser: auto-named methods of the new class

12:16 AWizzArd: rhickey: I think there is a type at https://www.assembla.com/spaces/clojure-contrib/milestones where it says "... decide to work on the and ..."

12:16 type ==> typo

12:16 :)

12:42 How can I make a private inner class and extend it from an existing one?

12:42 stuartsierra: In Clojure?

12:43 AWizzArd: yes

12:43 proxy, right?

12:43 stuartsierra: inner classes don't really have any meaning in Clojure

12:43 You can proxy almost any class.

12:43 AWizzArd: stuartsierra: please look at this example: http://www.rgagnon.com/javadetails/java-0538.html

12:44 stuartsierra: just proxy javax.mail.Authenticator

12:44 AWizzArd: oki good

12:50 stuartsierra: and how can I make an instance of that proxy?

12:51 in the example code the guy did Authenticator auth = new SMTPAuthenticator(); where SMTPAuthenticator was his private inner class that extended the Authenticator

12:51 But I can't just call new on a proxy

12:53 Chousuke: you have a function that contains (proxy [Authenticator] [] ...)

12:54 and then just call the function whenever you need an instance

12:54 AWizzArd: ok, I see

13:58 stuartsierra: rhickey: I maven-ized your rdfm sources: http://github.com/stuartsierra/rdfm

14:04 rhickey: stuartsierra: what does that mean?

14:04 stuartsierra: I wrote a pom.xml with all the necessary dependencies.

14:05 rhickey: wow - does it really need all of those?

14:05 stuartsierra: Sesame is weird, it's broken up into lots of little modules. I haven't figured out if there's a cleaner way to depend on the whole thing.

14:07 rhickey: I know consumers of rdfm using Sesame might end up using a lot of it, but I've tried to minimize the use in the lib itself, in case people want to use with allegrograph or virtuoso probably won't need more than repository and model

14:08 stuartsierra: true

14:08 I'll see if I can minimize it

14:08 rhickey: is there a reason to have src/main/clojure/ then org/clojure/rdfm.clj?

14:09 is that a maven thing?

14:09 * rhickey knows zip about maven

14:10 stuartsierra: It's the default maven directory layout, things are easier if you follow that.

14:10 technomancy: maven users generally get paid by the directory. =)

14:10 rhickey: ah

14:11 silly me, I just put the deps in http://github.com/richhickey/rdfm/downloads

14:11 stuartsierra: There's a kind of logic to it, dividing up all your sources by type means you never need to filter on file names.

14:11 rhickey: stuartsierra: I'm fine with whatever is easy, just wondering what it will take to rearrange my repo

14:12 stuartsierra: Nothing much, you can just pull from me if you want.

14:12 Just pushed a smaller pom.xml

14:13 I only changed one line in rdfm.clj, commenting out (set! *print-meta*...)

14:15 Copying jars around just got annoying, I'm trying hard to make Maven work.

14:15 rhickey: stuartsierra: did you get to look at the model? I dropped all used of bnodes, I'm kind of anti-bnode now. once an identity is in the rdf graph you can use rdfm/assoc/assoc*/dissoc/dissoc* (in transactions) to maintain it

14:16 * rhickey discovers he has maven installed and wonders how

14:17 rhickey: I have thoughts about being able to tie rdf and jms queue transactions to dosync

14:17 stuartsierra: I don't like bnodes either, but how do you avoid them?

14:17 rhickey: then you could dosync, with linked rdf/queue transactons, and on STM retries you'll get rollbacks, all commit together

14:18 then you could dosync, with linked rdf/queue transactons, and on STM retries you'll get rollbacks, all commit together

14:19 stuartsierra: I just never create bnodes. for this api the purpose is to rdf-persist Clojure data, so it's just a matter of choice

14:19 stuartsierra: Ok, that makes sense.

14:20 rhickey: plus, I can;t rely on bnodes being the determinant of whether something is 'owned/nested'

14:20 stuartsierra: what does owned/nested mean?

14:20 rhickey: finally, bnodes have startling existential semantics that few people using them are aware of

14:21 when you store an unnamed composite as an attribute (a nested map/vector) they are considered 'part' of your document (for document style use). These would normally be things for which bnodes would be used, not addressed directly only as a subpart

14:22 but storing nested as bnode doesn't imply bnode == nested

14:22 so now there is a proper ns for nested collections

14:23 stuartsierra: ok, so for rdfm, bnodes DO imply nesting?

14:23 rhickey: when you store-root you get a top-level identity (UUID URI if you don't supply your own)

14:26 stuartsierra: ok

14:26 rhickey: stuartsierra: no, there are no more bnodes at all,

14:28 nested aggregates are under the http://clojure.org/data/collection/ ns

14:28 http://clojure.org/data/collection/vector# "http://clojure.org/data/collection/hash-map#

14:29 uuid after the #

14:30 so pull will grab nested by default, but not walk into other URIs

14:30 the idea is inspired by CBD: http://www.w3.org/Submission/CBD/

14:31 but pervasive use of bnodes in some graphs renders cdb tricky

14:31 this way there is a clear document model - don't want ownership then store-root it separately

14:32 still up in the air are true functional properties, I really want them

14:32 stuartsierra: OWL has functional properties, but not RDF alone.

14:33 rhickey: yeah OWL has FunctionalProperty but no triplestore has enforcement

14:34 I could use that as a tag, but would need to preload and cache in order to avoid having to look up for every statement store

14:34 Chouser: ignore me if this is too off topic, but do you know of any revision control predicates for RDF?

14:34 rhickey: basically I need to know so I can restore a single-statement s p o as either o or #{o}

14:35 Chouser: I once built a triplestore on relational that had full point-in-time snapshot capability

14:36 Chouser: so the snapshoting was outside the RDF graph?

14:36 rhickey: basically was not triples (none are) and had a version/deleted field in each statement

14:36 stuartsierra: Chouser: http://vocab.org/changeset/schema.html

14:40 Chouser: stuartsierra: ok, interesting. I wish google wave used rdf internally.

14:43 stuartsierra: rhickey: re restoring single statements, I don't think that's solvable right now. RDF is too vague about that.

14:52 rhickey: stuartsierra: well. if I or the user would tag those predicates as functional I could easily restore as single vs 1-item-set

14:53 then {:a 1 :b #{2}} would round-trip =

14:53 :a functional, :b not

14:54 stuartsierra: ok, just figured out how to dump the triples:

14:54 (.exportStatements c nil nil nil false (org.openrdf.rio.turtle.TurtleWriter. *out*) (into-array org.openrdf.model.Resource []))

14:55 If you want to round-trip, you might as well define RDFS Classes for each Clojure type.

14:56 rhickey: stuartsierra: I really want to use as little of rdf as possible. I want to leverage triplestores. RDF itself is another story

14:57 the only reason I'd use owl:FunctionalProperty is it says what I want. I fully expect to pull partial graphs etc. I don't want an oodb

14:58 stuartsierra: hm, ok. Those predicates just look odd, like you're embedding type information in the URI.

14:58 rhickey: right now if you store :b #{2} you get back :b 2

14:59 stuartsierra: I'd prefer to store :b 2 and get back :b #{2}

14:59 rhickey: stuartsierra: I am, and yes. but the alternative is double lookup for everything and my data in your data

15:00 stuartsierra: that's the easy way, but really, most application data is not multi-valued

15:00 stuartsierra: true

15:00 rhickey: I asked about multimaps here a while ago and got a bunch of - who cares? :)

15:01 stuartsierra: What's a multimap? Like {#{:a :b} #{:c :d}} ?

15:01 rhickey: I'd find it really arduous to have to deal with a ton of single-value sets

15:02 stuartsierra: That doesn't bother me so much, only because I realized that merging maps that might contain duplicate information, I ended up with lots of single-value sets anyway.

15:02 rhickey: stuartsierra: multimap is exactly what I'm doing with rdfm (and what rdf does) - you can consider rdf subjects + predicates multivalue maps

15:03 stuartsierra: I think if you are working with pre-existing rdf data there is a completely different set of needs. In fact, AAA theory means you could always get another value for any predicate

15:04 stuartsierra: right

15:04 rhickey: this Clojure data model has a closed-world assumption

15:04 stuartsierra: ok

15:04 rhickey: I think it is a really interesting space, but triplestores have been dominated by rdf and semantic web

15:04 stuartsierra: got to go grab some lunch, back in a few

15:04 * stuartsierra leaves

15:06 rhickey: hmmm--- should we use cgrand's parsely for cinc? - http://github.com/cgrand/parsley/blob/master/src/net/cgrand/parsley/demo.clj#L11-42

15:07 Chouser: Chousuke's got a reader mostly done. I haven't looked at it.

15:07 ambiguous grammars. huh.

15:09 Chousuke: I should just find the time to make clojure actually use my reader and work out the bugs :P

15:10 but a reader based on a proper parser library might be better.

15:11 Chouser: I was thinking it might be nice to have a lib that converts a Compiler-produced AST to a clojure-collection AST

15:11 cgrand: rhickey: perfwise, I wouldn't recommend it. It's aim is to serve as the basis for the incremental parser in the Eclipse plugin. I think it has too much baggage to be used in lieu of a simple reader.

15:12 rhickey: cgrand: I'm sure not as fast as a reader, but incremental, recoverable parser is need for so many tools

15:13 Chouser: this would allow work on defining the cinc AST to proceed first (with immediate benefits for understanding current Compiler decisions ala expression-info) and allow java-emit code and cinc compiler work to proceed independently

15:14 also could be used to compare results of cinc compiler with current compiler.

15:14 the main drawback: it would all be throwaway code. :-/

15:15 another benefit: more fun to write than performance-tuning finger trees

15:18 stuartsierra: Question about all the parsers/readers: why not just write a grammar?

15:20 rhickey: stuartsierra: for what, antlr?

15:20 stuartsierra: sure, or JavaCC

15:20 antlr's easier

15:22 Chouser: we'd have to have all antlr in the clojure runtime then, right?

15:22 stuartsierra: yes, but it's not that big; if you can't bear the thought, use JavaCC

15:22 rhickey: stuartsierra: #1, it's another dep, #2, it's left-recursive

15:23 stuartsierra: Why is left-recursion a problem?

15:26 rhickey: http://code.google.com/p/clojure/source/browse/trunk/src/jvm/Reader.g?r=300

15:27 I forget how far I got...

15:28 stuartsierra: ah, ok

15:28 rhickey: in the end, a lisp-style reader is so trivial

15:28 stuartsierra: true

15:29 so why does everyone seem to want to rewrite it?

15:31 hamza: hey guys, i am trying to save a map to a file for some state saving, i am trying to use prn for this but i can't seem to find how should i direct prn to a file? doc says it outputs to *out* i am assuming it is console?

15:32 hiredman: *out* is a var

15:32 ,(doc *out*)

15:32 :(

15:33 hamza: in my system it defaults to System/out. can i change it without messing the repl or is there another way to save a map?

15:34 hiredman: you use binding

15:34 stuartsierra: You can bind it. (binding [*out* (java.io.FileWriter. "/your/file")] ...)

15:35 hamza: thanks, am i on the correct route at using prn to save things to files, or is there a better approach?

15:35 stuartsierra: yes

15:35 prn is good

15:37 hamza: one other thing how do i read it back?

15:37 stuartsierra: (read-string (slurp "/your/file"))

15:38 hamza: thanks, is there a limit on the size of the file for reading? that i should know about/

15:38 .

15:38 stuartsierra: Only the limit of memory in the JVM.

15:39 hamza: thanks a lot,

15:40 lambda-avenger: Are there any examples on using Java enums from clojure?

15:40 hiredman: ,(doc *out*)

15:40 clojurebot: "; A java.io.Writer object representing standard output for print operations. Defaults to System/out"

15:41 stuartsierra: lambda-avenger: you can refer to an existing enum just a static field, ClassName/VALUE_NAME

15:41 but you can't create new enum types

15:42 cschreiner: how can I change the bindings of *out* permantently?

15:42 hiredman: ,(doc reductions)

15:42 clojurebot: "clojure.contrib.seq-utils/reductions;[[f coll] [f init coll]]; Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

15:43 stuartsierra: cschreiner: not recommended, but (alter-var-root (var *out*) (fn [_] the-new-value))

15:43 lambda-avenger: Been trying that, but keep getting java.lang.Exception: Unable to find static field: OneStar in class jcolibri.test.recommenders.travelData.TravelDescription

15:43 cschreiner: stuartsierra: thx

15:44 hiredman: lambda-avenger: uh

15:45 according to http://guru-games.org/projects/jcolibri/jcolibri2/doc/api/jcolibri/test/recommenders/travelData/TravelDescription.Seasons.html there is no enum constant with that name in that enum

15:46 lambda-avenger: That's a different enum. http://gaia.fdi.ucm.es/projects/jcolibri/jcolibri2/doc/api/jcolibri/test/recommenders/travelData/TravelDescription.AccommodationTypes.html

15:47 hiredman: well that is the enum you are looking for OneStar in

15:47 according the exception you pasted

15:48 lambda-avenger: But both enums reside in the same class TravelDescription

15:48 hiredman: no

15:49 oh

15:49 are you sure that is the full exception message?

15:51 jcolibri.test.recommenders.travelData.TravelDescription$AccommodationTypes/OneStar

15:51 lambda-avenger: That works, thanks hiredman.

15:51 clojurebot: hiredman is lazy

15:51 hiredman: clojurebot: thanks, jerk

15:51 clojurebot: Huh?

15:52 hiredman: clojurebot: you heard me!

15:52 clojurebot: hiredman: I'm just giving you a second chance

15:52 hiredman: clojurebot: why, I outta!

15:52 clojurebot: http://clojure.org/rationale

15:53 hiredman: clojurebot: brain?

15:53 clojurebot: brain dump is http://clj.thelastcitadel.com/clojurebot

15:59 lpetit: hi

16:03 cschreiner: the clojurebot is pretty cool

16:03 can clojure rule the world?

16:03 hiredman: clojurebot: well?

16:03 clojurebot: Excuse me?

16:04 cschreiner: clojurebot: can you rule the world?

16:04 clojurebot: what the world needs is more higher order functions

16:04 cschreiner: clojurebot: what is reality?

16:04 clojurebot: reality is an illusion which arises due to a lack of drugs

16:04 cschreiner: ok, I see

16:04 hiredman: :/

16:06 technomancy: hamza: you can use with-out; that encapsulates what you want

16:06 ~doc with-out

16:06 clojurebot: I don't understand.

16:06 technomancy: ,doc with-out

16:06 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/doc

16:06 technomancy: ,(doc with-out)

16:06 clojurebot: No entiendo

16:06 hiredman: ,(doc with-out-str)

16:06 clojurebot: "([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."

16:06 technomancy: you think by now I'd get the hang of this

16:06 yes, that

16:06 stegano: hi guys I am curious about clojure ... and by reading the brief description on the home page it seems the language is dynamic like Ruby .. and its a compiled language too ... so I am wondering does the compilation to bytecode happen at execution time or not ??

16:06 hiredman: stegano: depends

16:07 technomancy: stegano: Ruby is compiled and dynamic too (YARV/Rubinius)

16:07 stegano: hiredman: hmm ... could you elaborate onthis

16:07 dnolen: stegano: when you start up a Clojure REPL and evaluate forms they get compiled on the fly.

16:08 hiredman: you can take a .clj file and compile it to byte code a head of time

16:08 dnolen: you can also Ahead-Of-Time (AOT) compile files as well.

16:08 stegano: Clojure is never interpreted.

16:08 hiredman: or you can just load the .clj file, and it will be compiled to bytecode then executed

16:08 cschreiner: ,(doc union)

16:08 clojurebot: Excuse me?

16:09 hiredman: clojure.set/union

16:09 cschreiner: ah, thx

16:11 stegano: dnolen: so clojure REPL is like Scala's and AOT is also similar .... actually there is only AOT in clojure right?

16:11 i mean AOT compilation

16:12 Chouser: for some reason we use AOT to refer only to saving out .class files

16:12 hiredman: well, the other is sort of JIT to bytecode

16:13 sort of

16:13 Chouser: Yeah, I suppose.

16:15 stegano: Chouser: so .clj i take it is the extension for clojure source file ... what I am trying to understand is when does JIT happen in clojure and when does AOT happen .... or is AOT always manual invoked ?

16:15 Chouser: AOT is manually invoked using the 'compile' fn.

16:15 ,(doc compile)

16:15 clojurebot: "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."

16:17 hiredman: stegano: I wouldn't actually go around calling it the compile to byte code just before execution bit a JIT

16:17 it is bound to be confused with the jvm's JIT to native code

16:19 stegano: hiredman: i agree it will be confusing ... so is there a term used in the clojure land to describe to compilation to bytecode .... and more importantly is the compilation to bytecode invoked from within the code ...... it seems it is using (doc compile) ... am I wrong ?

16:20 hiredman: compile is just for the AOT of time stuff

16:20 which is somewhat exceptional

16:21 mostly I just type stuff into the repl like (+ 1 2) and it gets compiled to bytecode and executed

16:22 stegano: hiredman: so compile is just for AOT ... which is manually invoked from within clojure code using (doc compile) ?? or is there a shell command to AOT compile clj sources

16:22 hiredman: there are a few ways you can do it

16:22 ~clojure-stub

16:22 clojurebot: clojure-stub is http://github.com/nakkaya/clojure-stub/tree/master

16:22 hiredman: is a stub project that uses ant to AOT compile clojure code

16:24 stegano: hiredman: cool thanx for letting me know about clojure-stub ..... so the dynamicity of clojure is from the fact that there is duck typing and the code doesn't need to compiled Ahead of Time ... so its almost interpreted in a way ??

16:24 hiredman: no

16:24 it is definetely compiled

16:26 stegano: hiredman: ok only in REPL the clj source doesn't need to be compiled ahead of time ... in that way its like lisp/ruby/scala REPL .... but outside of REPL I assume clojure is like scala in that the source file need to be pre-compiled

16:26 hiredman: nope

16:27 stegano: hiredman: ok i am thoroughly confused :(

16:27 hiredman: ~compile

16:27 clojurebot: the unit of compilation in clojure is the namespace. namespaces are compiled (not files). to compile a namspace the namespace needs to be on the classpath and so does ./classes/ (and the directory needs to exist) because clojure writes the class files to that directory. http://clojure.org/compilation

16:27 hiredman: the url there has a list of reasons why people might need to AOT compile their code

16:28 besides that there isn't much of a reason

16:28 Chouser: you can think of it this way: every top-level expression (at the REPL or in a file) gets compiled to bytecode and then run by the JVM

16:28 hiredman: rlwrap java -server -Djava.security.manager -cp $CLASSPATH:./clojurebot/ clojure.main -i clojurebot/hiredman/clojurebot.clj -r

16:28 Chouser: it can *also* (by use of the 'compile' function) be saved to a .class file just before it's run by the JVM.

16:28 hiredman: is how I launch clojurebot, from a .clj file, no AOT compilation

16:30 drewr: is there something, in commons-httpclient perhaps, that will decode HTML?

16:30 stegano: clojurebot: so namespace can span multiple clj files and these files can be loaded in REPL shell or they can be executed outside of REPL .... in the latter style of execution ... won't the clj files need to be precompiled ??

16:30 drewr: I need "foo & bar" -> "foo & bar"

16:30 dnolen: stegano: AOT is all about deployment. Perhaps you just want to deploy a jar of compiled code. Perhaps you want fast start up time (say you have a _lot_ of clojure files). perhaps you running on a platform where compiling code on the fly is unrealistic (Google App Engine, Android)

16:31 hiredman: the repl is not anything special

16:31 it is just a few clojure functions

16:32 drewr: ah, here we go

16:32 http://stackoverflow.com/questions/994331/java-how-to-decode-html-character-entities-in-java-like-httputility-htmldecode/994339#994339

16:32 stegano: hiredman: so basically clojure REPL is not much different from scala's REPL except that in clojure you can compile a namespace

16:32 hiredman: is that right ?

16:32 clojurebot: hiredman is an evil genius.

16:32 hiredman: drewr: http://gist.github.com/185550 is pretty useful

16:32 clojurebot: knock it off

16:32 clojurebot: Huh?

16:33 hiredman: stegano: I don't know anything about scala's repl

16:34 ~scala ((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)

16:34 clojurebot: Any = 1

16:35 stegano: you guys just drew circles around me and that too of parenthesis :) shame on you :)

16:35 just kidding

16:39 lpetit: Does anybody know if there's an automated way to migrate a google code project's wiki pages and issues to e.g. github ?

16:44 hiredman: there was an issue filed about it in the googlecode issue tracker

16:44 I know clojure's issues where migrated by hand

16:45 lpetit: oh ok. I just have 30 bugs in clojuredev to be migrated to ccw, I guess I'll do that by hand too.

18:17 manic12: is it better to use slime for clojure, because I'm having a helluva time with enclojure?

18:22 ambient: use what feels best for you. dont fix what aint broken

18:24 manic12: yeah, but I want to learn clojure, I'm already good with common lisp

18:25 ambient: enclojure is good, i use it. it's great. use it

18:25 manic12: then please help me

18:25 ambient: i've found no problems with it

18:25 you're not presenting me with any problem

18:26 manic12: i'm on the #enclojure channel, can you talk to me there?

18:26 ambient: sorry, can't right now

18:26 manic12: can't talk or can't switch?

18:45 stegano: hi guys could you name some testing frameworks for clojure and webframeworks too please

18:46 Chousuke: clojure.test (only in git at the moment though) and compojure :P

19:33 crios: hello

19:34 I'm a clojure newbe. Could anyone help me on an example of "clojure programming" book?

19:36 arbscht: crios: state your question and someone will help you if they can :)

19:37 crios: I cannot understand how the "parse" xml function is included into the "examples/tasklist.clj" example

19:38 the example starts with a "(:use [clojure.contrib.duck-streams :only (reader)])"

19:38 but does not contain (:use [clojure.xml :only (parse)])

19:39 the function is then used in this way: (parse (InputSource. (reader (File. arg)))

19:39 etc

19:41 How is 'parse' imported? After two hours trying to understand I'm a bit puzzled :)

19:43 Chousuke: it might just be a mistake in the example :/

19:43 crios: here the code: http://pastebin.com/d28b74b0e

19:44 no, it compiles with (compile 'examples.tasklist)

19:44 (and that was also my first thougth :))

19:45 Chousuke: that uses clojure.xml/parse directly though. hm.

19:45 crios: I checked also the "clojure.contrib.duck-streams" library, but no 'parse' import, too

19:45 Chousuke: does it run as well? :/

19:46 just compiling it does not guarantee that it runs.

19:46 crios: @Chousuke: the (clojure.xml/parse is mine

19:46 the original version is (parse

19:47 And yes, it worked.

19:48 JAS415: parse is in clojure ns

19:48 Chousuke: you're not running it from the repl or anything?

19:48 ,`parse

19:48 clojurebot: sandbox/parse

19:48 Chousuke: apparently not :/

19:48 JAS415: hmm

19:49 crios: here the original version: http://pastebin.com/d3bb9cfa2

19:49 parse is into xml.clj , into clojure.jar

19:49 Chousuke: ah, duh.

19:49 it's not clojure.xml/parse at all

19:50 it's a method of the SAX parser object.

19:50 note the .. form on the previous line

19:51 JAS415: lol

19:51 Chousuke: it's like SAXParserFactory.newInstance().newSAXParser().parse(new InputSource( ...))

19:51 crios: so an instance method can start without a dot? I was expecting (.parse

19:51 Chousuke: crios: it's ..

19:52 crios: (.. foo bar (foo bar)) means foo.bar().foo(bar)

19:52 crios: Ah ok, I understand!

19:53 Chousuke: you might prefer -> to ..

19:53 crios: really puzzled , thank you Chousuke

19:53 Chousuke: ,(-> "Hello" (.substring 2 5) .toUpperCase)

19:53 clojurebot: "LLO"

19:54 Chousuke: ,(.. "Hello" (substring 2 5) toUpperCase)

19:54 clojurebot: "LLO"

19:54 Chousuke: ,(-> "Hello" (subs 2 5) .toUpperCase); -> works with clojure functions too

19:54 clojurebot: "LLO"

19:55 Chousuke: .. is pretty much obsolete because of -> but it was there first.

19:55 crios: ah, never seen this notation : ->

19:55 so -> is "deprecated" ?

19:55 Chousuke: neither is. -> is more powerful than ..

19:56 if anything, .. should be deprecated

19:56 crios: why more powerful?

19:56 clojurebot: http://clojure.org/rationale

19:56 Chousuke: crios: you can't mix clojure functions and java methods with ..

19:56 crios: it's strictly method-only

19:57 crios: whereas -> actually just transforms code like (-> foo .bar) to (.bar foo)

19:58 crios: so if (.. whatever (whatever ()) ) then 'whatever' can be just java method and never functions?

19:58 Chousuke: and further (-> foo (.bar zonk) clojurefn) becomes (-> (.bar foo zonk) clojurefn)

19:58 yeah

19:58 -> is a more general macro that just accidentally happens to do what .. does if you use it with the ".method" method notation

20:00 crios: ok, thank you, I'm still reading the book and have not yet seen -> (I hope it will be explained)

20:02 Chousuke: in short, -> does the following: 1) if the second argument is a symbol, wrap it in a list. otherwise, do nothing 2) take the first argument and insert it after the head of whatever results from step 1. 3) if there are more arguments, call -> on the result of step 2 and the remaining arguments; otherwise, the code generated is what step 2 produced.

20:03 it sounds complicated no matter how you explain it but if you try and experiment a bit you should see it's pretty useful

20:03 and rather simple, in the end :)

20:03 crios: (I'm copying you description, to study it carefully :)

20:04 here where the author uses clojure.xml/parse: http://pastebin.com/dcf15462

20:06 coming from java, it is a sort of challenge read a source code as a parser/tokenizer would do, in a lexical way

20:06 in java you have just packages, and simple import stastement

20:08 -> is a reader macro? should it be here :http://clojure.org/reader ?

20:08 Chousuke: nah, it's just a macro.

20:09 (doc ->)

20:09 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

20:11 crios: also here http://clojure.org/API#toc35

20:11 Chousuke: the thing to remember with macros is that their arguments are not your program's values, but literally code.

20:13 so if you do (def foo (new SomeJavaClass)) and then do (-> foo .method .method2) you're not calling -> with the instance of SomeJavaClass as its parameter --- the parameter is the symbol foo

20:14 similarly, the .method and .method2 are also only symbols

20:15 the macro then does whatever it wants with these symbols, and outputs a data structure that (hopefully) is valid clojure code

20:15 and then the compiler compiles it.

20:17 this is one more thing that takes a while to sink in, but until it does you're free to consider macros magical. :P I know I used to.

20:18 crios: :)

20:19 ah another question: what is the difference between (var and (resolve ?

20:19 both return Var , if I understood correctly

20:20 Chousuke: ,(var +)

20:20 clojurebot: #'clojure.core/+

20:20 Chousuke: ,(resolve '+)

20:20 clojurebot: #'clojure.core/+

20:20 Chousuke: ,(resolve 'foo)

20:20 clojurebot: nil

20:20 Chousuke: ,(var foo)

20:20 clojurebot: java.lang.Exception: Unable to resolve var: foo in this context

20:20 Chousuke: var is also a special form

20:21 crios: ,(var 'foo)

20:21 Chousuke: also hm

20:21 clojurebot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol

20:22 Chousuke: heh, weird error messages

20:22 crios: quoting the symbol

20:22 hiredman: ,(macroexpand 'foo)

20:22 clojurebot: foo

20:22 hiredman: bah

20:22 var sees (quote foo)

20:22 Chousuke: crios: var doesn't evaluate its argument (it's a special form) so it doesn't need to be quoted

20:23 hiredman: ,(macroexpand-1 'foo)

20:23 clojurebot: foo

20:23 Chousuke: crios: in fact, if you quote it, var sees the list (quote foo)

20:23 (macroexpand ''foo)

20:23 ,(macroexpand ''foo)

20:23 clojurebot: (quote foo)

20:23 Chousuke: (macroexpand is not a macro)

20:23 crios: ,(var (quote foo))

20:23 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

20:24 Chousuke: hm.

20:24 details leaking out

20:24 apparently 'foo is not strictly equivalent to (quote foo)

20:25 it is as far as semantics are concerned though so never mind that

20:25 crios: anyway , the difference between (var and (resolve is just the error handling (exception versus nil) ?

20:25 Chousuke: well, resolve is a function

20:25 which is why you need to quote the argument, as it wants a symbol as a parameter

20:26 ,(resolve (symbol "+")); or you can do this

20:26 clojurebot: #'clojure.core/+

20:26 Chousuke: also hm

20:26 ,(resolve 'String)

20:26 clojurebot: java.lang.String

20:26 Chousuke: ,(var String)

20:26 clojurebot: java.lang.Exception: Expecting var, but String is mapped to class java.lang.String

20:28 crios: it seems (var expects a real Var, while resolve a symbol ?

20:30 Chousuke: nah, Var works with symbols too

20:31 I can't actually tell the primary motivation for it though :/

20:31 I suppose resolve is runtime and var, being a special form, is compile-time?

20:31 crios: who knows :)

20:31 Chousuke: rhickey would :P

20:32 oh well, read the docs for the special forms

20:32 hiredman: ~def resolve

20:32 Chousuke: I'll get some sleep.

20:34 crios2: here I am

20:34 after a firefox crash

20:34 Chousuke: :/

20:35 crios2: here don't see the history

20:35 you was giving me the link http://github.com/richhickey/clojure/blob/e35c4688f30a542d3585e72cfe9bc66936ca5afe/src/clj/clojure/core.clj#L2629

20:35 Chousuke: nothing of value was said after that

20:36 crios2: ok

20:37 mm still don't see any real difference between var and resolve...

20:38 at last at 2:40 a.m. ! :D

20:39 Chousuke: well the fundamental difference still is that var is a special form and resolve is not.

20:40 crios2: ok

20:41 see you, good night and thank you

20:41 ciao

21:04 manic12: how do I get enclojure project repl to require my libs when it starts?

21:41 JAS415: what type of stuff do people use as database backends with clojure?

21:58 Chouser: JAS415: rhickey's working hard to get RDF triple stores to behave well in that capacity.

22:04 JAS415: cool

22:04 now i just have to figure out what rdf triple is

22:05 oo

22:06 is like graph theory

22:06 Chouser: otherwise, regular java stuff -- jdbc sql, tokyo cabinet, etc.

22:08 JAS415: for anyone else for whom that went whoosh http://www.robertprice.co.uk/robblog/archive/2004/10/What_Is_An_RDF_Triple_.shtml

22:10 hiredman: ~google rdf prolog

22:10 clojurebot: First, out of 29700 results is:

22:10 XML.com: An Introduction to Prolog and RDF

22:10 http://www.xml.com/pub/a/2001/04/25/prologrdf/index.html

22:10 JAS415: if I use tokyo cabinet in a desktop application (presumably by using the java library) will i have to GPL (LGPL?) the entire project?

22:10 hiredman: kind of a neat idea

22:16 JAS415: prolog is a pretty nice query language

22:16 my minimal experience with sql involves headache

22:22 manic12: is there a way to import all the class names from a java package?

22:32 JAS415: i think there isn't

22:40 manic12: I must be trying to swim against the current

22:42 ambient: autoimports might be a cool IDE feature, because nothing seems to start with a capital letter in clojure :)

22:44 hiredman: eh? what does that have to do with aynthing?

22:46 ambient: you could type class names and automatically import them if they were found in the libs because they're capitalized

Logging service provided by n01se.net