#clojure log - May 16 2011

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

0:09 alandipert: anyone know off-hand the origin of take-while/drop-while? ML, miranda, other?

0:50 stirfoo: Did (read) and (read-line) work with slime/sbcl? It's been a while, but it seems like it did. What needs to be done to get those to work with swank-clojure?

0:51 amalloy: stirfoo: i think it's an issues caused by ant

0:54 stirfoo: is ~/.lein/bin/swank-clojure using ant? I know nothiing about ant :(

0:54 amalloy: i don't either, really

0:54 but technomancy says ant swallows his stdin

0:59 technomancy: the one in ~/.lein/bin avoids ant

0:59 I have a cunning plan for getting stdin working in regular swank too

0:59 http://p.hagelb.org/plan.jpg

0:59 stirfoo: technomancy: but the repl still blocks if I try (read) or (read-line)

1:00 technomancy: ahaha

1:00 technomancy: if read-line breaks in ~/.lein/bin/swank-clojure it's a different problem

1:00 probably worth opening an issue

1:01 stirfoo: RET after entering say "foo" just sits there

1:03 technomancy: is *slime-events* relevant to swank-clojure? like (swank:listener-eval "(read-line)\n")

1:03 technomancy: stirfoo: I don't think it's meant for user consumption.

1:05 actually my other swank-related plan is much more cunning.

1:06 looks like we may be able to bootstrap slime, durendal, and slamhound with nothing more than leiningen and clojure-mode.

1:06 hmmmm!

1:07 * technomancy &

1:07 sexpbot: java.lang.Exception: EOF while reading

2:07 ihodes: I've got to say, while mathematica is great (and is an IDE Clojure would be lucky to have), it sure makes me miss clojure

2:28 tomoj: should a breadth-first search of a PEG grammar be too difficult?

2:37 amalloy: that depends on what you mean by "too difficult", "PEG grammar", and "should"

2:37 * amalloy is pretty clear on "breadth-first search" though

2:40 tomoj: heh

2:40 I'm not, really

2:40 I mean, of a tree, sure

2:40 I'm not quite sure how to map a PEG into a tree of sentences

2:40 or, sentence structures I suppose

3:34 amalloy: ~source require

3:37 Fossi: ~source source

3:38 funky way to read stuff

3:39 somebody know why?

3:40 amalloy: huh?

3:50 Fossi: having the line and the pushbackreader i meant

3:52 amalloy: it's a bit gross, but since the reader doesn't maintain whitespace (and it shouldn't), there's no other obvious way to read the actual source with the whitespace it was given

3:54 so it creates a Reader which, as a side effect of reading, appends to a local buffer, then reads one object with that reader

3:56 Fossi: which reader doesnt maintain whitespace?

3:56 amalloy: the clojure reader

3:56 (1 2) is the same as (1 2)

3:57 Fossi: why is a clojure reader needed at all?

3:57 amalloy: how else do you know how many lines the function you're reading takes up?

3:57 Fossi: ah, now i see

3:58 weird construct ;)

3:59 amalloy: if you have a better way, i'm sure someone would love to have it

4:00 it would be possible to have :line-start and :line-end in the meta, but i think that just moves the problem somewhere else

5:21 ilyak: Has anybody had luck with clojure ant tasks?

5:21 I have some bizzare classloader problems like and always has

5:22 It looks like that the taskdef is loaded in one classpath but is used in another classpath

5:22 s/classpath/classloader

5:22 sexpbot: <ilyak> It looks like that the taskdef is loaded in one classloader but is used in another classloader

5:47 opqdonut_: has anybody done real tag generation for clojure? I mean using read or actually loading the ns and looking at what got defined?

5:58 jamesswift: $help

5:58 sexpbot: You're going to need to tell me what you want help with.

5:58 jamesswift: $help eval

5:58 sexpbot: Topic: "eval" doesn't exist!

5:58 jamesswift: $help topics

5:58 sexpbot: Topic: "topics" doesn't exist!

5:58 jamesswift: $help commands

5:58 sexpbot: jamesswift: http://github.com/Raynes/sexpbot/wiki/Commands

5:59 jamesswift: $help evaluation

5:59 sexpbot: Topic: "evaluation" doesn't exist!

5:59 jamesswift: (+ 1 2 3)

5:59 clojurebot: *suffusion of yellow*

6:03 jamesswift: $(+ 1 2 3)

6:07 &(+ 1 2 3)

6:07 sexpbot: ⟹ 6

6:07 jamesswift: &(not (empty? (clojure.set/intersection (set "test1") (set "1234"))))

6:07 sexpbot: ⟹ true

6:08 jamesswift: So anyone can tell me if this is a good or bad way to determine if a string contains any chars from another string? (not (empty? (clojure.set/intersection (set "test1") (set "1234"))))

6:09 opqdonut_: i'd maybe go with (not (some (set "test1") "1234"))

6:10 (not (some #(get (set "test1") %) "1234")) might be a bit more explicit

6:10 err and here "test1" are the banned characters and "1234" is the (potentially long) string to be processed

6:14 jamesswift: thanks

6:14 i guess some finishes on first match

6:14 raek: it does

6:14 jamesswift: thanks again

6:14 raek: (it also returns it)

6:50 opqdonut_: wait what? keywords aren't symbols?

6:50 (= :x (symbol ":x"))

6:50 is false, while (= :x (keyword "x")) is true

6:50 the problem is that the printed representation for (symbol ":x") is :x

8:27 ilyak: What's the clojure policy on - versus _ in file/package/namespace names?

8:28 opqdonut_: clojure namespaces tend to use -

8:29 which gets converted to _ in (java) package names and filenames because of technical reasons

9:43 the-kenny: Hello. What's the preferred way to do graphical stuff with Clojure? (Drawing onto a canvas, capturing mouse events etc.). I tried Processing-clj, but it's

9:43 Whops. Cont: not very pretty for bigger projects as it isn't even possible to load an image without passing the sketch-instance around.

9:57 lchaplin: would you guys be interested in java jobs in general, or only clojure based jobs?

9:57 Touqen: JVM yes, java not particularly

9:58 lchaplin: Touqen: can you please elaborate?

9:59 Touqen: I think the JVM as a platform is pretty awesomesauce.

9:59 I however am not a fan of java the language.

9:59 lchaplin: jvm as in java virtual machine?

9:59 Touqen: yes

9:59 aav: lchaplin: thread scheduling, garbage collection :)

10:00 Touqen: don't forget hotspot

10:00 lchaplin: Touqen: hmmmm. don't have such jobs atm :/

10:41 ttmrichter: lchaplin: Wouldn't you have better luck recruiting in ##java?

10:48 gfrlog: looks like (assert) is a bad way to validate user input

10:48 chouser: heh

10:48 gfrlog: I didn't even know java distinguished between Exception and Error :-/ you learn something new every time you learn that

10:57 aav: gfrlog: "For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow." :)

10:58 gfrlog: first time I've seen Solomon quoted in #clojure

11:07 do we like that compojure is trailing-slash-sensitive?

11:12 ejackson: technomancy: is it a bug in leiningen (1.6.0) that lein uberjar leaves ./lib in a state different lein deps. Specifically w/o jars specified in :native-deps dependencies, or do I have the wrong end of the stick ?

11:16 gfrlog: (def print-once (memoize println))

11:19 ejackson: i should clarify - the .so files from the native libs are extracted to ./native, as expected, but the native-deps jar contains within it normal jars, that make it into ./lib with lein deps, but not after lein uberjar :(

11:54 technomancy: ejackson: it's probably a bug; can you open an issue?

11:54 ejackson: technomancy: shall do.

11:56 technomancy: ejackson: keep in mind that I have never used any native libraries, so I'm depending on users to tell me their expectations to a degree.

11:57 ejackson: technomancy: no sweat. It also doesn't seem to bring in dev-dependencies as my swank-clojure gets wiped out after a lein uberjar.

11:57 technomancy: uberjars definitely shouldn't contain dev-dependencies

11:58 also, it may be possible to just place native dependencies in the regular :dependencies list and have them automatically get special treatment with a little more tweaking to lein.

11:58 that's something Sam Aaron suggested to me

11:59 I'm definitely interested in hearing what people want and what makes sense in this area though

11:59 ejackson: technomancy: that's a nice idea

12:00 technomancy: maybe some kind of jar-level metadata to signal special treatment

12:00 also I'd be glad to get more test case projects as well

12:02 ejackson: OK, I'll see what I can do. Right now I'm a bit knotted with this :)

12:25 ilyak: I wonder if anybody ever wants working clojure-ant-tasks

12:47 rlb: Is this a reasonable way to flatten a map into a (k v ...) list: (interleave (keys x) (vals x))?

12:48 dnolen: ,(apply concat {:a 'b :c 'd})

12:48 clojurebot: (:a b :c d)

12:50 rlb: dnolen: ahh, right, thanks.

12:53 gfrlog: rlb: also I think your way is not reasonable, as I don't believe there's a guarantee that (keys) and (vals) return in the same order

12:53 technomancy: actually it's guaranteed for any given map

12:54 gfrlog: technomancy: is it? I figured it probably DID return in the same order, but didn't expect it to be in the method contract

12:54 amalloy: it is guaranteed

12:54 gfrlog: the best way to learn is to assert stuff and see if you get corrected

12:54 amalloy: heh

12:54 technomancy: yeah, and it really should be mentioned in the docs

12:54 amalloy: 100% agree

12:55 you could also ##(mapcat identity {1 2 3 4})

12:55 sexpbot: ⟹ (1 2 3 4)

12:55 rlb: gregh: good point -- I hadn't considered that (even if it's true).

12:55 amalloy: if you happened to want to do some more processing on the way, rather than identity

12:56 rlb: In my case, apply concat works perfectly since I was already calling concat, and the map would be the final arg anyway.

13:00 scgilardi: these are coming out in order because they're small and constructed as an array-map. in general there's no guarantee about the order of the pairs returned by (seq my-map).

13:00 ,(seq {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9 :j 10})

13:00 clojurebot: ([:a 1] [:c 3] [:b 2] [:f 6] [:g 7] [:d 4] [:e 5] [:j 10] [:i 9] [:h 8])

13:01 amalloy: scgilardi: nobody asserted that there was

13:01 the assertion is that (keys x) and (vals x) will be in the same order

13:02 scgilardi: I wasn't refuting an assertion.

13:02 amalloy: ah. an educational aside, then? fair enough

13:07 edw: /Is/ it true that the output of KEYS and VALUES will be in the same order?

13:07 scgilardi: right, because it can be confusing when all example maps up to 8 k-v pairs do preserve the order from their construction.

13:07 edw: Ah, so the answer is "no"...

13:07 scgilardi: edw it is true. because for a given map, (seq the-map) has a deterministic order and keys and vals are both based on first constructiong that seq.

13:08 edw: Ah. OK. So the answer is "yes".

13:09 * amalloy desperately wishes he had an excuse to jump in here with a "maybe"

13:09 amalloy: but the answer is yes

13:10 edw: And here's where I should consult the docs, but...: Is that a guarantee of the implementation or just something that's true for now?

13:10 amalloy: but eg if you do something crazy like gather the keys, then assoc a new item, then gather the values, they won't necessarily match at all)

13:10 edw: my understanding is: it's a guarantee, but one that's poorly documented

13:10 edw: amalloy: But then it's not the same hash...

13:10 amalloy: hence "something crazy like"

13:12 gfrlog: amalloy: what's the difference between a poorly documented guarantee and an artifact of the implementation?

13:13 amalloy: gfrlog: rich

13:14 or stu or...someone on the clojure.core team who's said it'll stay that way

13:14 edw: amalloy: I would argue that you don't want to guarantee it, because it encourages inefficient code like (map #(... %1 %2) (keys foo) (values foo)).

13:15 timvisher: hey all

13:15 any clojure lib for url sanitation?

13:16 amalloy: java.net.UrlEncode, i think?

13:16 depending on what you mean by "sanitation"

13:16 edw: What do you want to do? Parse a URL? Create a canonical URL?

13:16 gfrlog: I agree that the (keys) (values) thing seems shaky either way

13:17 timvisher: I want to include a name in a url that might include any character valid on the filesystem (at the very least '?') and i'm running into issues passing that to a url

13:17 something like `Warcraft3-b&w-1024_1024x768.bmp`

13:18 or `And%20the%20Winner%20is?_1366x768.png`

13:18 amalloy: edw: inefficient, but not very. it allows easier code like (zipmap (map inc (keys m)) (vals m)), instead of (into {} (for [[k v] m] [(inc k) v])), which can be easier to think about depending on what you're doing

13:18 edw: timvisher: In JavaScript, at least, there's an "encode URL component" procedure that's distinct from a "encode URL string" procedure in that it escapes more chars e.g. question mark, equals

13:19 ...and ampersand. Look for something like that. It's pretty common,

13:20 timvisher: edw: i know exactly what you're talking about. I use that all the time

13:20 amalloy: $google java net url encode

13:20 sexpbot: First out of 274000 results is: URL (Java 2 Platform SE 5.0)

13:20 http://download.oracle.com/javase/1.5.0/docs/api/java/net/URL.html

13:20 timvisher: i need this to be server side

13:20 amalloy: http://download.oracle.com/javase/1.5.0/docs/api/java/net/URLEncoder.html

13:20 edw: amalloy: True. I'm the sort of anal programmer, however, that binds nearly anything I use more than once in a given scope. I program like CAR and CDR require communicating over the wire to a distant continent.

13:20 jarpiain: gfrlog: we have word of rhickey, http://clojure-log.n01se.net/date/2010-01-18.html#17:09

13:21 amalloy: edw: sure, me too. though i like to try to use HOFs instead of actually creating local bindings

13:21 pdk: cpu cache to main ram is a distant continent!

13:21 edw: timvisher: So does that do what you want?

13:21 amalloy: but it's nice to have multiple ways to do something

13:22 edw: amalloy: True again. Sometimes you just want to club your problem to death. It's OK.

13:22 amalloy: *laugh*

13:22 ataggart: timvisher: ##(java.net.URLEncoder/encode "Warcraft3-b&w-1024_1024x768.bmp" "utf-8")

13:22 sexpbot: ⟹ "Warcraft3-b%26w-1024_1024x768.bmp"

13:23 timvisher: edw amalloy ataggart: yeah. i was hoping for some shiny clojure lib, but that does indeed do the trick.

13:23 amalloy: timvisher: someone's wrapped this up somewhere, but it's not worth the effort of looking for it

13:23 ataggart: it's probably baked into one of the many libraries

13:23 edw: timvisher: Yes, I also interpret mixed case symbols with periods as errors.

13:23 amalloy: clojure takes the stance that if there's something perfectly serviceable in java, just use it

13:24 ataggart: at least until someone gets around to writing something more clojure-y, e.g., clojure.string

13:24 timvisher: edw: indeed. i'm trying to avoid sanitizing the file names if i can, just because i think i can avoid that and it's not a core part of this app

13:24 ilyak: ,(.contains (java.util.Collections/singleton "a") "a")

13:24 clojurebot: true

13:24 ilyak: ,(contains? (java.util.Collections/singleton "a") "a")

13:24 clojurebot: false

13:25 ilyak: wtf? why is that?

13:25 ataggart: contains?

13:25 clojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use the java method .contains

13:25 edw: amalloy: We're in the real world, so my Schemely obsession with orthogonality and clarity is misplaced, but the interaction of #(...) and the Java candied glue sometimes bites me in the buttocks.

13:25 ilyak: ,(contains? #{"a"} "a")

13:25 clojurebot: true

13:25 ilyak: I am rather annoyed that clojure treats java sets as second class citisens

13:25 This is wrong wrong wrong

13:26 ataggart: ilyak: contains? just doesn't mean what you (or most people) think it should mean

13:26 ilyak: ataggart: Why does it work on #{} then?

13:26 ataggart: ilyak: contains? is a check to see if calling get will return a value from the container

13:26 e.g. ##(contains? [1 nil 3])

13:26 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$contains-QMARK-

13:27 ilyak: And besides, if (or most people) sounds like language design error

13:27 ataggart: e.g. ##(contains? {:a nil} :a)

13:27 sexpbot: ⟹ true

13:28 ataggart: ilyak: yes, it seems a weekday doesn't go by that someone doesn't ask about it

13:28 use some intead

13:28 ,(some #{:a} [:a :b :c])

13:28 clojurebot: :a

13:28 ilyak: ,(some (java.util.Collections/singleton "a") "a")

13:28 clojurebot: java.lang.ClassCastException: java.util.Collections$SingletonSet cannot be cast to clojure.lang.IFn

13:29 ataggart: ,(doc some)

13:29 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

13:29 * ataggart checks off "explain contains?" on the daily work sheet

13:30 technomancy: ilyak: it's a badly-named function, no question.

13:30 amalloy: ataggart: i'll schedule you an appointment at 3:00 to explain how you can get a stackoverflow using lazy-seqs

13:30 ataggart: ha!

13:31 technomancy: hehe

13:31 ataggart: technomancy: contains? is a great name if you're only thinking about sets, which apparently was the case

13:32 ilyak: Also, am I the only one person who finds the pair (empty? not-empty) ridiculous?

13:32 amalloy: ilyak: yes. they are different things

13:32 ilyak: how about pair (empty not-empty)

13:32 ataggart: one is a predicate, the other converts empty collections to nil

13:33 ilyak: which are also different things which also smells of a design failure

13:33 scgilardi: I translate "contains?" in my head to "contains-key?"

13:33 ataggart: I translate "contains?" in my head to "will get return me a value that's actually in the collection (including nil)"

13:34 * ataggart doesn't actually ever use contains?

13:34 gfrlog: I translate "contains?" in my head to "don't use that function"

13:34 * hiredman uses contains? all the time

13:34 timvisher: thanks for the pointer everyone, sorry for the googleable question. that worked perfectly.

13:35 amalloy: np, #clojure is just a cluster of google AI machines anyway

13:35 * technomancy was surprised to discover not-empty

13:35 * gfrlog is always surprised to find out about being an AI machine

13:36 hiredman: like, if I have a an atom that is a cache, (swap! cache [some-value] (fn [cache] (if (contains? cache some-value) cache (assoc cache some-value ...))))

13:36 amalloy: technomancy: yeah, not-empty is a nice pair for if-let

13:36 technomancy: clojurebot: you're a replicant, aren't you?

13:36 clojurebot: Pardon?

13:36 technomancy: denial—just as I suspected.

13:37 amalloy: since we're complaining about the language today, i wish sets returned true instead of returning the value

13:38 so that i could do stuff like (filter #{false} [true false]) to look for false items

13:39 ataggart: ,(filter false? [true false])

13:39 clojurebot: (false)

13:39 amalloy: ataggart: yes, yes. special cases are easy

13:39 ataggart: heh

13:39 gfrlog: amalloy: and I wish more side-effect functions returned their arguments instead of nil

13:39 amalloy: &(filter #{false 1} [true 65 1 false])

13:39 sexpbot: ⟹ (1)

13:39 ataggart: yeah, dealing with logical-false values can get funny

13:40 same with nil values inside collections

13:43 amalloy: ataggart: my use case would be easier if sets returned true rather than the element, and i can't think of a case when i've needed to rely on (#{some set} x) returning x

13:44 though i did do well in a code-golf context for using keep instead of filter, when using a set

13:46 ataggart: I guess it's one of those cases where you need to use a custom pred, e.g. #(or (#{...} %) (false? %))

13:49 amalloy: ataggart: only if you know false is in the set

13:49 the general solution is more like (filter #(contains? the-set %) the-coll-to-filter)

13:52 jdsanders: Hi all, is this the best place for questions about clojure-contrib, or is there a separate room?

13:54 I'm playing around with the combinatorics library, specifically the subsets function

13:54 and I'm blowing out memory when trying to do a filter and count of subsets of a vector with around 30 entries

13:54 and I'm not sure why

13:54 gfrlog: jdsanders:

13:54 jdsanders: since subsets is lazy, and filter is lazy

13:54 gfrlog: there are a lot of them

13:55 oh

13:55 jdsanders: what is using the memory?

13:55 gfrlog: how many are you collecting?

13:55 jdsanders: is count actualizing the whole list?

13:55 gfrlog: yes

13:55 don't count a big sequence :)

13:55 jdsanders: there is no way to count a big sequence...?

13:55 I understand why the runtime may be long

13:55 b

13:55 ut

13:56 count wouldn't need to hold onto head so it shouldn't need much memory no?

13:56 gfrlog: right

13:56 so if you don't have the head you'll be okay, just run a while

13:56 be careful with things like (def my-seq (subsets ...)) vs (defn my-seq [] (subsets ...))

13:56 jdsanders: how do I make sure I don't have the head, I didn't think I would, but I guess I must

13:57 yeah I didn't def any of the sequences besides the original vector

13:57 gfrlog: jdsanders: just gotta be careful. if you link to some code we can look at it

13:57 jdsanders: (def numbers [ 1 2 3 ...

13:57 (count (filter #(< 4 (count %1)) (clojure.contrib.combinatorics/subsets numbers)))

13:58 gfrlog: jdsanders: on a side note, doing that manually will probably be much faster

13:59 well. not probably. it will be much faster.

13:59 jdsanders: you mean rather than grabbing all subsets and filtering, only getting subsets of size less than 4 in the first place?

13:59 gfrlog: also there's a formula for it :)

13:59 jdsanders: ah

13:59 yeah

13:59 well I simplified my example

13:59 gfrlog: okay

13:59 jdsanders: basically the anonymous function is replaced with something non-trivial

13:59 gfrlog: as long as you're aware of the number of total subsets...

13:59 okay

13:59 jdsanders: yeah for sure

13:59 that's precisely why I thought clojure would be excellent with it

13:59 because of laziness

14:00 just can't figure out how to throw away the memory I no longer care about :)

14:00 gfrlog: it looks good to me.

14:00 rpg: Has anyone used MCLIDE with Clojure? I was thinking about that as an easier path to starting up than using SLIME....

14:01 jdsanders: gfrlog: ok thanks, harumph!

14:01 i also have trouble using last rather than count

14:01 though things working from the front are ok

14:02 which I suppose is the way "holding onto head" always manifests...

14:06 tnovelli: Is anyone working on a native x86 or ARM implementation of Clojure?

14:07 or even LLVM...?

14:07 pjstadig: not as far as i know

14:07 i'm not sure it's even really on the radar

14:10 tnovelli: so CinC is basically about cleaning up the JVM implementation and making it easier to support .NET?

14:11 hiredman: it's about self hosting, ensuring clojure provides a rich enough implementation to self host

14:12 e.g. all the power and abstractions needed to write the runtime are available in the language

14:12 tnovelli: at least that'd make it easier to add a native code back-end

14:12 hiredman: i.e. I guess

14:12 technomancy: rpg: slime is about to be several orders of magnitude easier to set up.

14:12 hiredman: *shrug* people keep saying that, but there are no plans anywhere for a naitive backend

14:12 tnovelli: speaking of editors, anyone here use VIM for Clojure?

14:13 hiredman: naitive code is just not a very good host

14:14 tnovelli: you mean it's a lot more work :)

14:16 hiredman: tnovelli: I mean, you would need to implement half a buggy jvm, why bother?

14:16 tnovelli: I know Clojure really leans on Java, but it could be adapted to a C/POSIX environment, or anything really..

14:17 hiredman: tnovelli: doesn't come with gc, or a standard threading library, or java.util.concurrent, etc

14:17 tnovelli: suppose you don't want anything to do with the JVM, you just want a better Lisp.

14:17 hiredman: tnovelli: you would be better servered asking why you want nothing to do with the jvm

14:18 rpg: technomancy: My problem with the SLIME setup is setting up SLIME for Clojure without breaking SLIME for Common Lisp.,

14:18 hiredman: the jvm is a sweet piece of tech to be leveraged

14:19 technomancy: rpg: oh, ok. that's a lot harder.

14:19 hiredman: people tend to have bad experiences with Java then ignore anything that starts with a J

14:19 the jvm is not java, and gives you way too much as a platform to just ignore

14:19 tnovelli: hiredman: I think bytecode VMs in general are an unnecessary layer. JVM, CLR, LLVM, Smalltalk, you name it.

14:20 rpg: technomancy: I use CL every day for the stuff that pays the bills, so breaking it is a problem for me.

14:20 edw: But if only the face-palm inducing early design and implementation decisions with the standard classes could be quarantined or exiled...

14:20 technomancy: rpg: understood; swank just needs someone who's CL-savvy to step up and do the leg-work of making it compatible.

14:21 hiredman: tnovelli: what alternative do you propose then? compiling for each target arch seperately?

14:21 tnovelli: hiredman: I'm speaking about principles here, not practical enterprisey programming.

14:21 rpg: technomancy: I think there's also the problem that SLIME doesn't have versioning, so it's hard to avoid getting at least one of CL and Clojure broken!

14:21 (i.e., no release versions)

14:21 technomancy: rpg: yeah, if they just released proper versions like the big kids this would be a lot easier

14:22 rpg: that said, my upcoming hacks could let you use the CVS trunk version normally and then have the clojure-compatible version get loaded just for when you want to use Clojure

14:22 so it would taint the instance, but it would work.

14:24 hiredman: tnovelli: what problem do you perceive that your principles address?

14:24 tnovelli: hiredman: yes, you have a small 'kernel' of primitive functions to implement in assembly on any given platform, and write the rest in Clojure.

14:24 hiredman: :(

14:24 ataggart: implementing a GC in assembly?

14:25 hiredman: tnovelli: why? what is the point? what do you gain from that, besides making it monumentally difficult to implement languages

14:25 tnovelli: maybe a bit of inline asm... you can write most of a GC in Clojure itself..

14:25 dnolen: tnovelli: is there any language that you are aware of that uses your strategy that actually works across the heterogenous landscape of platforms?

14:26 hiredman: throwing away all of the optimizations the jvm does

14:26 ataggart: tnovelli: patches welcome

14:26 tnovelli: JVM is a shortcut. A perfectly legitimate one, but you're stuck with all of Sun's design decisions.. no tail recursion, etc.

14:26 hiredman: it's just a horrible idea, but don't let that stop you from doing it, just use your own irc channel to discuss it

14:27 tnovelli: yeah, I didn't come here to argue. Just wondered if anyone here was doing it.

14:27 It's a big project and I probably won't bother, but it's a thought.

14:27 dnolen: tnovelli: everything besides the JVM would require 20 years of effort. See Haskell.

14:28 tnovelli: Haskell's an academic project. Different goals.

14:29 hiredman: why?

14:29 clojurebot: http://clojure.org/rationale

14:29 hiredman: tnovelli: -^

14:29 dnolen_: tnovelli: many people would disagree w/ that claim.

14:29 tnovelli: people are interested in seeing Clojure run elsewhere, but a lot of other things need to get lined up first.

14:29 rpg: technomancy: There's a guy at our user group who forked the SLIME and renamed all its functions, so that it could be used without tainting the instance.

14:30 technomancy: https://github.com/bigfoote/slclj

14:31 technomancy: rpg: I've thought of that. I guess I'm not totally ready to give up on upstream compatibility, but I'm also not ready to do the grunt work of making it work.

14:31 if only elisp had modules =\

14:32 edw: technomancy: Sacre bleu! Then Emacs might someday not be the world's largest ball of mud.

14:33 rpg: technomancy: Isn't there a fair amount of work making clojure output masquerade as CL output?

14:35 technomancy: rpg: TBH I don't even know how much work it is. my knowledge of swank is pretty superficial

14:37 hiredman: rpg: swank actually sends back something like (print "{:a 1}") which is valid for both clojure and cl

14:37 and emacs lisp

14:38 rpg: technomancy: OK, thanks. Anyway, you can see why I was hoping that I could just get MCLIDE to work...

14:38 hiredman: the only real munging is for namespaced symbols

14:38 swank-clojure has to do stuff like rewrite foo:bar as foo/bar

14:38 rpg: hiredman: I was just typing "I had trouble where it would blow up for me with namespaced symbols..."~

14:39 technomancy: I'm a weirdo since I launch new emacs instances all the time, so the problem is a lot easier to solve in that case.

14:39 hiredman: but it doesn't even actually have to do that, just a design decision

14:40 ,foo:bar

14:40 clojurebot: java.lang.Exception: Unable to resolve symbol: foo:bar in this context

14:40 hiredman: valid symbol

14:40 tnovelli: hiredman, dnolen_: I see the part about VMs... the only part I disagree with is bytecode. There's an "abstract VM" idea, which might look sort of like core Lisp, like an uber-language (I'm not totally sold on that either)

14:41 Anyway, I'll definitely try some serious Clojure hacking under JVM before I seriously think about writing a compiler :)

14:42 hiredman: tnovelli: if you really want, I would suggest taking something like maxine and trying to rewrite it in clojure

14:42 ~maxine

14:42 clojurebot: maxine is http://research.sun.com/projects/maxine/

14:43 tnovelli: who'd Oracle buy that from?

14:43 hiredman: sun

14:43 a long with the rest of sun

14:43 pjstadig: oracle bought sun!!?!

14:43 tnovelli: and are you at Oracle now?

14:44 pjstadig: there's also jikes rvm or something

14:44 hiredman: pjstadig: crazy, right?

14:44 pjstadig: similar project to maxine

14:44 technomancy: pjstadig: you may want to sit down for this...

14:44 hiredman: pjstadig: jamvm

14:44 tnovelli: JikesRVM, yeah.. wow :)

14:44 hiredman: jikes is actually just a compiler, no?

14:44 tnovelli: pretty sure it's a VM

14:44 pjstadig: eh no there's a vm project

14:45 tnovelli: grew out of a parser project 20 years ago, apparently

14:46 pjstadig: technomancy: i kno... next you'll be telling me that M$ bought Skype or something

14:46 edw: There was a recent article linked to from Hacker News that discussed the GC styles of the three major JVMs: Hotspot, WebLogic, and the IBM one...

14:47 opqdonut_: what, is Jikes still alive?

14:47 or is "the IBM one" for their mainframes

14:49 edw: Hold on...

14:52 tnovelli: looks like Jikes is still maintained, and parts (like the GC) have been extracted

14:53 edw: Can't find the link, but IBM has a server JVM for webapps. WebSphere?

14:53 pjstadig: what is jrockit isn't that another JVM?

14:54 edw: Dunno. (Again, I wince when I see mixed case symbols and periods in Clojure code.)

14:54 hugod: hiredman: swank-clj 0.1.3 includes a basic frame disassembler - still need to add lookup of class statics and add a bit of unmangling

14:56 edw: It seems to me that "the JVM issue" has more to do with dependencies on crufty Java libraries than on the JVM in particular, though there are irritating issues like the JVM's difficulty with properly handling tail calls.

14:56 hiredman: hugod: wow

14:56 hugod: thought you'ld like that…

14:57 technomancy: edw: for me the pain points are primarily about the inflexibility of the classpath and the boot time.

14:59 tnovelli: edw: ahh. Yeah, every 'platform' has crufty libraries.. GNOME, KDE, Microsoft.. Python, if you call that a platform. It's getting ridiculous.

14:59 * dnolen_ wonders why someone hasn't implemented Clojure Light on top of Racket yet ...

14:59 tnovelli: hehe

15:00 pjstadig: technomancy: +1

15:00 edw: technomancy: It drives me nuts that I have to bounce the VM just because I added a dependency. I want to measure my REPLs uptime in months.

15:01 dnolen_: Speaking of PLT, is Arc anything more than just some really obstuse syntactic sugar atop Racket?

15:02 tnovelli: edw: that's all it is!

15:02 edw: s/obstuse/obtuse/

15:02 sexpbot: <edw> dnolen_: Speaking of PLT, is Arc anything more than just some really obtuse syntactic sugar atop Racket?

15:02 edw: tnovelli: Are you joking or serious?

15:03 tnovelli: serious. it's a snarfed implementation. unless something's changed in the last year or two.

15:03 not that there's anything wrong with snarfing :)

15:04 edw: The Schemer in me would like to see Clojure's #{} and {} and the cleaned-up LET and COND syntax baked into Scheme, enough that I've considered porting Clojure's reader to Scheme...

15:06 It's time Scheme used those curly braces for something useful.

15:08 tnovelli: yeah really :) When I was coding a little lisp-ish compiler last year I borrowed from Clojure and Arc... not Scheme or CL.

15:09 dnolen_: ewd: I'm not familiar w/ Arc. However, Racket does have persistent data structures, threads, continuations, tail call optimization. Seems like the easiest Clojure target really.

15:09 also good FFI

15:10 edw: dnolen_: I see Clojure as "Scheme, beaten into submission by reality."

15:11 tnovelli: hey, Racket has some kind of native code implementation.. actually I think it's just got its own bytecode VM, and Lightning JIT

15:11 edw: that's pretty accurate :)

15:12 dnolen_: edw: not totally accurate. The protocol oriented nature of Clojure is a real trump card on many Lisps.

15:12 tnovelli: all that hygiene and language-tower stuff in Racket is much too clever for me

15:13 KirinDave: tnovelli: Don't sell yourself short.

15:13 None of it is terribly complex.

15:13 edw: I like hygiene. I actually like SYNTAX-RULES.

15:13 KirinDave: edw: +1

15:13 tnovelli: Clojure still doesn't have macros, does it?

15:13 edw: Has someone written SYNTAX-RULES for Clojure?

15:13 KirinDave: It does

15:13 edw: tnovelli: Yes, messy ones.

15:14 KirinDave: edw: Someone was working on something like it

15:14 Actually clojure macros are more hygenic than common lisp macros.

15:14 And their gensym syntax is way nicer.

15:15 edw: KirinDave: Why aren't they just porting the portable Scheme implementation? It should be like a one day job. (And hear you re: GENSYM.)

15:17 tnovelli: Well, I've gotta run.. nice chatting with you guys.

15:18 edw: Spater

16:00 kotarak: How do I override a method of a proxy on a per instance basis?

16:01 amalloy: um. create a new proxy with different overrides?

16:02 kotarak: hmm.. I heard rumors, that it is possible, and was actually quite surprised.

16:02 So maybe I'll skip that part.

16:04 amalloy: &(doc update-proxy)

16:04 sexpbot: ⟹ "([proxy mappings]); Takes a proxy instance and a map of strings (which must correspond to methods of the proxy superclass/superinterfaces) to fns (which must take arguments matching the corresponding method, plus an additional (explicit) first arg corresponding to t... http://gist.github.com/975239

16:05 kotarak: amalloy: ah! thanks. I knew I was missing it.

16:05 amalloy: kotarak: there's that, but unless you need to *change* mappings of an existing proxy, you should just figure out what you want to override when you create the proxy

16:06 kotarak: It's just for a talk. For differences with proxy and reify.

16:07 amalloy: I think, I think too static for such dynamic behaviour....

19:30 gfrlog: $findfn [1 2 3] [[1 2] [2 3]]

19:30 sexpbot: []

19:31 gfrlog: $findfn [1 2 3] 2 [[1 2] [2 3]]

19:31 sexpbot: []

19:31 amalloy: &(partition 2 1 [1 2 3])

19:31 sexpbot: ⟹ ((1 2) (2 3))

19:31 gfrlog: $findfn [1 2 3] 2 1 [[1 2] [2 3]]

19:31 sexpbot: []

19:31 gfrlog: ah right

19:31 backwards

19:31 amalloy: indeed

19:31 gfrlog: amalloy: thx

19:31 amalloy: $findfn 2 1 [1 2 3] [[1 2] [2 3]]

19:31 sexpbot: [clojure.core/partition]

19:32 gfrlog: let's start a kickstarter project to finance a patch to sexpbot that will check alternate argument orderings

19:33 amalloy: gfrlog: knock yourself out. for three args there are only six orderings, so it's not like it's slow

20:07 no_mind: I am using enlive. I have a template in which I want to render some html in inside a div (id of div known). The html to be rendered is present in another file. How do I do this ?

20:14 akhudek: been a while, but I think you use can use defsnippet or deftemplate

20:16 no_mind: problem with defsnippet is that it will use selectors. I want the html from other file to be rendered as is

20:18 akhudek: just wrap it in some parent div and select the parent

20:20 ouch, so apparently I managed to create a memory leak :/

20:21 anyone have any tips on how to track these things down? I've managed a heap dump and found a referrer chain: http://pastebin.com/B5iPYYry

20:21 but it's not clear to me what is going on here

20:22 there should be no data allocated at all at this point

20:22 well, not of the alphabet type at least

20:22 amalloy: don't use finalizers

20:23 (if that's what you're doing)

20:23 akhudek: None of my code is doing that, although I've wrapped things from the MALLET library.

20:28 no_mind: wrapping in div's is not an option always.. I am looking for something like subtemplating

20:35 akhudek: no_mind: I've only ever done it with selectors. You could also try to see if there is a selector to match everything.

20:35 maybe :* ?

20:38 hmm, it looks like the memory leak is actually in MALLET

20:55 kiras: i've read that in clojure, data is often stored as .clj files as clojure code. does this mean that if, for example, i were writing a program to keep track of books and allow searching through them, i might have a file like books.clj, containing several maps like {:title "" :author "" :genre "" :data-published ""} and so on? it might even make sense to have all of these maps inside a vector or something?

20:57 dnolen: kiras: that works for simple things yes. nothing wrong w/ using a database either.

20:58 kiras: dnolen: ok, i'll have to look into whether a database is a better solution for my needs or not, but part of what i'm wondering is, it seems like a large part of the reason to store data in this way is to avoid having to write custom parsers for data files, right? since clojure should be able to parse these maps already?

20:59 dnolen: kiras: yes, if what your requirements are modest along the lines of JSON / yaml, then just storing Clojure data is great.

21:00 akhudek: just be careful about sanitizing that data if you are writing it based on user inputs!

21:00 kiras: dnolen: i'm not familiar with either JSON or yaml, unfortunately

21:00 akhudek: noted :)

21:01 dnolen: kiras: are you going to store many records? are you going to update this file often? if yes to both just use a db.

21:04 kiras: what i'm interested in at the moment is, how does one generally load/process these .clj data files? it doesn't seem like it would make sense to read each line as a string. i read a brief discussion on the mailing list where it looked like use of read or read-string was suggested? is that the typical way of reading .clj data files or is there a more typical way? do you know of a good page discussing this?

21:04 dnolen: i don't expect to update it very often, but i do expect to have a lot of records.

21:05 technomancy: kiras: the short version is: you use read-string+slurp if you know the data is going to be very small, you use reader+read if you need to process it lazily.

21:08 kiras: technomancy: ok, i'll do some searches on that. you don't happen to know of a site with a good explanation of this somewhere, do you?

21:17 amalloy: kiras: it's easiest to have the file look like [{:title blah, :pages 300}, {...}], because then you can just (read) the single object

21:23 kiras: amalloy: that seems to make sense. i found this page http://nakkaya.com/2009/11/01/clojure-persistence-for-java-programmers/ that seems like it explains the read-string+slurp method, now i'm looking for one explaining the reader+read method.

21:23 i have a feeling either reader+read or a database might be necessary for what i'm trying to do, since i will have a fair amount of records to deal with.

21:23 amalloy: kiras: the tricky part (for me) of reader is getting a PushbackReader, which the reader demands

21:24 i think you can just do (with-open [pb (java.io.PushbackReader. (clojure.java.io/reader "the-file-name"))] (read pb)), but i don't do this often

21:26 kiras: hey, i was right, that seems to work

21:26 kiras: amalloy: nice. i'll have to try that out.

21:27 amalloy: what do you mean by "the tricky part"? that it's tricky because you don't do it often or that there's actually something difficult about it that i should be aware of?

21:28 amalloy: the former

21:28 kiras: amalloy: ok :)

21:28 amalloy: it's also easy to forget that you even *need* a pushbackreader

21:29 kiras: amalloy: i see. so if you don't find yourself doing this often, what is it that you usually do as an alternative?

21:29 amalloy: haha i don't read a lot of files, i guess

21:29 kiras: amalloy: lol neither do i, usually

21:29 amalloy: this is the technique to use, afaik

21:35 kiras: well, i'm going to take a break. thanks for the help, everyone. :)

22:41 symbole: Is it possible to interoplate a symbol inside another symbol, e.g., `(defn ~foo?, where foo is a parameter to the macro. I'm tring to generate a predicate by attaching a ? to whatever was passed to the macro.

22:44 amalloy: &(let [name 'foo] `(defn ~(symbol (str foo "?"))))

22:44 sexpbot: java.lang.Exception: Unable to resolve symbol: foo in this context

22:44 amalloy: &(let [name 'foo] `(defn ~(symbol (str name "?"))))

22:44 sexpbot: ⟹ (clojure.core/defn foo?)

22:44 symbole: Oh, right. I can just write it outside `.

22:45 Thanks.

22:46 amalloy: welcome

23:05 does https://github.com/clojure/data.xml imply that there's no equivalent of clojure.contrib.pr-xml available on the 1.3 alphas?

23:05 symbole: (defmacro bar[] `(defn g[]) `(defn g?[])). After evaluating (bar) it seems that g? is defined, but g isn't. What's happening there?

23:05 amalloy: wrap them in a do

23:06 you're evaluating the first form (which evaluates to a list, remember) for side effects, then returning the second form as the one to macroexpand

23:07 symbole: Right. Thanks again.

23:09 amalloy: So is a do really necessary? Without the due, won't it evaluate the first list as a side-effect, and then return the last one for macro expansion?

23:09 amalloy: symbole: yes to both questions

23:09 it *constructs* the list, but doesn't evaluate it

23:10 because only the thing returned from the macroexpansion gets fed to the compiler

23:10 you may have misunderstood my recommendation, though

23:10 (defmacro bar [] `(do (defn g []) (defn g? []))) will work

23:11 (defmacro bar [] (do `(defn g []) `(defn g? []))) won't; it's identical to your previous version

23:12 the first of those is saying: "this macro means: do these two things!"

23:12 the latter is more like: "this macro means: do the last thing here. i had to compute that other thing in order to decide on this answer, but i'm not telling you about it"

23:13 symbole: I see.

23:15 I need to be more careful.

23:15 amalloy: it can take some work to get the different scopes straight in your head

23:17 tomoj: any less confusing written this way? (let [form-a `(defn g []) form-b `(defn g? [])] (defmacro bar [] (do form-a form-b)))

23:20 symbole: tomoj: Pretty much the same. I was simply confused about maco expantion time and evaluation time.

23:38 scottj: alternatives to cc.def's defnk? (looking for one that allows concise default values for non-keyword optional args)

23:39 technomancy: sneak preview: http://p.hagelb.org/slime-in-60-seconds.webm

23:39 gertalot: I wrote a with-defaults macro the other day

23:39 scottj: maybe this is useful? http://gertalot.com/2011/04/29/named-arguments-with-defaults/

23:43 scottj: technomancy: does clojure-mode install slime via elpa?

23:43 technomancy: scottj: no, via lein, sorta

23:44 scottj: https://github.com/technomancy/swank-clojure/blob/master/src/leiningen/jack_in.clj

23:44 scottj: ok so in this scenario you'd just git clone clojure-mode?

23:44 technomancy: scottj: git or marmalade, yeah

23:45 scottj: only changes that would have been nice I think would be to first show git cloning clojure-mode and maybe installing lein (if there's a one-liner for that)

23:45 might be hard to hit 60seconds then :)

23:46 technomancy: yeah, maybe show the marmalade installation

23:46 scottj: marmalade one would be more complicated than git clone, but maybe you prefer ppl to use that method. cause marmalade you'd have to show install package for non-24 plus repo etc

23:47 of course w/o I guess I forgot load-list and require lines

23:47 anyway, cool vid

23:48 technomancy: thanks

23:48 huge difference vs doing everything through package.el I think

23:50 scottj: btw your recent s/start-repl/start-swank commit doesn't fix swank so it works in lein swank, foo situation? I didn't look closely at it

23:53 hugod: technomancy: I like the elisp injection idea :)

23:54 being able to keep .el files rather than embed them in .clj seems like a win

23:54 technomancy: hugod: it would make it a lot easier to break compatibility with elpa slime if we ever need to

23:55 scottj: no, that's separate. not sure how to switch between blocking/non-blocking tasks

23:58 scottj: hugod: what is the motivation for your swank debug fork over jahad's recent work?

23:58 hugod: scottj slime debugger integration

23:59 scottj: so jahad's recent stuff into swank doesn't use the slime debugger UI?

23:59 btw does yours use jahad's stuff underneath for stepping?

23:59 hugod: as far as I know it uses GUD, though I could be wrong…

Logging service provided by n01se.net