#clojure log - Jan 07 2009

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

1:20 durka: Exception in thread "pool-2-thread-2" java.lang.OutOfMemoryError: Java heap space

1:20 does the agent system recover from this?

1:26 Chouser: I don't think so

1:28 durka: i think this may be a bug...

1:28 Chouser: If it's catchable/preventable, I would agree.

1:28 I've got a simple test case here, just a sec.

1:28 durka: i saw the exception in the console, but i can't get at it from the REPL

1:28 (agent-errors nil)

1:29 (.getQueueCount agt) = 1

1:29 i meant, (agent-errors agt) = nil

1:29 and it normally finishes faster than this...

1:29 i'll try giving the jvm more memory

1:30 lisppaste8: Chouser pasted "OOM in agent" at http://paste.lisp.org/display/73224

1:31 Chouser: durka: that's probably worth posting to the google group.

1:32 durka: shall i?

1:32 Chouser: please

1:33 I really ought to be in bed.

1:33 durka: goodnight then

1:34 Chouser: :-) g'night

1:34 durka: and can i cite your test case?

1:34 Chouser: sure

2:06 durka: apparently agents can throw Exceptions, but when they throw OutOfMemoryErrors this weirdness happens

2:09 lisppaste8: durka annotated #73224 with "more direct test case" at http://paste.lisp.org/display/73224#1

2:14 durka annotated #73224 with "more general" at http://paste.lisp.org/display/73224#2

2:14 durka: curiouser and curiouser

2:16 i think maybe there is a "catch (Exception e) {" that should be a "catch (Throwable e) {"

8:06 AWizzArd: clojurebot: max people

8:06 clojurebot: max people is 116

8:08 duck1123: I would be cool if clojurebot could announce when the record is broken. Does it have hooks for join/parts?

8:09 knapr: does it keep track itself?

8:09 GUIs have never been easier than swing+miglayouy+clojure

8:45 AWizzArd: How can I convert a collection (vector of numbers between -128 and 127) into a byte array? (to-array col) produces an Object[] and (into-array col) produces an Integer[].

8:45 (make-array Byte/TYPE (count col)) returns a byte array of the right size, but I can't fill it via doseq, as (aset ...) requires an index.

8:46 rhickey_: would it be difficult to add an optional parameter to to-array that specifies the type?

8:46 gnuvince_: AWizzArd: (doseq [[i e] (map vector (iterate inc 0) col)] ...)

8:48 AWizzArd: thx

8:57 gnuvince_: AWizzArd: you could make that map a function too; I like the name "enumerate" from Python.

9:10 knapr: Im using a database, now derby but will probably switch to mysql or postgresql because it is a bit slow. however I read about some people storing as binary? what does that mean? storing the records as hashes and then accessing them like that?

9:10 AWizzArd: knapr: you should try #sql or read an introduction to sql.

10:18 rhickey: Chouser: (count (reduce #(cons %2 %) [0] (range 4601)))

10:18 4602

10:18 user=>

10:18 (count (reduce #(cons %2 %) [0] (range 46010)))

10:18 46011

10:18 user=>

10:18 (count (reduce #(cons %2 %) [0] (range 460100)))

10:18 460101

10:18 ?

10:20 Chouser: that's what mine does too.

10:20 * Chouser backs out the patch

10:23 rhickey: heh, that was Java 5, on Java 6:

10:23 (count (reduce #(cons %2 %) [0] (range 46010)))

10:23 46011

10:23 aking: must vm dependent - I get: java.lang.StackOverflowError (NO_SOURCE_FILE:0)

10:23 rhickey: oops:

10:23 user=> (count (reduce #(cons %2 %) [0] (range 46010)))

10:23 java.lang.StackOverflowError (NO_SOURCE_FILE:0)

10:25 durka: did my message to the group go through?

10:32 AWizzArd: Is there an easy way to convert hex numbers between 0 and FF to a java (unsigned) byte?

10:32 rhickey: Chouser: I see this as a non-problem - why consing onto vector like that?

10:32 repeatedly consing

10:32 AWizzArd: Byte/parseByte only accepts numbers between 0 and 7F

10:35 Chouser: rhickey: It was reported here, not in my own code. But it seems easy to write code that expects a list and cons's onto it a lot, then to have a user that's using a vector, passes it to your func, and it works a lot of the time but has a landmine lurking.

10:35 *shrug* your call of course.

10:35 AWizzArd: hex numbers encoded as one or two chars in a string?

10:36 rhickey: Chouser: consing onto non-lists was originally disallowed specifically because of this, but the bottom line is vectors aren't lists

10:36 generally, people should use conj

10:36 AWizzArd: Chouser: as one/two chars in a string. (hex-to-signed-byte "F3")

10:38 drewolson: hey all, are the "correct" svn repos for both clojure and contrib on google code now?

10:39 pd: I think the primary clojure-contrib repo is on github now

10:39 http://github.com/kevinoneill/clojure-contrib/tree/master

10:39 Chouser: AWizzArd: (.byteValue (Integer/parseInt "FF" 16))

10:39 AWizzArd: does Java have such a thing as an unsigned byte?

10:39 pd: He also provides a mirror of the clojure svn if you'd prefer a git copy

10:39 drewolson: pd: i saw that a while ago, figured it was just a mirror

10:40 Chousuke: Chouser: apparently not

10:40 Chouser: java doesn't seem to have unsigned anything :/

10:40 AWizzArd: Chouser: cool thanks

10:40 Chouser: pd, drewolson: primary for clojure and contrib are SVN at code.google.com

10:40 drewolson: Chouser: ok, good, that's what i thought

10:40 pd: I didn't even know clojure-contrib was on code.google

10:41 ty

10:41 Chouser: Chousuke: I approve. If the complexity of dealing with unsigned numbers was ever worth that one bit, it certainly isn't now.

10:42 Chousuke: Chouser: unsigned types make more sense for size types though. :/

10:43 AFAIK most sizes in java are ints

10:43 though even having "primitive" types like ints and longs is somewhat fail.

10:44 Chouser: yeah

10:46 rhickey: if you're rejecting the patch on the grounds its unnecessary (or for any other reason, really) I'd appreciate very much a firm notification. Here is ok, but on the group is best.

10:47 rhickey: Chouser: sure, just discussing now, trying to understand the use case and options

10:48 Chouser: ok, wasn't sure if you were done or not. :-)

10:48 rhickey: also the difference between jdk 5 and 6 on this

10:49 Chouser: how is it possible that the jvm can avoid the stack overflow. It's clearly a non-tail mutually-recursive function, isn't it?

10:50 rhickey: Chouser: the JVM optimizer is always free to do TCO, just never promises it will

10:50 TCO at language level is a promise

10:50 Chouser: but it's not even in the tail position

10:51 1+RT.count(_rest)

10:51 rhickey: right, this is just some opt

10:51 Chouser: huh

10:51 rhickey: I agree :)

10:52 Chouser: I think I'm on OpenJDK 1.6 at the moment. I always forget how to check and change it.

10:54 * Chouser finds update-java-alternatives yet again

10:57 rhickey: durka: fixed

11:00 Chouser: in any case, I think we need Counted marker interface

11:02 durka: awesome

11:03 Chouser: rhickey: it would have other uses?

11:04 rhickey: Chouser: yes, there are several places where it could help - vector creation for example.

11:04 that was the reason on the todo list

11:05 * rhickey needs to move the rest of the todo list in to issues

11:05 Chouser: I can't get to it anymore

11:06 So Counted would mean its count() is faster than linear time?

11:07 rhickey: Chouser: right, Counted indicates O(1) count

11:08 danlarkin: at the cost of insertion time

11:08 rhickey: danlarkin: ?

11:08 danlarkin: right?

11:08 I mean, certainly a very small cost

11:09 rhickey: no, almost everything in Clojure is Counted

11:09 already, just no marker

11:09 Chousuke: I think he means incrementing the counter instance variable.

11:09 rhickey: whatever cost there is to counting is already being incurred

11:12 durka: is clojure intended for use with java 5 or 6 or either?

11:12 rhickey: durka: 5 and up

11:39 knapr: http://paste.pocoo.org/show/98460/

11:39 im trying to connect to postgresql

11:39 the database and table is there

11:40 so i must be doing something els wrong

11:42 ah be damned colons!

11:56 pjb3: just discovered clojure contrib javadoc, very neat

11:57 If you are at a REPL, and you have clojure contrib on your classpath

11:57 (use 'clojure.contrib.javadoc)

11:57 (javadoc String)

11:57 and you get the javadocs for String in a swing frame

12:00 Chouser: hm, maybe that and the stuff from repl-utils should be combined?

12:02 Chousuke: pjb3: I wish it'd open in Firefox though.

12:02 pjb3: the swing thing is *slow*

12:03 or at least, was last time I tried. :/

12:03 danlarkin: Chousuke: I just tried it... still pretty slow

12:22 triddell: I'm trying to port an existing eclipse plug-in to use Clojure instead of Groovy. At runtime I'm currently getting the following stack trace:

12:22 java.lang.ExceptionInInitializerError

12:22 at java.lang.J9VMInternals.initialize(J9VMInternals.java:222)

12:22 at clojure.lang.Namespace.<init>(Namespace.java:31)

12:22 at clojure.lang.Namespace.findOrCreate(Namespace.java:116)

12:23 Chouser: (with-alter [my-var inc] ...) vs. (binding [my-var (inc my-var)] ...) ?

12:23 triddell: line 31 of Namespace.java is: mappings.set(RT.DEFAULT_IMPORTS);

12:23 what is RT in this instance?

12:23 Lau_of_DK: Good evening gentlemen

12:23 Chouser: triddell: paste the whole stack trace to paste.lisp.org?

12:24 danlarkin: good afternoon Lau

12:24 kotarak: Hola, Lau.

12:25 lisppaste8: triddell pasted "untitled" at http://paste.lisp.org/display/73240

12:28 Chouser: triddell: the "Caused by:" sections are often pretty key.

12:29 rhickey: right:

12:29 Caused by: java.lang.IllegalArgumentException: URI scheme is not "file"

12:29 at java.io.File.<init>(File.java:377)

12:29 is the problem

12:30 Lau_of_DK: How difficult would it be to make some type of Fly-make for Clojure?

12:31 triddell: uh, ok, I'm stupid... I had a problem getting the clojure.jar to be found and this was the first error since... didn't pay attention very well... thanks

12:32 Chouser: it's a shame that slime apparently forces you to specifically ask to see anything more than the final cause.

12:37 Lau_of_DK: Whats involved in determining which line in the source is producing a given problem ?

12:38 Chouser: heh, um. It's a process called 'debugging' and is learned via much practice.

12:39 Lau_of_DK: So I cant expect to automate it ?

12:40 danlarkin: So I have a function in one namespace which calls (require ) a variable number of times based on its arguments. Calling (loaded-libs) in the namespace which calls my require-calling-function shows that the required-libs bleed through. Is there a way I can remove the lib from *loaded-libs* but still return a closure capable of calling a function from inside that lib?

12:40 ugh, that is pretty hard to read isn't it

12:41 Chouser: loaded-libs is global, isn't it?

12:42 you asking if there's a way for it to not be?

12:42 danlarkin: yeah

12:42 kotarak: side question: wouldn't it make sense to check for the namespace instead of bookkeeping a list in require?

12:44 Chouser: that would only exacerbate danlarkin's problem.

12:44 cgrand: Chousuke, danlarkin: which JRE are you using and which OS? (clojure.contrib.javadoc/javadoc try to use a real browser before opening the swing browser)

12:45 Chousuke: cgrand: Java 1.5, Mac OS 10.5.6

12:45 danlarkin: cgrand: same as Chousuke

12:46 Chousuke: I guess finding the native browser does not work on OS X java.

12:46 cgrand: well it requires java 6 ...

12:46 Chousuke: right.

12:47 kotarak: On OS X it's just "open <url>"...

12:47 Chouser: ooh, works here -- javadoc comes right up in firefox.

12:47 Chousuke: true.

12:47 Chouser: Ubunutu

12:48 Chousuke: maybe add a check for OS X and use the system "open" instead of java stuff :/

12:53 * Chousuke goes to hack it in

13:04 joma: I must say jdbc+postgresql+pgadminIII+clojure rocks

13:05 Chousuke: yay, works

13:06 * technomancy has high hopes for terracotta+clojure

13:08 mfredrickson: technomancy: ditto. i was looking at that yesterday. neat stuff

13:09 * mfredrickson doesn't really have a use case for it though....

13:09 * mfredrickson likes shiny stuff

13:09 technomancy: seems like you could use it for persistence instead of an RDBMS

13:10 joma: use what instead of rdbms?

13:10 technomancy: use terracotta

13:20 gnuvince_: What's terracotta?

13:21 technomancy: gnuvince_: it's a transparent clustering/persistence mechanism for the JVM

13:22 you just tell it what data to track, and it makes it available to any JVMs in the cluster as if it were local

13:23 gnuvince_: That's pretty cool

13:24 I'm looking at their web page: you just write your program exactly as you would and it automagically becomes clustered?

13:25 technomancy: you need to give it a little help just to tell it which pieces of data you want to share... maybe also tell it what terracotta server to connect to

13:25 but it's really simple

13:27 haven't actually *used* it yet; just read about it.

13:27 gnuvince_: ok

13:37 Chousuke: hm

13:38 joma: im using contrib.sql and it seems im evaing the functions outside the scope of the connection which means I should just pass the statement but eval it inside the function. so how can I do that? i pass (do-statement #(statm)) instead of (do-statement (statm))?

13:38 im asking becasue i cant test right now, damn windows

13:38 Chousuke: my hack to contrib.javadoc is far from optimal, but here it is for the mac users: http://code.google.com/p/clojure-contrib/issues/detail?id=2

13:39 I didn't even bother searching for a 1.5 cross-platform solution :/

13:40 now it only needs some way to set the documentation URL to 1.5 instead of 1.6...

13:41 makes me think; would a OS identification library be useful for contrib?

13:47 philscotted: Is there some variable that is always bound to the last expression evaluated at the REPL, like * in CL?

13:48 Chousuke: philscotted: *1, *2, *3, *e (last exception)

13:50 philscotted: Cheers! Sorry, I'm sure it's in the documentation somewhere, but I hadn't come across it.

13:50 gnuvince_: technomancy: about terracotta, does an instance of the application pick one of the terracotta server to execute on?

13:50 philscotted: Ack. Just found it. Right at the top of the API page.

13:51 technomancy: gnuvince_: I don't think so.

13:51 I've only done the most cursory of examinations though.

13:51 gnuvince_: ok

13:52 I'm wondering if it's the kind of thing were you add a new box, update the XML file and boom, you have more processing power to accomodate and larger number of concurrent users.

13:56 triddell: rhickey: looking back at this paste: http://paste.lisp.org/display/73240 is it possible that this error is caused by the clojure classloader within an eclipse/equinox/osgi environment? The error occurs when trying to initialize the first clojure-based class: solo.Generator on line 6

14:00 Lau_of_DK: Can someone here show me how to put 'binding' to good use?

14:00 leafw: Lau_of_DK: ?

14:01 you mean a good usage case?

14:01 the archetypical is for redirecting stdout

14:01 Lau_of_DK: Ok

14:01 brb

14:02 leafw: (binding [*out* (.getSomeStdout an-instance)] .... any code .... )

14:03 any calls to println in any of the code called within the binding block will use that *out*

14:03 including from other functions indirectly called by functions within the block.

14:04 Lau_of_DK: k

14:04 Thanks

14:04 knapr: http://paste.pocoo.org/show/98475/

14:04 leafw: Stuart's book calls it "acting at a distance", because it lets you redefine just about anything.

14:04 knapr: how do I replace that annoyingly ugly loop?

14:05 gnuvince_: (doc reduce)

14:05 clojurebot: f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val is supplied, returns the result of app

14:06 gnuvince_: knapr: with that

14:06 leafw: knapr: with map, likely, since you accumulate results into a vector. Just call vec on the resulting list from map.

14:07 Chouser: (reduce conj [] res)

14:08 knapr: ^^

14:08 knapr: except your loop stops when it finds a nil inside res, or reaches the end of res

14:08 ...while that reduce will include any nils, stopping only at the end.

14:08 oh, even better: (into [] res)

14:11 knapr: what is the standard return-value for sideeffectful functions in Clojure? return nothing? it seems it is to return nil whihc I hate since nil==false

14:11 returning true makes more sense

14:12 gnuvince_: knapr: a function returns the value of its last expression

14:12 danlarkin: knapr: perhaps have it return what it has affected

14:12 gnuvince_: If your last expression is a println, that'll be nil.

14:13 knapr: but lets say evaling statements into a database

14:13 examplemin contrib.sql returns nil

14:13 id rather have true

14:13 what is idiomatic?

14:15 Chouser: I don't know that there's a strong idiom

14:15 print and friends return nil

14:15 send and send-off return their first arg

14:16 leafw: Chouser: ref and agent -friendly functions return always the first arg ... because it's the ref itself.

14:18 Chouser: I use the return value from 'send' about as often as the return value from 'print'

14:18 knapr: Chouser: anyway why cant I just return res directly but have to perform that function?

14:20 StartsWithK_: triddell: do you have a working osgi bundle using clojure? if so, i would like to know how you created it

14:20 Chouser: knapr: with-results uses resultset-seq, which is a lazy seq over query results

14:22 triddell: StartsWithK_: not yet, working one right now

14:23 StartsWithK_: triddell: how far did you go? like, can you register clojure.jar as separate bundle and have it work with another that has some clojure code in it?

14:23 or you have to include clojure.jar with your own bundle

14:27 triddell: StartsWithK_: I'm building an eclipse plugin right now and I've tried separate bundles an d combined. I think I have a classloading issue as soon as a clojure compiled class is called.

14:27 RIght now trying to add: Class.forName("clojure.lang.RT") in bundle's start() according to this: http://groups.google.com/group/clojure/browse_thread/thread/d8e577b5bf41c1bb/4202854a7ed14aca?lnk=gst&q=osgi#4202854a7ed14aca

14:28 But it's not working yet

14:28 StartsWithK_: i had the same problem

14:28 "solved" it by including clojure.jar with my bunde, but had to do that for every bundle

14:29 and i couldn't make it talk with other bundles, classloader problem

14:29 triddell: were you creating an eclipse plug-in or an osgi bundle?

14:30 StartsWithK_: i tried equinox and knoplerfisg as osgi containers with clojure, none worked

14:30 i wanted to use osgi in my app

14:32 at the end i was able to create one mega bundle with everything inside it, no dependencies to other bundles.. not much point in that so i gived up

14:34 triddell: StartsWithK_: bummer... well I'm still banging my head on it.. for this app one bundle should work ok, since I'm just one of many bundles inside eclipse... I can see how it wouldn't work out for you... Do you have a Manifest from your mega-bundle that worked for reference?

14:35 StartsWithK_: triddell: sorry i don't, it was couple of months ago and i deleted it.

14:35 triddell: StartsWithK_: np, you've given me some hope though :-)

14:37 StartsWithK_: triddell: biggest problem was using (proxy), when i would create object with it and used it as argument to method with object from another bundle, i would get strange classloader errors

14:37 maybe creation of such proxy object should go inside (binding [*use-context-classloader* true] ..)

14:37 i don't know, its not documented anywhere how to use it

14:39 Chouser: StartsWithK_: It's likely the way proxy creates and loads classes may have changed since you tried.

14:39 triddell: I'm not using Proxy so I might not run into that.

14:40 StartsWithK_: Chouser: Problem is that when proxy object (maybe even a normal one) is created in one bundle it gets his classloader from RT, and then when used it another bundle it still remember its old classlader, but osgi will change that during objects lifetime

14:41 i don't think that changed, there is still one classloader that RT initializes in its static part

14:49 kotarak: Could this be considered a bug? (use/require :reload some.name.space) does not reload files included with load.

14:50 Chouser: StartsWithK_: but now you have the option of AOT compiling code, including the proxy, and then no special classloader is needed at runtime, even if you use a new proxy definition (as long as it has the same base classes as an already-compiled proxy)

14:51 StartsWithK_: Chouser: is then *use-context-classloader* unused now? if it was used before for anything

14:52 rhickey: StartsWithK_: yes, it is still used

14:53 StartsWithK_: rhickey: can you explain how it should be used

14:54 rhickey: one of the problems I have with people using osgi for Clojure is I never get a sense of why - i.e. what is the objective, or is some environment forcing it? Also, where is there a short description of how osgi supports dynamic bytecode?

14:55 StartsWithK_: by environment: glassfish v3 and eclipse, apache felix is ported do android

14:56 netbeans uses something similar to serviceloader from java6, but serviceloader uses same classloader for 'bundles' as for main app

14:56 rhickey: AOT-compiled Clojure should look like any other Java app

14:57 Clojure is not a service, so sharing it between modules would be an encapsulation violation - probably want one instance of Clojure per module

14:58 StartsWithK_: scala is not a service, but you can use scala standard library as osgi bundle (requires small change to manifest file)

14:58 it dosn't need to have any special osgi support in it

14:59 any .jar can be converted to osgi bundle by adding extra metadata to manifest

14:59 it then is not registered as service, more like its on 'classpath' for other bundles

15:00 rhickey: scala is a static language whose namespaces are java packages. Clojure is a dynamic language whose namespaces are in data structures you might not want to share

15:00 but if you did you could

15:00 seems like most osgi problems relate to dynamic bytecode, not a nissue for scala

15:00 StartsWithK_: only requirement i could find is that any code in it dosn't hold on to his classloader

15:00 Chousuke: hm

15:01 rhickey: StartsWithK_: right, but there is no standard classloader that loads bytecode from bytes publicly, so dynamic bytecode requires custom classloader

15:01 walters: rhickey: basically the java classpath and package concepts just aren't good enough as a module system

15:01 StartsWithK_: well i can take jetty.jar and turn it to osgi bundle, and jetty has no direct osgi support, or log4j or any other 'normal' jar

15:02 rhickey: StartsWithK_: and when you take AOT clojure.jar what happens?

15:02 StartsWithK_: i haven't tired, it was long before AOT

15:02 i should create new test suits with AOT

15:03 but it was such a pain last time to try all the combinations

15:03 rhickey: I'd much rather someone who understands how osgi supports dynamic bytecode would point me to a short reference

15:04 StartsWithK_: i'm not that someone :) but i'll try to find slides from knoplerfish project that have some problems outlined in them

15:04 joma: http://paste.pocoo.org/show/98494/

15:05 why doesnt that work when (Hmm) does?

15:05 (hmm)

15:05 ah wait

15:07 well that returns nil

15:07 but doesnt happen

15:11 how do I call getNextException ?

15:12 gnuvince_: Is there a quick tutorial on java.util.concurrent so that I could know what's in it?

15:13 I know Rich often recommends using it

15:16 philscotted: Anyone know if this issue has been resolved? http://groups.google.com/group/clojure/browse_thread/thread/43a413ae55ed25d0

15:16 I'm adding a jar file with add-classpath but imports are not working.

15:16 However, I can refer to the classes by their fully qualified names.

15:18 danlarkin: lisppaste8: url

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

15:19 danlarkin pasted "refactoring help" at http://paste.lisp.org/display/73247

15:20 danlarkin: so in the patterns function I just pasted I have the same (let ) block on lines 16 and 23

15:20 but I am not sure how to remove the duplication

15:22 StartsWithK_: rhickey: i don't know if it helps, http://www.eclipsecon.org/2008/?page=sub/&amp;id=145 link to pdf is under the title

15:24 kotarak: I think I found a bug: when using AOT compilation (require :reload-all 'some.name.space) does not correctly reload all "loaded" files! Only the master file of the namespace gets reloaded.

15:31 joma: how do I call getNextException ?

15:31 kotarak: How is the general procedure regarding the Issue Tracker? Should I post this to the list or should I add an issue?

15:32 joma: I'm not sure, what need, but that should give you a start: http://clojure.org/java_interop

15:32 Chouser: kotarak: it seems like that may be the current intended behavior. If there's any doubt at all as to whether it should be fixed, I think the list the right place to start.

15:32 rhickey: kotarak: for that one, please create an issue, then post on the list with a link to issue - thanks

15:33 StartsWithK_: not any help

15:33 * Chouser swings -- a miss!

15:33 kotarak: rhickey: ok, will do.

15:34 rhickey: Chouser: I'm sure it doesn't work, but reloading needs to be addressed - right now the built-in make-like logic prevents reloading

15:34 triddell: StartsWithK_ and rhickey: I think I just found a major issue with clojure on equinox/osgi. I now have a working eclipse plugin with clojure.

15:34 rhickey: Chouser: you

15:34 Chouser: your advice still generally correct, I pre-approve this report

15:34 Chouser: heh, ok.

15:35 rhickey: triddell: what's the trick

15:35 ?

15:35 StartsWithK_: triddell: yes, share please

15:36 triddell: rhickey: In RT.java, lastModified function... url.getProtocol() checks for "jar" and if it doesn't get it falls through to file... this produces:

15:36 Caused by: java.lang.IllegalArgumentException: URI scheme is not "file" at java.io.File.<init>(File.java:377) at clojure.lang.RT.lastModified(RT.java:351)

15:36 if I force the "jar" line: I get:

15:37 Caused by: java.lang.ClassCastException: org.eclipse.osgi.framework.internal.core.BundleURLConnection incompatible with java.net.JarURLConnection at clojure.lang.RT.lastModified(RT.java:347)

15:37 if I just return 1 it works!

15:38 rhickey: do BundleURLConnection and JarURLConnection share any superinterfaces?

15:39 triddell: I'm only within one bundle at this point but I was getting the same initial error when using multiple bundles

15:39 not sure, didn't check into that yet... will do though

15:39 StartsWithK_: clojure.jar is inside your bundle? or separete one?

15:39 triddell: the protocol also must be returning something other than "jar" as well

15:40 StartsWithK_: inside right now, but was getting same initial before

15:40 initial error

15:44 rhickey: no interface but base class java.net.URLConnection it appears

15:46 rhickey: triddell: fixed hard else to File in lastModified - svn 1200

15:47 zakwilson: Is anybody using Clojure with the current CVS version of Slime? I'm having a problem.

15:48 Chousuke: zakwilson: let me guess: no fancy repl?

15:48 joma: HOW DO I CALL getNextException?

15:48 zakwilson: Chousuke: yes.

15:48 Chousuke: zakwilson: wait a moment

15:49 http://github.com/Chousuke/dotfiles/tree/master/Aquamacs-customizations.el#L59 you need that

15:49 kotarak: joma: 21:30 joma: I'm not sure, what need, but that should give you a start: http://clojure.org/java_interop

15:50 zakwilson: Chousuke: Thanks. I'll give that a try.

15:54 Problem solved. Adding slime contrib and running slime-repl-init fixed it. Thanks Chousuke.

15:54 triddell: rhickey: that did it, thanks!

15:55 Chousuke: cgrand: your fix for OS X works too.

16:00 joma: how do I call printStackTrace?

16:00 Chousuke: just call it?

16:00 (.printStackTracke myexception)

16:30 knapr: when passing a string of "2008-12-02" to contrib/sql into a column with the type DATE it works in derby but it postgresql I get nosuchfieldexception. anyone know why?

16:36 i need to pass '2008-12-02' instead of "2008-12-02", how?

16:36 hiredman: I wonder if it might want a date object instead of a string?

16:37 I haven't used contrib/sql

16:38 Chouser: knapr: are you using do-prepared?

16:38 danlarkin: ugh it's so hard to choose a good name for software :-/

16:39 Chouser: it's hard to choose a good name for anything

16:49 rhickey: print-dup output has a whole lot of PersistentArrayMap/create in it now

16:52 joma: I wish github would format clojure better

16:52 rhickey: Chouser: yep - the problem is I can't tell when it is important to someone that they get back an ArrayMap. To be correct it needs to know the threshold for when using {} yields ArrayMap

16:52 those cases can be turned into {} literals

16:54 Chouser: print-dup of course has to be careful, I just thought that if you were no guaranteeing {} would default to PersistentArrayMap below a certain size, print-dup could take that into account.

16:54 rhickey: 8 items or less

16:54 joma: why does clojure code look like it is leaning?

16:54 Chouser: might also just be unnecessary fragility.

16:55 joma: why does java code look like it's trying to consume as many lines as possible?

16:55 rhickey: user=> (class {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8})

16:55 clojure.lang.PersistentArrayMap

16:55 user=> (class {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9})

16:55 clojure.lang.PersistentHashMap

16:55 Chouser: joma: sorry, that sounded testier than I meant it. Clojure has this is common with most lisps

16:57 _hrrld: Coming from a C++/Ruby/Scheme background (never having used java)... I want to write the result of my clojure program out to disk and I can't figure out how. Do I need to use java facilities to write files with clojure?

16:58 Chouser: _hrrld: it's fine to use Java classes directly. You have a string you want to write out?

16:59 _hrrld: Yup.

17:00 Chouser: _hrrld: I don't think there's anything in clojure.core to help you, so you can either look at clojure.contrib.duck-streams, or just use the Java calls directly.

17:00 joma: Can't infer the SQL type to use for an instance of java.util.Date.

17:01 _hrrld: So it would be a process of learning some Java file I/O, then translating it into clojure?

17:01 Chouser: _hrrld: yes, or looking at existing clojure examples, or using duck-streams.

17:02 hiredman: actaully the I/O thing is in the faq on the website

17:02 well

17:02 _hrrld: Can you point me to an example of file I/O, I didn't see anything in the reference docs.

17:02 hiredman: I thought it was in the faq

17:02 Chouser: joma: looks like you want java.sql.Timestamp

17:02 hiredman: where did I see that

17:02 Chouser: joma: http://github.com/stuarthalloway/programming-clojure/tree/master/examples/snippet.clj

17:04 hiredman: _hrrld: you can (doto (java.io.FileWriter. "somefile") (.write "string") (.close))

17:04 Chouser: Which is essentially what 'spit' does: http://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/duck_streams.clj#177

17:04 hiredman: there is also with-open

17:06 joma: ime - milliseconds since January 1, 1970, 00:00:00 GMT. A negative nu

17:06 _hrrld: what does the '&' mean in the docs for with-open? (from: http://clojure.org/api)

17:06 joma: yeah so how do I convert?

17:07 Chousuke: _hrrld: it means it's a variable-length argument

17:07 Chouser: varargs

17:07 Chousuke: _hrrld: your code is given as a parameter to the with-open macro

17:08 _hrrld: (with-open [myfile (java.io.FileWriter "out.txt")] (do-stuff-with myfile) (more-stuff-with myfile))

17:08 oops

17:08 missing a .

17:08 _hrrld: That's really helpful. Much appreciated. (:

17:09 Chousuke: with-open also supports multiple name, init pairs

17:10 _hrrld: And closes them all automatically, I presume?

17:10 Chousuke: yes

17:10 in reverse order of initialisation

17:12 _hrrld: "java.lang.IllegalArgumentException: No matching method found: .write" (Am I missing an import, or something?)

17:13 Chouser: that more indicates incorrect parameters to .write

17:14 Chousuke: you probably forgot to give the file as the first argument

17:14 Chouser: make sure the first arg really is a Writer, and the the rest are of types supported by the .write method

17:14 hiredman: or you are calling a write method on something that has no write method

17:14 Chousuke: or something.

17:14 _hrrld: Trying this: (doto (java.io.FileWriter. "a.txt") (.write "foo") (.close))

17:14 Chousuke: right

17:14 hmm

17:15 hiredman: wait

17:15 what version of clojure?

17:15 Chouser: hiredman: ah, good call.

17:15 _hrrld: clojure_20080916

17:15 Chousuke: old

17:15 _hrrld: (!)?

17:15 Chousuke: update from google code :)

17:16 _hrrld: haha. The way to write files out has changed in the last two months?

17:16 Chousuke: clojurebot: download?

17:16 clojurebot: It's greek to me.

17:16 Chousuke: clojurebot: download is http://code.google.com/p/clojure/downloads/list

17:16 clojurebot: Ok.

17:16 Chousuke: _hrrld: no, doto has changed

17:16 _hrrld: the old version of doto did not need the . for java methods

17:16 _hrrld: Neat. I'll get the latest and try again.

17:17 Chousuke: _hrrld: many other changes too

17:17 hiredman: which is why the exception shows the method as ".write" instead of "write"

17:17 Chousuke: _hrrld: for example, trying to open multiple files in with-open with that version would have worked, but there was a bug so that the files other than the first one never got closed

17:18 _hrrld: and there's precompilation, clojure.main, and all kinds of neat stuff.

17:18 or was clojure.main after that release? :/

17:18 _hrrld: Cute. Hey, it worked.

17:19 hiredman: clojure.main?

17:20 Chousuke: hiredman: the new startup thing

17:20 hiredman: clojure.lang.Repl and Script are deprecated now.

17:21 drewolson: Chousuke: hrm, didn't know that. does main handle both scripts and repl with no arg?

17:21 Chouser: I suppose that means I should switch over.

17:21 Chousuke: try java -cp clojure.jar clojure.main --help

17:22 hiredman: oh really

17:22 Chousuke: or java -jar clojure.jar --help I guess

17:22 hiredman: check that out

17:26 powr-toc: Chousuke: cool... I hadn't realised that had been implemented

17:30 drewolson: Chousuke: ahh, so much better this way, thanks.

17:30 red_fish: where is documentated #()?

17:31 vogelrn: red_fish: it's mentioned in the reader section of the webpage

17:32 rhickey: Chouser: got your test.html from you appletviewer test handy?

17:32 red_fish: vogelrn: thx

17:32 rhickey: trying to get applets working

17:34 Chouser: rhickey: dunno what code you're looking at, but here's what's in my clojure-applet directory:

17:34 <applet code="net.n01se.HelloWorld" archive="hello.jar" width="800" height="800"></applet>

17:35 rhickey: Chouser: thanks - looking at: http://groups.google.com/group/clojure/msg/6bc1c0fe0165053f

17:37 Chouser: ok

17:40 well, shoot. clojure.main doesn't do what I want, and I've accidentally overwritten my old clojure startup script.

17:40 drewolson: Chouser: i just actually rewrote mine, want me to pastie?

17:40 Chouser: heh. if you want.

17:40 clojure.main is close

17:41 drewolson: http://pastie.org/355135

17:41 Chouser: but I want to provide a startup script for when it runs a repl

17:41 and I want to be able to add to the classpath on the commandline

17:42 drewolson: ah, gotcha

17:42 Chouser: I'm amazed by how personal these startup scripts are.

17:42 drewolson: heh, yep

17:42 Chouser: I assumed we all wanted roughly the same thing (nobody has their own python or ruby startup script), but in fact they're all quite different.

17:42 * Chouser looks up rewrap's -b option

17:44 lisppaste8: rhickey pasted "applet load error" at http://paste.lisp.org/display/73258

17:44 rhickey: anyone know applets well enough to explain above error?

17:45 walters: rhickey: i'm guessing it means you can't refer to any class sun.awt.*

17:45 hiredman: interesting

17:45 walters: rhickey: maybe the AOT compiler is traversing the class hierarchy in a way that javac doesn't?

17:45 Chouser: I saw this.

17:45 powr-toc: rhickey: are you trying to popup a window or anthing like that?

17:46 Chouser: dangit. I can't remember what it was.

17:46 proxy tries to implement things it shouldn't. or something.

17:47 cmvkk: by the way, if you guys are working at making clojure applets work, then that is very exciting.

17:47 i was just trying to do it earlier today and it didn't work.

17:47 rhickey: just this simple class:

17:47 (ns clojure.examples.applet

17:47 (:gen-class

17:47 :extends java.applet.Applet))

17:48 Chouser: something descends into the Applet heirarchy and finds platform-specific classes that it's not supposed to touch

17:49 I'm very agitated. I had this, and I think I found a work-around.

17:49 fffej: I've got a confusing error - No matching method found: indexOf for class java.lang.String - can anyone point me into the right direction?

17:50 rhickey: Chouser: cuase it seems like I'm past the classloader problem

17:50 cause

17:50 Chouser: rhickey: excellent!

17:50 Chousuke: fffej: are you giving it the right argiuments?

17:50 rhickey: seems being the operative word :)

17:50 Chousuke: arguments*

17:51 fffej: chousuke: it's taking a JTextFIeld.getText() for both arguments and works most of the time until an exception is thrown

17:51 aking: ,(.indexOf "Hello" "o")

17:51 clojurebot: 4

17:51 Chouser: hm, I have :excludes #{"applyCompoundShape"} in my gen-class example

17:51 rhickey: basically I've made ROOT_CLASSLOADER load-on-demand, will never create a dynamic loader if no dynamic code

17:52 hiredman: the javadoc for runtime permission has a description of the accessClassInPackage permission, but it is greek to me

17:52 Chouser: apparently I had a patch against gen-class, but I don't seem to have it in my git repo

17:53 I'm pretty sure that :excludes is to work around the access error

17:55 durka: rhickey: where does add-classpath go then?

17:57 * technomancy listens up

18:04 fffej: i'm not understanding re-find. (re-find #"bar" "bar") => "bar" whereas (re-find #"(foo)|(bar)" "foo bar") => ["foo" "foo" nil] - why does one return a vector and one just the result directly?

18:05 durka: looks like the second is capturing groups?

18:06 fffej: but shouldn't the return type be consistent? (e.g. a vector of 1 in the first example), otherwise my code has to check whether the return val is a collection which doesn't feel right

18:06 hiredman: ,(re-find #"(foo)|(bar)" "foo bar")

18:06 clojurebot: [foo foo nil]

18:07 hiredman: ,(re-find #"bar" "foo bar")

18:07 clojurebot: bar

18:07 hiredman: ,(re-find #\w" "foo bar")

18:07 clojurebot: Eval-in-box threw an exception:No dispatch macro for: \

18:07 hiredman: ,(re-find #"\w" "foo bar")

18:07 clojurebot: well?

18:07 clojurebot: f

18:07 excusez-moi

18:08 cmvkk: f?

18:08 hiredman: ,(prn "f")

18:08 clojurebot: nil

18:08 "f"

18:09 hiredman: I guess clojurebot should capture a prn into a stringwriter instead of just calling .toString

18:10 fffej: Is the weirdness with re-find me being daft, or should I file a bug report?

18:11 joma: Why can't I load a namespace into the repl? #'progs.netflix.parsing/parse-intervals works but when I try to us it it fails

18:11 (parsing/str-to-date "2008-12-02")

18:11 java.lang.Exception: No such namespace: parsing (NO_SOURCE_FILE:44)

18:11 user=> (str-to-date "2008-12-02")

18:11 java.lang.Exception: Unable to resolve symbol: str-to-date in this context (NO_SOURCE_FILE:45)

18:11 user=>

18:12 hiredman: how are you trying to "load" the namespace?

18:13 joma: ah (progs.netflix.parsing/str-to-date "2008-12-02")

18:17 leafw: joma, how about (load-file "progs/netflixs/parsing") ?

18:18 hiredman: (doc require)

18:18 clojurebot: Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of

18:26 zakwilson: I'm having trouble getting Slime to eval expressions in the correct namespace. Has anybody else had a similar problem?

18:38 powr-toc: will clojure ever ship with contrib?

18:43 durka: (doc re-groups)

18:43 clojurebot: Returns the groups from the most recent match/find. If there are no nested groups, returns a string of the entire match. If there are nested groups, returns a vector of the groups, the first element being the entire match.; arglists ([m])

18:44 durka: fffej: so if it is a bug, it is a documented bug anyway

18:44 hiredman: ,(prn "f")

18:44 clojurebot: nil


18:44 "f"

18:45 hiredman: hmmm

18:45 ,(identity "f")

18:45 clojurebot: f



18:46 hiredman: we will call that a regression

18:49 ,(identity "f")

18:49 clojurebot: f

18:49 vladsharp: can you see how a macro was expanded?

18:50 danlarkin: (doc macroexpand)

18:50 clojurebot: Repeatedly calls macroexpand-1 on form until it no longer represents a macro form, then returns it. Note neither macroexpand-1 nor macroexpand expand macros in subforms.; arglists ([form])

18:51 vladsharp: ah ha, thanks

18:54 hiredman: ,(identity nil)

18:54 clojurebot: nil

18:54 Chousuke: fun to see you developing clojurebot :P

18:54 something magically changes and then the bot behaves differently!

18:55 hiredman: so the result is now (prn ...) to a stringwriter so we get quotes and stuff

18:57 joma: (defn split [string delim] (seq (.split string delim))) , into core?

18:59 hiredman: oops

19:00 I think I just commited to github with the wrong commit message

19:04 joma: why does clojure code look like it is leaning?

19:04 (defn split [string delim] (seq (.split string delim))) , into core?

19:05 can anyone add to clojurebot?

19:10 powr-toc: hiredman: if you've not pushed the commit you can git commit --amend

19:11 hiredman: powr-toc: I am figuring that out

19:12 powr-toc: hiredman: but if you've pushed it things are uglier

19:13 hiredman: yeah

19:13 well it's ugly now

19:13 powr-toc: lol

19:13 hiredman: I think I will leave it

19:13 damn it

19:13 now I have two duplicate commit messages

19:13 yeah, time to leave be

19:13 powr-toc: hiredman: is it your project? And is it highly unlikely anyone has pulled?

19:14 hiredman: yes, and yes

19:14 I can just leave it be

19:14 I don't mind too much

19:15 danlarkin: too late, hiredman, it's already in my feed reader as a duplicate message :)

19:16 hiredman: I know

19:16 dreish: People will be talking about it for years.

19:16 hiredman: there are 2 duplicate messages now

19:16 4 total messages

19:17 powr-toc: hiredman: it's probably reasonably easy to recover from by deleting the remote branch, rebasing it (so long as no one else has pulled it) and pushing back again

19:17 joma: anyone have an example of doing a prepared statement with contrib.sql?

19:18 hiredman: the "merge branch live" thing is new

19:18 live being the name of the branch I run clojurebot out of

19:18 must be because I made the commits in that branch?

19:18 rhickey: Applet started!

19:18 hiredman: !!

19:18 durka: :D

19:19 danlarkin: great success!

19:19 hiredman: ,(Date.)

19:20 clojurebot: #<Date Wed Jan 07 16:18:00 PST 2009>

19:20 hiredman: clojurebot: Wed Jan 07 16:18:00 PST 2009 is <reply>"Applet started!" -- rhickey

19:20 clojurebot: You don't have to tell me twice.

19:20 rhickey: last prob was that gen-class and proxy both gen stubs for package-private methods, shouldn't

15:20 durka: when java is looking through the classpath for imports, how does it decide which classes to make available?

15:21 it kind of looks like it ignores the versions of plain .class files, but checks the versions in .jar manifests against the current JVM version

15:21 does anyone know if this is the case?

15:47 rhickey: Chouser: any tests for binding-assertions patch? looks ok, but I haven't exercised it

15:47 pjb3: rhickey: Applet started? What was that about?

15:48 rhickey: pjb3: got a dummy applet running using AOT, resolved classloader and security issues

15:48 svn 1201

15:48 pjb3: cool, does that mean you can run Clojure code in an applet?

15:49 rhickey: yes, when AOT compiled

15:49 pjb3: Cool, it would be cool if we had something like this for Clojure: http://sisc-scheme.org/sisc-online.php

15:50 A REPL in an Applet, would that still work? Because you would be defn'ing stuff from a REPL in an applet

15:50 hiredman: clojurebot: Jan?

15:50 clojurebot: "Applet started!" -- rhickey

15:50 rhickey: pjb3: that is not going to happen, at least not without a cert - Clojure is not interpreted and the default security prohibits custom classloaders needed for eval

15:51 pjb3: Ah, that's what I thought

15:51 rhickey: clojurebot: svn?

15:51 clojurebot: svn is http://clojure.googlecode.com/svn/trunk/

15:51 pjb3: Step one would be making a swing REPL I guess

15:51 albino: why not do what all the cool kids do and put a REPL as a server process talking over a socket to an ajax front end

15:52 pjb3: then futzing around with a signed applet or whatever to get the custom classloaders, assuming that is possible

15:52 albino: Yeah, I thought about that, but then it's hard to have a general purpose "Try Clojure Online!" thing

15:52 hiredman: albino: hmmmmm

15:52 pjb3: right?

15:52 because then everybody is connected to the same repl, defing things, etc.

15:53 powr-toc: how would you create a constant unmodifiable reference in clojure?

15:54 i.e. an immutable pointer to an immutable object.

15:54 albino: IIRC that's how this one works http://tryruby.hobix.com/

15:54 rhickey: powr-toc: in a ref?

15:54 albino: pjb3: well you can have a process per user, or thread per user...whatever

15:55 pjb3: albino: right, then you got to host that and everything

15:55 albino: pjb3: perfect, so you're volunteering then? :)

15:55 pjb3: Where as if you had an applet, you can server it as a static file

15:55 hiredman: albino: the main diff between that and an applet is an applet runs on the user's computer and uses their resources

15:55 so you can let them do everything clojure does

15:55 albino: hiredman: right

15:55 I was just speaking on the fastest way to get a "try it now in a browser" clojure thing going

15:56 hiredman: but, uh, you need to sandbox a repl running on your own machine

15:56 and effective sandboxing blows

15:56 pjb3: What about that web start stuff? That just downloads a java app and runs it, right?

15:56 albino: hiredman: I assume you're already sandboxing clojurebot?

15:56 powr-toc: rhickey: not sure... I'm just trying to grok the difference between var's, ref's, agent's etc... I really just want a constant value equivalent to a final reference to something

15:56 hiredman: albino: yes

15:56 albino: but not very effectively

15:56 pjb3: Well, either way, step 1 is a swing gui REPL

15:56 albino: hiredman: so you've already got a start at it

15:56 rhickey: powr-toc: to prevent accident or malice?

15:57 hiredman: I mean, no IO out of the jvm

15:57 but you can still dealock the bot if you try hard

15:57 albino: what would be fun (maybe not practical) is forking a openvz container per user

15:57 hiredman: deadlock

15:57 albino: OS level sandboxing

15:57 powr-toc: accident

15:57 hiredman: albino: or just find someone who really understands jvm sandboxing

15:58 pjb3: Of Course I guess it should be that hard for people to download a jar file and run "java -jar clojure.jar" from the command line

15:58 hiredman: I just cargo culted the jvm sandboxing that clojuebot uses

15:58 albino: hiredman: who is the expert on that?

15:58 hiredman: no clue

15:58 rhickey: powr-toc: most Clojure data structures are immutable

15:59 albino: ha, just found this in my bookmarks http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

15:59 I wonder if you could build something with this http://www-jpc.physics.ox.ac.uk/index.html

16:00 maybe with JPC you could get it to run on the client machine without jumping through applet hoops

16:00 hiredman: ugh

16:00 powr-toc: rhickey: yeah, I understand that... I'm really just after the idiomatic way of doing it... the value will be accessible across a variety of threads. I'm wondering if there is effectively a way to freeze a reference to a particular object

16:00 do I just use def?

16:01 rhickey: powr-toc: how is it getting passed to the threads?

16:01 people don't usually accidentally say alter/swap!/set! etc

16:02 but you could set up a validator that will reject all changes like this:

16:02 (let [aval {:never :change}]

16:02 (def aconst (ref aval :validator #(identical? % aval))))

16:02 (dosync (alter aconst assoc :a 1))

16:02 java.lang.IllegalStateException: Invalid reference state (NO_SOURCE_FILE:0)

16:02 powr-toc: rhickey: it's not yet :-) - I'm thinking it'll be initialised immediately at start up though and I'd like it to be visible to all threads

16:02 rhickey: same technique could work for vars/atoms

16:04 powr-toc: ok... It's no biggy really... it's just when I'm in java I'm used to using the final modifier not only to help enforce immutability, but to also indicate intent... i.e. this reference won't ever be changed.

16:04 zakwilson: If you create a var with def, isn't it only rebindable thread-locally?

16:05 rhickey: powr-toc: that's kind of the default intent in Clojure

16:05 powr-toc: rhickey: lol - good point! :-)

16:07 rhickey: In which case presumably idiomatic clojure is simply to declare such values with something like (def pi 3.14159) and be done with it

16:07 which suits me

16:07 rhickey: yeah

16:08 pjb3: But if you can do (ns-unmap 'user 'pi) (def pi 42), right?

16:08 hiredman: is there a lazy-seq of the digits of pi yet?

16:09 mmcgrana: Anyone have a good solution for the problem of setting up different "environment" in e.g. Compojure? For example in a webapp I have a "host" config option that needs to be different in deployment and production. I've thought through several possibilities but none were satisfactory, hopefully someone has encountered this problem before.

16:09 * different "environments"

16:09 pjb3: mmcgrana: specify the environment as a startup option, load a .clj matching the environment?

16:09 production.clj, develoment.clj?

16:10 environment.clj loads for everything?

16:10 mmcgrana: how do you suggest "specifying the environment as a startup option"?

16:10 danlarkin: mmcgrana: I haven't used compojure, but in django it's commonly solved with having settings.py import settings_local.py -- where settings.py defines settings common to dev, prod, stage, etc. and settings_local.py defines database connection settings etc

16:10 mmcgrana: excuse my ignorance in advance...

16:10 pjb3: command-line argument

16:10 assume development if not present

16:11 Does compojure run in a servlet engine like Jetty?

16:11 Then maybe a JNDI or web.xml setting

16:12 mmcgrana: I think so, I'm not actually using compojure I just thought people who had been using it would have thought about the issue

16:12 pjb3: mmcgrana: not using it either

16:13 mmcgrana: btw the basic environment.clj, production.clj etc approach sounds basically right, i just have to get the mechanics down

16:14 powr-toc: mmcgrana: the environment.clj development.clj production.clj approach is used heavily in the ruby/rails community if you want any further inspiration

16:16 mmcgrana: in fact rails/merb is what pushed me away from ruby into clojure (did rails full time for a while)

16:16 powr-toc: mmcgrana: do you mean the rails/merb fracture?

16:17 or do you just dislike those frameworks? :-)

16:17 mmcgrana: just the style of the frameworks: crazy side effects and excessively coupled apis in particular

16:18 powr-toc: mmcgrana: yeah, I've been getting increasingly dissillusioned with OOP for many problems

16:19 danlarkin: "you know you've been programming in an FP language too long when"... side effects start to confuse you

16:20 that has been happening to me :-o

16:20 Chousuke: has there been a time when side effects have *not* confused you?

16:21 powr-toc: danlarkin: don't you mean you know you've NOT been programming in an FP language when side effects start to confuse you? ;-)

16:21 Chouser: absolutely

16:22 mmcgrana: i must be missing something obvious: say i'm in a boot script an i have an env value, like :dev. I'd like to require myapp.config and end up with myapp.config/env bound to :dev and the various myapp.config/setting{a,b,c} bound according to the env. I don't know how to communicate the env value to the myapp.config namespace so that it sets everything correctly. I guess i could put the env-determination logic in myapp.conf

16:24 hiredman: .conf? sounds like something that should be a .clj

16:25 mmcgrana: hiredman: when i say myapp.config i mean a namespace defined by /myapp/config.clj

16:26 hiredman: you want a seperate library for reading the the config that you can including in other projects?

16:27 mmcgrana: i'm not sure what you mean: myapp.config is just a namespace to hold config values

16:28 hiredman: you appear to be concerned with where to put the logic, and I am asking why

16:30 mmcgrana: I just want config values to be in a single place, that's all. I don't want to put the env-determination logic in the config namespace because I will want to use multiple mechanism to make such determinations.

16:31 lisppaste8: url

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

16:32 mmcgrana pasted "config" at http://paste.lisp.org/display/73269

16:33 mmcgrana annotated #73269 with "untitled" at http://paste.lisp.org/display/73269#1

16:33 hiredman: urm

16:34 you just need (eval (read ...))

16:35 Chouser: a.k.a. load-file

16:35 hiredman: Yes.

16:35 (doc load-file)

16:35 clojurebot: Sequentially read and evaluate the set of forms contained in the file.; arglists ([name])

16:39 mmcgrana: i like the idea of root config values and then additional/changed values for different envs, but i dont think i want to commit to requiring different files for each env. for example in the simple case in the paste everything could just be in the myapp.config file. sorry if i'm being thick, maybe i just need to sleep on it.

16:39 powr-toc: what's the clojure predicate that returns whether or not a supplied item is present in a seq?

16:39 hiredman: (doc some)

16:39 clojurebot: Returns the first logical true value of (pred x) for any x in coll, else nil.; arglists ([pred coll])

16:40 powr-toc: mmcgrana: can you not just represent the whole config as a hashmap?

16:40 hiredman: ,(#(some #{%} %2) :a [:a :b :c])

16:40 clojurebot: :a

16:40 hiredman: ,(#(some #{%} %2) :d [:a :b :c])

16:40 clojurebot: nil

16:41 mmcgrana: indeed i could, its how i have it sketched now, but you still need some val that holds the env that you use to index into the first level of the map

16:42 dreish: Why that syntax and not (some #{:a} [:a :b :c]) ... (some #{:d} [:a :b :c])

16:42 hiredman: mmcgrana: I have that val

16:43 (keyword (first *command-line-args*))

16:43 mmcgrana: yes i see, but outside of the myapp.config namespace only

16:44 hiredman: dreish: well he asked for a predicate

16:44 which is a function that returns nil or (not nil)

16:44 #(some #{%} %2) is such a function

16:49 powr-toc: (defn includes? [val seq]

16:49 (not (nil? (some #{val} seq))))


16:49 hiredman: uh

16:49 no

16:50 (defn includes? [val seq] (some #{val} seq))

16:50 mmcgrana: hiredman: the (keyword... code would correspond to (determine-env-from-cl) in the paste

16:50 hiredman: ,(let [f (fn [val seq] (some #{val} seq))] (f :a [:a :b :c]))

16:50 clojurebot: :a

16:50 hiredman: ,(let [f (fn [val seq] (some #{val} seq))] (f :d [:a :b :c]))

16:50 clojurebot: nil

16:52 hiredman: nil? is bascially the same as not

16:52 ,(= (nil? :a) (not :a))

16:52 clojurebot: true

16:52 hiredman: so you have a double negative

16:55 Chousuke: hiredman: except for (nil? false) (not false)

16:57 hiredman: well

16:57 Fine

16:58 actually

16:58 .(nil? false)

16:58 ,(nil? false)

16:58 clojurebot: false

16:58 hiredman: *sigh*

16:59 powr-toc: ,(true? :a)

16:59 clojurebot: false

17:00 hiredman: true and false are for java interop, so I don't care, so there

17:02 Chousuke: (true? (Boolean. true))

17:02 ,(true? (Boolean. true))

17:02 clojurebot: false

17:03 Chousuke: hmm :D

17:03 powr-toc: lol

17:03 danlarkin: JVM bug

17:03 Chousuke: creating new Boolean instances is apparently bad style anyway

17:04 I wonder why the constructor is even public :/

17:04 danlarkin: rich mentions it in his clojure-for-java-programmers presentation IIRC

17:04 hiredman: ,(true? true)

17:04 clojurebot: true

17:04 hiredman: for boxing booleans?

17:04 Chousuke: (true? (Boolean/TRUE))

17:04 gah

17:04 ,(true? Boolean/TRUE)

17:04 clojurebot: true

17:05 Chousuke: hiredman: you can just replace them with Boolean/TRUE

17:05 or FALSE

17:06 hiredman: *shrug*

17:06 Chousuke: or well, I guess the constructor is easier if you don't know which one it is :/

17:07 hiredman: clojurebot: java?

17:07 clojurebot: ?

17:09 vogelrn: ,(= true (Boolean. true))

17:09 clojurebot: true

17:09 Chousuke: well that's interesting :/

17:10 vogelrn: ah

17:10 it's because true? uses identical?

17:10 it assumes that all trues are the same

17:10 object, that is

17:10 whereas using Boolean to create a new true won't be the same, cached one

17:14 I'm kind of torn because that could lead to some really nasty bugs, but like you said, you shouldn't be using the constructor anyway, should use Boolean/TRUE or Boolean.valueOf

17:14 hiredman: clojurebot: max people?

17:14 clojurebot: max people is 116

17:18 danlarkin: how can I apply to a macro?

17:19 Chousuke: I think you'll have to write a macro-apply :/

17:19 mmcgrana: i don't think that you can, e.g. (apply or '(1 2 3)) doesn't work

17:20 * i dont think that you can apply to a macro that is, i dont' know about a macro-apply

17:20 hiredman: ugh

17:20 danlarkin: :'(

17:21 hiredman: thanks guys, I totally just burnt dinner

17:25 danlarkin: Hm. I'm not sure macro-apply is possible

17:25 one "can't take the value of a macro"

17:25 Chousuke: danlarkin: you can produce code that expands into a macro given the name of a macro though.

17:25 mmcgrana: what if macro-apply was itself a macro?

17:25 danlarkin: oh.. well I guess maybe if macro-apply were a macro

17:25 Chousuke: well it has to be

17:26 mmcgrana: right

17:26 Chousuke: I'm trying to figure it out

17:26 (defmacro macro-apply [mac & args] `(~mac ~@(apply concat args))) works somehow but fails for (macro-apply or 1) :/

17:27 mmcgrana: (defmacro macro-apply [mac & args] `(~mac ~@args)) ?

17:28 duck1123: How would I, in a macro, take a sequence of forms (from a macro-expand time function), and output it as just those forms.

17:28 mmcgrana: duck1123: i think a macro needs to return a single form

17:28 (do ~@forms)

17:28 hiredman: ^-

17:30 duck1123: ok, what I want to do, is in a compojure defservice form, break the list of my handlers into separate functions. ~@(users-handlers) would do the trick?

17:30 hiredman: uh

17:30 dreish: ,(System/identityHashCode (Boolean. true))

17:30 clojurebot: 13603674

17:30 danlarkin: Chousuke: you are getting close

17:30 dreish: ,(System/identityHashCode (Boolean. true))

17:30 clojurebot: 22150794

17:31 hiredman: duck1123: you want a macro to define more than one function?

17:33 duck1123: defservice requires all the handlers to be at the same level, I want to have several functions that each return a seq of handlers that get flattened into the same bottom level.

17:35 I think I can make ~@(handler-fn) work.

17:35 Chousuke: danlarkin: I'm going to have to go to sleep now though :/

17:35 danlarkin: Chousuke: aw :)

17:40 Chousuke: (defmacro macro-apply [mac & args] `(~mac ~@(apply eval args)))

17:40 one step better?

17:41 even though it uses eval, which could be avoided I think

17:42 oh and not to mention... java.lang.UnsupportedOperationException: Can't eval locals

18:12 lisppaste8: mmcgrana pasted "contrib broken on head?" at http://paste.lisp.org/display/73274

18:13 mmcgrana: anyone tried recent clojure + clojure-contrib together, particularly w.r.t. clojure.contrib.repl-utils?

18:13 I'm getting the pasted error.

18:19 Chouser: mmcgrana: huh. yeah, I'm seeing that. hang on.

18:29 mmcgrana: fixed, clojure-contrib SVN 352

18:31 mmcgrana: Chouser: wow, thanks for the quick response!

18:34 Chouser: sure, thanks for pointing it out. I'm flailing around with clojure.main and hadn't noticed I wasn't loading repl-utils.

18:41 scottj: Re: snakes w/o globals. Does putting variables that you might want to customize in a let inside a main function make it harder to make customizations than using globals?

18:43 that is, with globals you could just create a let binding with your customizations and run the program inside that, but with the main function and let inside that, you now have to write your own custom main function.

19:11 Chouser: Clojure applet. Warning: it's rather demanding and may take down your browser: http://chouser.n01se.net/misc/tree.html

19:13 vogelrn: surprisingly it hasn't killed my EEE PC

19:13 Chouser: but does it work?

19:13 vogelrn: yeah

19:13 Chouser: oh! well, cool.

19:14 vogelrn: it probably draws a lot more slowly than it's supposed to, but it does take form :P

19:14 Chouser: Then I'm off. g'night.

19:21 durka: Chouser: OS X: Applet net.n01se.Tree notinited

19:25 Chouser: it works in appletviewer, however

19:31 hiredman: ugh

19:31 clojurebot: haskell?

19:31 clojurebot: Yo dawg, I heard you like Haskell, so I put a lazy thunk inside a lazy thunk so you don't have to compute while you compute.

19:32 vogelrn: :P

19:33 danlarkin: haha

19:33 that is a good one

19:34 hiredman: some much good functional stuff in haskell

19:34 just looking at the code makes me break out in hives

19:35 lisppaste8: durka pasted "problem with Chouser's applet on OS X" at http://paste.lisp.org/display/73276

19:37 durka: (firefox tosses the same error at the java console)

20:20 hiredman: clojurebot: ping?

20:21 ping?

20:22 1d6

20:22 clojurebot: 5

20:25 hiredman: clojurebot: ping?

20:25 clojurebot: PONG!

20:30 hiredman: 2d8+2

20:32 2d8+2

20:32 clojurebot: 6

20:56 herdrick: question for the crowd:

20:58 sorry - answered my own question

23:49 AWizzArd: How can I make a Byte[] and put in some initial values? Something like (make-array Byte [1 2 3 4 5])?

23:52 (into-array Byte/TYPE [1 2 3 4 5]) throws an exception.

Logging service provided by n01se.net