#clojure log - Mar 20 2010

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

0:19 dcnstrct: I want to build a tiny webapp in a jar file using compojure. Is there a way for me to serve a static file such as an image or some javascript from within the jar or should I write it to the fs when the program starts ?

0:22 psykotic: dcnstrct: http://java.sun.com/j2se/1.5.0/docs/guide/lang/resources.html maybe

0:23 dcnstrct: thnx

0:25 psykotic: i guess you could also use java.util.zip.JarFile directly

0:25 performance would probably suffer though.

0:26 when it's stored on the file system, you have things like file system caching, etc,

0:26 so that would be my recommendation

0:26 if you want, you can always _deploy_ everything in a jar (a la google appengine) and then have your deployment script unjar the relevant parts to some subdirectory

1:52 dcnstrct: http://paste.lisp.org/display/96665 <-- do I just not understand how ExecutorService/submit works ? I'm trying to make a function that will run another function in the background

1:53 if I pass it #(doall (Thread/sleep 10000) (println "foo")) it returns a future but I never see "foo"

1:56 danlei: dcnstrct: where do you run it?

1:56 dcnstrct: slime repl

1:56 is that why ?

1:56 danlei: yes

1:56 rfg: dcnstrct: check the *inferior-lisp* buffer.

1:56 danlei: if you want to print in the repl, bind *out*

1:57 dcnstrct: !!! there's my foo !!!

1:57 thanks

1:58 KirinDave: dcnstrct: If you're going to experiment with that, you might want to do somethng like the clojure.inspector as meeting point for messages. Emacs isn't very friendly in that regard.

2:00 danlei: something like (run-in-background (let [out *out* ] #(binding [*out* out] (print 'hello)))) should do it

2:01 there used to be a var slime-redirect-inferior-output but I think it's gone

2:03 s/var/function/ and it's not gone, but doesn't seem to work with slime/clojure (used to in CL for me )

2:07 KirinDave: One of these days I need to ask technomancy

2:07 Why lein's defproject uses keywords

2:07 instead of just symbols.

2:08 Or even inverted keywords.

2:08 why :description instead of description:

2:09 * danlei shudders

2:09 danlei: what's wrong about keywords?

2:10 KirinDave: danlei: It just seems strange to use them.

2:10 Why bother?

2:10 danlei: that's just habits

2:12 one generally uses keywords there so that one can use them without qualifying/using, it's the usual thing to do for dsls

2:12 rfg: ,:description

2:12 clojurebot: :description

2:12 rfg: ,description:

2:12 clojurebot: Invalid token: description:

2:12 KirinDave: ,description

2:12 clojurebot: java.lang.Exception: Unable to resolve symbol: description in this context

2:13 KirinDave: The macro isn't really any different for that

2:13 danlei: different for what?

2:13 KirinDave: from the macro phil uses now.

2:14 danlei: I don't understand what you mean

2:14 KirinDave: I'm saying, supporting keywords was a choice.

2:14 I wonder why he made that choice.

2:14 danlei: the obvious choice, yes

2:14 KirinDave: It's not an obvious choice at all.

2:15 It's a macro. It looks like what you want it to look like.

2:15 danlei: sure

2:15 KirinDave: PLT Scheme and CL have keywords, you don't see them using them in macros.

2:15 danlei: then jou have not seen many macros

2:15 especially in CL, can't talk for PLT

2:15 KirinDave: danlei: I've seen a ton of macros. I've used them for years.

2:15 danlei: well, then you know that many, many dsls in CL are done like that

2:16 rfg: KirinDave: I've used keywords in CL macros.

2:16 danlei: not all of them, agreed

2:16 KirinDave: rfg: I know people have. I just find it an odd choice.

2:16 danlei: but still a lot

2:16 KirinDave: Every time I look and go, "Huh. I wonder why."

2:16 danlei: I told you

2:16 1.

2:16 KirinDave: danlei: Except that issue never comes up with defproject. Not a valid concern.

2:16 danlei: because you can pick the symbols to mean something else

2:17 2. because you won't have to qualify them or use the ns

2:17 that are the reasons

2:17 KirinDave: The ns argument is not valid here.

2:17 Defproject files don't get ns qualifications and are always in the namespace of phil's choice.

2:17 danlei: well, you dont HAVE to, I didn't say that

2:18 rfg: Another reason, purely aesthetic and moot, is syntax highlighting.

2:18 KirinDave: rfg: That's my suspicion.

2:18 rfg: Free syntax highlighting in emacs.

2:19 Actually thats probably the best reason I can think of.

2:22 The ns thing is pretty much never an issue, but syntax highlighting is.

2:24 rfg: KirinDave: Turning it around: why would you use symbols over keywords?

2:24 KirinDave: rfg: Less symboly garbage.

2:24 rfg: And I didn't say "description:" seriously, btw.

2:25 rfg: I mean, why doesn't (loop ...) in CL use symbols? It could. It just doesn't. Because that'd just increase the line noise.

2:26 rfg: KirinDave: you can use symbols or keywords with (loop).

2:26 KirinDave: rfg: I know. I rarely see it done.

2:26 rfg: Because it looks ugly.

2:28 danlei: KirinDave: you can use the symbols in LOOP, because they are in the CL package

2:29 KirinDave: danlei: Yes.

2:29 danlei: KirinDave: and thats precisely the reason some guys like pjb use keywords there, if they need the symbols for their own stuff

2:30 KirinDave: danlei: In any event, like we've said... the namespace issue is not a real issue for defproject forms as used.

2:31 rfg: KirinDave: You could argue that you have less chance of blowing your foot off with keywords.

2:32 danlei: KirinDave: ok, then let me put it like this: why use keywords at all? after all, you can get along without them pretty good. symbols as keys, in macros ... I'd say the reasons are: one recognizes them, highlighting (as you said), because they don't have to be qualified, ... tradition, etc

2:32 KirinDave: rfg: Perhaps I'm in the minority opinion in #clojure that how macros looks is more important than these sorts of implementation details.

2:33 danlei: what about ns?

2:34 rfg: KirinDave: You are saying symbols are more aesthetically pleasing?

2:34 danlei: what about cl-who

2:34 KirinDave: rfg: Yes.

2:35 rfg: KirinDave: But you prefer keywords to symbols with (loop)?

2:35 KirinDave: rfg: I said that?

2:35 danlei: some guys do

2:35 rfg: KirinDave: I'm not sure, that's what I took from one of your previous statements. Was it a typo?

2:36 KirinDave: rfg: maybe. I'm not a fan of keywords for this sort of use in macros unless they're somehow significant elsewhere in the code during the use of the macro.

2:37 danlei: KirinDave: why?

2:37 rfg: KirinDave: Could you elaborate on that?

2:38 KirinDave: rfg: Well if say you're specifying keys into a map then I'd say it'd be bad to use symbols over keywords, if later you have to pull data from the map with a keyword and you say, "Where did this keyword come from, I used a symbol!"

2:41 hiredman: keywords are self evaluating

2:41 ,(prn :x)

2:41 clojurebot: :x

2:41 danlei: I really don't understand what he's talking about

2:41 hiredman: ,(read-string (prn-str :x))

2:41 clojurebot: :x

2:41 hiredman: ,(read-string (prn-str 'x))

2:41 clojurebot: x

2:41 danlei: ,({:a 1} :a)

2:41 clojurebot: 1

2:41 danlei: ,({'a 1} 'a)

2:41 clojurebot: 1

2:41 hiredman: 'x and x are different

2:41 danlei: ,({:a 1} 'a)

2:41 clojurebot: nil

2:42 KirinDave: None of this matters for defproject forms.

2:42 danlei: let's take that last sentence

2:42 how did you mean that?

2:43 I'd say it'd be bad to use symbols over keywords, if later you have to pull data from the map with a keyword

2:43 I don't understand that

2:43 KirinDave: For example

2:44 (defsomething meep ...) => (... (alter *local-table* assoc :meep (fn () ...)) ...)

2:45 That'd be bad.

2:45 danlei: ah, ok

2:45 yes, I agree

2:45 KirinDave: I think everyone agrees, that'd suck.

2:45 danlei: sure

2:46 still

2:46 in general, I don't see the the problem in using keywords for dsls like ns

2:46 KirinDave: I don't see it as a problem, I just think it looks funny.

2:47 It's never really necessary.

2:47 danlei: I agree, but I do think its convenient

2:48 at the very least, and there we agree I think, because it sticks out visually

2:48 I mean: foo: or :foo ...

2:48 KirinDave: Yes, the syntax highlighting is a perk in some cases.

2:48 But in other cases I think it looks bad. I don't mean to belabor (loop ...)

2:49 but when you're making dsl-lites I don't like it.

3:01 seangrove: So I can't use (:import) to bring in a clojure script?

3:01 I have a small logger in opengl_test.logger/log

3:02 I'd like to be able to (:import [opengl_test logger]) and have log available in another namespace

3:02 danlei: seangrove: did you try use?

3:03 seangrove: Looks like that worked

3:03 I think I tried (:use 'opengl_test.logger)

3:03 But that didn't work

3:03 danlei: seangrove: without quoting

3:05 seangrove: Thanks danlei, looks good

3:05 danlei: seangrove: welcome

3:38 LauJensen: Morning

3:39 rfg: Good morning.

3:39 ...and what a lovely morning it is.

3:39 LauJensen: Indeed

4:07 maxhodak: how do you get a variable passed into a macro to be interpreted?

4:08 is there a fxn to resolve a symbol and then pass that in?

4:08 rfg: maxhodak: by interpreted do you mean evaluated?

4:08 maxhodak: like, (mymacro mysym)

4:08 but i really want to do (mymacro "mystring")

4:09 where "mystring" is bound to mysym

4:09 i'm doing string interpolation in the macro and it's messing with me

4:11 rfg: Remember that macros don't evaluate their arguments and the value of mysym won't be available at macro-expansion time.

4:12 maxhodak: right

4:13 rfg: Without really knowing what you are doing I think you want the macro to return code that does the string operations instead of doing them at expansion time.

4:14 Could you be more specific in what you are trying to accomplish?

4:15 maxhodak: rfg: i'm trying to dynamically import classes

4:16 rfg: Could you pastebin what you have so far and example use?

4:16 maxhodak: so basically i'm trying to do: (import ~(symbol (format "my.foo.%s.class.%s" baz quux))

4:16 sure

4:17 http://gist.github.com/338553

4:21 psykotic: maxhodak: look at penumbra, i think it has a macro for automating some importing of gl* methods

4:21 hoeck: maxhodak: ,(resolve (symbol (str "Str" "ing")))

4:22 ,(resolve (symbol (str "Str" "ing")))

4:22 clojurebot: java.lang.String

4:23 hoeck: I'm using that in some of my macrocode, not shure if it helps in your case though

4:23 maxhodak: hoeck: i don't think so, because the macro is expanded before the code is evaluated

4:24 (and before the binding happens)

4:27 hoeck: I don't think your function run will work as you expect

4:27 the problem is that import is a macro itself, so at least it has to know the name at compiletime

4:28 rfg: maxhodak: Ah I see. import is a macro that plays manipulates its arguments directly so you can't do this: http://clojure.pastebin.com/RT80jHdx

4:28 hoeck: and you cannot use a macro around it to somehow magically make it think it runs at compiletime

4:30 could you shed a light on the purpose of your run function?

4:30 maxhodak: hoeck: run is basically -main

4:31 hoeck: because I think that importing a class makes only sense if you want to load more code which actually uses that class

4:32 maxhodak: hoeck: the two importedd classes are immediately used; my next issue is putting together the statements that reference them a few lines down

4:33 but once i figure out how to get the import to work i figure the rest will be clear

4:34 i don't believe that theres *no way* to do dynamic imports

4:35 hoeck: of course there is, after all you can use reflection, but then import is maybe just not what you want or need

4:38 psykotic: hoeck: exactly. i already told him a reference: penumbra.

4:38 hoeck: to me it sounds like you want to switch implementations of something at runtime, and usually java libraries implement this by providing a common interface and something like a factory method

4:38 psykotic: look at penumbra/src/penumbra/opengl/core.clj

4:39 it has reflection methods that enumerate the methods of classes and then there is a gl-import macro that is used to create clojure wrappers for them

4:39 etc

4:39 maxhodak: psykotic: ah, ok; was looking for the file with the definitions

4:39 hoeck: but it does not switch opengl implementations at runtime?

4:40 psykotic: no

4:40 maxhodak: oh, wow; it's a macro that expands to a macro

4:41 psykotic: note that gl-import doesn't do the actual importing part

4:42 look at the containers defvar and the associated helper functions

4:42 rfg: Any sufficiently advanced macro is indistinguishable from a programmer.

4:43 psykotic: maxhodak: and there is always eval :) (i kid!)

4:44 maxhodak: psykotic: i'm considering it....

4:44 bytecoder: has anyone here built an app which uses google appengine datastore? need a quick help.

6:36 LauJensen: rfg: good one!

6:37 rfg: LauJensen: Thanks :) Feel free to quote that, you know, like all the time.

6:37 LauJensen: Haha!

6:37 Sure - And conviently forgetting to give due credit :)

7:11 I've taken Yegges advice on swapping caps-lock with control, man thats gonna take some getting used to

7:11 Mec: is there a print that returns what it was passed so you can do inline debugging?

7:11 Chousuke: write a debug macro instead

7:12 Mec: thought so, just wanted to make sure there wasnt already one

7:12 noidi: LauJensen, it'll take a while but it's worth it

7:12 LauJensen: yea I'm getting the sense of that already

7:12 Chousuke: or (comp first (juxt identity print)) :P

7:12 noidi: not only in emacs but in almost every app

7:12 Chousuke: for the pointless programmers

7:13 Mec: will that call the value twice?

7:13 LauJensen: noidi: oh there are other apps out now?

7:13 Chousuke: nah, it's evaluated only once

7:13 noidi: hehe

7:14 Chousuke: though there's a better way. that was just my idea for a point-free approach

7:14 LauJensen: Chousuke: Its very clever :)

7:14 Mec: indeed, makes my head hurt unraveling it

7:14 noidi: LauJensen, also switching to a US keyboard layout helps _a lot_, assuming that the danish keyboard is as uncomfortable for programming as the finnish one

7:15 Chousuke: I still program using a finnish layout. :P

7:15 noidi: now _that_ takes some time to get used to, but imho it's even more worth the trouble than remapping control

7:15 LauJensen: noidi: The US has big advantages

7:15 Chousuke: I haven't been able to learn the english layout

7:15 LauJensen: (.replace "able" "willing")

7:16 Chousuke: well, yes. I tried once but failed

7:16 all programming languages are optimised for the US layout :(

7:16 editors too

7:17 noidi: yup

7:17 after the week or two of painful relearning, suddenly all the default hotkeys made sense :)

7:18 Chousuke: vim is a good example, having \ as the leader key by default. that takes three keys to type on my macbook

7:18 noidi: when they no longer were behind some weird AltGr+Shift combos

7:25 psykotic: the keyboard's country of origin if you are one of those grandmother programmers who look at the keyboard as they type :)

7:25 *only matters if you are one ...

7:30 Chousuke: isn't the standard key count for US keyboards 104 or something?

7:31 Finnish ones have 105 and Japanese ones 109 I think (the space bar is very short)

7:31 Mec: #((println %) %)

7:31 that seems too simple

7:32 Chousuke: won't work

7:32 noidi: psykotic, on the contrary, you can only switch between layouts painleslly if you haven't memorized any of them

7:32 Chousuke: it'll get an NPE

7:32 Mec: and it does

7:32 Chousuke: you'll want #(do (println %) %)

7:32 but I still suggest making a debug macro instead :P

7:32 Mec: ah thought there was implicit

7:33 Chousuke: you can think of the # as a "make the following expression a function" :P

7:34 Mec: i know, i thought functions had an implicit do

7:34 psykotic: chousuke: # is a general dispatch character a la common lisp. it has dispatchers for functions with anonymous arguments, set construction and regular expressions, etc.

7:34 you can even hack the dispatch table from within clojure itself, if you're feeling naughty.

7:37 StartsWithK: when binding *in* do i need to wrap my reader with LineNumberingPushbackReader?

7:39 SynrG: Mec: i think the disconnect you're having is that when you say ((somefunction)) the thing after the first parenthesis isn't a function. it's an expression.

7:39 well, a list

7:39 tomsw: I have a macro that provides syntactic sugar to using the Jacob library (COM / ActiveX interop). For example (<< obj Property1 Property2 (Method arg1 arg2)) is exquivalent to obj.Property1.Property2.Method(arg1, arg2) in C#

7:39 LauJensen: How far are we in terms of removing transients with cells?

7:40 tomsW: like .. from core ?

7:40 tomsw: yes, more or less

7:41 I don't know a sensible way to deal with lookup up property or method names from an expression

7:41 eg (<< obj Property1 x) would look for a property named "x" whereas I might want it to look for the property whose name is x's value

7:42 Raynes: ,(println "test")

7:42 clojurebot: test

7:42 Raynes: ,(println "test\n")

7:42 clojurebot: test

7:42 Raynes: Indeed.

7:43 Chousuke: tomsw: you could use ~

7:43 tomsw: outside of `, ~x expands to (unquote x)

7:43 tomsw: you could perhaps use that in your macro

7:44 psykotic: ,(print "foo\n\nbar")

7:45 clojurebot: foo bar

7:46 tomsw: Chousuke: that's very neat, I will experiment (I wonder if ` and , are as flexible in common lisp)

7:46 Raynes: ,(do (print "hai") (print "thar") 3)

7:46 clojurebot: 3

7:46 haithar

7:48 psykotic: tomsw: yes, `foo and ,bar are just reader-macro-expanded to (backquote foo) and (unquote bar)

7:48 (in common lisp)

7:48 Chousuke: Clojure actually expands ` entirely at read-time

7:49 It turns out that implementing it as a macro is not trivial

7:49 I tried. :P

7:50 though I think most of the non-triviality comes from autogensyms and making them work properly.

7:50 tomsw: I don't know what autogensyms is

7:51 :)

7:51 Chousuke: `foo#

7:51 ,`foo#

7:51 clojurebot: foo__7125__auto__

7:51 Chousuke: that

7:51 Raynes: Unique names.

7:51 tomsw: that's a very nice feature

7:52 Chousuke: ,`(foo# foo# `foo# `~foo#)

7:52 clojurebot: (foo__7130__auto__ foo__7130__auto__ (quote sandbox/foo__7129__auto__) foo__7130__auto__)

7:52 tomsw: there was a neat way of doing it in CL, in "Let over Lambda", but it's nice how it's built in to Clojure

7:52 Mec: ,(String. (into-array Byte/TYPE (map byte (range 256))

7:52 clojurebot: EOF while reading

7:52 Mec: what am i missing there?

7:52 Chousuke: making them nest like that isn't exactly trivial

7:53 two closing parens

7:53 Mec: bah

7:53 ,(String. (into-array Byte/TYPE (map byte (range 256))))

7:53 clojurebot: "

7:53 Chousuke: huh

7:53 Raynes: huh

7:53 Chousuke: I suppose Clojurebot doesn't like control characters :P

7:53 Mec: i sware i was doing this fine last night

7:54 and now im getting a class cast exception

8:04 i must be losing my mind

8:05 psykotic: i both lose and hate the fact that you can C-o away from the minibuffer in emac

8:05 s

8:05 rfg: LauJensen: Invest in a set of foot pedals for Control/Alt etc.

8:05 psykotic: rfg: someone needs to make organ.el

8:05 LauJensen: hehe

8:06 psykotic: that is actually a fun hack. use midi to drive emacs.

8:06 * rfg now knows what to do with his arduino!

8:07 Mec: wow I restarted emacs and now its working again

8:08 how does that work?

8:08 rfg: emacs has some odd behaviour when you C-x C-b and select a buffer: it opens in a different frame than you did the shortcut. Why?!

8:09 And the list of buffers is in a different frame too.

8:09 psykotic: rfg: C-h k C-x C-b and all will be revealed.

8:10 oh, you said different FRAME

8:10 are you using aquamacs?

8:10 rfg: Genau. No I'm using Carbon Emacs

8:11 psykotic: i know that aquamacs has stupid defaults for things like mapping buffers to frames

8:11 i haven't used carbon emacs but maybe it does something like that too?

8:11 rfg: Possibly, yeah.

8:11 psykotic: google the emacswiki to find out

8:12 * psykotic never uses frames, ever.

8:13 rfg: psykotic: I typically have the slime-repl in one frame and code files in t'other.

8:13 psykotic: in that case, i suspect i know the problem.

8:14 it probably switches to the frame in which the buffer was last open.

8:14 rfg: Okay, that would make a small bit of sense.

8:15 But it's taken the concept of consistency, tied leather weights to its feet and thrown it in the river.

8:16 psykotic: that is what you get for messing with frames

8:16 why would you want to throw out emacs's wonderful window management?

8:17 the one case i can see it being justified is for something like speedbar that is omnipresent.

8:17 rfg: I'm going to give your "One Frame Paradigm" a shot.

8:18 psykotic: Do you tend to C-x b or C-x C-b?

8:18 psykotic: aquamacs has an insane "frame per buffer" paradigm

8:18 C-x b

8:18 i use ido-mode with that, which rebinds

8:18 try M-x ido-mode and then C-x b

8:19 rfg: psykotic: not a fan of aquamacs.

8:19 psykotic: yeah, i disagree with almost all of its attempts at making emacs not emacs and more macish

8:20 rfg: Yeah, and I don't like its icon.

8:20 psykotic: did you see the new vector art icon?

8:20 rfg: Only cool icons are allowed in my dock.

8:20 psykotic: i quite like it

8:21 rfg: Looks like I have an ancient version of it.

8:22 Hmm, 1.9 or 2.0 preview?

8:23 psykotic: i use the preview. it has a few bugs but i can live with it.

8:23 actually, the bugs seemed to go okay with the latest update push.

8:23 err, go away

8:23 rfg: heh

8:24 Raynes: Licenser: ping

8:24 psykotic: btw, one of my favorite things about aquamacs is that it lets you rebind the alt keys to act like alt rather than the usual "character map shift" function it usually serves in os x

8:24 that's a feature of the 2.0 preview

8:25 also, i selectively told aquamacs to rebind my right cmd as ctrl, while leaving the left one alone; i then use caps lock rebound as ctrl, so i still have a ctrl on each side of the keyb

8:25 and i can still use the left cmd for cmd-space (quicksilver), etc

8:26 rfg: Left command is meta?

8:26 Or alt?

8:26 psykotic: left command is just command

8:26 both left alt and right alt are meta

8:26 by leaving left command alone, it means i can still do my os x-ish things

8:27 btw i also disabled a bunch of the default os x key bindings

8:27 clojurebot: the genuine sieve of eratosthenes is http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf

8:27 psykotic: like i believe alt + arrow keys usually changes spaces, which i never use

8:28 that makes it work smoother with emacs

8:28 rfg: Hmm, Command as Meta is hardwired into me form Carbon Emacs.

8:28 psykotic: yeha

8:29 that's why i don't use carbon

8:29 rfg: Alt isn't that well placed on my MBP keyboard.

8:29 psykotic: i have a mbp too

8:29 that's why i rebound right cmd as ctrl--there is no right ctrl key on mbp

8:30 rfg: Yay, we are MBP buddies.

8:31 Apple were kind enough to replace my mobo the other month for free.

8:31 psykotic: i ran out of warranty right after my left fan decided to start dying

8:39 rfg: Mine was out of warranty, but it was a known fault, so I didn't have to pay them £676.

9:00 etate: is there a point to using SQL based databases et al when you can just serialize / deserialize data structures yourself?

9:01 i'm kind of confused

9:02 Chousuke: that's like asking "what's the point of using hash-maps when you have lists" :/

9:02 etate: to be more precise, if you have STM, the ability to do transaction logging, loading data from disk into memory, serialization / deserialization

9:03 is there a good argument to use mySQL et al with these tools?

9:03 Chousuke: Databases are an order of magnitude more efficient at storing and querying data than straightforward serialisation

9:03 etate: but most data ends up living in memory anyway right?

9:03 Chousuke: yes

9:03 but not all of it at the same time

9:04 etate: you'd have to have a pretty huge database to have to worry about that, i would imagine

9:04 Chousuke: there are databases with petabytes of data in them

9:04 psykotic: etate: when the data is what matters and the application is incidental, you use databases.

9:04 esj: indices

9:04 Chousuke: a database in the gigabyte scale is not even uncommon

9:05 etate: psykotic: could you give me an example of this?

9:05 Chousuke: etate: google

9:05 etate: so supposing you had this database which was a gigabyte, so thats a gig of memory, big deal

9:05 psykotic: accounting systems of all sorts

9:05 a gigabyte is nothing

9:05 Chousuke: etate: what about if you have a terabyte of data?

9:06 psykotic: you are also not considering the durability aspect

9:06 Chousuke: etate: which is also not too uncommon

9:06 etate: then you have some kind of partitioning scheme i would imagine

9:06 psykotic: serialization plus in-memory ACI does not give you durability

9:06 Chousuke: psykotic: it can, but it would be horribly inefficient

9:07 psykotic: Chousuke: well, if you reimplement a lot of database functionality.

9:07 etate: psykotic: why would it be inefficient to access a hash map using STM?

9:07 Chousuke: psykotic: indeed.

9:07 etate: writing it to disk to achieve durability is

9:07 etate: you don't want your bank to do transactions only in memory

9:07 etate: Chousuke: using a transaction log?

9:08 i mean i just wrote this db naively and it doesn't write to disk until the database is closed

9:08 Chousuke: yes, so it's not durable.

9:08 etate: its durable because it has a transaction log...

9:08 psykotic: a transaction log can work but you need to be careful, and you still need checkpointing unless you want to parse the transaction log from the beginning of time

9:08 etate: yeah i implemented snapshotting

9:09 Chousuke: etate: you're implementing a database :P

9:09 etate: Chousuke: well if this is a database then i fail to see whats difficult about writing one lol

9:09 Chousuke: etate: it's difficult to do efficiently

9:09 etate: Chousuke: cache oblivious data structures maybe?

9:09 Chousuke: which is why you should not do it yourself. there are many efficient databases available :P

9:10 it's basically a solved problem

9:10 etate: sure but if its all in clojure its easier to do and use

9:10 psykotic: err

9:10 Chousuke: sure, but it won't be as efficient as using a real database

9:10 psykotic: the time to wrap an existing high performance, highly tested, highly supported database is harder than to WRITE YOUR OWN?

9:10 Chousuke: it might be efficient enough for your needs though.

9:11 psykotic: i agree that a simple database isn't very difficult. it's a week-long project for an undergraduate.

9:11 etate: Chousuke: it is efficient enough for my needs, I just think that it would need a huge amount of data to notice any efficiency impact

9:11 Chousuke: I think you would notice it with data in the hundreds of megabytes

9:12 which is nothing to real database systems :P

9:12 etate: tbh the data reaches less than 1mb

9:12 well when i get to the stage where i need 100mb i can always transfer data to some other system right? :)

9:13 psykotic: i think its easier than a week for an undergrad

9:13 psykotic: i'm talking about a disk-based b-tree, query planner, buffer manager, etc

9:14 a rdbms

9:14 etate: oh i see

9:14 psykotic: it's like writing a simple operating system. not terribly difficult.

9:15 yet that doesn't mean that writing a real operating system isn't difficult or time consuming.

9:15 etate: so you could use a fast prolog compiler and do the same kind of thing

9:16 psykotic: prolog systems do generally support fast in-memory indexes, yes

9:16 in fact, if you've looked at couchdb, their approach of 'cached queries' as opposed to traditional indices is very close to the prolog style of indexing from the 80s

9:17 etate: interesting

9:18 so using the persistent data structures available its possible to write a db in clojure that scales to 100mb ?

9:18 psykotic: anyway, my greater point with the OS analogy is that when a database is fundamental infrastructure, you don't want to use a half-assed solution

9:18 etate: almost anything will scale to 100 mb :)

9:18 etate: hmm, what i really don't like about SQL dbs is the fact that your data is set as in C, so VARCHAR(55) i mean wtf

9:19 psykotic: you don't have to use a relational db

9:19 etate: what if you don't want arbitrary limits on your data

9:19 psykotic: there are things like berkeley db

9:19 which at their simplest are just persistent key-value stores

9:19 etate: yeah ive used BDB in a commercial project

9:20 its pretty simplistic

9:20 psykotic: yes

9:20 what you're doing sounds simplistic

9:20 good fit

9:20 etate: :D

9:21 psykotic: actually, berkeley db has grown some pretty non-simplistic features over the last 10 years

9:21 including replication

9:21 but it's nice that you can embed it as a simple library and create and populate and query a database with ten lines of c code

9:21 i guess there might be something like it in the java world, or a JNI wrapper for it

9:21 etate: yeah, hmm i see there is a java binding

9:22 sorry, a java edition

9:22 esj: I've been using mongodb through congomongo and its really working for me

9:23 etate: esj: i don't really understand document oriented databases, thats the only problem :p

9:23 esj: its a misnomer

9:24 In the simplest case just think of it as an indexed object store

9:24 s/object/struct

9:24 etate: esj: hmm that sounds nice

9:25 esj: when i checked out the congomongo bindings, the documentation looked a bit sparse

9:25 esj: extremely - its very fast, it has not predefined schema so its quick to get going

9:25 there isn't much to it all

9:25 etate: esj: how do the queries work?

9:26 esj: 1 sec, I'm putting up a gist for you

9:26 etate: nice thanks :D

9:27 esj: http://gist.github.com/338668

9:27 that's code I'm actually using

9:27 to wrap up some stuff

9:28 as you can see its really very simple

9:28 etate: esj: checking it now

9:28 esj: most of the mongo functions end in ! (which makes a great deal of sense)

9:29 etate: esj: wow nice code thank you for this insight!

9:30 esj: no sweat

9:30 etate: hmm i didn't realise it was this easy... i'll start using congomongo methinks

9:31 esj: db-insert-series! is illustrative

9:31 you just bang the db with maps, its serialises then to JSON (actually its BSON, which is a binary JSON, I believe) and stores em

9:32 etate: and fetching data turns json into a map?

9:32 sounds like it would be easy to fetch just JSON from the db

9:33 esj: that's right, your stuff is automagically serialised and de-serialised

9:33 (except for sets, which is causing me grief right now)

9:35 etate: esj: can you fetch the data as just JSON too? or is the serialization step implicit?

9:36 esj: i really dunno, I'm sure if you reach into somniums code you could find out though ;)

9:36 etate: esj: yeah i'm installing it now :)

9:36 esj: enjoy.

11:56 psykotic: what's the rationale for only having vectors implement the MapEntry interface, not lists?

11:57 it means that idioms like (into {...} (partition 2 keys-and-vals)) don't work unless you wrap the partition in a map vec call

12:00 chouser: I don't know the rationale, but you can do (apply assoc {...} keys-and-vals)

12:01 psykotic: that's nicer at least, thanks

12:13 Crowb4r: morning

12:20 raek: I need some sort of database in one of my projects. what libraries do you recommend looking into?

12:20 I'm thinking about something more structured that refs of sets of maps and less rigid than SQL

12:20 vegai: sqlite?

12:20 tokyodb

12:20 raek: I'm considering a schema-less db

12:21 The-Kenny: mongodb is very cool, couchdb too

12:21 raek: is congomongo clojure bindings for mongodb?

12:22 The-Kenny: raek: yes

12:23 raek: congomongo looks very interesting...

12:25 Raynes: Licenser: ping.

12:29 LauJensen: Any fast way to check if 2 transients will be the same persistent structure, w/o persisting them?

14:08 no takers on the transient question?

14:08 Or is it about that time now, where I dont use transients but use cells instead?

14:11 dnolen: LauJensen: I thought cells were still considered speculative work.

14:11 LauJensen: perhaps, but looks more interesting than transients :)

14:17 arohner: why can't maven projects tell you what the valid 'mvn foo' commands are for that project?

14:17 like rake --tasks

14:20 LauJensen: arohner: I'm afraid Clojure-land is not where you're most likely to get Maven help

14:21 arohner: LauJensen: I was just grumbling. I'm trying to interop with a maven project

14:21 Raynes: Licenser: In case you get this: I sent an email a few hours ago with a question. I sent it on my phone, so I'm not sure if it made it or not. Just letting ya know. <3

14:22 arohner: I'm curious, but not enough to go find the real answer

14:22 :-)

14:22 LauJensen: arohner: Isnt there a Maven community on IRC somewhere?

14:22 Chousuke: hmh

16:05 seangrove: How can I get a list of methods for a java class?

16:05 I can't seem to get .getMethods() to work :P

16:06 Ah, I think I got it

16:06 Just can't use it with a proxy

16:12 notallama: hey guys

16:13 LauJensen: Hey

16:17 marten: anyone here using swank-clojure embedded?

16:17 i can connect to it fine

16:18 but as soon as i disconnect, the server stops?

16:18 any way to keep the swank server up, or restart it after it stops when the client disconnects?

16:20 dnolen: marten: do you mean disconnect from emacs?

16:20 The-Kenny: marten: What means "embedded"?

16:21 marten: basically, during initialization of my app, i do a (swank/start-repl)

16:22 The-Kenny: ah, and the swank-server stops after the disconnect from emacs?

16:22 marten: yes, exactly

16:22 The-Kenny: You have to supply some argument to start-repl or start-server or so. like :multiple-connect true

16:22 marten: which is frustrating, because that means i have to restart my app :)

16:54 wooby: anyone know off hand the name of that jogl wrapper for clj?

16:55 LauJensen: penumbra?

16:55 @wooby

17:00 wooby: LauJensen, thanks! that's it

17:01 LauJensen: np

17:01 xb

17:01 oops

17:07 marten: The-Kenny: hmm, apparently after disconnecting, the socket hangs in CLOSE_WAIT state...

17:07 and the :dont-close true option doesn't help this

17:08 The-Kenny: marten: huh, that's strange

17:09 dcnstrct: (.replaceAll "foo" "o") <--- No matching method found: replaceAll for class java.lang.String

17:09 I don't understand why this doesn't work

17:09 http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#replaceAll(java.lang.String, java.lang.String)

17:09 LauJensen: dcnstrct: What are you looking to replace? you left out an arg

17:09 You said replace in "str1" "o" with ?

17:10 ,(.replaceAll "aaa" "a" "b")

17:10 clojurebot: "bbb"

17:10 dcnstrct: doh! so obvious..

17:10 I guess that "no matching method found" made me think it wasn't finding the method.. when really it was just a case of wrong number of args

17:10 thnx

17:10 LauJensen: np

17:11 And for what its worth, I think the error should indicate that the name exists but it has a different signature

17:29 marten: aha, swank.swank/start-repl (which the README recommends) doesn't pass on the options to start-server

18:07 boojum: ,(contains? (transient [1 2 3]) 2)

18:07 clojurebot: false

18:11 wooby: ,(contains? (transient {1 :a 2 :b}) 2)

18:11 clojurebot: false

18:11 wooby: ,(contains? (persistent! (transient {1 :a 2 :b})) 2)

18:11 clojurebot: true

18:12 wooby: interesting :)

18:12 LauJensen: Yea, I was asking a question on a similar note earlier

18:12 rhickey: Is there anyway to test if 2 transients are equal in their current content ?

18:14 technomancy: LauJensen: I don't think that's what transients are for

18:15 LauJensen: technomancy: They're for fast local mutation right? So sometimes you need a little status on that mutation :)

18:15 boojum: ,(clojure-version)

18:15 clojurebot: "1.1.0-master-SNAPSHOT"

20:07 notallama: say i have a protocol A, and a datatype B. how can i tell if an instance of B extends A?

20:07 i can't seem to figure out how to get 'extends?' or 'isa?' to return true for that.

20:07 B is made with deftype

20:09 nevermind, found the 'satisfies?' function.

20:18 stacktracer: is there a way to declare a method in the :methods part of a :gen-class that returns an instance of the class being gen-classed?

20:19 (static factory method, for Java interop reasons)

20:19 hiredman: gen-interface + gen-class

20:20 stacktracer: hiredman: ah, thanks

20:23 Raynes: What is the best way to do default-argument-style stuff?

20:29 I should point out that I need default keyword arguments. I suppose the best way would be to use map destructuring with :or, but I guess maps shouldn't be used for optional arguments. :(

20:33 Should I use defnk?

20:33 I guess I should.

20:57 Licenser: You around?

21:00 vvsh: hi everybody, i thinking to try out enlive for clojure, so i follow the tutorial, but cant' get REPL working , can someone help me ? ( i got this error message http://pastebin.com/pv89fwbJ)

21:00 Raynes: Methinks Licenser didn't test his sandbox's timeout mech with anything but Thread/sleep. It suffers from the same problem that chouser and friends helped me with yesterday. I think I'll take the liberty to hack it.

21:01 hiredman: vvsh: means you are missing clojure from the classpath

21:02 vvsh: hiredman: sorry for the noob question(i never use java before), how can i add clojure to my classpath?

21:02 i thought lein will take care of that

21:03 hiredman: do you have clojure as a dependency in your project.clj?

21:05 vvsh: no, i can't see clojure on the dependancies list

21:05 i suppose i need to add it in the project.clj, but what are available versions?

21:06 hiredman: I would just find some other project.clj (on github? google?) and copy and paste

21:09 vvsh: sounds good, i just fond out even without clojure on dependency list, i got clojure-1.1.0-master-20091231.150150-10.jar and clojure-contrib-1.0-20091212.214557-33.jar under my lib directory, are these two clojure jars ?

21:16 i tried to put clojure in project.clj dependency list, but still doesn't work

22:22 dcnstrct: lein uberjar

22:22 errr

22:30 polypus: ~ping

22:30 clojurebot: PONG!

23:02 alexyk: I need to parallelize processing of a list of length N over P processors. I need the starting point of each chunk. What's the best way to get such a list of the starting indices?

23:12 Mec: is there a dissoc-in?

23:51 bmason: how do I determine what version of emacs is installed?

23:51 mikem_: M-x version?

23:51 bmason: ah thanks!

Logging service provided by n01se.net